@uxelle/skills 0.2.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +58 -0
  3. package/dist/index.d.ts +26 -0
  4. package/dist/index.js +586 -0
  5. package/index.json +573 -0
  6. package/package.json +57 -0
  7. package/skills/uxelle-components/Accordion.md +51 -0
  8. package/skills/uxelle-components/AccordionGroup.md +39 -0
  9. package/skills/uxelle-components/Banner.md +73 -0
  10. package/skills/uxelle-components/BannerAnnouncement.md +63 -0
  11. package/skills/uxelle-components/Breadcrumb.md +38 -0
  12. package/skills/uxelle-components/Breadcrumbs.md +32 -0
  13. package/skills/uxelle-components/Bubble.md +34 -0
  14. package/skills/uxelle-components/Button.md +54 -0
  15. package/skills/uxelle-components/ButtonGroup.md +43 -0
  16. package/skills/uxelle-components/Card.md +35 -0
  17. package/skills/uxelle-components/Checkbox.md +57 -0
  18. package/skills/uxelle-components/CheckboxGroup.md +47 -0
  19. package/skills/uxelle-components/ChoiceChip.md +44 -0
  20. package/skills/uxelle-components/ChoiceChipGroup.md +50 -0
  21. package/skills/uxelle-components/DatePicker.md +59 -0
  22. package/skills/uxelle-components/DatePickerRange.md +73 -0
  23. package/skills/uxelle-components/Dialog.md +83 -0
  24. package/skills/uxelle-components/Divider.md +37 -0
  25. package/skills/uxelle-components/DynamicAngleLine.md +36 -0
  26. package/skills/uxelle-components/DynamicAngleLineCombo.md +30 -0
  27. package/skills/uxelle-components/DynamicAngleShape.md +32 -0
  28. package/skills/uxelle-components/DynamicAngleShapeSurface.md +35 -0
  29. package/skills/uxelle-components/DynamicAngleTexture.md +29 -0
  30. package/skills/uxelle-components/DynamicAngleTextureText.md +35 -0
  31. package/skills/uxelle-components/FieldMessage.md +31 -0
  32. package/skills/uxelle-components/FileUpload.md +53 -0
  33. package/skills/uxelle-components/FilterChip.md +35 -0
  34. package/skills/uxelle-components/FilterChipGroup.md +42 -0
  35. package/skills/uxelle-components/Footer.md +34 -0
  36. package/skills/uxelle-components/Hero.md +61 -0
  37. package/skills/uxelle-components/Icon.md +43 -0
  38. package/skills/uxelle-components/IconButton.md +44 -0
  39. package/skills/uxelle-components/Image.md +40 -0
  40. package/skills/uxelle-components/Label.md +35 -0
  41. package/skills/uxelle-components/LabelBadge.md +58 -0
  42. package/skills/uxelle-components/LanguageSelector.md +38 -0
  43. package/skills/uxelle-components/LanguageSelectorButton.md +34 -0
  44. package/skills/uxelle-components/Layout.md +81 -0
  45. package/skills/uxelle-components/LinearProgress.md +53 -0
  46. package/skills/uxelle-components/Link.md +52 -0
  47. package/skills/uxelle-components/List.md +35 -0
  48. package/skills/uxelle-components/ListControls.md +100 -0
  49. package/skills/uxelle-components/ListItem.md +69 -0
  50. package/skills/uxelle-components/Lockup.md +50 -0
  51. package/skills/uxelle-components/Logo.md +39 -0
  52. package/skills/uxelle-components/Menu.md +48 -0
  53. package/skills/uxelle-components/MultiSelect.md +54 -0
  54. package/skills/uxelle-components/NavLink.md +44 -0
  55. package/skills/uxelle-components/Navigation.md +61 -0
  56. package/skills/uxelle-components/NavigationSide.md +51 -0
  57. package/skills/uxelle-components/NavigationSideGroup.md +36 -0
  58. package/skills/uxelle-components/NavigationSideItem.md +56 -0
  59. package/skills/uxelle-components/NavigationSideSubItem.md +39 -0
  60. package/skills/uxelle-components/NotificationBadge.md +62 -0
  61. package/skills/uxelle-components/Pagination.md +49 -0
  62. package/skills/uxelle-components/PaginationComplex.md +51 -0
  63. package/skills/uxelle-components/PaginationSimple.md +44 -0
  64. package/skills/uxelle-components/ProductCard.md +46 -0
  65. package/skills/uxelle-components/Quantity.md +45 -0
  66. package/skills/uxelle-components/Radio.md +55 -0
  67. package/skills/uxelle-components/RadioGroup.md +49 -0
  68. package/skills/uxelle-components/SKILL.md +242 -0
  69. package/skills/uxelle-components/Scrim.md +28 -0
  70. package/skills/uxelle-components/SegmentedControl.md +118 -0
  71. package/skills/uxelle-components/Select.md +55 -0
  72. package/skills/uxelle-components/Sheet.md +31 -0
  73. package/skills/uxelle-components/Skeleton.md +35 -0
  74. package/skills/uxelle-components/Spinner.md +33 -0
  75. package/skills/uxelle-components/StatTile.md +150 -0
  76. package/skills/uxelle-components/Stepper.md +73 -0
  77. package/skills/uxelle-components/Switch.md +41 -0
  78. package/skills/uxelle-components/Tab.md +41 -0
  79. package/skills/uxelle-components/Table.md +55 -0
  80. package/skills/uxelle-components/TabsCompact.md +37 -0
  81. package/skills/uxelle-components/TabsStretch.md +35 -0
  82. package/skills/uxelle-components/Text.md +56 -0
  83. package/skills/uxelle-components/Textarea.md +77 -0
  84. package/skills/uxelle-components/Textfield.md +62 -0
  85. package/skills/uxelle-components/Tooltip.md +33 -0
  86. package/skills/uxelle-design-harness/SKILL.md +149 -0
  87. package/skills/uxelle-design-harness/a2ui.md +73 -0
  88. package/skills/uxelle-design-harness/how-to-accessibility.md +31 -0
  89. package/skills/uxelle-design-harness/how-to-color.md +82 -0
  90. package/skills/uxelle-design-harness/how-to-host.md +108 -0
  91. package/skills/uxelle-design-harness/how-to-page-layout.md +203 -0
  92. package/skills/uxelle-design-harness/principles.md +72 -0
  93. package/skills/uxelle-design-harness/recipe-app-chrome.md +168 -0
  94. package/skills/uxelle-design-harness/recipe-card-grid.md +104 -0
  95. package/skills/uxelle-design-harness/recipe-cta-band.md +91 -0
  96. package/skills/uxelle-design-harness/recipe-dashboard-overview.md +118 -0
  97. package/skills/uxelle-design-harness/recipe-data-table-page.md +323 -0
  98. package/skills/uxelle-design-harness/recipe-feature-section.md +96 -0
  99. package/skills/uxelle-design-harness/recipe-footer.md +156 -0
  100. package/skills/uxelle-design-harness/recipe-form-section.md +163 -0
  101. package/skills/uxelle-design-harness/recipe-hero.md +89 -0
  102. package/skills/uxelle-design-harness/recipe-landing-page.md +94 -0
  103. package/skills/uxelle-design-harness/recipe-logo-wall.md +80 -0
  104. package/skills/uxelle-design-harness/recipe-multi-step-flow.md +108 -0
  105. package/skills/uxelle-design-harness/recipe-page-header.md +102 -0
  106. package/skills/uxelle-design-harness/recipe-page-shell.md +82 -0
  107. package/skills/uxelle-design-harness/recipe-pricing.md +83 -0
  108. package/skills/uxelle-design-harness/recipe-query-bar.md +108 -0
  109. package/skills/uxelle-design-harness/recipe-record-detail.md +96 -0
  110. package/skills/uxelle-design-harness/recipe-settings-page.md +170 -0
  111. package/skills/uxelle-design-harness/recipe-stat-callouts.md +111 -0
  112. package/skills/uxelle-design-harness/recipe-states.md +119 -0
  113. package/skills/uxelle-design-harness/recipe-summary-list.md +88 -0
  114. package/skills/uxelle-design-harness/recipe-template.md +62 -0
  115. package/skills/uxelle-design-harness/recipe-testimonial.md +73 -0
  116. package/skills/uxelle-design-harness/spacing-steps.md +57 -0
  117. package/skills/uxelle-design-harness/tokens.md +101 -0
