@sdaia-ds/mcp 0.0.0-stage → 3.1.0

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 +1113 -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 +12080 -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,82 @@
1
+ # Button Menu
2
+
3
+ ## Metadata
4
+ - Component: Button Menu
5
+ - Slug: `button-menu`
6
+ - Category: Actions
7
+ - Install: `npx sdaia-ui@latest add button-menu`
8
+ - Import: `import { ButtonMenu } from '@/components/ui/ButtonMenu'`
9
+ - Installed files: `ButtonMenu.tsx`, `ButtonMenu.types.ts`, `ButtonMenu.variants.ts`, `ButtonMenuPanel.tsx`, `index.ts`, `useMenuButton.ts`
10
+ - Docs: https://ds.nacew.com/components/buttonmenu
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 button-menu`. It copies the source into your components folder (`components/ui/ButtonMenu/`, under `src/` when the project has one); import it as `@/components/ui/ButtonMenu`. 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 applied to the trigger (and its menu). Leave unset to inherit. |
18
+ | `variant?` | `'neutral' \| 'primary' \| 'secondary-solid' \| 'secondary-outline' \| 'subtle' \| 'transparent'` | 'neutral' | Visual style variant. Defaults to 'neutral'. |
19
+ | `size?` | `'sm' \| 'md' \| 'lg'` | 'md' | Size tier. Defaults to 'md'. |
20
+ | `leadingIcon?` | `ReactNode` | — | Icon displayed before the label. Direction-aware: appears on the logical start side. |
21
+ | `iconOnly?` | `boolean` | false | When true: renders only the leading icon + trailing chevron, no label text. Uses the same padding as a regular button (not the square icon-only padding). Give the button an accessible name with `aria-label`. |
22
+ | `disabled?` | `boolean` | false | Disables the button and prevents interaction. |
23
+ | `selected?` | `boolean` | false | Shows the selected (pressed-in) look. ButtonMenu also shows it while its menu is open. Unlike Button, it never sets `aria-pressed` — a menu button exposes `aria-expanded` instead. |
24
+ | `fullWidth?` | `boolean` | false | Makes the button take the full width of its container. |
25
+ | `as?` | `ElementType` | — | Override the rendered HTML element (e.g. 'a' for link-styled trigger). |
26
+ | `children?` | `ReactNode` | — | Button label. Hidden when iconOnly is true. |
27
+ | `menuItems?` | `ButtonMenuItem[]` | — | Actions of the built-in WAI-ARIA menu. When provided, clicking the button (or pressing Enter / Space / ArrowDown / ArrowUp) opens a `role="menu"` panel with full keyboard support. Omit it to wire your own menu and pass `open` so the trigger exposes `aria-expanded`. |
28
+ | `open?` | `boolean` | — | Open state of the menu (controlled). Sets `aria-expanded` on the trigger — also when you render your own menu instead of `menuItems`. |
29
+ | `defaultOpen?` | `boolean` | — | Initial open state when uncontrolled (built-in menu only). |
30
+ | `onOpenChange?` | `(open: boolean) => void` | — | Called when the built-in menu opens or closes. |
31
+ | `menuAlign?` | `'start' \| 'end'` | 'start' | Which edge of the trigger the built-in menu aligns to (logical, so it flips in RTL). Use 'end' for overflow menus near the end of a row. |
32
+
33
+ Also accepts standard `<button>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `dir`.
34
+
35
+ ## Options (allowed values)
36
+ - `dir`: `'ltr'` \| `'rtl'` — Text direction applied to the trigger (and its menu). Leave unset to inherit.
37
+ - `variant`: `'neutral'` \| `'primary'` \| `'secondary-solid'` \| `'secondary-outline'` \| `'subtle'` \| `'transparent'` — Six visual styles — matches Figma "Button_Menu" Style property exactly.
38
+ Maps 1-to-1 to the existing Button variants.
39
+ Destructive is excluded — not in the Figma ButtonMenu spec.
40
+ - `size`: `'sm'` \| `'md'` \| `'lg'` — Three sizes — maps Figma Large→lg, Medium→md, Small→sm
41
+ - `menuAlign`: `'start'` \| `'end'` — Which edge of the trigger the built-in menu aligns to (logical, so it
42
+ flips in RTL). Use 'end' for overflow menus near the end of a row.
43
+
44
+ ## Deprecated props
45
+ Do not use in new code:
46
+ - `rtl`
47
+
48
+ ## Accessibility
49
+ - Icon-only usage must include an accessible label (`aria-label`).
50
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
51
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
52
+
53
+ ## Design tokens used
54
+ Keep these consistent (resolve values with `get_tokens`):
55
+ - `var(--ds-color-bg-emphasis-high)`
56
+ - `var(--ds-color-bg-raised)`
57
+ - `var(--ds-color-border-danger-strong)`
58
+ - `var(--ds-color-border-default)`
59
+ - `var(--ds-color-button-bg-danger-secondary-default)`
60
+ - `var(--ds-color-button-bg-danger-secondary-hovered)`
61
+ - `var(--ds-color-form-option-bg-hover)`
62
+ - `var(--ds-color-form-option-bg-pressed)`
63
+ - `var(--ds-color-text-danger)`
64
+ - `var(--ds-color-text-default)`
65
+ - `var(--ds-color-text-disabled)`
66
+ - `var(--ds-motion-feedback-duration)`
67
+ - `var(--ds-motion-feedback-easing)`
68
+ - `var(--ds-radius-m)`
69
+ - `var(--ds-radius-xxs)`
70
+ - `var(--ds-spacing-lg)`
71
+ - `var(--ds-spacing-md)`
72
+ - `var(--ds-spacing-sm)`
73
+ - `var(--ds-spacing-xs)`
74
+
75
+ ## AI usage guidance
76
+ When generating UI:
77
+ - Install with `npx sdaia-ui@latest add button-menu` (after `npx sdaia-ui@latest init`), then import `{ ButtonMenu }` from `@/components/ui/ButtonMenu`.
78
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
79
+ - Use only the documented option values listed under "Options".
80
+ - 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).
81
+ - Express the disabled state with the `disabled` prop, not custom styling.
82
+ - 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,69 @@
1
+ # Button Split
2
+
3
+ ## Metadata
4
+ - Component: Button Split
5
+ - Slug: `button-split`
6
+ - Category: Actions
7
+ - Install: `npx sdaia-ui@latest add button-split`
8
+ - Import: `import { ButtonSplit } from '@/components/ui/ButtonSplit'`
9
+ - Installed files: `ButtonSplit.tsx`, `ButtonSplit.types.ts`, `ButtonSplit.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/buttonsplit
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 button-split`. It copies the source into your components folder (`components/ui/ButtonSplit/`, under `src/` when the project has one); import it as `@/components/ui/ButtonSplit`. 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 for the main action button. Use `label` for the explicit prop-driven API (preferred). |
18
+ | `variant?` | `'neutral' \| 'primary' \| 'secondary-solid' \| 'secondary-outline' \| 'subtle' \| 'transparent'` | 'neutral' | Visual style variant. Defaults to 'neutral'. |
19
+ | `size?` | `'sm' \| 'md' \| 'lg'` | 'md' | Size tier. Defaults to 'md'. |
20
+ | `leadingIcon?` | `ReactNode` | — | Icon displayed before the label in the main action button. Direction-aware: appears on the logical-start side. |
21
+ | `onClick?` | `ButtonHTMLAttributes<HTMLButtonElement>['onClick']` | — | Click handler for the main action button (start section). Separate from the dropdown menu button click. |
22
+ | `onMenuClick?` | `ButtonHTMLAttributes<HTMLButtonElement>['onClick']` | — | Click handler for the dropdown/menu chevron button (end section). Called when the chevron is clicked regardless of `open` / `onOpenChange`. |
23
+ | `menuItems?` | `ButtonSplitMenuItem[]` | — | Items rendered inside the dropdown menu panel. When provided, clicking the chevron toggles the panel. |
24
+ | `open?` | `boolean` | — | Controlled open state of the dropdown panel. When provided together with `onOpenChange`, the component is fully controlled. |
25
+ | `onOpenChange?` | `(open: boolean) => void` | — | Called when the open state should change (controlled mode). |
26
+ | `labels?` | `Partial<ButtonSplitLabels>` | — | Translatable built-in strings (English defaults). |
27
+ | `defaultOpen?` | `boolean` | — | Initial open state of the dropdown panel when uncontrolled. |
28
+ | `disabled?` | `boolean` | false | Disables both button sections simultaneously. |
29
+ | `className?` | `string` | — | Additional className applied to the outer wrapper. |
30
+ | `dir?` | `'ltr' \| 'rtl'` | — | Direction override for RTL layout. Leave unset to inherit. |
31
+ | `mainButtonProps?` | `Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' \| 'disabled'>` | — | Extra props forwarded to the main action button element. |
32
+ | `menuButtonProps?` | `Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' \| 'disabled'>` | — | Extra props forwarded to the menu/chevron button element. |
33
+
34
+ ## Options (allowed values)
35
+ - `variant`: `'neutral'` \| `'primary'` \| `'secondary-solid'` \| `'secondary-outline'` \| `'subtle'` \| `'transparent'` — Six visual styles — matches Figma "Button_Split" Style property exactly.
36
+ "Transparence" (Figma typo) is normalised to "transparent" in the API.
37
+ Maps 1-to-1 to the existing Button variant names.
38
+ - `size`: `'sm'` \| `'md'` \| `'lg'` — Three sizes — maps Figma Large→lg, Medium→md, Small→sm
39
+ - `dir`: `'ltr'` \| `'rtl'` — Direction override for RTL layout. Leave unset to inherit.
40
+
41
+ ## Deprecated props
42
+ Do not use in new code:
43
+ - `children` — Legacy children API — used as label text when `label` is not provided.
44
+ - `menuAriaLabel` — Accessible label for the chevron/menu button.
45
+ - `rtl`
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-color-border-default)`
55
+ - `var(--ds-color-border-muted)`
56
+ - `var(--ds-color-border-on-dark-40)`
57
+ - `var(--ds-spacing-lg)`
58
+ - `var(--ds-spacing-md)`
59
+ - `var(--ds-spacing-xl)`
60
+ - `var(--ds-spacing-xs)`
61
+
62
+ ## AI usage guidance
63
+ When generating UI:
64
+ - Install with `npx sdaia-ui@latest add button-split` (after `npx sdaia-ui@latest init`), then import `{ ButtonSplit }` from `@/components/ui/ButtonSplit`.
65
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
66
+ - Use only the documented option values listed under "Options".
67
+ - 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).
68
+ - Express the disabled state with the `disabled` prop, not custom styling.
69
+ - 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,101 @@
1
+ # Button
2
+
3
+ ## Metadata
4
+ - Component: Button
5
+ - Slug: `button`
6
+ - Category: Actions
7
+ - Install: `npx sdaia-ui@latest add button`
8
+ - Import: `import { Button } from '@/components/ui/Button'`
9
+ - Installed files: `Button.tsx`, `Button.types.ts`, `Button.variants.ts`, `index.ts`, `resolveButtonStyle.ts`
10
+ - Docs: https://ds.nacew.com/components/button
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 button`. It copies the source into your components folder (`components/ui/Button/`, under `src/` when the project has one); import it as `@/components/ui/Button`. 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?` | `ButtonHTMLAttributes<HTMLButtonElement>['dir']` | — | Text direction applied to the button root. Leave unset to inherit from the page; icons placed with `leadingIcon` / `trailingIcon` follow it. Use 'ltr' \| 'rtl'; typed as the native `dir` attribute for backward compatibility. |
18
+ | `variant?` | `'neutral' \| 'primary' \| 'secondary-solid' \| 'secondary-outline' \| 'subtle' \| 'transparent'` | 'primary' | Visual style of the button |
19
+ | `size?` | `'sm' \| 'md' \| 'lg'` | 'md' | Size of the button |
20
+ | `disabled?` | `boolean` | false | Disables the button and prevents interaction |
21
+ | `leadingIcon?` | `ReactNode` | — | Icon displayed before the button label (direction-aware) |
22
+ | `trailingIcon?` | `ReactNode` | — | Icon displayed after the button label (direction-aware) |
23
+ | `iconOnly?` | `boolean` | false | Renders the button as a square icon-only button |
24
+ | `selected?` | `boolean` | false | Marks the button as selected (toggled on) |
25
+ | `fullWidth?` | `boolean` | false | Makes the button take the full width of its container |
26
+ | `destructive?` | `boolean` | false | Applies destructive (danger) styling to the current `variant`. Matches Figma `Destructive=True` — not a separate style value. Works with: primary, secondary-solid, secondary-outline, subtle, transparent. |
27
+ | `as?` | `ElementType` | — | Override the rendered HTML element |
28
+ | `href?` | `string` | — | Destination URL when rendering the button as a link (`as="a"`). Only meaningful on an anchor element. |
29
+ | `target?` | `HTMLAttributeAnchorTarget` | — | Anchor `target` — only meaningful alongside `href`. |
30
+ | `rel?` | `string` | — | Anchor `rel` — only meaningful alongside `href`. |
31
+ | `children?` | `ReactNode` | — | — |
32
+
33
+ Also accepts standard `<button>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …).
34
+
35
+ ## Options (allowed values)
36
+ - `variant`: `'neutral'` \| `'primary'` \| `'secondary-solid'` \| `'secondary-outline'` \| `'subtle'` \| `'transparent'` — Style variants — matches Figma `Style` (Transparent, not ghost).
37
+ - `size`: `'sm'` \| `'md'` \| `'lg'` — Size of the button
38
+
39
+ ## Deprecated props
40
+ Do not use in new code:
41
+ - `rtl`
42
+ - `leftIcon`
43
+ - `rightIcon`
44
+
45
+ ## Accessibility
46
+ - Icon-only usage must include an accessible label (`aria-label`).
47
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
48
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
49
+
50
+ ## Design tokens used
51
+ Keep these consistent (resolve values with `get_tokens`):
52
+ - `var(--ds-color-)`
53
+ - `var(--ds-color-bg-default)`
54
+ - `var(--ds-color-bg-disabled)`
55
+ - `var(--ds-color-bg-emphasis-high)`
56
+ - `var(--ds-color-bg-subtle)`
57
+ - `var(--ds-color-border-brand)`
58
+ - `var(--ds-color-border-danger-strong)`
59
+ - `var(--ds-color-border-danger-subtle)`
60
+ - `var(--ds-color-border-default)`
61
+ - `var(--ds-color-border-focus)`
62
+ - `var(--ds-color-border-muted)`
63
+ - `var(--ds-color-button-bg-black-default)`
64
+ - `var(--ds-color-button-bg-black-focused)`
65
+ - `var(--ds-color-button-bg-black-hovered)`
66
+ - `var(--ds-color-button-bg-black-pressed)`
67
+ - `var(--ds-color-button-bg-black-selected)`
68
+ - `var(--ds-color-button-bg-danger-primary-default)`
69
+ - `var(--ds-color-button-bg-danger-primary-hovered)`
70
+ - `var(--ds-color-button-bg-danger-primary-pressed)`
71
+ - `var(--ds-color-button-bg-danger-primary-selected)`
72
+ - `var(--ds-color-button-bg-danger-secondary-default)`
73
+ - `var(--ds-color-button-bg-danger-secondary-hovered)`
74
+ - `var(--ds-color-button-bg-danger-secondary-pressed)`
75
+ - `var(--ds-color-button-bg-neutral-default)`
76
+ - `var(--ds-color-button-bg-neutral-hovered)`
77
+ - `var(--ds-color-button-bg-neutral-pressed)`
78
+ - `var(--ds-color-button-bg-neutral-selected)`
79
+ - `var(--ds-color-button-bg-primary-default)`
80
+ - `var(--ds-color-button-bg-primary-hovered)`
81
+ - `var(--ds-color-button-bg-primary-pressed)`
82
+ - `var(--ds-color-button-bg-primary-selected)`
83
+ - `var(--ds-color-icon-danger)`
84
+ - `var(--ds-color-link-danger)`
85
+ - `var(--ds-color-link-danger-hovered)`
86
+ - `var(--ds-color-link-danger-pressed)`
87
+ - `var(--ds-color-link-icon-danger-hovered)`
88
+ - `var(--ds-color-link-icon-danger-pressed)`
89
+ - `var(--ds-color-link-primary)`
90
+ - `var(--ds-color-link-primary-hovered)`
91
+ - `var(--ds-color-link-primary-pressed)`
92
+ - …and 10 more
93
+
94
+ ## AI usage guidance
95
+ When generating UI:
96
+ - Install with `npx sdaia-ui@latest add button` (after `npx sdaia-ui@latest init`), then import `{ Button }` from `@/components/ui/Button`.
97
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
98
+ - Use only the documented option values listed under "Options".
99
+ - 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).
100
+ - Express the disabled state with the `disabled` prop, not custom styling.
101
+ - 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,66 @@
1
+ # Content Switcher
2
+
3
+ ## Metadata
4
+ - Component: Content Switcher
5
+ - Slug: `content-switcher`
6
+ - Category: Actions
7
+ - Install: `npx sdaia-ui@latest add content-switcher`
8
+ - Import: `import { ContentSwitcher } from '@/components/ui/ContentSwitcher'`
9
+ - Installed files: `ContentSwitcher.tsx`, `ContentSwitcher.types.ts`, `ContentSwitcher.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/contentswitcher
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 content-switcher`. It copies the source into your components folder (`components/ui/ContentSwitcher/`, under `src/` when the project has one); import it as `@/components/ui/ContentSwitcher`. 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
+ | `items` | `ContentSwitcherItem[]` | — | Array of switcher items (2–5) |
18
+ | `size?` | `'sm' \| 'md' \| 'lg'` | 'sm' | Size of the switcher |
19
+ | `border?` | `boolean` | false | Figma Border — outer container stroke when true. |
20
+ | `placement?` | `'start' \| 'center' \| 'end'` | 'start' | Figma Placement — aligns the switcher track within a full-width parent. |
21
+ | `dir?` | `'ltr' \| 'rtl'` | — | Layout direction. Arrow keys follow it (Left/Right swap in RTL). |
22
+ | `value?` | `string` | — | Controlled selected value |
23
+ | `defaultValue?` | `string` | — | Initial selected value (uncontrolled) — defaults to first item |
24
+ | `onValueChange?` | `(value: string) => void` | — | Called with the selected item's value when selection changes |
25
+
26
+ Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …).
27
+
28
+ ## Options (allowed values)
29
+ - `size`: `'sm'` \| `'md'` \| `'lg'` — Size of the switcher
30
+ - `placement`: `'start'` \| `'center'` \| `'end'` — Figma Placement — horizontal alignment of the switcher within its container.
31
+ - `dir`: `'ltr'` \| `'rtl'` — Layout direction. Arrow keys follow it (Left/Right swap in RTL).
32
+
33
+ ## Deprecated props
34
+ Do not use in new code:
35
+ - `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-)`
44
+ - `var(--ds-color-border-brand)`
45
+ - `var(--ds-color-border-default)`
46
+ - `var(--ds-color-button-bg-black-default)`
47
+ - `var(--ds-color-button-bg-neutral-default)`
48
+ - `var(--ds-color-button-bg-neutral-hovered)`
49
+ - `var(--ds-color-text-default)`
50
+ - `var(--ds-color-text-on-color)`
51
+ - `var(--ds-motion-feedback-duration)`
52
+ - `var(--ds-motion-feedback-easing)`
53
+ - `var(--ds-radius-m)`
54
+ - `var(--ds-spacing-2xl)`
55
+ - `var(--ds-spacing-3xl)`
56
+ - `var(--ds-spacing-md)`
57
+ - `var(--ds-spacing-sm)`
58
+ - `var(--ds-spacing-xl)`
59
+ - `var(--ds-spacing-xs)`
60
+
61
+ ## AI usage guidance
62
+ When generating UI:
63
+ - Install with `npx sdaia-ui@latest add content-switcher` (after `npx sdaia-ui@latest init`), then import `{ ContentSwitcher }` from `@/components/ui/ContentSwitcher`.
64
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
65
+ - Use only the documented option values listed under "Options".
66
+ - 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,115 @@
1
+ # Date Picker
2
+
3
+ ## Metadata
4
+ - Component: Date Picker
5
+ - Slug: `date-picker`
6
+ - Category: Actions
7
+ - Install: `npx sdaia-ui@latest add date-picker`
8
+ - Import: `import { DatePicker } from '@/components/ui/DatePicker'`
9
+ - Installed files: `DatePicker.tsx`, `DatePicker.types.ts`, `DatePicker.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/datepicker
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-picker`. It copies the source into your components folder (`components/ui/DatePicker/`, under `src/` when the project has one); import it as `@/components/ui/DatePicker`. 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 — applied to the root element for RTL support. Unset inherits. |
18
+ | `locale?` | `string` | — | BCP 47 locale of the built-in month / weekday names and date formats (digits stay Latin), e.g. `'ar'` or `'en-GB'`. `labels` overrides win. Defaults to `'ar'` when `dir="rtl"`, else `'en'`. Without `dir`, it follows the inherited language / direction: `'ar'` inside an Arabic (`lang="ar…"`) or RTL ancestor, else `'en'`. |
19
+ | `type?` | `'default' \| 'withSidepanel'` | 'default' | Layout type — `'default'` (no sidepanel) or `'withSidepanel'`. Defaults to `'default'`. |
20
+ | `single?` | `boolean` | false | Render a single calendar pane instead of two side-by-side panes. Works with either `type`. Defaults to `false`. |
21
+ | `surface?` | `'solid' \| 'glass'` | 'solid' | Surface treatment — `'solid'` (default) or `'glass'` (translucent liquid-glass material). Applies to both the desktop and mobile layouts. |
22
+ | `calendar?` | `'hijri' \| 'hijri-gregorian' \| 'gregorian' \| 'gregorian-hijri'` | — | Calendar system and date-label order. Defaults to `'hijri'`. |
23
+ | `mobile?` | `boolean` | — | Compact mobile layout — single calendar, stacked action row, preset as a select. |
24
+ | `range?` | `boolean` | false | Enable range selection (start + end date). |
25
+ | `value?` | `Date \| null` | — | Controlled single-date value. |
26
+ | `rangeValue?` | `DateRange` | — | Controlled range value. |
27
+ | `defaultValue?` | `Date \| null` | null | Uncontrolled initial single-date value. |
28
+ | `defaultRangeValue?` | `DateRange` | { start: null, end: null } | Uncontrolled initial range value. |
29
+ | `onChange?` | `(date: Date \| null) => void` | — | Fired when a date is picked (single mode). |
30
+ | `onRangeChange?` | `(range: DateRange) => void` | — | Fired whenever the range changes (range mode). |
31
+ | `onSubmit?` | `(value: DateRange) => void` | — | Fired when the Submit button is clicked. |
32
+ | `onCancel?` | `() => void` | — | Fired when the Cancel button is clicked — and when Escape is pressed inside the picker. When the picker lives in a popup, close the popup here and move focus back to the element that opened it. |
33
+ | `presets?` | `boolean \| DatePickerPreset[]` | — | Preset sidebar configuration. - `true` (default for `type="withSidepanel"`) — show all presets. - `false` — hide presets entirely. - `string[]` — show only the listed presets, in that order. When `type="default"`, presets default to `false` (no sidebar). |
34
+ | `showDateInputs?` | `boolean` | — | Show the date-input fields at the bottom. Defaults to `true`. |
35
+ | `showSecondMonth?` | `boolean` | — | Show the second calendar pane. Defaults to `!single` (two panes unless single). |
36
+ | `minDate?` | `Date` | — | Minimum selectable date (inclusive). |
37
+ | `maxDate?` | `Date` | — | Maximum selectable date (inclusive). |
38
+ | `labels?` | `Partial<DatePickerLabels>` | — | Localised built-in strings. |
39
+ | `presetFooter?` | `ReactNode` | — | Rendered after the preset list (advanced slot, e.g. custom preset). |
40
+
41
+ Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `onChange`, `defaultValue`, `onSubmit`, `dir`.
42
+
43
+ ## Options (allowed values)
44
+ - `dir`: `'ltr'` \| `'rtl'` — Layout direction — applied to the root element for RTL support. Unset inherits.
45
+ - `type`: `'default'` \| `'withSidepanel'` — Date picker layout type.
46
+ - `'default'` — calendar(s) only, no preset sidebar.
47
+ - `'withSidepanel'` — adds the preset sidebar (Today, Yesterday, …) on the inline-start edge.
48
+
49
+ The previous `'single' | 'dual'` API has been collapsed into the `single`
50
+ boolean prop — pass `single={true}` with either type to render one calendar
51
+ pane instead of two.
52
+ - `surface`: `'solid'` \| `'glass'` — Surface treatment of the picker card.
53
+ - `'solid'` (default) — opaque card with the standard drop shadow.
54
+ - `'glass'` — translucent liquid-glass material (blurred backdrop +
55
+ beveled edge highlight). Reads best placed over imagery or color.
56
+
57
+ The visual is provided by the shared `.glass-surface` utility, so it is
58
+ theme-aware (light / dark) and identical across every component that
59
+ exposes a `surface` prop.
60
+ - `calendar`: `'hijri'` \| `'hijri-gregorian'` \| `'gregorian'` \| `'gregorian-hijri'` — Calendar system and date-label order.
61
+
62
+ The first calendar is the primary calendar: it controls the visible month,
63
+ navigation, month/year menus, and primary date-cell label. The optional
64
+ second calendar is rendered as supporting text.
65
+
66
+ ## Deprecated props
67
+ Do not use in new code:
68
+ - `showHijri`
69
+
70
+ ## Accessibility
71
+ Built in (SDAIA review item A5) — verified by `tests/a11y/keyboard/date-picker.spec.ts` in the design system's test suite:
72
+ - Each calendar is a `grid` → `row` → `gridcell` structure.
73
+ - Each calendar is a single `Tab` stop (roving tabindex); arrow keys move between days.
74
+ - Arabic locale (`locale="ar"`, `dir="rtl"` or an RTL parent) switches month names and built-in button / field strings to Arabic; `labels` overrides any string.
75
+
76
+ - Built-in strings (button names, announcements) come from `labels`; pass translated strings for Arabic or other languages.
77
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
78
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
79
+
80
+ ## Design tokens used
81
+ Keep these consistent (resolve values with `get_tokens`):
82
+ - `var(--ds-color-)`
83
+ - `var(--ds-color-bg-default)`
84
+ - `var(--ds-color-bg-raised)`
85
+ - `var(--ds-color-border-brand)`
86
+ - `var(--ds-color-border-default)`
87
+ - `var(--ds-color-border-muted)`
88
+ - `var(--ds-color-border-on-default-10)`
89
+ - `var(--ds-color-chip-bg-neutral-default)`
90
+ - `var(--ds-color-chip-bg-neutral-hovered)`
91
+ - `var(--ds-color-form-datecell-bg-default)`
92
+ - `var(--ds-color-form-datecell-bg-hovered)`
93
+ - `var(--ds-color-text-on-color)`
94
+ - `var(--ds-color-text-paragraph)`
95
+ - `var(--ds-color-text-paragraph-muted)`
96
+ - `var(--ds-motion-feedback-duration)`
97
+ - `var(--ds-motion-feedback-easing)`
98
+ - `var(--ds-radius-full)`
99
+ - `var(--ds-radius-m)`
100
+ - `var(--ds-radius-xxs)`
101
+ - `var(--ds-spacing-2xl)`
102
+ - `var(--ds-spacing-lg)`
103
+ - `var(--ds-spacing-md)`
104
+ - `var(--ds-spacing-xl)`
105
+ - `var(--ds-spacing-xs)`
106
+ - `var(--ds-spacing-xxs)`
107
+ - `var(--ds-text-leading-line-heights-text-md)`
108
+ - `var(--ds-text-leading-line-heights-text-sm)`
109
+
110
+ ## AI usage guidance
111
+ When generating UI:
112
+ - Install with `npx sdaia-ui@latest add date-picker` (after `npx sdaia-ui@latest init`), then import `{ DatePicker }` from `@/components/ui/DatePicker`.
113
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
114
+ - Use only the documented option values listed under "Options".
115
+ - 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,100 @@
1
+ # Floating Button
2
+
3
+ ## Metadata
4
+ - Component: Floating Button
5
+ - Slug: `floating-button`
6
+ - Category: Actions
7
+ - Install: `npx sdaia-ui@latest add floating-button`
8
+ - Import: `import { FloatingButton } from '@/components/ui/FloatingButton'`
9
+ - Installed files: `FloatingButton.tsx`, `FloatingButton.types.ts`, `FloatingButton.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/floatingbutton
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 floating-button`. It copies the source into your components folder (`components/ui/FloatingButton/`, under `src/` when the project has one); import it as `@/components/ui/FloatingButton`. 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 for RTL support. Leave unset to inherit. |
18
+ | `variant?` | `'neutral' \| 'primary' \| 'secondary-solid'` | 'primary' | Visual style of the button |
19
+ | `size?` | `'sm' \| 'md' \| 'lg'` | 'md' | Size of the button |
20
+ | `surface?` | `'solid' \| 'glass'` | 'solid' | Surface treatment — `'solid'` (default) or `'glass'` (translucent liquid-glass material). Overrides `variant` when set to `'glass'`. |
21
+ | `disabled?` | `boolean` | false | Disables the button and prevents interaction |
22
+ | `leadingIcon?` | `ReactNode` | — | Icon displayed before the button label (direction-aware) |
23
+ | `trailingIcon?` | `ReactNode` | — | Icon displayed after the button label (direction-aware) |
24
+ | `iconOnly?` | `boolean` | false | Renders the button as a square icon-only floating button — give it an `aria-label` |
25
+ | `selected?` | `boolean` | false | Marks the button as selected (toggled on) |
26
+ | `as?` | `ElementType` | — | Override the rendered HTML element |
27
+ | `children?` | `ReactNode` | — | — |
28
+
29
+ Also accepts standard `<button>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …) — except: `dir`.
30
+
31
+ ## Options (allowed values)
32
+ - `dir`: `'ltr'` \| `'rtl'` — Layout direction for RTL support. Leave unset to inherit.
33
+ - `variant`: `'neutral'` \| `'primary'` \| `'secondary-solid'` — Visual style of the floating button
34
+ - `size`: `'sm'` \| `'md'` \| `'lg'` — Size of the floating button
35
+ - `surface`: `'solid'` \| `'glass'` — Surface treatment of the floating button.
36
+ - `'solid'` (default) — opaque variant fill.
37
+ - `'glass'` — translucent liquid-glass material (blurred backdrop +
38
+ beveled edge highlight). Reads best when the button overlays imagery
39
+ or color.
40
+
41
+ The visual is provided by the shared `.glass-surface` utility, so it is
42
+ theme-aware (light / dark) and identical across every component that
43
+ exposes a `surface` prop. When set, it overrides `variant`.
44
+
45
+ ## Deprecated props
46
+ Do not use in new code:
47
+ - `rtl`
48
+
49
+ ## Accessibility
50
+ - Icon-only usage must include an accessible label (`aria-label`).
51
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
52
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
53
+
54
+ ## Design tokens used
55
+ Keep these consistent (resolve values with `get_tokens`):
56
+ - `var(--ds-color-bg-default)`
57
+ - `var(--ds-color-bg-disabled)`
58
+ - `var(--ds-color-border-focus)`
59
+ - `var(--ds-color-button-)`
60
+ - `var(--ds-color-button-bg-black-default)`
61
+ - `var(--ds-color-button-bg-black-hovered)`
62
+ - `var(--ds-color-button-bg-black-pressed)`
63
+ - `var(--ds-color-button-bg-black-selected)`
64
+ - `var(--ds-color-button-bg-neutral-default)`
65
+ - `var(--ds-color-button-bg-neutral-hovered)`
66
+ - `var(--ds-color-button-bg-neutral-pressed)`
67
+ - `var(--ds-color-button-bg-neutral-selected)`
68
+ - `var(--ds-color-button-bg-primary-default)`
69
+ - `var(--ds-color-button-bg-primary-hovered)`
70
+ - `var(--ds-color-button-bg-primary-pressed)`
71
+ - `var(--ds-color-button-bg-primary-selected)`
72
+ - `var(--ds-color-text-default)`
73
+ - `var(--ds-color-text-disabled)`
74
+ - `var(--ds-color-text-on-color)`
75
+ - `var(--ds-glass-shadow)`
76
+ - `var(--ds-icon-)`
77
+ - `var(--ds-radius-full)`
78
+ - `var(--ds-spacing-)`
79
+ - `var(--ds-spacing-2xl)`
80
+ - `var(--ds-spacing-lg)`
81
+ - `var(--ds-spacing-md)`
82
+ - `var(--ds-spacing-xl)`
83
+ - `var(--ds-text-)`
84
+ - `var(--ds-text-family-text)`
85
+ - `var(--ds-text-leading-line-heights-text-md)`
86
+ - `var(--ds-text-leading-line-heights-text-sm)`
87
+ - `var(--ds-text-leading-line-heights-text-xs)`
88
+ - `var(--ds-text-size-text-md)`
89
+ - `var(--ds-text-size-text-sm)`
90
+ - `var(--ds-text-size-text-xs)`
91
+ - `var(--ds-text-weight-medium)`
92
+
93
+ ## AI usage guidance
94
+ When generating UI:
95
+ - Install with `npx sdaia-ui@latest add floating-button` (after `npx sdaia-ui@latest init`), then import `{ FloatingButton }` from `@/components/ui/FloatingButton`.
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,52 @@
1
+ # Horizontal Tabs
2
+
3
+ ## Metadata
4
+ - Component: Horizontal Tabs
5
+ - Slug: `horizontal-tabs`
6
+ - Category: Actions
7
+ - Install: `npx sdaia-ui@latest add horizontal-tabs`
8
+ - Import: `import { HorizontalTabs } from '@/components/ui/HorizontalTabs'`
9
+ - Installed files: `HorizontalTabs.tsx`, `HorizontalTabs.types.ts`, `HorizontalTabs.variants.ts`, `index.ts`
10
+ - Docs: https://ds.nacew.com/components/horizontal-tabs
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 horizontal-tabs`. It copies the source into your components folder (`components/ui/HorizontalTabs/`, under `src/` when the project has one); import it as `@/components/ui/HorizontalTabs`. 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
+ | `items` | `HorizontalTabItem[]` | — | Tabs to render. |
18
+ | `type?` | `'primary' \| 'neutral' \| 'underline' \| 'shadow' \| 'outline'` | 'primary' | Visual type. |
19
+ | `size?` | `TabSize` | 'md' | Size of every tab in the group. |
20
+ | `value?` | `string` | — | Controlled selected value. |
21
+ | `defaultValue?` | `string` | — | Uncontrolled initial value. |
22
+ | `onValueChange?` | `(value: string) => void` | — | Selection change callback. |
23
+ | `disabled?` | `boolean` | false | Disable the entire tab group. |
24
+ | `dir?` | `'ltr' \| 'rtl'` | — | Layout direction applied to the root. Arrow keys follow it (Left/Right swap in RTL). Inherits the ambient direction when omitted. |
25
+
26
+ Also accepts standard `<div>` HTML attributes (`className`, `style`, `onClick`, `aria-*`, …).
27
+
28
+ ## Options (allowed values)
29
+ - `type`: `'primary'` \| `'neutral'` \| `'underline'` \| `'shadow'` \| `'outline'` — Container-level type. Determines both the wrapper styling and the
30
+ inner `Tab` variant used for each item.
31
+ - `dir`: `'ltr'` \| `'rtl'` — Layout direction applied to the root. Arrow keys follow it
32
+ (Left/Right swap in RTL). Inherits the ambient direction when omitted.
33
+
34
+ ## Accessibility
35
+ - Don't remove the focus ring or replace interactive elements with `div`s; keep the control keyboard-operable.
36
+ - For contrast, keyboard patterns and RTL rules, call `get_foundations` (`accessibility`, `rtl`).
37
+
38
+ ## Design tokens used
39
+ Keep these consistent (resolve values with `get_tokens`):
40
+ - `var(--ds-color-bg-emphasis-low)`
41
+ - `var(--ds-color-border-default)`
42
+ - `var(--ds-radius-m)`
43
+ - `var(--ds-spacing-xs)`
44
+
45
+ ## AI usage guidance
46
+ When generating UI:
47
+ - Install with `npx sdaia-ui@latest add horizontal-tabs` (after `npx sdaia-ui@latest init`), then import `{ HorizontalTabs }` from `@/components/ui/HorizontalTabs`.
48
+ - NEVER run `npm install sdaia-ui` and NEVER `import` from the `sdaia-ui` package — it is a source-copying CLI, not a component library.
49
+ - Use only the documented option values listed under "Options".
50
+ - 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).
51
+ - Express the disabled state with the `disabled` prop, not custom styling.
52
+ - Pick one theme per screen: dark is `.theme-dark` (or `.dark`) on `<html>`; style surrounding layout with DS tokens (`get_tokens`), never hardcoded colors.