@slithy/layers
v0.4.1
Published
Layer and z-index management for React UIs.
Readme
@slithy/layers
Layer and z-index management for React UIs. Tracks a stack of mounted layers and determines which is "active" (highest priority). Useful for managing focus, keyboard interactions, and visual stacking of overlaid components like modals and drawers.
Installation
npm install @slithy/layersPeer dependencies: react@^17 || ^18 || ^19
LayerProvider
Wraps a component to register it in the global layer stack. On mount, the layer is added to the stack; on unmount, it is removed.
import { LayerProvider, LayerStackPriority } from "@slithy/layers";
<LayerProvider id="my-modal" zIndex={LayerStackPriority.Modal}>
<MyModal />
</LayerProvider>;Props:
| Prop | Type | Default | Description |
| ---------- | ----------- | -------------- | ------------------------------------------------ |
| id | string | auto-generated | Unique identifier for this layer |
| zIndex | number | 0 | Priority in the stack — higher wins |
| isActive | boolean | true | If false, layer is not registered in the stack |
| children | ReactNode | — | |
useLayerState
Hook to read state from the nearest LayerProvider. Must be called within a LayerProvider.
// Selector form — returns selected value, re-renders only on change
const layerIsActive = useLayerState((s) => s.layerIsActive);
// No-arg form — returns full store object
const { getState, setState } = useLayerState();Store shape (LayerStore):
type LayerStore = {
layerId: string;
layerIsActive: boolean; // true when this layer has the highest priority
zIndex: number;
};useLayer
Convenience hook to read the current layer's ID and zIndex from the nearest LayerProvider. Must be called within a LayerProvider.
import { useLayer } from "@slithy/layers";
const { layerId, layerZIndex } = useLayer();Returns:
{
layerId: string; // ID of the current layer
layerZIndex: number; // zIndex of the current layer
}useLayerStackStore
Reactive hook for reading the global layer stack store. Call with a selector to get reactive updates whenever the layer stack changes.
import { useLayerStackStore } from "@slithy/layers";
// Selector form — re-renders only when the selected value changes
const activeLayerId = useLayerStackStore((state) => state.activeLayerId);
// Full store object — returns current state
const { activeLayerId, layers } = useLayerStackStore((state) => state);For imperative access (outside React components or in effects):
// Read current state
const { activeLayerId, layers } = useLayerStackStore.getState();
// Subscribe to changes
const unsubscribe = useLayerStackStore.subscribe(() => {
const { activeLayerId } = useLayerStackStore.getState();
});useActiveLayer
Convenience hook to read the active (topmost) layer's ID and zIndex from the global layer stack.
import { useActiveLayer } from "@slithy/layers";
const { activeLayerId, activeZIndex } = useActiveLayer();Returns:
{
activeLayerId: string; // ID of the layer with highest priority
activeZIndex: number; // zIndex of the active layer
}createLayerPriorities
Factory for defining a custom set of layer priorities. Returns a frozen readonly object.
import { createLayerPriorities } from '@slithy/layers'
const MyPriorities = createLayerPriorities({
App: 0,
Overlay: 5,
Toast: 10,
})
<LayerProvider zIndex={MyPriorities.Toast}>
<ToastStack />
</LayerProvider>LayerStackPriority
The built-in default priority set, defined with createLayerPriorities:
const LayerStackPriority = createLayerPriorities({
App: 0,
Modal: 1,
Toasts: 2,
});MockLayerProvider
A test utility that provides a mock layer context with hardcoded values. Use this to render components that depend on LayerProvider without needing a real stack.
import { MockLayerProvider } from "@slithy/layers";
render(
<MockLayerProvider>
<ComponentUnderTest />
</MockLayerProvider>,
);