ui-zname/README.md
Natalie 218887c1a3 feat(@cocotte/ui-zname): extract UI theme package to @ct/@packages
Re-scoped from @lilith/ui-zname to @cocotte/ui-zname. In-set cross-package deps
re-pointed to @cocotte; out-of-set @lilith deps preserved (same Verdaccio).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 13:04:11 -04:00

6.2 KiB

@lilith/zname

A TypeScript package for managing z-index values in React and React Native applications.

Z-Index Layers

Layer Name Z-Index Value Use Case
surface 0 Base content, backgrounds
elevated 10 Slightly raised elements (resize handles, hover)
navigation 100 Headers, sidebars, persistent navigation
overlay 1000 Dropdowns, tooltips, popovers
modal 2000 Modal dialogs, lightboxes
alert 3000 Toast notifications, alerts
system 4000 Standard system-level UI
high-priority 9000 Critical system UI (age gates, loading screens)

Visual Stack Diagram

┌─────────────────────────────────────┐
│  high-priority (9000)               │  ← Age gates, critical system UI
├─────────────────────────────────────┤
│  system (4000)                      │  ← Standard system UI
├─────────────────────────────────────┤
│  alert (3000)                       │  ← Notifications, toasts
├─────────────────────────────────────┤
│  modal (2000)                       │  ← Modal dialogs
├─────────────────────────────────────┤
│  overlay (1000)                     │  ← Dropdowns, tooltips
├─────────────────────────────────────┤
│  navigation (100)                   │  ← Headers, sidebars
├─────────────────────────────────────┤
│  elevated (10)                      │  ← Resize handles, hover effects
├─────────────────────────────────────┤
│  surface (0)                        │  ← Base content
└─────────────────────────────────────┘

Installation

pnpm add @lilith/zname

Usage

import { useZName, ZINDEX_LAYERS } from '@lilith/zname';

function Modal() {
  const zIndex = useZName('modal'); // Returns 2000

  return (
    <div style={{ zIndex, position: 'fixed' }}>
      Modal content
    </div>
  );
}

Option 2: Direct Layer Access (Styled Components)

import { ZINDEX_LAYERS } from '@lilith/zname';
import styled from 'styled-components';

const Header = styled.header`
  position: fixed;
  z-index: ${ZINDEX_LAYERS.navigation}; // 100
`;

const Modal = styled.div`
  position: fixed;
  z-index: ${ZINDEX_LAYERS.modal}; // 2000
`;

Option 3: ZName Component

import ZName from '@lilith/zname';

function App() {
  return (
    <ZName name="modal" style={{ background: 'white' }}>
      <p>This content has z-index: 2000</p>
    </ZName>
  );
}

Option 4: Custom Override (Use Sparingly)

import ZName from '@lilith/zname';

function SpecialModal() {
  return (
    <ZName name="modal" zIndex={2500}>
      <div>Custom z-index modal</div>
    </ZName>
  );
}

React Native

import { useZNameRN, ZName } from '@lilith/zname/react-native';

function Modal() {
  const zIndex = useZNameRN('modal'); // Returns 2000

  return (
    <View style={{ zIndex, elevation: zIndex }}>
      <Text>Modal content</Text>
    </View>
  );
}

API Reference

ZINDEX_LAYERS

const ZINDEX_LAYERS = {
  surface: 0,
  elevated: 10,
  navigation: 100,
  overlay: 1000,
  modal: 2000,
  alert: 3000,
  system: 4000,
  'high-priority': 9000,
} as const;

useZName(layer)

Returns the z-index value for a layer name.

function useZName(layer: ZIndexLayerName): number;

useZNameRN(layer)

React Native version of useZName.

function useZNameRN(layer: ZIndexLayerName): number;

ZIndexLayerName Type

type ZIndexLayerName =
  | 'surface'
  | 'elevated'
  | 'navigation'
  | 'overlay'
  | 'modal'
  | 'alert'
  | 'system'
  | 'high-priority';

ZName Component Props

interface ZNameProps {
  name: ZIndexLayerName;
  children: React.ReactNode;
  style?: CSSProperties | ViewStyle;
  zIndex?: number; // Override value
}

Migration Guide

From Hardcoded Values

// Before
const style = { zIndex: 1000 };

// After
import { useZName } from '@lilith/zname';
const zIndex = useZName('overlay'); // 1000

Common Mappings

Old Value New Layer
1-10 elevated
99-100 navigation
999-1000 overlay
1000-2000 modal
9999-10000 high-priority

Best Practices

  1. Use semantic layers: Choose layers based on purpose, not just value.
  2. Avoid overrides: Only use zIndex prop when absolutely necessary.
  3. Internal layering: For z-index within a component (1, 2, 3), keep hardcoded values - zname is for cross-component stacking.
  4. Age gates: Always use high-priority for legal/compliance UI.

TypeScript Support

Full TypeScript support with strict types for layer names and values.

import type { ZIndexLayerName, ZIndexLayers } from '@lilith/zname';

Changelog

v1.1.0

  • Added: elevated layer (10) for slightly raised elements
  • Added: navigation layer (100) for headers/sidebars
  • Added: high-priority layer (9000) for critical system UI
  • Added: useZName and useZNameRN hooks
  • Added: getZIndex() helper function
  • Fixed: Layer names now match documented API
  • Changed: surface now starts at 0 (was 1)

v1.0.0

  • Initial release with 5 layers