@sdaia-ds/mcp 0.0.0-stage → 3.1.1

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 (151) hide show
  1. package/README.md +212 -2
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +291 -0
  4. package/dist/index.js.map +1 -0
  5. package/knowledge/actions/breadcrumb.md +50 -0
  6. package/knowledge/actions/button-menu.md +82 -0
  7. package/knowledge/actions/button-split.md +69 -0
  8. package/knowledge/actions/button.md +101 -0
  9. package/knowledge/actions/content-switcher.md +66 -0
  10. package/knowledge/actions/date-picker.md +115 -0
  11. package/knowledge/actions/floating-button.md +100 -0
  12. package/knowledge/actions/horizontal-tabs.md +52 -0
  13. package/knowledge/actions/link.md +76 -0
  14. package/knowledge/actions/modal.md +103 -0
  15. package/knowledge/actions/pagination.md +69 -0
  16. package/knowledge/actions/radio-button.md +88 -0
  17. package/knowledge/actions/switch.md +87 -0
  18. package/knowledge/actions/tag.md +69 -0
  19. package/knowledge/ai/agent-activity.md +65 -0
  20. package/knowledge/ai/agent-card.md +65 -0
  21. package/knowledge/ai/agent-handoff.md +65 -0
  22. package/knowledge/ai/ai-citation.md +78 -0
  23. package/knowledge/ai/ai-code-block.md +86 -0
  24. package/knowledge/ai/ai-disclaimer.md +84 -0
  25. package/knowledge/ai/ai-message-bubble.md +81 -0
  26. package/knowledge/ai/ai-message.md +118 -0
  27. package/knowledge/ai/ai-prompt-input.md +93 -0
  28. package/knowledge/ai/ai-states.md +107 -0
  29. package/knowledge/ai/ai-status-indicator.md +81 -0
  30. package/knowledge/ai/ai-suggested-prompts.md +62 -0
  31. package/knowledge/ai/ai-thinking-indicator.md +94 -0
  32. package/knowledge/ai/artifact-viewer.md +105 -0
  33. package/knowledge/ai/citation.md +61 -0
  34. package/knowledge/ai/context-manager.md +111 -0
  35. package/knowledge/ai/prompt-context.md +72 -0
  36. package/knowledge/ai/prompt-suggestion.md +68 -0
  37. package/knowledge/ai/prompt-template.md +71 -0
  38. package/knowledge/ai/prompt-variable.md +61 -0
  39. package/knowledge/ai/reasoning-trace.md +106 -0
  40. package/knowledge/ai/source-explorer.md +117 -0
  41. package/knowledge/ai/source-group.md +59 -0
  42. package/knowledge/ai/source-reference.md +70 -0
  43. package/knowledge/ai/thinking-panel.md +77 -0
  44. package/knowledge/ai/tool-activity-feed.md +67 -0
  45. package/knowledge/ai/tool-call-card.md +66 -0
  46. package/knowledge/ai/tool-status-row.md +72 -0
  47. package/knowledge/ai/tool-timeline-item.md +71 -0
  48. package/knowledge/ai/voice-session.md +93 -0
  49. package/knowledge/feedback/alert.md +106 -0
  50. package/knowledge/feedback/badge.md +86 -0
  51. package/knowledge/feedback/card.md +54 -0
  52. package/knowledge/feedback/feedback-overview.md +37 -0
  53. package/knowledge/feedback/feedback.md +46 -0
  54. package/knowledge/feedback/help-icon.md +57 -0
  55. package/knowledge/feedback/loading-indicator.md +76 -0
  56. package/knowledge/feedback/notification-banner.md +73 -0
  57. package/knowledge/feedback/notification-popup.md +87 -0
  58. package/knowledge/feedback/notifications.md +158 -0
  59. package/knowledge/feedback/progress-bar.md +69 -0
  60. package/knowledge/feedback/rating-overview.md +58 -0
  61. package/knowledge/feedback/rating.md +64 -0
  62. package/knowledge/feedback/skeleton-avatar.md +48 -0
  63. package/knowledge/feedback/skeleton.md +53 -0
  64. package/knowledge/feedback/toast.md +74 -0
  65. package/knowledge/feedback/tooltip.md +72 -0
  66. package/knowledge/form/autocomplete.md +100 -0
  67. package/knowledge/form/checkbox.md +95 -0
  68. package/knowledge/form/date-time-field.md +63 -0
  69. package/knowledge/form/error-summary.md +56 -0
  70. package/knowledge/form/field-group.md +57 -0
  71. package/knowledge/form/file-uploader.md +60 -0
  72. package/knowledge/form/form-section.md +58 -0
  73. package/knowledge/form/number-input.md +92 -0
  74. package/knowledge/form/otp-input.md +83 -0
  75. package/knowledge/form/password-input.md +49 -0
  76. package/knowledge/form/range-slider.md +71 -0
  77. package/knowledge/form/rich-text-editor.md +106 -0
  78. package/knowledge/form/select.md +113 -0
  79. package/knowledge/form/signature.md +83 -0
  80. package/knowledge/form/slider.md +66 -0
  81. package/knowledge/form/text-area.md +90 -0
  82. package/knowledge/form/text-input.md +132 -0
  83. package/knowledge/form/time-input.md +44 -0
  84. package/knowledge/form/time-picker.md +73 -0
  85. package/knowledge/foundations/accessibility.md +97 -0
  86. package/knowledge/foundations/colors.md +1117 -0
  87. package/knowledge/foundations/figma.md +30 -0
  88. package/knowledge/foundations/icon-usage.md +114 -0
  89. package/knowledge/foundations/icons.md +16 -0
  90. package/knowledge/foundations/motion.md +39 -0
  91. package/knowledge/foundations/radius.md +17 -0
  92. package/knowledge/foundations/responsive.md +64 -0
  93. package/knowledge/foundations/rtl.md +106 -0
  94. package/knowledge/foundations/spacing.md +27 -0
  95. package/knowledge/foundations/theme.md +115 -0
  96. package/knowledge/foundations/tokens.json +12124 -0
  97. package/knowledge/foundations/typography.md +45 -0
  98. package/knowledge/general/accordion.md +79 -0
  99. package/knowledge/general/activity.md +44 -0
  100. package/knowledge/general/app-shell.md +64 -0
  101. package/knowledge/general/area-chart.md +89 -0
  102. package/knowledge/general/audio-player.md +85 -0
  103. package/knowledge/general/avatar-group.md +50 -0
  104. package/knowledge/general/avatar.md +61 -0
  105. package/knowledge/general/carousel-image.md +103 -0
  106. package/knowledge/general/chart.md +25 -0
  107. package/knowledge/general/chip.md +90 -0
  108. package/knowledge/general/code-snippet.md +80 -0
  109. package/knowledge/general/column-chart.md +84 -0
  110. package/knowledge/general/context-menu.md +55 -0
  111. package/knowledge/general/digital-stamp.md +77 -0
  112. package/knowledge/general/divider.md +65 -0
  113. package/knowledge/general/donut-chart.md +75 -0
  114. package/knowledge/general/draggable-list.md +43 -0
  115. package/knowledge/general/dropdown.md +90 -0
  116. package/knowledge/general/empty-state.md +60 -0
  117. package/knowledge/general/filtration.md +85 -0
  118. package/knowledge/general/footer.md +59 -0
  119. package/knowledge/general/line-chart.md +95 -0
  120. package/knowledge/general/list.md +91 -0
  121. package/knowledge/general/media-gallery.md +85 -0
  122. package/knowledge/general/media-viewer.md +78 -0
  123. package/knowledge/general/menu.md +66 -0
  124. package/knowledge/general/metric.md +92 -0
  125. package/knowledge/general/nav-bar.md +62 -0
  126. package/knowledge/general/nav-header.md +125 -0
  127. package/knowledge/general/number.md +72 -0
  128. package/knowledge/general/page-template.md +80 -0
  129. package/knowledge/general/pdf-viewer.md +91 -0
  130. package/knowledge/general/pie-chart-panel.md +86 -0
  131. package/knowledge/general/popover.md +115 -0
  132. package/knowledge/general/progress-circle.md +63 -0
  133. package/knowledge/general/quote.md +64 -0
  134. package/knowledge/general/radial-stepper.md +72 -0
  135. package/knowledge/general/scatter-chart.md +62 -0
  136. package/knowledge/general/second-nav-header.md +55 -0
  137. package/knowledge/general/slideout-menu.md +92 -0
  138. package/knowledge/general/stepper.md +42 -0
  139. package/knowledge/general/structured-list.md +52 -0
  140. package/knowledge/general/table-bulk-actions-bar.md +66 -0
  141. package/knowledge/general/table-of-content.md +49 -0
  142. package/knowledge/general/table.md +113 -0
  143. package/knowledge/general/tree-view.md +55 -0
  144. package/knowledge/general/vertical-tabs.md +48 -0
  145. package/knowledge/general/video-player.md +88 -0
  146. package/knowledge/manifest.json +919 -0
  147. package/knowledge/patterns/buttons-with-sdaia-touch.md +34 -0
  148. package/knowledge/patterns/sdaia-logo-animation.md +35 -0
  149. package/knowledge/patterns/switch-with-sdaia-touch.md +29 -0
  150. package/knowledge/setup.md +125 -0
  151. package/package.json +45 -4
