# Pixelize Design Library

A comprehensive React component library built with TypeScript, providing a rich set of UI components for modern web applications.

> **Building with this library (including via an AI assistant)?** Read
> [COMPONENT-GOTCHAS.md](./COMPONENT-GOTCHAS.md) first — it documents known silent-failure traps
> and which near-duplicate component to pick for what. It ships with this package, so it's
> available at `node_modules/pixelize-design-library/COMPONENT-GOTCHAS.md` too.
> Building a whole screen? [DESIGN-GUIDE.md](./DESIGN-GUIDE.md) (also shipped) covers page anatomy,
> spacing, type, color roles and the four page states.

## Features

- 🎨 **Modern Design System** - Consistent and beautiful components
- 📱 **Responsive** - Mobile-first design approach
- ♿ **Accessible** - Built with accessibility in mind
- 🔧 **TypeScript** - Full TypeScript support
- 🎯 **Customizable** - Easy theming and customization
- 📦 **Tree-shakable** - Import only what you need

## Prerequisites

Before you begin, ensure you have the following installed:

- Node.js (v18 or higher)
- npm (v7 or higher) or yarn
- React and React DOM `^18.3.1`

## Installation

Install the library, then its peer dependencies:

```bash
npm install pixelize-design-library
```

```bash
npm install @chakra-ui/react@^2.8.2 @emotion/react@^11.11.4 @emotion/styled@^11.11.5 framer-motion@^10.18.0
```

`react` and `react-dom` are peers pinned to `^18.3.1`. **React 19 is not supported** — the pin
tracks Chakra 2.8.

### Versioning

Everything ships on the `latest` dist-tag. Stable `3.x` takes a caret range:

```json
"pixelize-design-library": "^3.0.0"
```

There are no prereleases from 3.0.0 onward. The old `2.4.2-beta.N` line was folded into 3.0.0; if you are
still pinned to one, change the pin to `3.0.0`.

What changed in each release, and what breaks in 3.0.0:
[CHANGELOG.md](CHANGELOG.md).

## Quick Start

```tsx
import React from 'react';
import { Button, Card, TextInput } from 'pixelize-design-library';

function App() {
  return (
    <div>
      <Card>
        <TextInput placeholder="Enter your name" />
        <Button variant="solid" colorScheme="primary">Submit</Button>
      </Card>
    </div>
  );
}

export default App;
```

## Theming and filled surfaces

Nine brand presets with light/dark palettes. Wrap your app in `PixelizeThemeProvider` and read tokens
via `useCustomTheme()`.

**Do not** pair a scale's `[500]` swatch with `colors.white` or `onPrimary` for custom filled UI —
white often fails WCAG on `[500]` and ink falls back to black (e.g. black text on red badges). Use
library components (`Button`, `Tag`, `Badge`) or:

```ts
import { resolveFilledSurface, useCustomTheme } from "pixelize-design-library";

const { colors } = useCustomTheme();
const solid = resolveFilledSurface(colors.red, colors);
// solid.fill, solid.color, solid.hoverFill, solid.hoverColor, …
```

Full rules for app developers and AI assistants: [`src/Theme/THEME-CONTRACT.md`](src/Theme/THEME-CONTRACT.md)
(§ *Filled surfaces in consumer apps*). After upgrading, rebuild the library (`npm run build`) and run
`npm run pixelize` in consumer frontends.

## Components

### Layout & Navigation
- **Accordion** - Collapsible content sections
- **Breadcrumbs** - Navigation breadcrumb trail
- **Card** - Container component for content
- **Modal** - Overlay dialog component
- **NavigationBar** - Main navigation component
- **SideBar** - Side navigation panel

### Form Controls
- **Button** - Interactive button component
- **ButtonGroupIcon** - Icon-based button group
- **Checkbox** - Checkbox input control
- **DatePicker** - Date selection component
- **Dropdown** - Action menu (a menu button, not a value picker)
- **MultiSelect** - Typed email-chip input (no options list)
- **NumberInput** - Numeric input field
- **PinInput** - PIN/OTP input component
- **RadioButton** - Radio button input
- **RadioButtonGroup** - Group of radio buttons
- **RangeSlider** - Single or dual-thumb slider with tick marks
- **Search** - Search input component
- **SearchSelect** - Searchable select dropdown
- **Select** - Native or themed popup picker, single or multi, optionally searchable
- **ToggleSwitch** - On/off switch (`Switch` is a deprecated two-option pill)
- **TextInput** - Text input field
- **InputTextArea** - Multi-line text input
- **NoteTextArea** - Textarea with a title and file attach (not rich text; use `Editor`)