@@ -0,0 +1,242 @@
1
+ ---
2
+ name: uxelle-components
3
+ description: Reference for uxElle Generative Product Foundation (GPF) components. Use when generating UI with uxElle, implementing designs, building layouts, or when the user mentions uxElle components, design system, or enterprise UI.
4
+ ---
5
+
6
+ # uxElle Components — Generative Workflow Reference
7
+
8
+ Reference for accurately using uxElle Generative Product Foundation (GPF) components in generative workflows. Import from `@uxelle/components`.
9
+
10
+ ## Context discipline
11
+
12
+ - Load this SKILL.md when working with uxElle components.
13
+ - Load individual component files (e.g. Button.md, ListItem.md) only when you need that component's props or examples.
14
+ - Do not preload all component files.
15
+
16
+ ## Reading a component file
17
+
18
+ Each component file leads with its import and a one-line summary, then a Props table of `Prop | Type | Default | Description`.
19
+
20
+ - A prop marked **`(required)`** must be passed — the component will not render correctly without it.
21
+ - The Default column shows the value the component applies when the prop is omitted; `—` means there is no default.
22
+ - Props tables list the supported public surface. Prefer these over spreading arbitrary HTML attributes.
23
+
24
+ ## Quick Import Reference
25
+
26
+ ```tsx
27
+ import {
28
+ Accordion,
29
+ AccordionGroup,
30
+ Banner,
31
+ BannerAnnouncement,
32
+ Breadcrumb,
33
+ Breadcrumbs,
34
+ Bubble,
35
+ Button,
36
+ ButtonGroup,
37
+ Card,
38
+ Checkbox,
39
+ CheckboxGroup,
40
+ ChoiceChip,
41
+ ChoiceChipGroup,
42
+ DatePicker,
43
+ DatePickerRange,
44
+ Dialog,
45
+ Divider,
46
+ DynamicAngleLine,
47
+ DynamicAngleLineCombo,
48
+ DynamicAngleShape,
49
+ DynamicAngleShapeSurface,
50
+ DynamicAngleTexture,
51
+ DynamicAngleTextureText,
52
+ FieldMessage,
53
+ FileUpload,
54
+ FilterChip,
55
+ FilterChipGroup,
56
+ Footer,
57
+ Hero,
58
+ Icon,
59
+ IconButton,
60
+ Image,
61
+ Label,
62
+ LabelBadge,
63
+ LanguageSelector,
64
+ LanguageSelectorButton,
65
+ Layout,
66
+ LinearProgress,
67
+ Link,
68
+ List,
69
+ ListControls,
70
+ ListItem,
71
+ Lockup,
72
+ Logo,
73
+ Menu,
74
+ MultiSelect,
75
+ NavLink,
76
+ Navigation,
77
+ NavigationSide,
78
+ NavigationSideGroup,
79
+ NavigationSideItem,
80
+ NavigationSideSubItem,
81
+ NotificationBadge,
82
+ Pagination,
83
+ PaginationComplex,
84
+ PaginationSimple,
85
+ ProductCard,
86
+ Quantity,
87
+ Radio,
88
+ RadioGroup,
89
+ Select,
90
+ SegmentedControl,
91
+ Scrim,
92
+ Sheet,
93
+ Skeleton,
94
+ SkeletonGroup,
95
+ Spinner,
96
+ StatTile,
97
+ Stepper,
98
+ Switch,
99
+ Tab,
100
+ Table,
101
+ TabsCompact,
102
+ TabsStretch,
103
+ Textarea,
104
+ Textfield,
105
+ Tooltip,
106
+ Text,
107
+ } from "@uxelle/components";
108
+ ```
109
+
110
+ ## Component Index
111
+
112
+ | Component | File | Use when |
113
+ |-----------|------|----------|
114
+ | **Accordion** | [Accordion.md](Accordion.md) | Expandable sections, FAQs |
115
+ | **AccordionGroup** | [AccordionGroup.md](AccordionGroup.md) | Multiple elevated accordions |
116
+ | **Banner** | [Banner.md](Banner.md) | In-page contextual notices with optional actions and dismiss |
117
+ | **BannerAnnouncement** | [BannerAnnouncement.md](BannerAnnouncement.md) | System-wide bar above nav that displaces layout |
118
+ | **Breadcrumb** | [Breadcrumb.md](Breadcrumb.md) | Single crumb in a trail; compose inside `Breadcrumbs` |
119
+ | **Breadcrumbs** | [Breadcrumbs.md](Breadcrumbs.md) | Nav landmark trail of `Breadcrumb` children with optional overflow |
120
+ | **Bubble** | [Bubble.md](Bubble.md) | Compact icon or text chips, inline labels |
121
+ | **Button** | [Button.md](Button.md) | Primary actions, CTAs |
122
+ | **ButtonGroup** | [ButtonGroup.md](ButtonGroup.md) | Layout group for related `Button` actions (not segmented control) |
123
+ | **Card** | [Card.md](Card.md) | Elevated surface for arbitrary content |
124
+ | **Checkbox** | [Checkbox.md](Checkbox.md) | Single checkbox inputs in forms |
125
+ | **CheckboxGroup** | [CheckboxGroup.md](CheckboxGroup.md) | Fieldset-backed groups; nested **`Checkbox`** children share **`name`** and group **`value`** |
126
+ | **ChoiceChip** | [ChoiceChip.md](ChoiceChip.md) | Toggle pill for multi-select choice sets (facets, sort, view) |
127
+ | **ChoiceChipGroup** | [ChoiceChipGroup.md](ChoiceChipGroup.md) | Groups multi-select choice toggles under an optional label |
128
+ | **DatePicker** | [DatePicker.md](DatePicker.md) | Single calendar date field (ISO `YYYY-MM-DD`); type or pick from a month grid |
129
+ | **DatePickerRange** | [DatePickerRange.md](DatePickerRange.md) | Start and end calendar dates (ISO `YYYY-MM-DD`); type or pick from a month grid |
130
+ | **Dialog** | [Dialog.md](Dialog.md) | Centered modal confirmations and forms with scrim and focus trap |
131
+ | **Divider** | [Divider.md](Divider.md) | Visual separation, section boundaries |
132
+ | **DynamicAngleLine** | [DynamicAngleLine.md](DynamicAngleLine.md) | Decorative diagonal brand accent for hero and section layouts |
133
+ | **DynamicAngleLineCombo** | [DynamicAngleLineCombo.md](DynamicAngleLineCombo.md) | Decorative paired diagonal accents for hero layouts |
134
+ | **DynamicAngleShape** | [DynamicAngleShape.md](DynamicAngleShape.md) | Decorative angled shard for hero bands and section accents |
135
+ | **DynamicAngleShapeSurface** | [DynamicAngleShapeSurface.md](DynamicAngleShapeSurface.md) | Decorative angled surface for hero and section backgrounds |
136
+ | **DynamicAngleTexture** | [DynamicAngleTexture.md](DynamicAngleTexture.md) | Decorative repeating diagonal texture strip |
137
+ | **DynamicAngleTextureText** | [DynamicAngleTextureText.md](DynamicAngleTextureText.md) | Texture strip paired with a tagline for hero layouts |
138
+ | **FieldMessage** | [FieldMessage.md](FieldMessage.md) | Field validation, helper text |
139
+ | **FileUpload** | [FileUpload.md](FileUpload.md) | File picker with button or drag-and-drop, file list, validation |
140
+ | **FilterChip** | [FilterChip.md](FilterChip.md) | Removable pill for an applied filter |
141
+ | **FilterChipGroup** | [FilterChipGroup.md](FilterChipGroup.md) | Groups dismissible applied-filter chips under an optional label |
142
+ | **Footer** | [Footer.md](Footer.md) | Page footer, legal, branding |
143
+ | **Hero** | [Hero.md](Hero.md) | Full-bleed marketing band with overlaid copy and actions |
144
+ | **Icon** | [Icon.md](Icon.md) | Material Symbols icons |
145
+ | **IconButton** | [IconButton.md](IconButton.md) | Icon-only actions |
146
+ | **Image** | [Image.md](Image.md) | Responsive images with controlled aspect ratios |
147
+ | **Label** | [Label.md](Label.md) | Form field labels, required indicator |
148
+ | **LabelBadge** | [LabelBadge.md](LabelBadge.md) | Status pills, emphasis labels, badges |
149
+ | **LanguageSelector** | [LanguageSelector.md](LanguageSelector.md) | Locale switching |
150
+ | **LanguageSelectorButton** | [LanguageSelectorButton.md](LanguageSelectorButton.md) | Language selector menu button |
151
+ | **Layout** | [Layout.md](Layout.md) | Flex/grid containers, spacing |
152
+ | **LinearProgress** | [LinearProgress.md](LinearProgress.md) | Progress bars; determinate/indeterminate; optional label and field message slots |
153
+ | **Link** | [Link.md](Link.md) | Navigation links, hyperlinks |
154
+ | **List** | [List.md](List.md) | Vertical list container |
155
+ | **ListControls** | [ListControls.md](ListControls.md) | Settings/choice list with embedded Switch, Checkbox, or Radio (`controlType`) |
156
+ | **ListItem** | [ListItem.md](ListItem.md) | List items with slots |
157
+ | **Lockup** | [Lockup.md](Lockup.md) | Stacked eyebrow, heading, and supporting copy for section intros |
158
+ | **Logo** | [Logo.md](Logo.md) | Brand logo slot for navigation, footer, and marketing surfaces |
159
+ | **Menu** | [Menu.md](Menu.md) | Dropdown menus |
160
+ | **MultiSelect** | [MultiSelect.md](MultiSelect.md) | Multi-value combobox with chip overflow |
161
+ | **NavLink** | [NavLink.md](NavLink.md) | Primary/secondary nav links (optional menu) |
162
+ | **Navigation** | [Navigation.md](Navigation.md) | Header/nav bar |
163
+ | **NavigationSide** | [NavigationSide.md](NavigationSide.md) | Side-rail chrome (`<aside>`) or compact top bar; SSR hosts pass `mobile`; omit only in client-only surfaces |
164
+ | **NavigationSideGroup** | [NavigationSideGroup.md](NavigationSideGroup.md) | Side-nav landmark (`<nav>`) grouping destination rows with optional end divider and collapsed layout |
165
+ | **NavigationSideItem** | [NavigationSideItem.md](NavigationSideItem.md) | Destination row for a vertical side rail — icon, label, activated indicator, accordion, collapsed flyout |
166
+ | **NavigationSideSubItem** | [NavigationSideSubItem.md](NavigationSideSubItem.md) | Nested destination under an accordion side-rail parent |
167
+ | **NotificationBadge** | [NotificationBadge.md](NotificationBadge.md) | Dot or counter overlays on icons and avatars |
168
+ | **Pagination** | [Pagination.md](Pagination.md) | Numbered page footer with optional summary (items-per-page menu + range) |
169
+ | **PaginationComplex** | [PaginationComplex.md](PaginationComplex.md) | Full footer with items-per-page menu, range, page-jump menu, prev/next |
170
+ | **PaginationSimple** | [PaginationSimple.md](PaginationSimple.md) | Compact prev/next with optional item-range label |
171
+ | **ProductCard** | [ProductCard.md](ProductCard.md) | Product tile with top, center, and bottom content regions |
172
+ | **Quantity** | [Quantity.md](Quantity.md) | Numeric stepper (minus/plus, spinbutton); enforces `min`/`max`; optional `FieldMessage` |
173
+ | **Radio** | [Radio.md](Radio.md) | Single radio option (`<label>` + native `input type="radio"`) |
174
+ | **RadioGroup** | [RadioGroup.md](RadioGroup.md) | Fieldset-backed groups; nested **`Radio`** children share **`name`** and group **`value`** |
175
+ | **Select** | [Select.md](Select.md) | Single-select combobox with listbox options |
176
+ | **SegmentedControl** | [SegmentedControl.md](SegmentedControl.md) | Exclusive multi-segment view/mode switcher |
177
+ | **Scrim** | [Scrim.md](Scrim.md) | Semi-transparent backdrop behind modal overlays (Sheet, Dialog) |
178
+ | **Sheet** | [Sheet.md](Sheet.md) | Slide-over panels and edge sheets |
179
+ | **Skeleton** | [Skeleton.md](Skeleton.md) | Layout loading placeholders; compose with `SkeletonGroup` |
180
+ | **Spinner** | [Spinner.md](Spinner.md) | Loading / success / error async status beside optional label |
181
+ | **StatTile** | [StatTile.md](StatTile.md) | KPI readout with label, value, optional qualifier, info tooltip, and trailing region |
182
+ | **Stepper** | [Stepper.md](Stepper.md) | Multi-step progress; includes **`StepperItem`** composition |
183
+ | **Switch** | [Switch.md](Switch.md) | Toggle controls, on/off states |
184
+ | **Tab** | [Tab.md](Tab.md) | Tab labels for tab navigation |
185
+ | **Table** | [Table.md](Table.md) | Data tables with sort, reorder, resize, and pinning |
186
+ | **TabsCompact** | [TabsCompact.md](TabsCompact.md) | Intrinsic tab widths, optional scroll |
187
+ | **TabsStretch** | [TabsStretch.md](TabsStretch.md) | Equal-width tabs |
188
+ | **Textarea** | [Textarea.md](Textarea.md) | Multi-line text fields with optional character counter, auto-grow, and soft overflow |
189
+ | **Textfield** | [Textfield.md](Textfield.md) | Single-line text input fields, forms |
190
+ | **Tooltip** | [Tooltip.md](Tooltip.md) | Contextual hints on hover or focus |
191
+ | **Text** | [Text.md](Text.md) | Text, headings, labels |
192
+
193
+ ## Core Patterns
194
+
195
+ ### Button labels
196
+ Pass the label as plain `children`. `Button` wraps it in `<Text type="Button">` for you — adding your own `Text` nests one inside another:
197
+
198
+ ```tsx
199
+ <Button emphasis="high">Click me</Button>
200
+ ```
201
+
202
+ `IconButton` has no visible label, so give it an `aria-label` instead.
203
+
204
+ ### List structure
205
+ Use `List` + `ListItem` for menus and lists. Prefer `centerText` / `bottomText` / `topText`:
206
+
207
+ ```tsx
208
+ <List>
209
+ <ListItem divider centerText={<Text type="Body Small Alt">Header</Text>} />
210
+ <ListItem
211
+ interactive
212
+ trailingSlot
213
+ trailingIconName="outbound"
214
+ centerText={<Text type="Body Small Alt">Item</Text>}
215
+ />
216
+ </List>
217
+ ```
218
+
219
+ ### List controls
220
+ Prefer **`ListControls`** when each row has title/description plus an embedded trailing control (settings and exclusive choices). Page layout: harness [recipe-settings-page.md](../uxelle-design-harness/recipe-settings-page.md). Set **`controlType`** to **`switch`**, **`checkbox`**, or **`radio`**. Same selection roles as **`RadioGroup`** / **`CheckboxGroup`** for checkbox/radio, list layout instead of stacked form options. Use **`interactive`** **`ListItem`** rows with **`embedded`** Switch / Checkbox / Radio in **`trailing`**. Set **`dense`** on **`ListControls`** (or per **`ListItem`**) for compact row padding.
221
+
222
+ ### Icon variants
223
+ Icons use `sharpFilled` or `sharpUnfilled`. Default is `sharpUnfilled`.
224
+
225
+ ### Theme tokens
226
+ Generated app CSS uses `--uxl-color-switcher-*` and layout/page-chrome tokens. Do not use `--uxl-component-*` in app CSS (those tokens belong inside components). Focus rings on catalog controls already use `--uxl-color-switcher-interactive-icon`.
227
+
228
+ ### Radio groups
229
+ Use **`RadioGroup`** for a shared **`name`** and selection state; each option is a **`Radio`** with a stable **`value`** and **`Text`** (or similar) as **`children`**. Wire **`value`** / **`onChange`** for controlled mode (`onChange` receives the next string). Without a visible **`legend`** (**`label`** + **`labelText`**), set **`aria-label`** or **`aria-labelledby`** on **`RadioGroup`** (the **`fieldset`**).
230
+
231
+ ### Checkbox groups
232
+ Use **`CheckboxGroup`** for related multi-select options under one legend; each option is a **`Checkbox`** with a stable **`value`** and **`Text`** (or similar) as **`children`**. **`value`** / **`defaultValue`** are **`string[]`**. Without a visible **`legend`**, set **`aria-label`** or **`aria-labelledby`** on **`CheckboxGroup`**.
233
+
234
+ ### Color switcher
235
+ For secondary nav or brand hero bands: `data-color-switcher="brand-2"` on secondary nav (or `brand-1` on hero regions); use `NavLink` with `navigationLevel="Secondary"` in that band.
236
+
237
+ ## Additional Resources
238
+
239
+ - [Design harness](../uxelle-design-harness/SKILL.md) — principles, variables, page chrome, responsiveness, WCAG AA, recipes
240
+ - [Form field contract](../../docs/guides/form-field-contract.md) — HTML `value` / `checked` (not Figma `Selected` / `Activated`)
241
+ - [Design variables (`--uxl-*`)](../uxelle-design-harness/tokens.md) — spacing, radius, elevation, color switcher, type
242
+ - Do not import `InternalDialog` or `InternalImageOverlay` in generated UI — use `Dialog` and `Image`.
@@ -0,0 +1,28 @@
1
+ # Scrim
2
+
3
+ Import: `import { Scrim } from "@uxelle/components";`
4
+
5
+ Semi-transparent backdrop that dims page content behind modal overlays.
6
+
7
+ ## Props
8
+
9
+ | Prop | Type | Description |
10
+ |------|------|-------------|
11
+ | `className` | `string` | Optional class names merged onto the scrim surface. |
12
+
13
+ Parent overlays own open/close state, motion, positioning, and dismiss behavior.
14
+
15
+ ## Usage
16
+
17
+ ```tsx
18
+ <div className="overlay" data-state={open ? "open" : "closed"}>
19
+ <Scrim className="overlay__scrim" />
20
+ <DialogPanel />
21
+ </div>
22
+ ```
23
+
24
+ ## Notes
25
+
26
+ - **Visual only**: Themed semi-transparent background — no state, motion, or dismiss logic.
27
+ - **Decorative**: Always `aria-hidden`; the parent dialog or sheet owns modal semantics and focus management.
28
+ - **Composition**: Parent sets positioning on `className`, plus `data-state`, fade animations, and click handling as needed. `Sheet` passes `className="uxl-sheet__scrim"` and dismisses on overlay clicks outside the panel.
@@ -0,0 +1,118 @@
1
+ # SegmentedControl
2
+
3
+ Import: `import { SegmentedControl } from "@uxelle/components";`
4
+
5
+ Compact single-select control for switching related views or modes (list vs grid, chart period, toolbar filters). Suitable for forms with optional **FieldMessage**, `required` / `invalid`, and a form `name`.
6
+
7
+ ## Props — SegmentedControl
8
+
9
+ <!-- prettier-ignore-start -->
10
+
11
+ | Prop | Type | Default | Description |
12
+ |------|------|---------|-------------|
13
+ | name | `string` | `""` | Form field name for a hidden input carrying the selected segment value. Omit when the control is not submitted with a native form. |
14
+ | label | `boolean` | `true` | Renders a `<legend>` when true and `labelText` (or `labelSlot`) is set; the legend names the group. When false, name the group with `aria-label` or `aria-labelledby` — `fieldDescription` is not rendered without a legend. |
15
+ | labelText | `string` | `""` | Visible group name rendered in the legend (Body Medium Alt). Leave it empty to drop the legend entirely, then name the group with `aria-label`. |
16
+ | fieldDescription | `string` | `""` | Supporting copy below the legend, wired to the fieldset through `aria-describedby`. Rendered only while the legend is visible. |
17
+ | labelSlot | `ReactNode` | `—` | Custom legend content replacing the default `Label` + `Text`, and with them the `required` asterisk and `fieldDescription`. Setting it also shows the legend when `labelText` is empty. |
18
+ | segments | `readonly SegmentedControlSegmentConfig[]` | `—` | Segment definitions for A2UI, codegen, or simple configs. Prefer **SegmentedControlSegment** children for hand-written React. When both are set, `children` wins. |
19
+ | children | `ReactNode` | `—` | Compose 2–5 `SegmentedControlSegment` children (preferred for React apps). Fragments are unwrapped; any other child is skipped with a development warning. |
20
+ | controlType | `"Button" \| "Icon Button"` | `"Button"` | Layout mode applied to every segment: `Button` shows a text label with optional leading and trailing icons, `Icon Button` shows `iconName` alone and needs each segment's `aria-label`. |
21
+ | value | `string` | `undefined` | Selected segment value; controlled whenever this is a non-empty string. Pair it with `onValueChange`, and omit it entirely (never `""`) to fall back to index-based `activated`. |
22
+ | defaultValue | `string` | `""` | Initially selected segment value while `value` is omitted, after which the component owns selection. Falls back to `defaultActivated` when empty or unmatched. |
23
+ | onValueChange | `(value: string) => void` | `—` | Called with the newly selected segment's value on click or keyboard selection. Preferred over `onActivatedChange`; both fire when both are set. |
24
+ | activated | `number` | `undefined` | Selected segment as a 1-based index, controlled and clamped to the segment count. Read only while `value` is omitted; prefer `value` in application code so selection survives reordered or localized options. |
25
+ | defaultActivated | `number` | `1` | Initially selected segment as a 1-based index while `value` and `defaultValue` are both omitted; clamped to the segment count. Prefer `defaultValue` when segment identity matters. |
26
+ | onActivatedChange | `(activated: number) => void` | `—` | Called with the newly selected segment's 1-based index. Prefer `onValueChange` when segment identity matters; both fire when both are set. |
27
+ | disabled | `boolean` | `false` | Locks the group as non-interactive while keeping options perceivable (`aria-disabled` on the group and segments). The hidden `name` input is disabled too, so nothing is submitted. |
28
+ | fieldMessage | `ReactNode` | `—` | Shown below the control; plain string or number uses `fieldMessageType` with **FieldMessage**. Its region `id` is merged into fieldset `aria-describedby` (or `aria-errormessage` when the type is Danger). |
29
+ | fieldMessageType | `"Info" \| "Danger" \| "Warning" \| "Success"` | `SEGMENTED_CONTROL_DEFAULTS.fieldMessageType` | Style applied to `FieldMessage` when `fieldMessage` is a string or number. Forced to `Danger` while `invalid` is true. |
30
+ | required | `boolean` | `false` | Maps to `aria-required` on the radiogroup, and shows the `Label` asterisk while a legend is visible. Announces that a selection is mandatory before any option is chosen. |
31
+ | invalid | `boolean` | `false` | Sets `aria-invalid="true"` and shows a Danger field message (uses `fieldMessage` when set, otherwise a default error string). Also wires `aria-errormessage` and announces the message politely. |
32
+ | width | `string` | `""` | Width of the control. Numbers and bare numeric strings become px; other strings pass through as CSS (`100%`, `16rem`, `var(--uxl-…)`). Omit to size from the segments, which truncate long labels and reveal the full text in a tooltip. |
33
+ | "aria-label" | `string` | `""` | Accessible name for the radiogroup when no legend is visible. Prefer `label` + `labelText` when a visible group name exists. |
34
+ | "aria-labelledby" | `string` | `""` | Space-separated ids of elements that name the group. Ignored while a legend is visible, since the legend already names the fieldset. |
35
+ | "aria-describedby" | `string` | `""` | Space-separated ids of helper or instruction copy. Merged with the `fieldDescription` id and the id of a non-error field message. |
36
+ | "aria-errormessage" | `string` | `""` | Id of the element holding the error text. Defaults to the field message region id once the resolved message type is Danger, and is only announced while `aria-invalid` is true. |
37
+ | "aria-invalid" | `boolean` | `false` | Explicit `aria-invalid` on the radiogroup, overriding what `invalid` would set. Marking it true also triggers the Danger field message. |
38
+ | "aria-required" | `boolean` | `false` | Explicit `aria-required` on the radiogroup, overriding what `required` would set. Omit it to let `required` drive the announcement. |
39
+
40
+ <!-- prettier-ignore-end -->
41
+
42
+ ## Props — SegmentedControlSegment
43
+
44
+ <!-- prettier-ignore-start -->
45
+
46
+ | Prop | Type | Default | Description |
47
+ |------|------|---------|-------------|
48
+ | value | `string` | `""` | Stable segment identity matched against the parent's `value` and reported by `onValueChange`. When empty it falls back to the visible label — or, for `Icon Button` segments, to `aria-label` then `iconName` — and finally to a positional `segment-N`. |
49
+ | text | `string` | `""` | Visible label when the parent `controlType` is `Button`. Prefer `children` when composing in React; `text` is the string form for configs and codegen. |
50
+ | children | `ReactNode` | `—` | Label content when the parent `controlType` is `Button`. Wins over `text`, and long labels truncate with the full text shown in a tooltip on hover or focus. |
51
+ | leadingIcon | `boolean` | `false` | Renders `leadingIconName` before the label. Ignored when the parent `controlType` is `Icon Button`. |
52
+ | trailingIcon | `boolean` | `false` | Renders `trailingIconName` after the label. Ignored when the parent `controlType` is `Icon Button`. |
53
+ | leadingIconName | `string` | `"chevron_left"` | Material Symbol drawn before the label. Only read when `leadingIcon` is true, and falls back to `chevron_left` when omitted. |
54
+ | trailingIconName | `string` | `"chevron_right"` | Material Symbol drawn after the label. Only read when `trailingIcon` is true, and falls back to `chevron_right` when omitted. |
55
+ | leadingIconVariant | `"sharpFilled" \| "sharpUnfilled"` | `"sharpFilled"` | Fill style of the leading icon: `sharpFilled` (solid) or `sharpUnfilled` (outline). |
56
+ | trailingIconVariant | `"sharpFilled" \| "sharpUnfilled"` | `"sharpFilled"` | Fill style of the trailing icon: `sharpFilled` (solid) or `sharpUnfilled` (outline). |
57
+ | iconName | `string` | `"add"` | Material Symbol shown in place of a label when the parent `controlType` is `Icon Button`. Falls back to `add` when omitted; pair it with `aria-label`. |
58
+ | iconVariant | `"sharpFilled" \| "sharpUnfilled"` | `"sharpFilled"` | Fill style of the icon-only glyph: `sharpFilled` (solid) or `sharpUnfilled` (outline). |
59
+ | disabled | `boolean` | `false` | Blocks selection of this one segment while keeping it visible and announced (`aria-disabled`). Arrow, Home, and End navigation skips it. |
60
+ | "aria-label" | `string` | `""` | Accessible name for the segment. Required for `Icon Button` segments, which have no visible text, and useful when a visible label is too terse on its own. |
61
+
62
+ <!-- prettier-ignore-end -->
63
+
64
+
65
+ ## Usage
66
+
67
+ ```tsx
68
+ <SegmentedControl
69
+ name="chartType"
70
+ controlType="Button"
71
+ label
72
+ labelText="Chart Type"
73
+ fieldDescription="Choose how your data is displayed in the chart."
74
+ value={chart}
75
+ onValueChange={setChart}
76
+ fieldMessage={error}
77
+ fieldMessageType="Danger"
78
+ invalid={Boolean(error)}
79
+ required
80
+ >
81
+ <SegmentedControl.Segment value="bar">Bar</SegmentedControl.Segment>
82
+ <SegmentedControl.Segment value="line">Line</SegmentedControl.Segment>
83
+ <SegmentedControl.Segment value="area">Area</SegmentedControl.Segment>
84
+ </SegmentedControl>
85
+ ```
86
+
87
+ ```tsx
88
+ <SegmentedControl
89
+ controlType="Icon Button"
90
+ label={false}
91
+ aria-label="View mode"
92
+ value={view}
93
+ onValueChange={setView}
94
+ >
95
+ <SegmentedControl.Segment value="list" iconName="view_list" aria-label="List" />
96
+ <SegmentedControl.Segment value="grid" iconName="grid_view" aria-label="Grid" />
97
+ </SegmentedControl>
98
+ ```
99
+
100
+ ```tsx
101
+ <SegmentedControl label={false} aria-label="View mode" value={view} onValueChange={setView}>
102
+ <SegmentedControl.Segment value="list" leadingIcon leadingIconName="list">
103
+ List
104
+ </SegmentedControl.Segment>
105
+ <SegmentedControl.Segment value="grid">Grid</SegmentedControl.Segment>
106
+ </SegmentedControl>
107
+ ```
108
+
109
+
110
+ ## Notes
111
+
112
+ - Compose 2–5 `SegmentedControl.Segment` children, or pass a `segments` array for generated configs. Exactly one segment is active at a time. Not a ButtonGroup for independent actions or Choice Chips for multi-select.
113
+ - **Selection**: Prefer `value` / `defaultValue` / `onValueChange` in application code, with a `value` on each segment. Omit `value` entirely (do not pass `""`) only when you need index-based `activated` / `defaultActivated` / `onActivatedChange` (e.g. Code Connect). A non-empty `value` is controlled.
114
+ - **Keyboard**: Arrow keys, Home, and End move focus and selection together (radiogroup pattern). Space and Enter also select the focused segment.
115
+ - **Segments**: Each option renders a `SegmentedControl.Segment`. Set `controlType` on this parent (`Button` with optional leading/trailing icons + label, or `Icon Button` with `iconName` + `aria-label`); it applies to every segment.
116
+ - **Forms**: Optional `name` submits the selected segment value via a hidden input. Use `Label` (via `label` + `labelText` + `required`) for a visible required marker, plus `fieldMessage`, `fieldMessageType`, and `invalid`. When `invalid` is true, a Danger field message is shown (author `fieldMessage` when provided, otherwise a default error string).
117
+ - **Accessibility**: Root is a **`fieldset`** with **`role="radiogroup"`**. Native **`<legend>`** names the group when shown (do not also point `aria-labelledby` at that legend). Segments are `role="radio"` with `aria-checked`. Arrow keys (RTL-aware), Home, and End move focus and selection and skip disabled segments. Group `disabled` uses `aria-disabled` so options stay perceivable. When `label` is false, set `aria-label` or `aria-labelledby`. Icon-only segments require `aria-label`.
118
+ - **Width**: Numbers map to pixels; strings accept `%`, lengths, or `var(--uxl-…)`. Narrow the width to verify label truncation; truncated Button labels show the full text in a tooltip on hover or focus.
@@ -0,0 +1,55 @@
1
+ # Select
2
+
3
+ Import: `import { Select } from "@uxelle/components";`
4
+
5
+ Single-select dropdown with label, design tokens, optional `FieldMessage`, and listbox options.
6
+
7
+ ## Props
8
+
9
+ <!-- prettier-ignore-start -->
10
+
11
+ | Prop | Type | Default | Description |
12
+ |------|------|---------|-------------|
13
+ | label | `boolean` | `true` | When false, the label row is not rendered; pass `aria-label` so the combobox keeps an accessible name. |
14
+ | labelText | `string` | `"Department"` | Visible label text, rendered as Body Medium Alt inside `Label`; ignored when `labelSlot` is set, and an empty string hides the label row. |
15
+ | labelSlot | `ReactNode` | `—` | Replaces `labelText` with custom content inside `Label`, which keeps `htmlFor` and the required asterisk. Reach for it when the label needs a link or badge. |
16
+ | fieldDescription | `string` | `""` | Helper copy rendered under the label and linked to the combobox with `aria-describedby`; only rendered while the label row is visible. |
17
+ | fieldMessage | `boolean` | `false` | Renders a `FieldMessage` row below the control; `validation` set to `error` shows the row as well, so use this flag for neutral helper copy. |
18
+ | fieldMessageContent | `string` | `""` | Content for the `FieldMessage` row; when omitted, the row falls back to built-in copy for the current `validation` state. |
19
+ | validation | `"none" \| "error"` | `"none"` | Validation state: `error` switches the field message to the danger style, sets `aria-invalid`, and forces the message row; `none` leaves the field neutral. |
20
+ | placeholder | `string` | `""` | Text shown in the trigger while no option is selected; nothing is rendered when it is an empty string. |
21
+ | leadingIcon | `boolean` | `false` | When true, renders the built-in leading `Icon` from `leadingIconName` inside the trigger; `leadingSlot` is the identical alias and `leading` overrides both. |
22
+ | leadingSlot | `boolean` | `false` | Alias of `leadingIcon`: either flag turns the leading region on, matching the Textfield leading-slot naming. |
23
+ | leadingIconName | `string` | `"add"` | Material Symbol rendered in the leading region; used only when `leadingIcon` (or `leadingSlot`) is true and `leading` is unset. An empty string falls back to `add`. |
24
+ | leadingIconVariant | `"sharpFilled" \| "sharpUnfilled"` | `"sharpUnfilled"` | Icon style for the built-in leading icon — `sharpUnfilled` (outlined) or `sharpFilled` (solid); ignored when `leading` supplies its own icon. |
25
+ | leading | `ReactNode` | `—` | Custom node rendered in the leading region instead of the built-in icon, with no need for `leadingIcon`. The wrapper is `aria-hidden`, so keep it decorative. |
26
+ | value | `string` | `""` | Selected option value in controlled mode. Pass it with `onChange`; omit it to let the component track the selection itself. |
27
+ | defaultValue | `string` | `—` | Starting selection for uncontrolled usage; ignored once `value` is set. |
28
+ | onChange | `(value: string) => void` | `—` | Called with the chosen option's `value` after the user commits a selection; the listbox closes and focus returns to the trigger. |
29
+ | options | `SelectOption[]` | `SELECT_DEFAULT_OPTIONS` | Options rendered as listbox rows, and the lookup that resolves the label shown in the trigger — still used when `children` replaces the rows. Omitting it falls back to three placeholder department options. |
30
+ | children | `ReactNode` | `—` | Custom listbox rows (usually `ListItem`) replacing the rows built from `options`; each row must spread `listboxOptionProps()` plus an activate handler such as `onClick`. The trigger still resolves the selected label from `options`, so keep the two in sync. |
31
+ | open | `boolean` | `—` | Controlled open state of the listbox. Pass it with `onOpenChange`; omit it to let the component manage its own. `disabled` and `readOnly` keep the list closed. |
32
+ | defaultOpen | `boolean` | `false` | Whether the listbox starts open when uncontrolled; ignored once `open` is set. |
33
+ | onOpenChange | `(open: boolean) => void` | `—` | Called with the next open state whenever the listbox opens or closes, including outside clicks, Escape, and Tab. |
34
+ | readOnly | `boolean` | `false` | Shows the current selection but blocks opening the listbox and hides the trailing chevron; the trigger stays focusable and reports `aria-readonly`. |
35
+ | required | `boolean` | `—` | Adds the asterisk to `Label` and `aria-required` on the trigger. Advisory only — no native constraint validation runs on the hidden input. |
36
+ | name | `string` | `—` | Form field name for the hidden input that posts the selected value. No input is rendered while nothing is selected, so an empty selection is never submitted. |
37
+ | disabled | `boolean` | `false` | Blocks interaction, removes the trigger from the tab order, and applies disabled styling; a `name` hidden input still submits the current value. |
38
+
39
+ <!-- prettier-ignore-end -->
40
+
41
+ ## Usage
42
+
43
+ ```tsx
44
+ <Select>
45
+ {/* Content */}
46
+ </Select>
47
+ ```
48
+
49
+ ## Notes
50
+
51
+ - **Simple API** — pass `options` with `value` / `onChange` for controlled usage; optional `leadingIcon` / `leadingIconName`.
52
+ - **Composable API** — pass `children` to render custom `ListItem` rows in the listbox; pass `leading` for a custom leading slot. Each row should spread `listboxOptionProps()` plus selection handlers (see dev console when the list opens).
53
+ - **Accessibility**: Visible label uses `<Label htmlFor>`; the combobox name uses `aria-labelledby` on the label text only (not `fieldDescription`, which is linked via `aria-describedby`). `FieldMessage` uses `aria-describedby` (info) or `aria-errormessage` (error). Pass `id` for stable ids; use `aria-label` when `label={false}`.
54
+ - **Focus**: Tab focuses the combobox trigger only; **Arrow** keys move the active option (`aria-activedescendant`) while open. **Enter** commits the active option; **Escape** closes the list. Options use `tabIndex={-1}` and are not separate tab stops.
55
+ - **Forms**: With `name`, a hidden input posts the selected value; when nothing is selected, no hidden input is rendered.
@@ -0,0 +1,31 @@
1
+ # Sheet
2
+
3
+ Import: `import { Sheet } from "@uxelle/components";`
4
+
5
+ ## Props
6
+
7
+ <!-- prettier-ignore-start -->
8
+
9
+ | Prop | Type | Default | Description |
10
+ |------|------|---------|-------------|
11
+ | direction | `"Right" \| "Left" \| "Bottom"` | `"Right"` | Edge the panel slides in from. `Right` / `Left` give a side sheet with a header and close button; `Bottom` gives a bottom sheet with a drag handle that can be swiped down to dismiss. |
12
+ | open | `boolean` | `—` | Controlled visibility. Pass it with `onOpenChange` and update it yourself; omit it to let the sheet track its own state from `defaultOpen`. |
13
+ | defaultOpen | `boolean` | `false` | Whether the sheet starts open on first render. Ignored afterwards, and whenever `open` is passed. |
14
+ | onOpenChange | `(open: boolean) => void` | `—` | Called with the requested visibility when the trigger is clicked, Escape or the scrim dismisses the sheet, or a bottom sheet is dragged down. Required when `open` is controlled. |
15
+ | trigger | `ReactElement` | `—` | Single element that toggles the sheet; it is cloned to receive `onClick`, `aria-expanded`, `aria-haspopup`, and `aria-controls`, and takes focus back on close. Omit it and control `open` yourself when the opener lives elsewhere. |
16
+ | title | `string` | `"Title"` | Heading text for the default top slot: visible on `Left` / `Right` sheets and screen-reader-only on `Bottom`. It also becomes the sheet's accessible name unless `topSlot`, `aria-label`, or `aria-labelledby` is supplied. |
17
+ | closeLabel | `string` | `"Close"` | Text shared by both default dismiss affordances — the `aria-label` on the header close button and the visible label on the footer button. Blank falls back to `Close`. |
18
+ | topSlot | `ReactNode` | `—` | Replaces the entire default top region: the side header with its close button, or the bottom sheet's drag handle. `title` is then dropped, so supply your own heading and dismiss affordance. |
19
+ | bottomSlot | `ReactNode` | `—` | Replaces the default footer close button — use it for the sheet's real actions. Keep a dismiss control among them, since Escape and the scrim are otherwise the only way out. |
20
+ | initialFocusRef | `RefObject<HTMLElement \| null>` | `—` | Ref to the element that should take focus when the sheet opens — typically the first input or the primary action. Omit it to focus the panel itself, which announces the sheet's accessible name and lets Tab walk the content in DOM order; a target outside the panel or one that refuses focus falls back there too. Focus always enters the panel: the sheet is a modal dialog (`aria-modal`). |
21
+ | children | `ReactNode` | `—` | Main body of the sheet, rendered between the top and bottom slots and scrolled independently once it overflows. |
22
+
23
+ <!-- prettier-ignore-end -->
24
+
25
+ ## Usage
26
+
27
+ ```tsx
28
+ <Sheet>
29
+ {/* Content */}
30
+ </Sheet>
31
+ ```
@@ -0,0 +1,35 @@
1
+ # Skeleton
2
+
3
+ Import: `import { Skeleton } from "@uxelle/components";`
4
+
5
+ Decorative loading placeholder for a single shape. Use with **SkeletonGroup** so assistive technology hears one loading announcement for the region. Individual shapes are `aria-hidden`.
6
+
7
+ ## Props
8
+
9
+ <!-- prettier-ignore-start -->
10
+
11
+ | Prop | Type | Default | Description |
12
+ |------|------|---------|-------------|
13
+ | type | `"circle" \| "square" \| "rectangle" \| "textLoader"` | `"circle"` | Placeholder geometry: `circle` for avatars, `square` for thumbnails, `rectangle` for image and block placeholders, `textLoader` for stacked text lines. |
14
+ | size | `"extraSmall" \| "small" \| "medium" \| "large"` | `"small"` | Token-backed footprint preset, and for `textLoader` the height of each line. `width` / `height` override the dimensions it produces. |
15
+ | width | `string` | `""` | Explicit width in place of the `size` preset: numbers are pixels, strings take any CSS length (e.g. `100%`, `4rem`). `rectangle` and `textLoader` already fill the parent width when this is omitted. |
16
+ | height | `string` | `""` | Explicit height in place of the `size` preset: numbers are pixels, strings take any CSS length. For `textLoader` this sizes the whole block — per-line height still follows `size`. |
17
+ | motion | `boolean` | `true` | Runs the shimmer sweep on this shape. A `SkeletonGroup` with `motion` false suppresses it regardless, as does `prefers-reduced-motion`. |
18
+ | contentSlot | `ReactNode` | `—` | Replaces the three default lines of a `textLoader` with your own shapes — nest **Skeleton** instances to mirror a specific text layout. Ignored by every other `type`. |
19
+
20
+ <!-- prettier-ignore-end -->
21
+
22
+ Extends `HTMLAttributes` — supports standard HTML attributes.
23
+
24
+ ## Usage
25
+
26
+ ```tsx
27
+ <Skeleton>
28
+ {/* Content */}
29
+ </Skeleton>
30
+ ```
31
+
32
+ ## Notes
33
+
34
+ - For async operation feedback (save, submit), use **Spinner** or **LinearProgress**instead. Provide a fallback if loading exceeds ~5 seconds.
35
+ - Use `size` for token-backed presets. Set `width` and/or `height` to mirror specific content dimensions; those props override preset footprint sizing. Rectangle and text-loader shapes default to 100% parent width when `width` is omitted.
@@ -0,0 +1,33 @@
1
+ # Spinner
2
+
3
+ Import: `import { Spinner } from "@uxelle/components";`
4
+
5
+ Status indicator that communicates loading, success, or error state.
6
+
7
+ ## Props
8
+
9
+ <!-- prettier-ignore-start -->
10
+
11
+ | Prop | Type | Default | Description |
12
+ |------|------|---------|-------------|
13
+ | status | `"loading" \| "success" \| "error"` | `"loading"` | Which indicator and default message the live region shows: `loading` spins and sets `aria-busy`, `success` shows a filled check, `error` a filled error glyph. Default copy per status comes from `SPINNER_STATUS_MESSAGES`. |
14
+ | label | `boolean` | `true` | Shows text beside the indicator — `children` when supplied, otherwise the default message for `status`. With `label` false the same message becomes the root `aria-label` instead, and `size` starts applying. Avoid setting `aria-label` alongside a visible label; it duplicates the announcement. |
15
+ | size | `number` | `SPINNER_ICON_ONLY_DEFAULT_PX` | Icon box in px, honoured only when `label` is false; values are clamped to 8–128. Omit it to inherit `--uxl-spinner-icon-box` from CSS or a parent. With a label the icon size follows the composed `Text` type instead. |
16
+ | inheritColor | `boolean` | `false` | Drops the loading indicator's info color switcher so the parent's tokens supply its color — this is how the `Button` and `IconButton` loaders are styled. Standalone spinners should keep the switcher. |
17
+ | children | `ReactNode` | `—` | Status label shown beside the indicator when `label` is true. When omitted, the default message for `status` is used. |
18
+
19
+ <!-- prettier-ignore-end -->
20
+
21
+ Extends `HTMLAttributes` — supports standard HTML attributes.
22
+
23
+ ## Usage
24
+
25
+ ```tsx
26
+ <Spinner>
27
+ {/* Content */}
28
+ </Spinner>
29
+ ```
30
+
31
+ ## Notes
32
+
33
+ - Uses a live region (`role="status"`, `aria-live`, `aria-busy` while loading); icons are `aria-hidden`. Use `aria-describedby` for related context — do not override `role`, `aria-live`, `aria-busy`, or `aria-atomic` via forwarded props (they’re applied last and are part of this component contract). While loading, disable the triggering control; this component does not add an overlay or manage focus. With `label` + **Text**, icon size follows the type’s line-height via a root modifier class (`.uxl-spinner--text-*`). With `label` false, pass `size` (px) or omit it so `--uxl-spinner-icon-box` from CSS / a parent applies.