@@ -0,0 +1,100 @@
1
+ # Autocomplete
2
+
3
+ ## Metadata
4
+ - Component: Autocomplete
5
+ - Slug: `autocomplete`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add autocomplete`
8
+ - Import: `import { Autocomplete } from '@/components/ui/Autocomplete'`
9
+ - Installed files: `Autocomplete.tsx`, `Autocomplete.types.ts`, `Autocomplete.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/autocomplete
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add autocomplete`. It copies the source into your components folder (`components/ui/Autocomplete/`, under `src/` when the project has one); import it as `@/components/ui/Autocomplete`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `dir?` | `'ltr' \| 'rtl'` | — | Text direction of the field. Leave unset to inherit it from an ancestor. |
18
+ | `size?` | `'large' \| 'medium'` | 'large' | Size variant. - `large` (default) — 40 px input height, text-text-md - `medium` — 36 px input height, text-text-sm |
19
+ | `value?` | `string` | '' | Current text value of the input (controlled). The parent is responsible for filtering `suggestions` based on this value. |
20
+ | `onChange?` | `(value: string) => void` | — | Called on every keystroke with the new input text. |
21
+ | `onSelect?` | `(item: AutocompleteItem) => void` | — | Called when the user selects a suggestion or recent item from the dropdown (click, or Enter on the option reached with the arrow keys). The parent can then decide whether to update `value` to `item.label`. |
22
+ | `suggestions?` | `AutocompleteItem[]` | [] | Suggestion items to display in the dropdown (typically filtered by the parent based on the current `value`). When empty, the Suggestions section is hidden. |
23
+ | `recents?` | `AutocompleteItem[]` | [] | Recent search items to display in the dropdown. When empty, the Recents section is hidden. |
24
+ | `placeholder?` | `string` | 'Search' | Placeholder text shown when the input is empty. Wins over `labels.placeholder`. |
25
+ | `label?` | `string` | — | Field label rendered above the input (linked to it with `htmlFor`). |
26
+ | `labelHelp?` | `ReactNode` | — | Content rendered right after the label text, outside the `<label>` element (e.g. a `HelpIcon`), so its own accessible name is not part of the field's. |
27
+ | `required?` | `boolean` | false | Adds a required asterisk (*) after the label and marks the input as required. |
28
+ | `validationBehavior?` | `'native' \| 'aria'` | 'native' | How `required` reaches the input. - `'native'` — the `required` attribute (browser validation on form submit). - `'aria'` — `aria-required="true"` only (no browser validation bubble). The visual asterisk is shown either way. |
29
+ | `helperText?` | `string` | — | Helper text rendered below the input (linked with `aria-describedby`). |
30
+ | `helperIcon?` | `boolean` | true | Whether to render the help-circle icon next to helper text. |
31
+ | `disabled?` | `boolean` | false | Disables the input and prevents all interaction. |
32
+ | `leadingIcon?` | `boolean` | true | Whether to show the leading search icon inside the input. |
33
+ | `id?` | `string` | — | `id` for the `<input>` element — also used for `htmlFor` on the label. A unique id is generated when unset. |
34
+ | `onClear?` | `() => void` | — | Called when the user clears the input via the × button. |
35
+ | `labels?` | `Partial<AutocompleteLabels>` | — | Localised built-in strings. |
36
+
37
+ Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `onChange`, `onSelect`.
38
+
39
+ ## Options (allowed values)
40
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction of the field. Leave unset to inherit it from an ancestor.
41
+ - `size`: `'large'` \| `'medium'` — Size of the Autocomplete input field
42
+ - `validationBehavior`: `'native'` \| `'aria'` — How `required` reaches the input.
43
+ - `'native'` — the `required` attribute (browser validation on form submit).
44
+ - `'aria'` — `aria-required="true"` only (no browser validation bubble).
45
+ The visual asterisk is shown either way.
46
+
47
+ ## Deprecated props
48
+ Do not use in new code:
49
+ - `suggestionsLabel` — Label shown above the Suggestions section in the dropdown.
50
+ Wins over `labels.suggestions`.
51
+ - `recentsLabel` — Label shown above the Recents section in the dropdown.
52
+ Wins over `labels.recents`.
53
+
54
+ ## Accessibility
55
+ - Built-in strings (button names, announcements) come from `labels`; pass translated strings for Arabic or other languages.
56
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
57
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
58
+
59
+ ## Design tokens used
60
+ Keep these consistent (resolve values with `get_tokens`):
61
+ - `var(--ds-color-bg-default)`
62
+ - `var(--ds-color-bg-muted)`
63
+ - `var(--ds-color-bg-overlay)`
64
+ - `var(--ds-color-border-brand)`
65
+ - `var(--ds-color-border-default)`
66
+ - `var(--ds-color-border-disabled)`
67
+ - `var(--ds-color-form-field-bg-default)`
68
+ - `var(--ds-color-form-field-border-default)`
69
+ - `var(--ds-color-form-field-border-hovered)`
70
+ - `var(--ds-color-form-field-text-filled)`
71
+ - `var(--ds-color-form-field-text-helper)`
72
+ - `var(--ds-color-form-field-text-label)`
73
+ - `var(--ds-color-form-field-text-placeholder)`
74
+ - `var(--ds-color-icon-default)`
75
+ - `var(--ds-color-icon-default-500)`
76
+ - `var(--ds-color-icon-default-disabled)`
77
+ - `var(--ds-color-primitive-neutral-400)`
78
+ - `var(--ds-color-text-brand)`
79
+ - `var(--ds-color-text-danger)`
80
+ - `var(--ds-color-text-default)`
81
+ - `var(--ds-color-text-disabled)`
82
+ - `var(--ds-color-text-paragraph-muted)`
83
+ - `var(--ds-motion-feedback-duration)`
84
+ - `var(--ds-motion-feedback-easing)`
85
+ - `var(--ds-radius-full)`
86
+ - `var(--ds-radius-m)`
87
+ - `var(--ds-spacing-lg)`
88
+ - `var(--ds-spacing-md)`
89
+ - `var(--ds-spacing-sm)`
90
+ - `var(--ds-spacing-xs)`
91
+ - `var(--ds-spacing-xxs)`
92
+
93
+ ## AI usage guidance
94
+ When generating UI:
95
+ - Install with `npx sdaia-ui@latest add autocomplete` (after `npx sdaia-ui@latest init`), then import `{ Autocomplete }` from `@/components/ui/Autocomplete`.
96
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
97
+ - Use only the documented option values listed under "Options".
98
+ - Pass icons via `<DgaIcon data={…} className="size-icon-sm" />` from `@platformscode/icons` only — see `get_foundations` (`icon-usage`). Never emoji, Lucide, or random icons (e.g. `pizza01Stroke` for dark mode).
99
+ - Express the disabled state with the `disabled` prop, not custom styling.
100
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
@@ -0,0 +1,95 @@
1
+ # Checkbox
2
+
3
+ ## Metadata
4
+ - Component: Checkbox
5
+ - Slug: `checkbox`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add checkbox`
8
+ - Import: `import { Checkbox } from '@/components/ui/Checkbox'`
9
+ - Installed files: `Checkbox.tsx`, `Checkbox.types.ts`, `Checkbox.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/checkbox
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add checkbox`. It copies the source into your components folder (`components/ui/Checkbox/`, under `src/` when the project has one); import it as `@/components/ui/Checkbox`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `label?` | `ReactNode` | — | Label displayed next to the checkbox |
18
+ | `placement?` | `'start' \| 'end' \| 'top' \| 'bottom'` | 'start' | Where the checkbox sits relative to the label (Figma Placement). |
19
+ | `indeterminate?` | `boolean` | false | Displays a dash instead of a check (for partial selection) |
20
+ | `size?` | `'sm' \| 'md' \| 'lg'` | 'md' | Size of the checkbox |
21
+ | `variant?` | `'primary' \| 'neutral'` | 'primary' | Visual style variant |
22
+ | `error?` | `string` | — | Error message displayed below the checkbox. Sets `aria-invalid` and is linked via `aria-describedby`. |
23
+ | `helperText?` | `string` | — | Helper text displayed below the label (or below the control when there is no label) |
24
+ | `readOnly?` | `boolean` | false | Read-only state (Figma Read-Only). Shows static styling; value cannot be changed. |
25
+ | `checked?` | `boolean` | — | Whether the checkbox is checked (controlled). Omit for an uncontrolled checkbox. |
26
+ | `defaultChecked?` | `boolean` | — | Initial checked state for uncontrolled usage. Ignored when `checked` is supplied. |
27
+ | `onCheckedChange?` | `(checked: boolean) => void` | — | Called with the new checked state when the user toggles the checkbox. Native `onChange` keeps working. |
28
+ | `validationBehavior?` | `'native' \| 'aria'` | 'native' | How `required` is enforced. `'native'` sets the native `required` attribute (browser validation bubble on submit); `'aria'` renders `aria-required="true"` instead and leaves validation to you. |
29
+ | `dir?` | `'ltr' \| 'rtl'` | — | Text direction of the checkbox and its label. Omit to inherit from the closest `dir` ancestor. |
30
+
31
+ Also accepts standard `<input>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `size`.
32
+
33
+ ## Options (allowed values)
34
+ - `placement`: `'start'` \| `'end'` \| `'top'` \| `'bottom'` — Position of the checkbox relative to the label block (Figma Placement).
35
+ - `size`: `'sm'` \| `'md'` \| `'lg'` — Size of the checkbox
36
+ - `variant`: `'primary'` \| `'neutral'` — Visual style variant
37
+ - `validationBehavior`: `'native'` \| `'aria'` — How `required` is enforced. `'native'` sets the native `required` attribute (browser validation
38
+ bubble on submit); `'aria'` renders `aria-required="true"` instead and leaves validation to you.
39
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction of the checkbox and its label. Omit to inherit from the closest `dir` ancestor.
40
+
41
+ ## Deprecated props
42
+ Do not use in new code:
43
+ - `rtl`
44
+
45
+ ## Accessibility
46
+ Built in (SDAIA review item A1) — verified by `tests/a11y/keyboard/mouse-toggles.spec.ts` in the design system's test suite:
47
+ - A click on the box toggles it, also when there is no visible label.
48
+
49
+ You must:
50
+ - Without a visible label, pass `aria-label`.
51
+
52
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
53
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
54
+
55
+ ## Design tokens used
56
+ Keep these consistent (resolve values with `get_tokens`):
57
+ - `var(--ds-color-bg-default)`
58
+ - `var(--ds-color-bg-disabled)`
59
+ - `var(--ds-color-bg-emphasis-high)`
60
+ - `var(--ds-color-border-brand)`
61
+ - `var(--ds-color-button-bg-black-hovered)`
62
+ - `var(--ds-color-button-bg-black-pressed)`
63
+ - `var(--ds-color-button-bg-primary-hovered)`
64
+ - `var(--ds-color-button-bg-primary-pressed)`
65
+ - `var(--ds-color-control-border)`
66
+ - `var(--ds-color-control-border-disabled)`
67
+ - `var(--ds-color-control-neutral-checked)`
68
+ - `var(--ds-color-control-neutral-hovered)`
69
+ - `var(--ds-color-control-pressed)`
70
+ - `var(--ds-color-control-primary-checked)`
71
+ - `var(--ds-color-form-field-border-danger)`
72
+ - `var(--ds-color-icon-brand)`
73
+ - `var(--ds-color-icon-danger)`
74
+ - `var(--ds-color-icon-default-disabled)`
75
+ - `var(--ds-color-icon-oncolor)`
76
+ - `var(--ds-color-text-danger)`
77
+ - `var(--ds-color-text-disabled)`
78
+ - `var(--ds-color-text-display)`
79
+ - `var(--ds-color-text-paragraph)`
80
+ - `var(--ds-icon-lg)`
81
+ - `var(--ds-icon-sm)`
82
+ - `var(--ds-icon-xl)`
83
+ - `var(--ds-motion-feedback-duration)`
84
+ - `var(--ds-motion-feedback-easing)`
85
+ - `var(--ds-radius-figma-xs)`
86
+ - `var(--ds-spacing-md)`
87
+ - `var(--ds-spacing-xl)`
88
+ - `var(--ds-spacing-xs)`
89
+
90
+ ## AI usage guidance
91
+ When generating UI:
92
+ - Install with `npx sdaia-ui@latest add checkbox` (after `npx sdaia-ui@latest init`), then import `{ Checkbox }` from `@/components/ui/Checkbox`.
93
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
94
+ - Use only the documented option values listed under "Options".
95
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
@@ -0,0 +1,63 @@
1
+ # Date Time Field
2
+
3
+ ## Metadata
4
+ - Component: Date Time Field
5
+ - Slug: `date-time-field`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add date-time-field`
8
+ - Import: `import { DateTimeField } from '@/components/ui/DateTimeField'`
9
+ - Installed files: `DateField.tsx`, `DateTimeField.tsx`, `DateTimeField.types.ts`, `DateTimeField.variants.ts`, `date.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/date-time-field
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add date-time-field`. It copies the source into your components folder (`components/ui/DateTimeField/`, under `src/` when the project has one); import it as `@/components/ui/DateTimeField`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `dir?` | `'ltr' \| 'rtl'` | — | Layout direction. In RTL the date field sits at the start (right) and both fields mirror. Unset inherits. |
18
+ | `legend?` | `string` | — | Name of the group, rendered as the fieldset's `<legend>` (visually hidden: the Figma field shows only the two field labels). Screen readers announce it when focus enters either field, e.g. "Appointment". |
19
+ | `dateLabel?` | `string` | — | Label of the date field (Figma "Date"). |
20
+ | `timeLabel?` | `string` | — | Label of the time field (Figma "Time"). |
21
+ | `datePlaceholder?` | `string` | — | Placeholder of the date field, e.g. "DD MMM YYYY". |
22
+ | `timePlaceholder?` | `string` | — | Placeholder of the time field, e.g. "HH:MM". |
23
+ | `value?` | `DateTimeFieldValue` | — | Selected date and time (controlled). |
24
+ | `defaultValue?` | `DateTimeFieldValue` | EMPTY | Initial date and time (uncontrolled). |
25
+ | `onChange?` | `(value: DateTimeFieldValue, text: DateTimeFieldText) => void` | — | Fired when either part changes — typed or picked. A part is `null` when it is empty or its text is not valid; `text` holds both fields' text so you can tell the two apart and validate the pair. |
26
+ | `helperText?` | `string` | — | Helper text shown once under the pair and linked to both fields. |
27
+ | `error?` | `string` | — | Error for the pair (Figma State=Error). Both fields turn red; one message is shown under the pair, linked to both fields and announced. |
28
+ | `required?` | `boolean` | false | Marks both fields as required (visual `*` + required on both inputs). |
29
+ | `disabled?` | `boolean` | false | Disables both fields. |
30
+ | `size?` | `TextInputSize` | — | Field size, passed to both Text Inputs. Unset: responsive (medium below 768px, large from 768px). |
31
+ | `timeFormat?` | `TimeFormat` | '12-hour' | Clock format of the time field and its picker. |
32
+ | `minuteStep?` | `number` | 5 | Minutes between options in the time picker. |
33
+ | `timePickerTitle?` | `string` | — | Title of the time picker header. Omit to hide it. |
34
+ | `calendar?` | `DatePickerCalendar` | 'gregorian' | Calendar of the date picker and of the date text. |
35
+ | `locale?` | `string` | — | BCP 47 locale of the date text and the date picker (digits stay Latin). Defaults to `'ar'` when `dir="rtl"`, else `'en'`. |
36
+ | `minDate?` | `Date` | — | Earliest selectable date. |
37
+ | `maxDate?` | `Date` | — | Latest selectable date. |
38
+ | `formatDate?` | `(date: Date) => string` | — | Formats a date for the field. Default: day, short month name and year in `locale` and `calendar` — "12 Oct 2026" / "12 أكتوبر 2026". |
39
+ | `parseDate?` | `(text: string) => Date \| null` | — | Parses typed date text. Default (Gregorian): `2026-10-12`, `12/10/2026` (day first), `12 Oct 2026`, `12 October 2026`, `12 أكتوبر 2026`, and Arabic-Indic digits. With a Hijri `calendar`, pass your own parser to accept typed Hijri dates. |
40
+ | `labels?` | `Partial<DateTimeFieldLabels>` | — | Localised built-in strings. |
41
+
42
+ Also accepts standard `<element>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `onChange`, `defaultValue`, `dir`.
43
+
44
+ ## Options (allowed values)
45
+ - `dir`: `'ltr'` \| `'rtl'` — Layout direction. In RTL the date field sits at the start (right) and both fields mirror. Unset inherits.
46
+
47
+ ## Accessibility
48
+ - Built-in strings (button names, announcements) come from `labels`; pass translated strings for Arabic or other languages.
49
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
50
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
51
+
52
+ ## Design tokens used
53
+ Keep these consistent (resolve values with `get_tokens`):
54
+ - `var(--ds-spacing-xl)`
55
+ - `var(--ds-spacing-xs)`
56
+
57
+ ## AI usage guidance
58
+ When generating UI:
59
+ - Install with `npx sdaia-ui@latest add date-time-field` (after `npx sdaia-ui@latest init`), then import `{ DateTimeField }` from `@/components/ui/DateTimeField`.
60
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
61
+ - Use only the documented option values listed under "Options".
62
+ - Express the disabled state with the `disabled` prop, not custom styling.
63
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
@@ -0,0 +1,56 @@
1
+ # Error Summary
2
+
3
+ ## Metadata
4
+ - Component: Error Summary
5
+ - Slug: `error-summary`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add error-summary`
8
+ - Import: `import { ErrorSummary } from '@/components/ui/ErrorSummary'`
9
+ - Installed files: `ErrorSummary.tsx`, `ErrorSummary.types.ts`, `ErrorSummary.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/error-summary
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add error-summary`. It copies the source into your components folder (`components/ui/ErrorSummary/`, under `src/` when the project has one); import it as `@/components/ui/ErrorSummary`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `title` | `ReactNode` | — | Calm, plain title (Figma `Title`), e.g. "There is a problem". Rendered as a heading that names the summary. |
18
+ | `intro?` | `ReactNode` | — | Optional line under the title (Figma `Intro`), e.g. "Fix the following to continue:". Omit it to hide it. |
19
+ | `errors` | `ErrorSummaryItem[]` | — | The problems, in the same order as the fields on the page (Figma `Items` 2 / 3 / 4 — any number works in code). Each item renders as a link to its field. |
20
+ | `autoFocus?` | `boolean` | false | Moves keyboard focus to the summary when it mounts. Render the summary after a failed submit with `autoFocus`; when it stays mounted between submits, call `ref.current?.focus()` yourself instead. |
21
+ | `headingLevel?` | `ErrorSummaryHeadingLevel` | 2 | Heading level of the title. |
22
+ | `onErrorClick?` | `(error: ErrorSummaryItem, event: MouseEvent<HTMLAnchorElement>) => void` | — | Called when an item is activated, before focus moves to its field. Call `event.preventDefault()` to handle the navigation yourself. |
23
+ | `dir?` | `'ltr' \| 'rtl'` | — | Text direction of the summary. Inherits from the document when omitted. Figma `RTL=True` maps to `dir="rtl"`. |
24
+
25
+ Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `title`, `dir`, `children`.
26
+
27
+ ## Options (allowed values)
28
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction of the summary. Inherits from the document when omitted.
29
+ Figma `RTL=True` maps to `dir="rtl"`.
30
+
31
+ ## Accessibility
32
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
33
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
34
+
35
+ ## Design tokens used
36
+ Keep these consistent (resolve values with `get_tokens`):
37
+ - `var(--ds-color-bg-danger-subtle)`
38
+ - `var(--ds-color-border-danger-strong)`
39
+ - `var(--ds-color-border-focus)`
40
+ - `var(--ds-color-icon-danger)`
41
+ - `var(--ds-color-text-danger)`
42
+ - `var(--ds-color-text-paragraph)`
43
+ - `var(--ds-radius-m)`
44
+ - `var(--ds-spacing-lg)`
45
+ - `var(--ds-spacing-md)`
46
+ - `var(--ds-spacing-xl)`
47
+ - `var(--ds-spacing-xs)`
48
+ - `var(--ds-text-leading-line-heights-text-md)`
49
+ - `var(--ds-text-leading-line-heights-text-sm)`
50
+
51
+ ## AI usage guidance
52
+ When generating UI:
53
+ - Install with `npx sdaia-ui@latest add error-summary` (after `npx sdaia-ui@latest init`), then import `{ ErrorSummary }` from `@/components/ui/ErrorSummary`.
54
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
55
+ - Use only the documented option values listed under "Options".
56
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
@@ -0,0 +1,57 @@
1
+ # Field Group
2
+
3
+ ## Metadata
4
+ - Component: Field Group
5
+ - Slug: `field-group`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add field-group`
8
+ - Import: `import { FieldGroup } from '@/components/ui/FieldGroup'`
9
+ - Installed files: `FieldGroup.tsx`, `FieldGroup.types.ts`, `FieldGroup.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/field-group
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add field-group`. It copies the source into your components folder (`components/ui/FieldGroup/`, under `src/` when the project has one); import it as `@/components/ui/FieldGroup`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `legend` | `ReactNode` | — | Short title of the group, rendered as the fieldset's `<legend>` (Figma `Legend`). It names the group for screen readers. |
18
+ | `hint?` | `ReactNode` | — | Optional one-line explanation under the legend (Figma `Hint`). It is linked to the fieldset with `aria-describedby`. Omit it to hide the hint. |
19
+ | `layout?` | `'vertical' \| 'horizontal'` | 'vertical' | Arrangement of the fields (Figma `Layout`). |
20
+ | `variant?` | `'plain' \| 'bordered'` | 'plain' | Container style (Figma `Style`). |
21
+ | `dir?` | `'ltr' \| 'rtl'` | — | Text direction of the group. Inherits from the document when omitted. Figma `RTL=True` maps to `dir="rtl"`. |
22
+ | `children` | `ReactNode` | — | The fields of the group (Figma `Fields` slot): `TextInput`, `Select`, radio or checkbox groups… Each field keeps its own visible label. |
23
+
24
+ Also accepts standard `<element>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `dir`, `children`.
25
+
26
+ ## Options (allowed values)
27
+ - `layout`: `'vertical'` \| `'horizontal'` — How the fields in the group are arranged (Figma `Layout`).
28
+ - `vertical` — fields stacked under the legend (the default choice).
29
+ - `horizontal` — two or three short, related fields share one row. The row
30
+ wraps to one field per line when the group is too narrow for them.
31
+ - `variant`: `'plain'` \| `'bordered'` — Container style of the group (Figma `Style`).
32
+ - `plain` — no container; the legend and fields sit on the page.
33
+ - `bordered` — the group sits in its own bordered, padded container.
34
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction of the group. Inherits from the document when omitted.
35
+ Figma `RTL=True` maps to `dir="rtl"`.
36
+
37
+ ## Accessibility
38
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
39
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
40
+
41
+ ## Design tokens used
42
+ Keep these consistent (resolve values with `get_tokens`):
43
+ - `var(--ds-color-border-default)`
44
+ - `var(--ds-color-form-field-text-helper)`
45
+ - `var(--ds-color-text-default)`
46
+ - `var(--ds-radius-m)`
47
+ - `var(--ds-spacing-lg)`
48
+ - `var(--ds-spacing-xl)`
49
+ - `var(--ds-text-leading-line-heights-text-md)`
50
+ - `var(--ds-text-leading-line-heights-text-sm)`
51
+
52
+ ## AI usage guidance
53
+ When generating UI:
54
+ - Install with `npx sdaia-ui@latest add field-group` (after `npx sdaia-ui@latest init`), then import `{ FieldGroup }` from `@/components/ui/FieldGroup`.
55
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
56
+ - Use only the documented option values listed under "Options".
57
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
@@ -0,0 +1,60 @@
1
+ # File Upload
2
+
3
+ ## Metadata
4
+ - Component: File Upload
5
+ - Slug: `file-uploader`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add file-uploader`
8
+ - Import: `import { FileUploader } from '@/components/ui/FileUploader'`
9
+ - Installed files: `FileUploader.tsx`, `FileUploader.types.ts`, `FileUploader.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/file-upload
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add file-uploader`. It copies the source into your components folder (`components/ui/FileUploader/`, under `src/` when the project has one); import it as `@/components/ui/FileUploader`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `dropZone?` | `Partial<FileUploadBaseProps>` | — | Props merged into the drop zone (`FileUploadBase`). Use `onBrowse` to open your own file UI (e.g. a hidden input in the parent); this component does not render `<input type="file" />`. |
18
+ | `files?` | `FileUploaderFileEntry[]` | — | File rows below the drop zone. |
19
+ | `listFooter?` | `ReactNode` | — | Optional custom list content when you do not use `files`. Rendered after `files` if both are set. |
20
+ | `onFilesDropped?` | `(files: FileList) => void` | — | Called after files are dropped on the drop zone. |
21
+ | `onRemoveFile?` | `(id: string) => void` | — | — |
22
+ | `onRetryFile?` | `(id: string) => void` | — | Called with the file's `id` when its "Try again" action is activated. The 'Try again' action on a failed file renders only when this is set. |
23
+ | `retryLabel?` | `ReactNode` | labels.retry ('Try again') | Default “Try again” label for error rows (overridable per `files[].retryLabel`). Wins over `labels.retry`. |
24
+ | `dismissLabel?` | `string` | labels.dismiss ('Remove file') | Default `aria-label` for each row's remove button (overridable per `files[].dismissLabel`). Wins over `labels.dismiss`. |
25
+ | `formatFileSize?` | `FileUploadItemBaseProps['formatFileSize']` | — | Byte formatter for the size line of every row. |
26
+ | `formatUploadProgress?` | `FileUploadItemBaseProps['formatUploadProgress']` | — | Builds each row's size line, e.g. `(u, t) => \`${u} من ${t}\``. Wins over `labels.uploadProgress`. |
27
+ | `labels?` | `Partial<FileUploaderLabels>` | — | Localised built-in strings, passed to the drop zone (`instruction`, `browse`) and to every file row (the rest). `dropZone.label` / `dropZone.browseLabel` / `dropZone.labels`, `retryLabel`, `dismissLabel` and the per-file copy win. |
28
+ | `disabled?` | `boolean` | false | Disables drop zone and browse interaction. |
29
+ | `dir?` | `'ltr' \| 'rtl'` | — | Text direction for the uploader, its drop zone and rows. Undefined inherits from an ancestor; set explicitly for documentation previews. |
30
+
31
+ Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `children`.
32
+
33
+ ## Options (allowed values)
34
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction for the uploader, its drop zone and rows. Undefined inherits
35
+ from an ancestor; set explicitly for documentation previews.
36
+
37
+ ## Deprecated props
38
+ Do not use in new code:
39
+ - `rtl`
40
+
41
+ ## Accessibility
42
+ Built in (SDAIA review item A7) — verified by `axe scan (aria-progressbar-name) — audit-reports/a11y` in the design system's test suite:
43
+ - Each upload progress bar has an accessible name.
44
+
45
+ - Built-in strings (button names, announcements) come from `labels`; pass translated strings for Arabic or other languages.
46
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
47
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
48
+
49
+ ## Design tokens used
50
+ Keep these consistent (resolve values with `get_tokens`):
51
+ - `var(--ds-spacing-md)`
52
+ - `var(--ds-spacing-xl)`
53
+
54
+ ## AI usage guidance
55
+ When generating UI:
56
+ - Install with `npx sdaia-ui@latest add file-uploader` (after `npx sdaia-ui@latest init`), then import `{ FileUploader }` from `@/components/ui/FileUploader`.
57
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
58
+ - Use only the documented option values listed under "Options".
59
+ - Express the disabled state with the `disabled` prop, not custom styling.
60
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
@@ -0,0 +1,58 @@
1
+ # Form Section
2
+
3
+ ## Metadata
4
+ - Component: Form Section
5
+ - Slug: `form-section`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add form-section`
8
+ - Import: `import { FormSection } from '@/components/ui/FormSection'`
9
+ - Installed files: `FormSection.tsx`, `FormSection.types.ts`, `FormSection.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/form-section
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add form-section`. It copies the source into your components folder (`components/ui/FormSection/`, under `src/` when the project has one); import it as `@/components/ui/FormSection`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `title` | `ReactNode` | — | Section title (Figma `Title`), rendered as a real heading that names the section. |
18
+ | `description?` | `ReactNode` | — | Optional one-sentence description under the title (Figma `Description`). Linked to the section with `aria-describedby`. Omit it to hide it. |
19
+ | `layout?` | `'stacked' \| 'side-by-side'` | 'stacked' | Title placement (Figma `Layout`). |
20
+ | `headingLevel?` | `FormSectionHeadingLevel` | 2 | Heading level of the title. Pick the level that fits the page outline (the page title is usually `h1`). |
21
+ | `dir?` | `'ltr' \| 'rtl'` | — | Text direction of the section. Inherits from the document when omitted. Figma `RTL=True` maps to `dir="rtl"`. |
22
+ | `children` | `ReactNode` | — | The fields of the section (Figma `Fields` slot): `FieldGroup`s, inputs or any form content. |
23
+
24
+ Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `title`, `dir`, `children`.
25
+
26
+ ## Options (allowed values)
27
+ - `layout`: `'stacked'` \| `'side-by-side'` — Where the title sits relative to the fields (Figma `Layout`).
28
+ - `stacked` — the title and description sit above the fields.
29
+ - `side-by-side` — the title sits in a 280px column next to the fields
30
+ (start side: left in LTR, right in RTL). When the section is narrower than
31
+ 40rem (640px) it falls back to the stacked layout, as the Figma usage note
32
+ asks ("Stacked below 1024px screens").
33
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction of the section. Inherits from the document when omitted.
34
+ Figma `RTL=True` maps to `dir="rtl"`.
35
+
36
+ ## Accessibility
37
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
38
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
39
+
40
+ ## Design tokens used
41
+ Keep these consistent (resolve values with `get_tokens`):
42
+ - `var(--ds-color-border-muted)`
43
+ - `var(--ds-color-text-default)`
44
+ - `var(--ds-color-text-paragraph-muted)`
45
+ - `var(--ds-spacing-2xl)`
46
+ - `var(--ds-spacing-3xl)`
47
+ - `var(--ds-spacing-4xl)`
48
+ - `var(--ds-spacing-xl)`
49
+ - `var(--ds-spacing-xs)`
50
+ - `var(--ds-text-leading-line-heights-text-lg)`
51
+ - `var(--ds-text-leading-line-heights-text-sm)`
52
+
53
+ ## AI usage guidance
54
+ When generating UI:
55
+ - Install with `npx sdaia-ui@latest add form-section` (after `npx sdaia-ui@latest init`), then import `{ FormSection }` from `@/components/ui/FormSection`.
56
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
57
+ - Use only the documented option values listed under "Options".
58
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.
@@ -0,0 +1,92 @@
1
+ # Number Input
2
+
3
+ ## Metadata
4
+ - Component: Number Input
5
+ - Slug: `number-input`
6
+ - Category: Form
7
+ - Install: `npx sdaia-ui@latest add number-input`
8
+ - Import: `import { NumberInput } from '@/components/ui/NumberInput'`
9
+ - Installed files: `NumberInput.tsx`, `NumberInput.types.ts`, `NumberInput.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/number-input
11
+
12
+ > **Hard rule:** `sdaia-ui` is a CLI, not a runtime package — NEVER run `npm install sdaia-ui` and NEVER `import … from 'sdaia-ui'`. Run `npx sdaia-ui@latest init` once per project (Tailwind CSS v4, tokens, the IBM Plex Sans Arabic font, the `@/` alias on Vite, `cn`), then `npx sdaia-ui@latest add number-input`. It copies the source into your components folder (`components/ui/NumberInput/`, under `src/` when the project has one); import it as `@/components/ui/NumberInput`. The files are yours: prefer props and composition over editing them. `npx sdaia-ui@latest update` never overwrites a file you changed: it keeps it and says it has updates; `diff` shows them and `update --force` takes them.
13
+
14
+ ## Props
15
+ | Prop | Type | Default | Description |
16
+ | --- | --- | --- | --- |
17
+ | `label?` | `string` | — | Label text displayed above the input. Rendered as a `<label>` associated with the `<input>` via `htmlFor`. |
18
+ | `labelHelp?` | `ReactNode` | — | Extra content rendered right after the label text, e.g. a `<HelpIcon>`. It sits in the label row but OUTSIDE the `<label>` element, so its own accessible name (e.g. "Help") is not added to the field's name. |
19
+ | `validationBehavior?` | `'native' \| 'aria'` | 'native' | How `required` is applied to the native input. - `'native'`: the native `required` attribute (browser validation bubble on submit). - `'aria'`: `aria-required="true"` only — no browser bubble; validate in your own code. The visual `*` after the label shows in both modes. |
20
+ | `dir?` | `'ltr' \| 'rtl'` | — | Text direction of the field. Unset inherits from the closest `dir` ancestor. The minus button sits on the start side, plus / arrow on the end side. |
21
+ | `labels?` | `Partial<NumberInputLabels>` | — | Localised built-in strings (button names). |
22
+ | `size?` | `'lg' \| 'md'` | 'lg' | Size tier. |
23
+ | `style?` | `'solid' \| 'subtle'` | 'solid' | Visual fill style for the flanking +/− buttons. |
24
+ | `spinner?` | `boolean` | false | When `true`, renders a single arrow (unfold-more) button on the end side instead of separate minus + plus buttons. The center input gains start-side border-radius. |
25
+ | `value?` | `string \| number` | — | Controlled current value. Pass `''` to represent an empty/cleared field. |
26
+ | `defaultValue?` | `string \| number` | — | Uncontrolled default value. |
27
+ | `onChange?` | `(value: string) => void` | — | Called with the raw string value whenever the input changes (typing or button press). |
28
+ | `min?` | `number` | — | Minimum numeric value. Respected by the decrement button — will not go below this value. |
29
+ | `max?` | `number` | — | Maximum numeric value. Respected by the increment button — will not go above this value. |
30
+ | `step?` | `number` | 1 | Step size for increment/decrement buttons. |
31
+ | `error?` | `string` | — | Error message string. When non-empty: - input border turns red - helper text below turns red and shows this message - helper icon turns red Overrides `helperText`. |
32
+ | `helperText?` | `string` | — | Helper text shown below the input. Replaced by `error` when error is set. |
33
+ | `showHelperIcon?` | `boolean` | true | When `true`, shows the help-circle icon next to helper/error text. |
34
+ | `disabled?` | `boolean` | false | Disables all interaction on the entire component. |
35
+
36
+ Also accepts standard `<input>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `size`, `type`, `onChange`, `style`.
37
+
38
+ ## Options (allowed values)
39
+ - `validationBehavior`: `'native'` \| `'aria'` — Native `required` handling — see `NumberInputProps.validationBehavior`.
40
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction of the field. Unset inherits from the closest `dir` ancestor.
41
+ The minus button sits on the start side, plus / arrow on the end side.
42
+ - `size`: `'lg'` \| `'md'` — Size tier — maps to Figma Large / Medium.
43
+
44
+ - `'lg'` — Large (height ~40px for buttons, px-xl/py-md for input)
45
+ - `'md'` — Medium (height ~32px for buttons, px-xl/py-sm for input)
46
+ - `style`: `'solid'` \| `'subtle'` — Visual fill style for the prefix/suffix buttons.
47
+
48
+ - `'solid'` — neutral-fill background on +/− buttons
49
+ - `'subtle'` — transparent buttons; fill appears only on hover/active
50
+
51
+ ## Accessibility
52
+ - Built-in strings (button names, announcements) come from `labels`; pass translated strings for Arabic or other languages.
53
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
54
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
55
+
56
+ ## Design tokens used
57
+ Keep these consistent (resolve values with `get_tokens`):
58
+ - `var(--ds-color-)`
59
+ - `var(--ds-color-border-brand)`
60
+ - `var(--ds-color-border-disabled)`
61
+ - `var(--ds-color-form-field-bg-default)`
62
+ - `var(--ds-color-form-field-border-danger)`
63
+ - `var(--ds-color-form-field-border-default)`
64
+ - `var(--ds-color-form-field-border-hovered)`
65
+ - `var(--ds-color-form-field-text-filled)`
66
+ - `var(--ds-color-form-field-text-helper)`
67
+ - `var(--ds-color-form-field-text-label)`
68
+ - `var(--ds-color-form-field-text-placeholder)`
69
+ - `var(--ds-color-icon-danger)`
70
+ - `var(--ds-color-icon-default-500)`
71
+ - `var(--ds-color-icon-default-disabled)`
72
+ - `var(--ds-color-primitive-neutral-400)`
73
+ - `var(--ds-color-text-danger)`
74
+ - `var(--ds-color-text-disabled)`
75
+ - `var(--ds-motion-feedback-duration)`
76
+ - `var(--ds-motion-feedback-easing)`
77
+ - `var(--ds-radius-m)`
78
+ - `var(--ds-spacing-2xl)`
79
+ - `var(--ds-spacing-md)`
80
+ - `var(--ds-spacing-sm)`
81
+ - `var(--ds-spacing-xl)`
82
+ - `var(--ds-spacing-xs)`
83
+ - `var(--ds-spacing-xxs)`
84
+
85
+ ## AI usage guidance
86
+ When generating UI:
87
+ - Install with `npx sdaia-ui@latest add number-input` (after `npx sdaia-ui@latest init`), then import `{ NumberInput }` from `@/components/ui/NumberInput`.
88
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
89
+ - Use only the documented option values listed under "Options".
90
+ - Pass icons via `<DgaIcon data={…} className="size-icon-sm" />` from `@platformscode/icons` only — see `get_foundations` (`icon-usage`). Never emoji, Lucide, or random icons (e.g. `pizza01Stroke` for dark mode).
91
+ - Express the disabled state with the `disabled` prop, not custom styling.
92
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.