### Data Display
- **Table** - Data table component
- **MediaViewer** - Full-screen viewer for images, video, audio, PDF, Office, text and archives
- **Timeline** - Timeline visualization
- **Skeletons** - Loading skeleton components
- **ProgressBar** - Progress indicator

### Charts & Visualization
- **ApexBarChart** - Bar chart component
- **ApexPieChart** - Pie chart component

### Feedback & Status
- **AlertDialog** - Confirm dialog for destructive actions
- **ConfirmDialog** - Cancel/Confirm prompt, with optional typed confirmation
- **NotificationBell** - Badge/bell button
  - **NotificationPanel** / **NotificationList** / **NotificationItem** - the tray, its body and one row
- **Loading** - Blocking loading overlay (`Backdrop` for a lighter scrim)
- **Spinner** - Themed inline spinner
- **Toaster** - Toast notification system
  - **useToaster** - Hook for toast management
- **ToolTip** - Tooltip component

### User & Profile
- **Avatar** / **AvatarGroup** - Fill derived from `name`, so it follows brand and dark mode
- **ProfileCard** - User profile card
- **ProfilePhotoViewer** - Profile photo viewer
- **VerifyEmailOtp** - Email verification component

### Editor
- **Editor** - Rich text editor component

The lists above are the common components. Every export, including the helpers, hooks and tokens, is
in the [Exports index](#exports-index).

## Usage Examples

### Basic Button Usage

```tsx
import { Button } from 'pixelize-design-library';

function MyComponent() {
  return (
    <div>
      <Button variant="solid" colorScheme="primary">Primary Button</Button>
      <Button variant="outline" colorScheme="gray">Secondary Button</Button>
    </div>
  );
}
```

### Form with Validation

```tsx
import { useState } from 'react';
import { TextInput, Button, Card } from 'pixelize-design-library';

function LoginForm() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  return (
    <Card>
      <TextInput
        label="Email"
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        required
      />
      <TextInput
        label="Password"
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        required
      />
      <Button variant="solid" colorScheme="primary" type="submit">
        Login
      </Button>
    </Card>
  );
}
```

### Data Table

```tsx
import { Table } from 'pixelize-design-library';

const columns = [
  { id: 'name', label: 'Name' },
  { id: 'email', label: 'Email' },
  { id: 'role', label: 'Role' }
];

// every row needs a unique id
const data = [
  { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' }
];

function DataTable() {
  return (
    <Table
      columns={columns}
      data={data}
      paginationMode="client"
      isGlobalSearch
    />
  );
}
```

## Theming

The library ships **9 brand themes** (`lavender`, `meadow`, `radiant`, `skyline`, `slate`,
`emerald`, `rosewood`, `storefront`, `zinc`), each with a **light and a dark palette**.

### Existing apps (unchanged)

`withTheme` is the original default export and still renders **light only**. Upgrading the package
changes nothing visually:

```tsx
import withTheme, { ThemesList } from 'pixelize-design-library';

export default withTheme(App, ThemesList.lavender);
```

### Opting into light / dark / system

Wrap the app in `PixelizeThemeProvider` instead. It defaults to **`system`** (follows the OS) and
persists the user's choice to `localStorage`.

```tsx
import { PixelizeThemeProvider, ThemeSwitcher } from 'pixelize-design-library';

function Root() {
  return (
    <PixelizeThemeProvider brand="lavender" defaultMode="system">
      <App />
    </PixelizeThemeProvider>
  );
}

// Drop the switcher anywhere inside the provider:
<ThemeSwitcher />                                    // icon toggle
<ThemeSwitcher variant="segmented" />                // Light / System / Dark
<ThemeSwitcher variant="menu" showBrandPicker />     // + brand picker
```

| `PixelizeThemeProvider` prop | Default | Meaning |
| ---------------------------- | ------- | ------- |
| `brand` | `"lavender"` | Which brand theme to use |
| `defaultMode` | `"system"` | `"light"` \| `"dark"` \| `"system"` |
| `storageKey` | `"pixelize-theme"` | localStorage key |
| `disablePersistence` | `false` | Don't read/write localStorage |
| `onBrandChange` / `onModeChange` | — | Fire on user-driven changes only |
| `themeOverrides` | — | Chakra theme object merged over the brand theme |
| `reducedMotion` | `"components"` | `"global"` applies one reduced-motion rule to the whole document |

### Reading or changing the theme in code

```tsx
import { useThemeMode, useCustomTheme } from 'pixelize-design-library';

const { mode, resolvedMode, setMode, toggle, brand, setBrand } = useThemeMode();
const theme = useCustomTheme(); // returns the palette for the ACTIVE color mode
```

`useCustomTheme()` returns the dark palette automatically in dark mode, so components that read
their colors from it are dark-aware with no extra work.

### Building components

Read colors from the theme — never hardcode a hex, or the component will be stuck in light mode:

```tsx
const theme = useCustomTheme();
<Box bg={theme.colors.background[50]} color={theme.colors.text[900]} />  // ✅ adapts
<Box bg="#ffffff" color="#26213c" />                                     // ❌ breaks in dark
```

`colors.white` is a **foreground** token (the label on a filled button) and stays white in dark
mode. For a white **surface**, use `colors.background[50]`.

### Design tokens (shared with the mobile library)

`lightPalettes`, `darkPalettes`, `palettes`, `themeNames`, and `buildDarkPalette` are exported for
apps that build custom themes. The token source (`src/Theme/tokens/`) is pure TypeScript with no
Chakra, React, or CSS imports, so it is portable to React Native.

```ts
import { lightPalettes, buildDarkPalette } from 'pixelize-design-library';

const myDark = buildDarkPalette(lightPalettes.emerald);
```

## TypeScript Support

All components are built with TypeScript and include full type definitions:

```tsx
import { Button, ButtonProps } from 'pixelize-design-library';

interface CustomButtonProps extends ButtonProps {
  customProp?: string;
}

function CustomButton({ customProp, ...props }: CustomButtonProps) {
  return <Button {...props} />;
}
```

## Bundle size and tree-shaking

The package ships both CommonJS (`main`) and ES modules (`module`). Bundlers pick the ESM
build and tree-shake it, so **you only pay for what you import**:

```tsx
import { Button } from 'pixelize-design-library';
```

That import produces roughly **113 KB** — it contains no chart, editor, drag-and-drop,
virtual-list or date code, even though the package depends on all of them.

To keep it that way:

- **Import from the package root.** The root barrel is tree-shakeable; there is no size
  penalty for it, and it is the only path covered by semver.
- **Do not import from `dist/` for values.** Deep imports still work (and are used for types),
  but they bypass the ESM build and pull in the CommonJS copy.
- **Do not disable `sideEffects` handling** in your bundler config.

### Heavy components load on demand

`Editor` wraps Jodit, which is by far the largest dependency. It is loaded lazily, when the
component first renders, rather than when the package is imported. An app that uses `Editor`
ships about **96 KB** up front and fetches the ~1.5 MB editor chunk on demand. No extra setup
is required — `Editor` renders its own `Suspense` boundary.

### Fonts

The theme self-hosts Inter Variable. The stylesheet is split by `unicode-range`, so a
Latin-script page downloads a single **47 KB** font file; Cyrillic, Greek and Vietnamese
subsets are only fetched if the page actually renders those scripts.

### Server-side rendering

Components are browser-targeted and the theme imports a CSS file, so the package must be
transpiled by your bundler rather than imported by bare Node. In Next.js:

```js
// next.config.js
module.exports = { transpilePackages: ['pixelize-design-library'] };
```

## Exports index

Every value the package root exports, so an export is never invisible to a developer or an LLM that
only has this package. For how to use a component see [DESIGN-GUIDE.md](./DESIGN-GUIDE.md) and
[COMPONENT-GOTCHAS.md](./COMPONENT-GOTCHAS.md); props are documented in the `*Props` types. This
block is generated: after adding or removing an export run
`UPDATE_README_EXPORTS=1 npx jest src/readmeExportsIndex.test.ts --coverage=false`.

<!-- exports-index:start -->

**Components and primitives (256)**

`Accordian`, `Accordion`, `AddressCard`, `AddressCardGroup`, `Alert`, `AlertDescription`, `AlertDialog`, `AlertIcon`, `AlertTitle`, `ApexAreaChart`, `ApexBarChart`, `ApexLineChart`, `ApexPieChart`, `ApexPolarChart`, `ApexRadialChart`, `AppSwitcher`, `AppearanceSettings`, `AudioRecorder`, `Avatar`, `AvatarGroup`, `Backdrop`, `Badge`, `BagBar`, `Box`, `Breadcrumbs`, `BulkSelectionBar`, `Button`, `ButtonGroupIcon`, `CalendarGrid`, `Card`, `CartItem`, `Center`, `ChakraProvider`, `Checkbox`, `ChoiceCard`, `ChoiceCardGroup`, `CircularProgress`, `Collapse`, `ConfirmDialog`, `ContactForm`, `Container`, `CopyButton`, `CouponField`, `CustomModulesTable`, `DatePicker`, `DescriptionList`, `DetailSections`, `Divider`, `Drawer`, `DrawerBody`, `DrawerFooter`, `DrawerHeader`, `Dropdown`, `Editor`, `EmptyState`, `ErrorState`, `FeedbackForm`, `FieldMessage`, `FieldSelectModal`, `FilePreview`, `FilePreviewTrigger`, `FileUpload`, `FileUploader`, `FilterBar`, `FilterSidebar`, `FilteredEmptyState`, `Flex`, `FormControl`, `FormDrawer`, `FormErrorMessage`, `FormField`, `FormHelperText`, `FormLabel`, `FormWrapper`, `Grid`, `GridItem`, `Header`, `HeaderActions`, `Heading`, `Hide`, `Icon`, `IconButton`, `Image`, `InputSwitch`, `InputTextArea`, `KanbanActions`, `KanbanBoard`, `Kbd`, `KbdShortcut`, `LauncherSearchEngine`, `LauncherTrigger`, `LazyWrapper`, `LimitReachedModal`, `Link`, `List`, `ListIcon`, `ListItem`, `Loading`, `MediaAudioPlayer`, `MediaDocumentStage`, `MediaGallery`, `MediaImageViewer`, `MediaLightbox`, `MediaScrubber`, `MediaStatusPanel`, `MediaVideoPlayer`, `MediaViewer`, `Menu`, `MenuButton`, `MenuDivider`, `MenuGroup`, `MenuItem`, `MenuItemOption`, `MenuList`, `MenuOptionGroup`, `Modal`, `ModalBody`, `ModalFooter`, `ModalHeader`, `MoreItems`, `MultiSelect`, `NavLauncher`, `NavigationBar`, `NewTabLink`, `NoteTextArea`, `Notification`, `NotificationBell`, `NotificationItem`, `NotificationList`, `NotificationPanel`, `NumberInput`, `OffersList`, `OptionChip`, `OrderStatusTimeline`, `OrderSummary`, `OrderedList`, `OrgSwitcher`, `OrganizationDetails`, `OverflowToolTip`, `PageHeader`, `Pagination`, `PaymentCard`, `PaymentOption`, `PaymentOptionGroup`, `PdfViewer`, `PersonChip`, `PhoneNumberInput`, `PinInput`, `PinToggle`, `PincodeChecker`, `PixelizeThemeProvider`, `PlanBadge`, `PlanPill`, `Popover`, `PopoverArrow`, `PopoverBody`, `PopoverCloseButton`, `PopoverContent`, `PopoverFooter`, `PopoverHeader`, `PopoverTrigger`, `Portal`, `PriceBlock`, `ProductBadges`, `ProductCard`, `ProductCardGrid`, `ProductCardSkeleton`, `ProductDetails`, `ProfileCard`, `ProfileCardBody`, `ProfileCardFooter`, `ProfileCardHeader`, `ProfilePhotoViewer`, `ProgressBar`, `QuantityStepper`, `QueryStateBoundary`, `QuickAddSheet`, `RadioButton`, `RadioButtonGroup`, `RangeSlider`, `Rating`, `Reorder`, `ReviewList`, `ReviewSummary`, `RolesPermission`, `SaveBar`, `ScrollToTop`, `ScrollbarBox`, `Search`, `SearchSelect`, `SectionRail`, `SegmentedControl`, `Select`, `SelectSearch`, `SelectV2`, `SettingRow`, `SettingsSection`, `Show`, `SideBar`, `SignInActivityTable`, `SimpleGrid`, `Skeletons`, `SkipLink`, `Slider`, `Spacer`, `SpecTable`, `Spinner`, `Stack`, `StageItem`, `StageProgress`, `StatCard`, `StatusTag`, `StickyBuyBar`, `StockStatus`, `Switch`, `Tab`, `TabList`, `TabPanel`, `TabPanels`, `Table`, `TableContainer`, `TableRoot`, `TableToggle`, `Tabs`, `Tag`, `TagInput`, `Tbody`, `Td`, `Text`, `TextInput`, `Tfoot`, `Th`, `Thead`, `ThemeSwitcher`, `ThemesList`, `TimePicker`, `Timeline`, `Toaster`, `ToggleSwitch`, `ToolTip`, `Tr`, `TrustBadges`, `UnorderedList`, `UpgradeButton`, `UserDetails`, `VariantSelector`, `VerifyEmailOtp`, `VisuallyHidden`, `WishlistToggle`, `Wizard`, `WizardDialog`, `WorkspaceTray`, `WorkspaceTrayPreview`, `WorkspaceWindow`, `Wrap`, `WrapItem`

**Hooks (18)**

`useAnchoredPanelHeight`, `useAppSwitcherShortcut`, `useBreakpointValue`, `useChartTheme`, `useCustomTheme`, `useDebouncedCallback`, `useDebouncedValue`, `useDisclosure`, `useFieldIds`, `useFileViewer`, `useFontSizeSync`, `useIsTruncated`, `useMediaQuery`, `usePrefersReducedMotion`, `useSidebarPrefs`, `useThemeMode`, `useToaster`, `useToken`

**Constants (45)**

`AA_NON_TEXT`, `AA_NORMAL_TEXT`, `ACCENT_GRADIENT`, `AVATAR_SEEDS`, `BORDER_WIDTHS`, `CALENDAR_DAY_CLASS`, `CATEGORICAL_SERIES`, `CONTROL_SIZES`, `CONTROL_SIZE_NAMES`, `DARK_CANVAS_LUMINANCE`, `DAY_STATE_KEYS`, `DEFAULT_CONTROL_SIZE`, `DEFAULT_DATE_FALLBACK`, `DEFAULT_FONT_SIZE`, `DISABLED_OPACITY`, `EMAIL_REGEX`, `FOCUS_HALO_WIDTH`, `FOCUS_RING_WIDTH`, `FOCUS_VISIBLE_OVER_STATE`, `FONT_SIZE_OPTIONS`, `LOW_STOCK_THRESHOLD`, `MAX_ZOOM`, `MIN_ZOOM`, `MOTION_BEZIER`, `MOTION_EASE`, `MOTION_EASE_IN`, `MOTION_EASE_OUT`, `MOTION_KEEP_CLASS`, `MOTION_LOOP_MS`, `MOTION_MS`, `MOTION_PRESS_SCALE`, `NUMERIC_TEXT`, `OVERLAY_BLUR`, `PIXELIZE_SUITE`, `PLAYBACK_SPEEDS`, `RADIUS_ROLE`, `RAISED_OVERLAY`, `REDUCED_MOTION_QUERY`, `SCRIM_OPACITY`, `SCROLLBAR_WIDTH`, `SEEK_STEP_SECONDS`, `STATUS_INK`, `TEXT_STYLES`, `TONES`, `ZOOM_STEP`

**Helpers and tokens (185)**

`HStack`, `VStack`, `accentTextOnCanvas`, `accentTextOnPlanes`, `appInitials`, `avatarFillFor`, `avatarScaleKeyFor`, `bandOn`, `brandThemes`, `buildDarkPalette`, `buildFileItems`, `buildFocusRing`, `buildMediaItems`, `buildSuiteApps`, `buildSurfaceRaised`, `cardRule`, `chartAxisLabelColor`, `chartInk`, `chartMode`, `chipBorder`, `chipFill`, `chipHtml`, `chipify`, `clearChunkReloadGuard`, `compositeOver`, `contrastRatio`, `controlSizeStyles`, `countMedia`, `createAccountHandoff`, `createEnumLabelResolver`, `darkPalettes`, `darkerFillRung`, `debounce`, `default`, `defaultMediaAudioPlayerLabels`, `defaultMediaDocumentStageLabels`, `defaultMediaGalleryLabels`, `defaultMediaImageViewerLabels`, `defaultMediaLightboxLabels`, `defaultMediaVideoPlayerLabels`, `defaultMediaViewerLabels`, `defaultPaginationLabels`, `defaultValidationMessages`, `describeDayStates`, `discountAmount`, `discountPercent`, `downloadBlob`, `extendTheme`, `extractTokens`, `fieldControlStyles`, `fieldLabelStyles`, `fieldMessageStyles`, `fieldSurfaces`, `fieldToken`, `fileKind`, `filterApps`, `findVariant`, `firstAvailableSelection`, `firstInvalidStep`, `flattenScreens`, `focusRingShadow`, `focusVisibleRing`, `focusVisibleStyles`, `formatCount`, `formatDate`, `formatDateRange`, `formatDateTime`, `formatPlanElapsed`, `formatPlanExpiry`, `formatPlanRemaining`, `formatPrice`, `formatRelativeTime`, `formatShortcut`, `getApiErrorMessage`, `getApiErrorStatus`, `getCategoricalSeriesColors`, `getDefaultSeriesColors`, `globalScrollbarStyles`, `gradientCss`, `groupConsecutive`, `hexToHsl`, `hexToRgb`, `hexToRgba`, `highlightSegments`, `hslToHex`, `hslToRgb`, `humanize`, `initialsFor`, `inkSafeGradient`, `inkSafeGradientToken`, `installPreloadErrorReload`, `isAllowedReturnUrl`, `isChunkLoadError`, `isControlSize`, `isDarkCanvas`, `isDayStateKey`, `isFontSize`, `isOptionAvailable`, `isTone`, `labelOnFill`, `labelOnSeries`, `lazyWithRetry`, `liftToContrast`, `lightPalettes`, `listRowBackgrounds`, `matchesShortcut`, `meetsBodyText`, `mergeRefs`, `mix`, `motionTransition`, `onFilled`, `onGradient`, `optionRowCursorSx`, `optionRowDescriptionInk`, `optionRowFill`, `optionRowInk`, `optionRowWeight`, `overlayScrim`, `overlayScrimStyles`, `palettes`, `pickAccentText`, `placeholderInk`, `placeholderInkOn`, `planPreview`, `priceRange`, `rafThrottle`, `raisedRule`, `recessOn`, `reducedMotionSx`, `relativeLuminance`, `remainingStock`, `resolveAvatarColorway`, `resolveAvatarFill`, `resolveDayStateVisual`, `resolveFilledSurface`, `resolveFontSize`, `resolveGradient`, `resolveMediaUrl`, `resolvePlanBadge`, `resolveReturnUrl`, `resolveSoftTone`, `resolveStatusTone`, `resolveSuiteApps`, `rgbToHex`, `rgbToHsl`, `ruleOn`, `safeFileName`, `scrollbarStyles`, `searchLauncher`, `searchLauncherSections`, `sectionizeByDay`, `selectionComplete`, `serializeChips`, `setRef`, `settleBetween`, `shadowsFor`, `solidFillRung`, `splitMonthsAndDays`, `statusGradient`, `stockState`, `themeNames`, `toCsv`, `toWords`, `toneInk`, `toneScale`, `toneToColorScheme`, `toneToSemantic`, `tooltipSurface`, `transitionFor`, `unitPrice`, `unknownTokens`, `validateEmail`, `validateFile`, `validateFileSize`, `validateFileType`, `validatePassword`, `validatePositiveNumber`, `validateRequired`, `validateVideoFile`, `validateVideoFileType`, `validateYoutubeUrl`, `withFocusRing`, `withLightness`, `withOutlineRung`, `wizardTransition`

<!-- exports-index:end -->

## Demo app

`npm start` runs a local component explorer on `http://localhost:5173` — every exported
component on its own page, with live variants, an interactive playground for editing props,
and a generated props reference. The **Page examples** section shows full screens (dashboard,
records list, record detail, settings, pipeline, inbox, app launcher, wizard, template editor,
storefront) built only from library exports, each with its loading, empty and error states.

```bash
npm install
npm start
```

The demo lives in `src/Pages/` and is excluded from the published package. See
[GOTCHAS.md](GOTCHAS.md) for the traps involved in keeping it that way.

## Contributing

Read [CLAUDE.md](CLAUDE.md) for the repo layout, component pattern and the checklist for
adding a component, and [GOTCHAS.md](GOTCHAS.md) before touching the theme provider, the
build config or `package.json`.

```bash
npm install
npm start        # demo app on :5173
npm test         # Jest — not vitest
npm run lint
npm run typecheck
```

Every component needs a demo page in `src/Pages/` and Jest tests next to the component.

## License

Not yet declared. The `license` field in `package.json` is unset and there is no `LICENSE`
file in the repo — both need the owning entity's decision before the package is published
outside the organisation.

## Support

- Issues: [github.com/pixelize-tech/Micro-Components/issues](https://github.com/pixelize-tech/Micro-Components/issues)
