@inui/design-system 0.0.0-stage → 1.22.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.
- package/README.md +360 -2
- package/dist/components/ui/accordion.d.ts +44 -0
- package/dist/components/ui/accordion.d.ts.map +1 -0
- package/dist/components/ui/accordion.js +86 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/ai-avatar.d.ts +46 -0
- package/dist/components/ui/ai-avatar.d.ts.map +1 -0
- package/dist/components/ui/ai-avatar.js +43 -0
- package/dist/components/ui/ai-avatar.js.map +1 -0
- package/dist/components/ui/ai-label.d.ts +118 -0
- package/dist/components/ui/ai-label.d.ts.map +1 -0
- package/dist/components/ui/ai-label.js +184 -0
- package/dist/components/ui/ai-label.js.map +1 -0
- package/dist/components/ui/ai-sparkle.d.ts +91 -0
- package/dist/components/ui/ai-sparkle.d.ts.map +1 -0
- package/dist/components/ui/ai-sparkle.js +200 -0
- package/dist/components/ui/ai-sparkle.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +79 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +147 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/alert.d.ts +71 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/alert.js +108 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/aspect-ratio.d.ts +30 -0
- package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
- package/dist/components/ui/aspect-ratio.js +40 -0
- package/dist/components/ui/aspect-ratio.js.map +1 -0
- package/dist/components/ui/attachment.d.ts +74 -0
- package/dist/components/ui/attachment.d.ts.map +1 -0
- package/dist/components/ui/attachment.js +142 -0
- package/dist/components/ui/attachment.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +82 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +123 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +130 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +226 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +43 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.js +98 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/browser-tabs.d.ts +218 -0
- package/dist/components/ui/browser-tabs.d.ts.map +1 -0
- package/dist/components/ui/browser-tabs.js +528 -0
- package/dist/components/ui/browser-tabs.js.map +1 -0
- package/dist/components/ui/bubble.d.ts +80 -0
- package/dist/components/ui/bubble.d.ts.map +1 -0
- package/dist/components/ui/bubble.js +235 -0
- package/dist/components/ui/bubble.js.map +1 -0
- package/dist/components/ui/button-group.d.ts +60 -0
- package/dist/components/ui/button-group.d.ts.map +1 -0
- package/dist/components/ui/button-group.js +89 -0
- package/dist/components/ui/button-group.js.map +1 -0
- package/dist/components/ui/button.d.ts +157 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +144 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +57 -0
- package/dist/components/ui/calendar.d.ts.map +1 -0
- package/dist/components/ui/calendar.js +163 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +96 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +131 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/carousel.d.ts +86 -0
- package/dist/components/ui/carousel.d.ts.map +1 -0
- package/dist/components/ui/carousel.js +207 -0
- package/dist/components/ui/carousel.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +54 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +78 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +45 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +65 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/combobox.d.ts +111 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox.js +264 -0
- package/dist/components/ui/combobox.js.map +1 -0
- package/dist/components/ui/command.d.ts +71 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/command.js +133 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +70 -0
- package/dist/components/ui/context-menu.d.ts.map +1 -0
- package/dist/components/ui/context-menu.js +163 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/count-badge.d.ts +40 -0
- package/dist/components/ui/count-badge.d.ts.map +1 -0
- package/dist/components/ui/count-badge.js +43 -0
- package/dist/components/ui/count-badge.js.map +1 -0
- package/dist/components/ui/data-table.d.ts +1026 -0
- package/dist/components/ui/data-table.d.ts.map +1 -0
- package/dist/components/ui/data-table.js +3423 -0
- package/dist/components/ui/data-table.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +73 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +145 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/direction.d.ts +35 -0
- package/dist/components/ui/direction.d.ts.map +1 -0
- package/dist/components/ui/direction.js +35 -0
- package/dist/components/ui/direction.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +53 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/drawer.js +115 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +75 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +173 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/dropzone.d.ts +141 -0
- package/dist/components/ui/dropzone.d.ts.map +1 -0
- package/dist/components/ui/dropzone.js +257 -0
- package/dist/components/ui/dropzone.js.map +1 -0
- package/dist/components/ui/empty.d.ts +94 -0
- package/dist/components/ui/empty.d.ts.map +1 -0
- package/dist/components/ui/empty.js +149 -0
- package/dist/components/ui/empty.js.map +1 -0
- package/dist/components/ui/field.d.ts +122 -0
- package/dist/components/ui/field.d.ts.map +1 -0
- package/dist/components/ui/field.js +254 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +51 -0
- package/dist/components/ui/hover-card.d.ts.map +1 -0
- package/dist/components/ui/hover-card.js +101 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +62 -0
- package/dist/components/ui/input-group.d.ts.map +1 -0
- package/dist/components/ui/input-group.js +115 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-otp.d.ts +52 -0
- package/dist/components/ui/input-otp.d.ts.map +1 -0
- package/dist/components/ui/input-otp.js +89 -0
- package/dist/components/ui/input-otp.js.map +1 -0
- package/dist/components/ui/input.d.ts +47 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +47 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/item.d.ts +74 -0
- package/dist/components/ui/item.d.ts.map +1 -0
- package/dist/components/ui/item.js +176 -0
- package/dist/components/ui/item.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +41 -0
- package/dist/components/ui/kbd.d.ts.map +1 -0
- package/dist/components/ui/kbd.js +58 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/key-value-pair.d.ts +56 -0
- package/dist/components/ui/key-value-pair.d.ts.map +1 -0
- package/dist/components/ui/key-value-pair.js +110 -0
- package/dist/components/ui/key-value-pair.js.map +1 -0
- package/dist/components/ui/label.d.ts +83 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +85 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/marker.d.ts +54 -0
- package/dist/components/ui/marker.d.ts.map +1 -0
- package/dist/components/ui/marker.js +79 -0
- package/dist/components/ui/marker.js.map +1 -0
- package/dist/components/ui/menubar.d.ts +72 -0
- package/dist/components/ui/menubar.d.ts.map +1 -0
- package/dist/components/ui/menubar.js +174 -0
- package/dist/components/ui/menubar.js.map +1 -0
- package/dist/components/ui/message-scroller.d.ts +53 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller.js +95 -0
- package/dist/components/ui/message-scroller.js.map +1 -0
- package/dist/components/ui/message.d.ts +63 -0
- package/dist/components/ui/message.d.ts.map +1 -0
- package/dist/components/ui/message.js +92 -0
- package/dist/components/ui/message.js.map +1 -0
- package/dist/components/ui/meta-list.d.ts +55 -0
- package/dist/components/ui/meta-list.d.ts.map +1 -0
- package/dist/components/ui/meta-list.js +75 -0
- package/dist/components/ui/meta-list.js.map +1 -0
- package/dist/components/ui/native-select.d.ts +51 -0
- package/dist/components/ui/native-select.d.ts.map +1 -0
- package/dist/components/ui/native-select.js +75 -0
- package/dist/components/ui/native-select.js.map +1 -0
- package/dist/components/ui/navigation-menu.d.ts +56 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.js +116 -0
- package/dist/components/ui/navigation-menu.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +223 -0
- package/dist/components/ui/page-header.d.ts.map +1 -0
- package/dist/components/ui/page-header.js +233 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/pagination.d.ts +68 -0
- package/dist/components/ui/pagination.d.ts.map +1 -0
- package/dist/components/ui/pagination.js +145 -0
- package/dist/components/ui/pagination.js.map +1 -0
- package/dist/components/ui/popover.d.ts +61 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +144 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/progress.d.ts +35 -0
- package/dist/components/ui/progress.d.ts.map +1 -0
- package/dist/components/ui/progress.js +46 -0
- package/dist/components/ui/progress.js.map +1 -0
- package/dist/components/ui/questionnaire.d.ts +92 -0
- package/dist/components/ui/questionnaire.d.ts.map +1 -0
- package/dist/components/ui/questionnaire.js +277 -0
- package/dist/components/ui/questionnaire.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +50 -0
- package/dist/components/ui/radio-group.d.ts.map +1 -0
- package/dist/components/ui/radio-group.js +65 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +44 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/resizable.js +73 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +55 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +72 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +274 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +609 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.d.ts +31 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +38 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +59 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +128 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +166 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +512 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +35 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +46 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +39 -0
- package/dist/components/ui/slider.d.ts.map +1 -0
- package/dist/components/ui/slider.js +75 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +56 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/sonner.js +96 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/spinner.d.ts +37 -0
- package/dist/components/ui/spinner.d.ts.map +1 -0
- package/dist/components/ui/spinner.js +51 -0
- package/dist/components/ui/spinner.js.map +1 -0
- package/dist/components/ui/stepper.d.ts +84 -0
- package/dist/components/ui/stepper.d.ts.map +1 -0
- package/dist/components/ui/stepper.js +145 -0
- package/dist/components/ui/stepper.js.map +1 -0
- package/dist/components/ui/switch.d.ts +36 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +44 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.d.ts +80 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +130 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +87 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +128 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +35 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +38 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/time-picker.d.ts +58 -0
- package/dist/components/ui/time-picker.d.ts.map +1 -0
- package/dist/components/ui/time-picker.js +188 -0
- package/dist/components/ui/time-picker.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +52 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.js +94 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +50 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +70 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +51 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +78 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/hooks/use-dark-mode.d.ts +2 -0
- package/dist/hooks/use-dark-mode.d.ts.map +1 -0
- package/dist/hooks/use-dark-mode.js +36 -0
- package/dist/hooks/use-dark-mode.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-mobile.js +20 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/lib/scope.d.ts +64 -0
- package/dist/lib/scope.d.ts.map +1 -0
- package/dist/lib/scope.js +74 -0
- package/dist/lib/scope.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +11 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/theme-tokens.css +537 -0
- package/dist/theme.css +417 -0
- package/package.json +103 -3
package/README.md
CHANGED
|
@@ -1,3 +1,361 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @inui/design-system
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
61 React components on Tailwind CSS v4, with a shared design token palette.
|
|
4
|
+
Built from shadcn/ui on Radix primitives.
|
|
5
|
+
|
|
6
|
+
- **React 19** (peer dependency — you provide it)
|
|
7
|
+
- **Tailwind not required.** The package ships a prebuilt stylesheet.
|
|
8
|
+
- **Dark mode** via a `dark` class, no theme provider needed.
|
|
9
|
+
- **Tree-shakeable** — importing `Button` pulls in Button, not all 61.
|
|
10
|
+
|
|
11
|
+
[Live on Storybook](https://gitlab-pages.innovaccer.com/inui-design-system-b7dcd2/?path=/docs/actions-buttongroup--docs)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @inui/design-system
|
|
19
|
+
# or: npm i @inui/design-system
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`lucide-react` is a peer dependency (the components render its icons), so install
|
|
23
|
+
it alongside:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add lucide-react
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 2. Import the stylesheet and mark your root
|
|
30
|
+
|
|
31
|
+
Import once at your app's entry point (`main.tsx`, `App.tsx`, or `app/layout.tsx`):
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import "@inui/design-system/styles.css"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Then put `data-m2ds-root` on the element your app renders into:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<div data-m2ds-root>{/* your app */}</div>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Both steps are required.** Every rule in the stylesheet is wrapped in a CSS
|
|
44
|
+
[`@scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/@scope) block, so
|
|
45
|
+
without that attribute on an ancestor nothing is styled. This is deliberate — see
|
|
46
|
+
[Why it's scoped](#why-its-scoped).
|
|
47
|
+
|
|
48
|
+
It works on a custom element too (`<my-app data-m2ds-root>`), and multiple roots on
|
|
49
|
+
one page are each scoped independently.
|
|
50
|
+
|
|
51
|
+
> Put the attribute on a **wrapper**, not on an element you also style with utility
|
|
52
|
+
> classes. `@scope` does not match its own scoping root with bare selectors, so
|
|
53
|
+
> `<div data-m2ds-root className="bg-card">` would not get `bg-card`.
|
|
54
|
+
|
|
55
|
+
## 3. Use the components
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import {
|
|
59
|
+
Button,
|
|
60
|
+
Card,
|
|
61
|
+
CardContent,
|
|
62
|
+
CardHeader,
|
|
63
|
+
CardTitle,
|
|
64
|
+
} from "@inui/design-system"
|
|
65
|
+
|
|
66
|
+
export function Example() {
|
|
67
|
+
return (
|
|
68
|
+
<Card>
|
|
69
|
+
<CardHeader>
|
|
70
|
+
<CardTitle>Deploy</CardTitle>
|
|
71
|
+
</CardHeader>
|
|
72
|
+
<CardContent>
|
|
73
|
+
<Button>Ship it</Button>
|
|
74
|
+
</CardContent>
|
|
75
|
+
</Card>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
That's the whole setup. Everything below is optional or situational.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Fonts
|
|
85
|
+
|
|
86
|
+
The palette expects **DM Sans** and **DM Mono**, but the package does not ship
|
|
87
|
+
font files (bundling them would break the published CSS). Install them yourself:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm add @fontsource-variable/dm-sans @fontsource/dm-mono
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import "@fontsource-variable/dm-sans"
|
|
95
|
+
import "@fontsource/dm-mono"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Or skip it and point the tokens at a font you already load. Override on your root
|
|
99
|
+
element — the stylesheet declares `--font-sans` there, so a `:root` override would
|
|
100
|
+
be shadowed:
|
|
101
|
+
|
|
102
|
+
```css
|
|
103
|
+
[data-m2ds-root] {
|
|
104
|
+
--font-sans: "Inter", system-ui, sans-serif;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Dark mode
|
|
109
|
+
|
|
110
|
+
Add the `dark` class to `<html>`. Every token flips automatically — there is no
|
|
111
|
+
provider to install and no context to wire up.
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
document.documentElement.classList.toggle("dark", isDark)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
If you already use `next-themes` or similar, it does this for you; nothing extra
|
|
118
|
+
is needed.
|
|
119
|
+
|
|
120
|
+
This keeps working even though `<html>` sits _outside_ the scope root: `@scope`
|
|
121
|
+
confines only a selector's subject, not its ancestors. `dark` on your root element
|
|
122
|
+
or on a subtree inside it works too, so a dark sidebar in a light app is fine.
|
|
123
|
+
|
|
124
|
+
## Components that need a wrapper
|
|
125
|
+
|
|
126
|
+
Three components need something mounted before they work:
|
|
127
|
+
|
|
128
|
+
| Component | What to add | Where |
|
|
129
|
+
| ------------------ | ------------------- | -------------------------------- |
|
|
130
|
+
| `Tooltip` | `<TooltipProvider>` | once, at your app root |
|
|
131
|
+
| `Toaster` (toasts) | `<Toaster />` | once, at your app root |
|
|
132
|
+
| `Sidebar` | `<SidebarProvider>` | around the sidebar + its content |
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { TooltipProvider, Toaster } from "@inui/design-system"
|
|
136
|
+
|
|
137
|
+
export function Root({ children }: { children: React.ReactNode }) {
|
|
138
|
+
return (
|
|
139
|
+
<TooltipProvider>
|
|
140
|
+
{children}
|
|
141
|
+
<Toaster />
|
|
142
|
+
</TooltipProvider>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Then anywhere: `import { toast } from "sonner"` → `toast.success("Saved")`.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Using the design tokens
|
|
152
|
+
|
|
153
|
+
The stylesheet exposes 87 colour tokens as CSS custom properties, declared on your
|
|
154
|
+
`data-m2ds-root` element. Use them in your own styles anywhere **inside** that
|
|
155
|
+
element — they don't resolve outside it:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<div style={{ background: "var(--color-surface-chat)" }} />
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```css
|
|
162
|
+
.my-panel {
|
|
163
|
+
background: var(--color-surface);
|
|
164
|
+
color: var(--color-surface-foreground);
|
|
165
|
+
border: 1px solid var(--color-border-subtle);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Browse them all** in Storybook under **Design System → Tokens → Colors**. Each
|
|
170
|
+
swatch has a click-to-copy `var(...)` snippet.
|
|
171
|
+
|
|
172
|
+
Token families: `background` / `foreground`, `card`, `popover`, `surface*`,
|
|
173
|
+
`primary*`, `secondary`, `muted*`, `accent`, `border*`, `input`, `ring*`, the
|
|
174
|
+
status set (`destructive`, `success`, `warning`, `alert`, `info` — each with
|
|
175
|
+
`-foreground`, `-light`, `-ultra-light`, `-text`), `sidebar*`, `chart-1..8`,
|
|
176
|
+
and `ai-*`.
|
|
177
|
+
|
|
178
|
+
> Pair a surface with its own foreground: `--color-card` with
|
|
179
|
+
> `--color-card-foreground`, never with `--color-foreground`.
|
|
180
|
+
|
|
181
|
+
### Utility classes (`bg-primary`, `text-muted-foreground`)
|
|
182
|
+
|
|
183
|
+
These work for the ~20 tokens the components use, because Tailwind only
|
|
184
|
+
generates utilities for classes it sees used. `bg-ai-wash` is **not** in
|
|
185
|
+
the prebuilt CSS.
|
|
186
|
+
|
|
187
|
+
If you want a utility for any token, run your own Tailwind v4 build over our
|
|
188
|
+
`dist/` instead of importing our stylesheet — see [Opting out](#opting-out). You
|
|
189
|
+
then get every token as a utility, plus opacity steps like `bg-alert/30`. Don't
|
|
190
|
+
import `styles.css` as well, or you'll ship the CSS twice.
|
|
191
|
+
|
|
192
|
+
### Overriding a token
|
|
193
|
+
|
|
194
|
+
Redefine it after the import. Scope it to a class if you need more than one
|
|
195
|
+
theme live at once:
|
|
196
|
+
|
|
197
|
+
```css
|
|
198
|
+
@import "@inui/design-system/styles.css";
|
|
199
|
+
|
|
200
|
+
:root {
|
|
201
|
+
--color-primary: #7c3aed;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.theme-acme {
|
|
205
|
+
--color-primary: #0f766e;
|
|
206
|
+
}
|
|
207
|
+
.dark .theme-acme,
|
|
208
|
+
.theme-acme.dark {
|
|
209
|
+
--color-primary: #5eead4;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
> Override on your root element, not `:root` — the stylesheet declares tokens on
|
|
214
|
+
> the element carrying `data-m2ds-root`, which is a closer ancestor and therefore
|
|
215
|
+
> wins. Use `[data-m2ds-root] { --color-primary: #7c3aed }`, or set it inline on the
|
|
216
|
+
> element.
|
|
217
|
+
|
|
218
|
+
## Why it's scoped
|
|
219
|
+
|
|
220
|
+
This library is built to run as one web component among several on a shared page,
|
|
221
|
+
in the light DOM (no shadow root). A document-wide stylesheet is hostile there, so
|
|
222
|
+
there isn't one — `styles.css` is scoped and that is the only mode shipped.
|
|
223
|
+
|
|
224
|
+
**What that buys you.**
|
|
225
|
+
|
|
226
|
+
- Tailwind's preflight (`*`, `ol`/`ul`/`menu`, `img`/`svg`, form controls) doesn't
|
|
227
|
+
reset the host document.
|
|
228
|
+
- `font-family` and `background`/`color` land on your root element, not on `html`
|
|
229
|
+
and `body`.
|
|
230
|
+
- **No design token touches `:root`.** Isolation is two-way: a co-loaded design
|
|
231
|
+
system declaring `--color-primary` or `--radius` on `:root` keeps its own values,
|
|
232
|
+
and your components keep theirs.
|
|
233
|
+
- Specificity is unchanged, so your own overrides beat a utility exactly as they
|
|
234
|
+
would against any ordinary Tailwind build.
|
|
235
|
+
|
|
236
|
+
**Caveats.**
|
|
237
|
+
|
|
238
|
+
- **Browser support is a hard floor:** `@scope` needs Chrome/Edge 118+,
|
|
239
|
+
Safari 17.4+, Firefox 128+. There is no polyfill, and an unsupported `@scope`
|
|
240
|
+
block is dropped _with its contents_ — so on an older browser your app renders
|
|
241
|
+
unstyled rather than degrading. Since this is the only stylesheet shipped, that
|
|
242
|
+
matrix is the package's.
|
|
243
|
+
- **It stops us leaking out, not others leaking in.** Unlayered host CSS such as
|
|
244
|
+
`ul { list-style: square }` still overrides our preflight inside the scope,
|
|
245
|
+
because unlayered CSS always beats layered CSS. That's a property of Tailwind's
|
|
246
|
+
cascade layers, not of `@scope`.
|
|
247
|
+
- **`@keyframes` names stay global.** Ours is prefixed (`mmds-step-in`), but names
|
|
248
|
+
from dependencies (`enter`/`exit`, `spin`, `pulse`, `accordion-down`) are not, so
|
|
249
|
+
another sheet defining the same name wins for both.
|
|
250
|
+
- **Portals are handled for you.** Overlays portal into `document.body`, outside
|
|
251
|
+
your root, so the 12 overlay components tag their own portal wrapper with
|
|
252
|
+
`data-m2ds-portal` — the sheet scopes to that as a second root. If you portal
|
|
253
|
+
library content yourself, spread `portalScopeProps` onto your container:
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
import { portalScopeProps } from "@inui/design-system"
|
|
257
|
+
createPortal(<div {...portalScopeProps}>{content}</div>, document.body)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`M2DS_ROOT_ATTRIBUTE`, `M2DS_PORTAL_ATTRIBUTE`, `rootScopeProps` and
|
|
261
|
+
`portalScopeProps` are all exported if you'd rather not hardcode the strings.
|
|
262
|
+
|
|
263
|
+
### Opting out
|
|
264
|
+
|
|
265
|
+
If your app owns the whole page and you want unscoped, document-wide CSS, don't
|
|
266
|
+
import `styles.css` — run your own Tailwind build over our `dist/` instead:
|
|
267
|
+
|
|
268
|
+
```css
|
|
269
|
+
@import "tailwindcss";
|
|
270
|
+
@import "@inui/design-system/theme.css";
|
|
271
|
+
@source "../node_modules/@inui/design-system/dist";
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
`theme.css` emits the palette on `:root` when imported directly, so this path needs
|
|
275
|
+
no `data-m2ds-root`. You also get every token as a utility (see
|
|
276
|
+
[Utility classes](#utility-classes-bg-primary-text-muted-foreground)).
|
|
277
|
+
|
|
278
|
+
`theme.css` also carries the Tailwind v4 border-color compatibility rule
|
|
279
|
+
(`* { border-color: var(--color-border) }`, base layer) — Tailwind v4 stopped
|
|
280
|
+
defaulting a bare `border`/`border-b`/etc. to gray and resolves it to
|
|
281
|
+
`currentColor` instead, which every component here that uses an unsuffixed
|
|
282
|
+
border (Table's rows, Card's footer, Sidebar's rail edge, and others — same
|
|
283
|
+
as shadcn/ui's own source) depends on not happening. Nothing to configure;
|
|
284
|
+
it's already active once you import `theme.css`.
|
|
285
|
+
|
|
286
|
+
## Good to know
|
|
287
|
+
|
|
288
|
+
- **Nothing is styled without `data-m2ds-root`** on an ancestor. If your app renders
|
|
289
|
+
completely unstyled, that's the first thing to check.
|
|
290
|
+
- **The stylesheet sets no document-level rules.** `font-family`,
|
|
291
|
+
`background` and `color` land on your root element, so your app shell keeps
|
|
292
|
+
control of `html` and `body`.
|
|
293
|
+
- **Everything is a named export** from the package root — there are no deep
|
|
294
|
+
import paths like `@inui/design-system/button`.
|
|
295
|
+
- **TypeScript** types ship with the package; no `@types/*` needed.
|
|
296
|
+
|
|
297
|
+
## Component list
|
|
298
|
+
|
|
299
|
+
`manifest.json` at the repo root is a machine-readable index of all 61 — id,
|
|
300
|
+
category, a summary of the real variants and sizes, and `when` / `not_when`
|
|
301
|
+
guidance. It's meant for AI coding agents: scan it to pick a component, then read
|
|
302
|
+
the `file` path for the source.
|
|
303
|
+
|
|
304
|
+
Actions · Button, ButtonGroup, Toggle, ToggleGroup
|
|
305
|
+
Forms · Input, Textarea, Label, Checkbox, RadioGroup, Switch, Select,
|
|
306
|
+
NativeSelect, Combobox, Slider, InputOTP, InputGroup, Field, Questionnaire,
|
|
307
|
+
Calendar
|
|
308
|
+
Navigation · Breadcrumb, Tabs, Pagination, Menubar, NavigationMenu, Sidebar
|
|
309
|
+
Menus · DropdownMenu, ContextMenu, Command
|
|
310
|
+
Overlays · Dialog, AlertDialog, Sheet, Drawer, Popover, HoverCard, Tooltip
|
|
311
|
+
Data display · Table, Card, Badge, Avatar, Item, Kbd, Marker
|
|
312
|
+
Feedback · Alert, Toaster, Progress, Skeleton, Spinner, Empty
|
|
313
|
+
Layout · Accordion, Collapsible, Carousel, ResizablePanelGroup, ScrollArea,
|
|
314
|
+
Separator, AspectRatio
|
|
315
|
+
Chat · Bubble, Message, MessageScroller, Attachment
|
|
316
|
+
Utilities · DirectionProvider, `cn()`, `useIsMobile()`, `useIsDarkMode()`
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Developing this library
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
pnpm install
|
|
324
|
+
pnpm storybook # docs + playground at localhost:6006
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
| Script | Does |
|
|
328
|
+
| --------------------------- | ----------------------------------- |
|
|
329
|
+
| `pnpm storybook` | Storybook dev server |
|
|
330
|
+
| `pnpm build` | Build `dist/` — JS, types, then CSS |
|
|
331
|
+
| `pnpm build:storybook` | Static Storybook |
|
|
332
|
+
| `pnpm typecheck` | `tsc --noEmit` |
|
|
333
|
+
| `pnpm lint` / `pnpm format` | ESLint / Prettier |
|
|
334
|
+
|
|
335
|
+
**Layout**
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
src/components/ui/ the 61 components (vendored from the shadcn registry)
|
|
339
|
+
src/styles/index.css the scoped Tailwind entry -> dist/styles.css
|
|
340
|
+
src/styles/theme.css token registration; also the published theme.css
|
|
341
|
+
src/styles/theme-tokens.css the palette, light + dark — EDIT HERE to rebrand
|
|
342
|
+
src/lib/scope.ts the data-m2ds-root / data-m2ds-portal markers
|
|
343
|
+
stories/components/ one story file per component
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
`theme-tokens.css` is a selector-less declaration list, which is what lets one set
|
|
347
|
+
of values be placed on `:root` by `theme.css` and on `:scope` by the scoped entry.
|
|
348
|
+
Dark mode is a nested rule inside it, so `&` resolves to whichever element that
|
|
349
|
+
entry chose. It stays a separate file because `@theme` always emits to `:root`
|
|
350
|
+
(Tailwind hardcodes that selector), so the scoped build registers the theme with
|
|
351
|
+
`@reference` — emitting nothing — and declares the values itself.
|
|
352
|
+
|
|
353
|
+
To rebrand, edit `theme-tokens.css`, then mirror the values into the
|
|
354
|
+
`@theme static reference` block in `theme.css`. That block is registration only and
|
|
355
|
+
feeds `var()` fallbacks that never resolve, so a mismatch cannot change a rendered
|
|
356
|
+
colour.
|
|
357
|
+
|
|
358
|
+
To change the theme, edit `src/styles/theme.css` and rebuild. To pull a component
|
|
359
|
+
update from upstream, `pnpm dlx shadcn@latest add --overwrite <name>` — then
|
|
360
|
+
re-check `sonner.tsx`, which is intentionally patched to drop its `next-themes`
|
|
361
|
+
dependency.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accordion — coordinated set of collapsible sections.
|
|
3
|
+
*
|
|
4
|
+
* Built on the Radix Accordion primitive. The open/closed chevron swap is
|
|
5
|
+
* done via data-slot targeting instead of a rotate transform.
|
|
6
|
+
*/
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { Accordion as AccordionPrimitive } from "radix-ui";
|
|
9
|
+
declare function Accordion({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Root>): React.JSX.Element;
|
|
10
|
+
declare function AccordionItem({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Item>): React.JSX.Element;
|
|
11
|
+
declare function AccordionTrigger({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Trigger>): React.JSX.Element;
|
|
12
|
+
declare function AccordionContent({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Content>): React.JSX.Element;
|
|
13
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
|
|
14
|
+
/**
|
|
15
|
+
* WHEN TO USE
|
|
16
|
+
* - Progressive disclosure of several grouped, peer sections — FAQs, nested
|
|
17
|
+
* settings, a long form split into sections.
|
|
18
|
+
*
|
|
19
|
+
* NOT WHEN
|
|
20
|
+
* - Switching between peer views that replace each other — use Tabs.
|
|
21
|
+
* - Exactly one independent expandable region — use Collapsible (Accordion
|
|
22
|
+
* is Collapsible plus coordination between multiple items).
|
|
23
|
+
* - Content the user needs visible immediately — an accordion adds a click
|
|
24
|
+
* before it's readable.
|
|
25
|
+
*
|
|
26
|
+
* KEY RULES
|
|
27
|
+
* - `type` is required and changes exclusivity: "single" closes other items
|
|
28
|
+
* when one opens (add `collapsible` to also allow all-closed); "multiple"
|
|
29
|
+
* lets any number stay open independently.
|
|
30
|
+
* - Any AccordionItem can take `disabled` to lock it regardless of `type`.
|
|
31
|
+
* - Height animates via the `--radix-accordion-content-height` CSS var — do
|
|
32
|
+
* not replace AccordionContent's wrapper div with a fixed-height container.
|
|
33
|
+
*
|
|
34
|
+
* USAGE
|
|
35
|
+
* <Accordion type="single" collapsible defaultValue="tokens">
|
|
36
|
+
* <AccordionItem value="tokens">
|
|
37
|
+
* <AccordionTrigger>How do I customise the theme?</AccordionTrigger>
|
|
38
|
+
* <AccordionContent>Edit the oklch values in theme.css.</AccordionContent>
|
|
39
|
+
* </AccordionItem>
|
|
40
|
+
* </Accordion>
|
|
41
|
+
*
|
|
42
|
+
* <Accordion type="multiple" defaultValue={["tokens", "tailwind"]}>...</Accordion>
|
|
43
|
+
*/
|
|
44
|
+
//# sourceMappingURL=accordion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../../src/components/ui/accordion.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAK1D,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,IAAI,CAAC,qBAQtD;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,IAAI,CAAC,qBAQtD;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,OAAO,CAAC,qBAuBzD;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,OAAO,CAAC,qBAiBzD;AAED,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import "react";
|
|
3
|
+
import { Accordion as Accordion$1 } from "radix-ui";
|
|
4
|
+
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/ui/accordion.tsx
|
|
7
|
+
function Accordion({ className, ...props }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(Accordion$1.Root, {
|
|
9
|
+
"data-slot": "accordion",
|
|
10
|
+
className: cn("flex w-full flex-col", className),
|
|
11
|
+
...props
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function AccordionItem({ className, ...props }) {
|
|
15
|
+
return /* @__PURE__ */ jsx(Accordion$1.Item, {
|
|
16
|
+
"data-slot": "accordion-item",
|
|
17
|
+
className: cn("not-last:border-b", className),
|
|
18
|
+
...props
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function AccordionTrigger({ className, children, ...props }) {
|
|
22
|
+
return /* @__PURE__ */ jsx(Accordion$1.Header, {
|
|
23
|
+
className: "flex",
|
|
24
|
+
children: /* @__PURE__ */ jsxs(Accordion$1.Trigger, {
|
|
25
|
+
"data-slot": "accordion-trigger",
|
|
26
|
+
className: cn("group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-colors outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground", className),
|
|
27
|
+
...props,
|
|
28
|
+
children: [
|
|
29
|
+
children,
|
|
30
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, {
|
|
31
|
+
"data-slot": "accordion-trigger-icon",
|
|
32
|
+
className: "pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
|
|
33
|
+
}),
|
|
34
|
+
/* @__PURE__ */ jsx(ChevronUpIcon, {
|
|
35
|
+
"data-slot": "accordion-trigger-icon",
|
|
36
|
+
className: "pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
|
|
37
|
+
})
|
|
38
|
+
]
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function AccordionContent({ className, children, ...props }) {
|
|
43
|
+
return /* @__PURE__ */ jsx(Accordion$1.Content, {
|
|
44
|
+
"data-slot": "accordion-content",
|
|
45
|
+
className: "overflow-hidden text-sm data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up",
|
|
46
|
+
...props,
|
|
47
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
48
|
+
className: cn("h-(--radix-accordion-content-height) pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4", className),
|
|
49
|
+
children
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* WHEN TO USE
|
|
55
|
+
* - Progressive disclosure of several grouped, peer sections — FAQs, nested
|
|
56
|
+
* settings, a long form split into sections.
|
|
57
|
+
*
|
|
58
|
+
* NOT WHEN
|
|
59
|
+
* - Switching between peer views that replace each other — use Tabs.
|
|
60
|
+
* - Exactly one independent expandable region — use Collapsible (Accordion
|
|
61
|
+
* is Collapsible plus coordination between multiple items).
|
|
62
|
+
* - Content the user needs visible immediately — an accordion adds a click
|
|
63
|
+
* before it's readable.
|
|
64
|
+
*
|
|
65
|
+
* KEY RULES
|
|
66
|
+
* - `type` is required and changes exclusivity: "single" closes other items
|
|
67
|
+
* when one opens (add `collapsible` to also allow all-closed); "multiple"
|
|
68
|
+
* lets any number stay open independently.
|
|
69
|
+
* - Any AccordionItem can take `disabled` to lock it regardless of `type`.
|
|
70
|
+
* - Height animates via the `--radix-accordion-content-height` CSS var — do
|
|
71
|
+
* not replace AccordionContent's wrapper div with a fixed-height container.
|
|
72
|
+
*
|
|
73
|
+
* USAGE
|
|
74
|
+
* <Accordion type="single" collapsible defaultValue="tokens">
|
|
75
|
+
* <AccordionItem value="tokens">
|
|
76
|
+
* <AccordionTrigger>How do I customise the theme?</AccordionTrigger>
|
|
77
|
+
* <AccordionContent>Edit the oklch values in theme.css.</AccordionContent>
|
|
78
|
+
* </AccordionItem>
|
|
79
|
+
* </Accordion>
|
|
80
|
+
*
|
|
81
|
+
* <Accordion type="multiple" defaultValue={["tokens", "tailwind"]}>...</Accordion>
|
|
82
|
+
*/
|
|
83
|
+
//#endregion
|
|
84
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=accordion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accordion.js","names":[],"sources":["../../../src/components/ui/accordion.tsx"],"sourcesContent":["/**\n * Accordion — coordinated set of collapsible sections.\n *\n * Built on the Radix Accordion primitive. The open/closed chevron swap is\n * done via data-slot targeting instead of a rotate transform.\n */\n\nimport * as React from \"react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\n\nfunction Accordion({\n className,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Root>) {\n return (\n <AccordionPrimitive.Root\n data-slot=\"accordion\"\n className={cn(\"flex w-full flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction AccordionItem({\n className,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn(\"not-last:border-b\", className)}\n {...props}\n />\n )\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n \"group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-colors outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronDownIcon\n data-slot=\"accordion-trigger-icon\"\n className=\"pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden\"\n />\n <ChevronUpIcon\n data-slot=\"accordion-trigger-icon\"\n className=\"pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n )\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className=\"overflow-hidden text-sm data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up\"\n {...props}\n >\n <div\n className={cn(\n \"h-(--radix-accordion-content-height) pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4\",\n className\n )}\n >\n {children}\n </div>\n </AccordionPrimitive.Content>\n )\n}\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\n\n/**\n * WHEN TO USE\n * - Progressive disclosure of several grouped, peer sections — FAQs, nested\n * settings, a long form split into sections.\n *\n * NOT WHEN\n * - Switching between peer views that replace each other — use Tabs.\n * - Exactly one independent expandable region — use Collapsible (Accordion\n * is Collapsible plus coordination between multiple items).\n * - Content the user needs visible immediately — an accordion adds a click\n * before it's readable.\n *\n * KEY RULES\n * - `type` is required and changes exclusivity: \"single\" closes other items\n * when one opens (add `collapsible` to also allow all-closed); \"multiple\"\n * lets any number stay open independently.\n * - Any AccordionItem can take `disabled` to lock it regardless of `type`.\n * - Height animates via the `--radix-accordion-content-height` CSS var — do\n * not replace AccordionContent's wrapper div with a fixed-height container.\n *\n * USAGE\n * <Accordion type=\"single\" collapsible defaultValue=\"tokens\">\n * <AccordionItem value=\"tokens\">\n * <AccordionTrigger>How do I customise the theme?</AccordionTrigger>\n * <AccordionContent>Edit the oklch values in theme.css.</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n *\n * <Accordion type=\"multiple\" defaultValue={[\"tokens\", \"tailwind\"]}>...</Accordion>\n */\n"],"mappings":";;;;;;AAaA,SAAS,UAAU,EACjB,WACA,GAAG,SACoD;CACvD,OACE,oBAAC,YAAmB,MAApB;EACE,aAAU;EACV,WAAW,GAAG,wBAAwB,SAAS;EAC/C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EACrB,WACA,GAAG,SACoD;CACvD,OACE,oBAAC,YAAmB,MAApB;EACE,aAAU;EACV,WAAW,GAAG,qBAAqB,SAAS;EAC5C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SACuD;CAC1D,OACE,oBAAC,YAAmB,QAApB;EAA2B,WAAU;EACnC,UAAA,qBAAC,YAAmB,SAApB;GACE,aAAU;GACV,WAAW,GACT,ufACA,SACF;GACA,GAAI;GANN,UAAA;IAQG;IACD,oBAAC,iBAAD;KACE,aAAU;KACV,WAAU;IACX,CAAA;IACD,oBAAC,eAAD;KACE,aAAU;KACV,WAAU;IACX,CAAA;GACyB;;CACH,CAAA;AAE/B;AAEA,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SACuD;CAC1D,OACE,oBAAC,YAAmB,SAApB;EACE,aAAU;EACV,WAAU;EACV,GAAI;EAEJ,UAAA,oBAAC,OAAD;GACE,WAAW,GACT,qJACA,SACF;GAEC;EACE,CAAA;CACqB,CAAA;AAEhC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIAvatar — an avatar-shaped AI-identity marker.
|
|
3
|
+
*
|
|
4
|
+
* A plain `Avatar`, fixed to an AI-Identity gradient background instead of
|
|
5
|
+
* `AvatarFallback`'s usual hash-derived color, holding `AISparkle`
|
|
6
|
+
* (`tone="mono"`, rendered white via `text-white`) instead of initials.
|
|
7
|
+
* The full brand gradient icon on top of an already-gradient background
|
|
8
|
+
* would read as muddy — a flat white mark reads clean, the same
|
|
9
|
+
* colored-circle-plus-white-icon convention avatar badges generally use.
|
|
10
|
+
*
|
|
11
|
+
* The background is `ai-grad-from` to `ai-grad-to` (pink to orange), not
|
|
12
|
+
* the usual `ai-wash` to `ai-grad-from` (yellow to pink) — computed
|
|
13
|
+
* contrast of white against `ai-wash` is only 1.62:1, and still only
|
|
14
|
+
* ~2.9:1 at the gradient's own visual midpoint, failing WCAG 1.4.11's 3:1
|
|
15
|
+
* non-text minimum across a meaningful chunk of the icon's footprint.
|
|
16
|
+
* `ai-grad-from`/`ai-grad-to` individually clear 3.6-4.3:1 against white —
|
|
17
|
+
* same AI Identity palette, just without the one stop that doesn't hold
|
|
18
|
+
* up against a white icon.
|
|
19
|
+
*
|
|
20
|
+
* Marks genuine AI involvement only, never decoration — see manifest.json's
|
|
21
|
+
* `ai_presence` convention for the full rule and every current AI-treatment
|
|
22
|
+
* recipe.
|
|
23
|
+
*/
|
|
24
|
+
import * as React from "react";
|
|
25
|
+
import { Avatar } from "../../components/ui/avatar";
|
|
26
|
+
declare function AIAvatar({ className, size, ...props }: Omit<React.ComponentProps<typeof Avatar>, "children"> & {
|
|
27
|
+
size?: "default" | "sm" | "lg";
|
|
28
|
+
}): React.JSX.Element;
|
|
29
|
+
export { AIAvatar };
|
|
30
|
+
/**
|
|
31
|
+
* WHEN TO USE
|
|
32
|
+
* - An avatar-shaped slot that needs to read as "this is Sara/AI" at a glance — a collaborator list that includes an AI participant, a DataTable row's assignee avatar when AI is the assignee
|
|
33
|
+
*
|
|
34
|
+
* NOT WHEN
|
|
35
|
+
* - A chat surface that's already inside its own Sara-branded container — per message.tsx's own doc comment, per-message AI marking is redundant there; omit the avatar entirely instead
|
|
36
|
+
* - Marking AI presence on content that isn't itself a person/entity slot — use AILabel or Button variant="ai" instead
|
|
37
|
+
*
|
|
38
|
+
* KEY RULES
|
|
39
|
+
* - size: "default" | "sm" | "lg" — same vocabulary as Avatar itself, passed straight through
|
|
40
|
+
* - No `children`/`colorSeed` — always the fixed AI Gradient background + white AISparkle, not a hash-derived color
|
|
41
|
+
*
|
|
42
|
+
* USAGE
|
|
43
|
+
* <AIAvatar />
|
|
44
|
+
* <AIAvatar size="sm" />
|
|
45
|
+
*/
|
|
46
|
+
//# sourceMappingURL=ai-avatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-avatar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/ai-avatar.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAS/C,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG;IACzD,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAAA;CAC/B,qBA0BA;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA;AAEnB;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import { AISparkle } from "./ai-sparkle.js";
|
|
3
|
+
import { Avatar } from "./avatar.js";
|
|
4
|
+
import "react";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/ui/ai-avatar.tsx
|
|
7
|
+
var SPARKLE_SIZE_BY_AVATAR_SIZE = {
|
|
8
|
+
default: "md",
|
|
9
|
+
sm: "sm",
|
|
10
|
+
lg: "lg"
|
|
11
|
+
};
|
|
12
|
+
function AIAvatar({ className, size = "default", ...props }) {
|
|
13
|
+
return /* @__PURE__ */ jsx(Avatar, {
|
|
14
|
+
"data-slot": "ai-avatar",
|
|
15
|
+
size,
|
|
16
|
+
className: cn("items-center justify-center bg-gradient-to-br from-ai-grad-from to-ai-grad-to text-white", className),
|
|
17
|
+
...props,
|
|
18
|
+
children: /* @__PURE__ */ jsx(AISparkle, {
|
|
19
|
+
tone: "mono",
|
|
20
|
+
size: SPARKLE_SIZE_BY_AVATAR_SIZE[size]
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* WHEN TO USE
|
|
26
|
+
* - An avatar-shaped slot that needs to read as "this is Sara/AI" at a glance — a collaborator list that includes an AI participant, a DataTable row's assignee avatar when AI is the assignee
|
|
27
|
+
*
|
|
28
|
+
* NOT WHEN
|
|
29
|
+
* - A chat surface that's already inside its own Sara-branded container — per message.tsx's own doc comment, per-message AI marking is redundant there; omit the avatar entirely instead
|
|
30
|
+
* - Marking AI presence on content that isn't itself a person/entity slot — use AILabel or Button variant="ai" instead
|
|
31
|
+
*
|
|
32
|
+
* KEY RULES
|
|
33
|
+
* - size: "default" | "sm" | "lg" — same vocabulary as Avatar itself, passed straight through
|
|
34
|
+
* - No `children`/`colorSeed` — always the fixed AI Gradient background + white AISparkle, not a hash-derived color
|
|
35
|
+
*
|
|
36
|
+
* USAGE
|
|
37
|
+
* <AIAvatar />
|
|
38
|
+
* <AIAvatar size="sm" />
|
|
39
|
+
*/
|
|
40
|
+
//#endregion
|
|
41
|
+
export { AIAvatar };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=ai-avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-avatar.js","names":[],"sources":["../../../src/components/ui/ai-avatar.tsx"],"sourcesContent":["/**\n * AIAvatar — an avatar-shaped AI-identity marker.\n *\n * A plain `Avatar`, fixed to an AI-Identity gradient background instead of\n * `AvatarFallback`'s usual hash-derived color, holding `AISparkle`\n * (`tone=\"mono\"`, rendered white via `text-white`) instead of initials.\n * The full brand gradient icon on top of an already-gradient background\n * would read as muddy — a flat white mark reads clean, the same\n * colored-circle-plus-white-icon convention avatar badges generally use.\n *\n * The background is `ai-grad-from` to `ai-grad-to` (pink to orange), not\n * the usual `ai-wash` to `ai-grad-from` (yellow to pink) — computed\n * contrast of white against `ai-wash` is only 1.62:1, and still only\n * ~2.9:1 at the gradient's own visual midpoint, failing WCAG 1.4.11's 3:1\n * non-text minimum across a meaningful chunk of the icon's footprint.\n * `ai-grad-from`/`ai-grad-to` individually clear 3.6-4.3:1 against white —\n * same AI Identity palette, just without the one stop that doesn't hold\n * up against a white icon.\n *\n * Marks genuine AI involvement only, never decoration — see manifest.json's\n * `ai_presence` convention for the full rule and every current AI-treatment\n * recipe.\n */\n\nimport * as React from \"react\"\n\nimport { AISparkle } from \"@/components/ui/ai-sparkle\"\nimport { Avatar } from \"@/components/ui/avatar\"\nimport { cn } from \"@/lib/utils\"\n\nconst SPARKLE_SIZE_BY_AVATAR_SIZE = {\n default: \"md\",\n sm: \"sm\",\n lg: \"lg\",\n} as const\n\nfunction AIAvatar({\n className,\n size = \"default\",\n ...props\n}: Omit<React.ComponentProps<typeof Avatar>, \"children\"> & {\n size?: \"default\" | \"sm\" | \"lg\"\n}) {\n return (\n <Avatar\n data-slot=\"ai-avatar\"\n size={size}\n // grad-from -> grad-to (pink -> orange), not the wash's pale yellow —\n // computed contrast of white against ai-wash is only 1.62:1 (and\n // ~2.9:1 even at the gradient's own visual midpoint), failing WCAG\n // 1.4.11's 3:1 non-text minimum across a meaningful chunk of the\n // icon's footprint. grad-from/grad-to individually clear 3.6-4.3:1,\n // same AI Identity palette, just without the one stop that doesn't\n // hold up against a white icon.\n className={cn(\n \"items-center justify-center bg-gradient-to-br from-ai-grad-from to-ai-grad-to text-white\",\n className\n )}\n {...props}\n >\n {/*\n * Avatar has no ambient `[&_svg]` sizing rule the way Button does\n * (see AISparkle's own doc comment) — AISparkle needs an explicit\n * size here or it renders at the SVG's unconstrained default.\n */}\n <AISparkle tone=\"mono\" size={SPARKLE_SIZE_BY_AVATAR_SIZE[size]} />\n </Avatar>\n )\n}\n\nexport { AIAvatar }\n\n/**\n * WHEN TO USE\n * - An avatar-shaped slot that needs to read as \"this is Sara/AI\" at a glance — a collaborator list that includes an AI participant, a DataTable row's assignee avatar when AI is the assignee\n *\n * NOT WHEN\n * - A chat surface that's already inside its own Sara-branded container — per message.tsx's own doc comment, per-message AI marking is redundant there; omit the avatar entirely instead\n * - Marking AI presence on content that isn't itself a person/entity slot — use AILabel or Button variant=\"ai\" instead\n *\n * KEY RULES\n * - size: \"default\" | \"sm\" | \"lg\" — same vocabulary as Avatar itself, passed straight through\n * - No `children`/`colorSeed` — always the fixed AI Gradient background + white AISparkle, not a hash-derived color\n *\n * USAGE\n * <AIAvatar />\n * <AIAvatar size=\"sm\" />\n */\n"],"mappings":";;;;;;AA8BA,IAAM,8BAA8B;CAClC,SAAS;CACT,IAAI;CACJ,IAAI;AACN;AAEA,SAAS,SAAS,EAChB,WACA,OAAO,WACP,GAAG,SAGF;CACD,OACE,oBAAC,QAAD;EACE,aAAU;EACJ;EAQN,WAAW,GACT,4FACA,SACF;EACA,GAAI;EAOJ,UAAA,oBAAC,WAAD;GAAW,MAAK;GAAO,MAAM,4BAA4B;EAAQ,CAAA;CAC3D,CAAA;AAEZ"}
|