@adamosuiteservices/ui 2.18.6 → 2.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/accordion-rounded.cjs +8 -8
- package/dist/accordion-rounded.js +12 -12
- package/dist/accordion.cjs +1 -1
- package/dist/accordion.js +1 -1
- package/dist/alert.cjs +32 -23
- package/dist/alert.js +53 -43
- package/dist/amount-input.cjs +8 -0
- package/dist/amount-input.js +191 -0
- package/dist/avatar.cjs +7 -7
- package/dist/avatar.js +18 -18
- package/dist/badge.cjs +24 -28
- package/dist/badge.js +45 -42
- package/dist/breadcrumb.cjs +3 -4
- package/dist/breadcrumb.js +17 -18
- package/dist/button-CPm4-98H.cjs +87 -0
- package/dist/button-D4ddrxyp.js +156 -0
- package/dist/button-group.cjs +1 -1
- package/dist/button-group.js +1 -1
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/{calendar-Dorq3-wv.cjs → calendar-DXq90PYV.cjs} +20 -22
- package/dist/{calendar-xBaFu2sB.js → calendar-DgfO9zab.js} +239 -240
- package/dist/calendar.cjs +1 -1
- package/dist/calendar.js +1 -1
- package/dist/card.cjs +3 -3
- package/dist/card.js +4 -4
- package/dist/checkbox-CIzBdqN7.cjs +24 -0
- package/dist/{checkbox-DL_jFvgl.js → checkbox-DPlUjwLi.js} +54 -52
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/colors.css +1 -1
- package/dist/combobox-DG9u4g84.js +692 -0
- package/dist/combobox-DylTjGrw.cjs +57 -0
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.js +1 -1
- package/dist/components/layout/sidebar/sidebar.d.ts +2 -1
- package/dist/components/layout/toaster/toaster.d.ts +1 -1
- package/dist/components/ui/alert/alert.d.ts +1 -1
- package/dist/components/ui/amount-input/amount-input.d.ts +32 -0
- package/dist/components/ui/amount-input/index.d.ts +1 -0
- package/dist/components/ui/badge/badge.d.ts +3 -2
- package/dist/components/ui/calendar/calendar.d.ts +1 -1
- package/dist/components/ui/combobox/combobox.d.ts +3 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +3 -1
- package/dist/components/ui/selectable-card/index.d.ts +1 -0
- package/dist/components/ui/selectable-card/selectable-card.d.ts +22 -0
- package/dist/components/ui/timeline/index.d.ts +1 -0
- package/dist/components/ui/timeline/timeline.d.ts +30 -0
- package/dist/components/ui/typography/typography.d.ts +1 -1
- package/dist/context-menu.cjs +18 -19
- package/dist/context-menu.js +37 -38
- package/dist/date-picker-selector.cjs +1 -1
- package/dist/date-picker-selector.js +3 -3
- package/dist/dialog.cjs +7 -9
- package/dist/dialog.js +36 -38
- package/dist/dropdown-menu.cjs +57 -36
- package/dist/dropdown-menu.js +206 -173
- package/dist/field.cjs +12 -7
- package/dist/field.js +51 -45
- package/dist/file-upload-v2.cjs +11 -5
- package/dist/file-upload-v2.js +75 -60
- package/dist/file-upload.cjs +11 -5
- package/dist/file-upload.js +118 -110
- package/dist/full-screen-loader.cjs +1 -1
- package/dist/full-screen-loader.js +1 -1
- package/dist/{icon-B7joBr0A.cjs → icon-C5Q2b1Am.cjs} +1 -1
- package/dist/{icon-BFQz1tQC.js → icon-t4jt1Z2h.js} +1 -1
- package/dist/icon.cjs +1 -1
- package/dist/icon.js +1 -1
- package/dist/index-BBT2EGq8.js +18 -0
- package/dist/index-DCsgSkBj.cjs +1 -0
- package/dist/input-8sEO5zwD.js +44 -0
- package/dist/input-AONeSXcs.cjs +22 -0
- package/dist/input-group-BLffLxyg.cjs +86 -0
- package/dist/input-group-DmevJAqa.js +240 -0
- package/dist/input-group.cjs +1 -84
- package/dist/input-group.js +7 -234
- package/dist/input-otp.cjs +5 -7
- package/dist/input-otp.js +58 -60
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/kbd.cjs +6 -7
- package/dist/kbd.js +14 -15
- package/dist/{label-DqfX9cHc.cjs → label-B7Z1D5-Q.cjs} +5 -4
- package/dist/{label-C6zVnc3d.js → label-_BWRIH7C.js} +14 -13
- package/dist/label.cjs +1 -1
- package/dist/label.js +1 -1
- package/dist/pagination.cjs +5 -5
- package/dist/pagination.js +18 -18
- package/dist/radio-group.cjs +12 -9
- package/dist/radio-group.js +66 -63
- package/dist/select.cjs +18 -16
- package/dist/select.js +18 -16
- package/dist/selectable-card.cjs +29 -0
- package/dist/selectable-card.js +129 -0
- package/dist/separator-DXdc7LcC.cjs +7 -0
- package/dist/{separator-CsaqP20m.js → separator-DZfXXbNt.js} +1 -1
- package/dist/separator.cjs +1 -1
- package/dist/separator.js +1 -1
- package/dist/{sheet-Cnq7TCzu.cjs → sheet-Cp6JGhWC.cjs} +10 -10
- package/dist/{sheet-C9vce0ut.js → sheet-hWerE8S1.js} +9 -6
- package/dist/sheet.cjs +1 -1
- package/dist/sheet.js +1 -1
- package/dist/sidebar.cjs +10 -10
- package/dist/sidebar.js +83 -92
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +1 -1
- package/dist/{spinner-C7q7NthY.cjs → spinner-DUZ2vcus.cjs} +1 -1
- package/dist/{spinner-DQ5JLL3U.js → spinner-_-J3zJ_g.js} +1 -1
- package/dist/spinner.cjs +1 -1
- package/dist/spinner.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/switch.cjs +2 -4
- package/dist/switch.js +71 -73
- package/dist/table.cjs +14 -14
- package/dist/table.js +12 -12
- package/dist/tabs-underline.cjs +11 -15
- package/dist/tabs-underline.js +20 -24
- package/dist/tabs.cjs +10 -14
- package/dist/tabs.js +20 -24
- package/dist/tailwind-colors.css +1 -1
- package/dist/tailwind-theme.css +1 -1
- package/dist/textarea-BSooGyp-.cjs +18 -0
- package/dist/textarea-D_sj6ivo.js +39 -0
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/themes.css +1 -1
- package/dist/timeline.cjs +4 -0
- package/dist/timeline.js +189 -0
- package/dist/toaster.cjs +5 -4
- package/dist/toaster.js +33 -32
- package/dist/toggle.cjs +4 -4
- package/dist/toggle.js +17 -17
- package/dist/tooltip.cjs +5 -6
- package/dist/tooltip.js +4 -5
- package/docs/components/layout/sidebar.md +81 -53
- package/docs/components/layout/toaster.md +35 -55
- package/docs/components/ui/accordion-rounded.md +12 -11
- package/docs/components/ui/alert.md +66 -36
- package/docs/components/ui/amount-input.md +229 -0
- package/docs/components/ui/avatar.md +28 -32
- package/docs/components/ui/badge.md +85 -32
- package/docs/components/ui/breadcrumb.md +5 -7
- package/docs/components/ui/button-group.md +16 -16
- package/docs/components/ui/button.md +23 -36
- package/docs/components/ui/calendar.md +54 -27
- package/docs/components/ui/card.md +5 -4
- package/docs/components/ui/checkbox.md +3 -3
- package/docs/components/ui/combobox.md +35 -1
- package/docs/components/ui/command.md +7 -7
- package/docs/components/ui/context-menu.md +14 -15
- package/docs/components/ui/date-picker-selector.md +31 -31
- package/docs/components/ui/dialog.md +47 -49
- package/docs/components/ui/dropdown-menu.md +34 -37
- package/docs/components/ui/field.md +25 -31
- package/docs/components/ui/file-upload-v2.md +11 -0
- package/docs/components/ui/file-upload.md +105 -108
- package/docs/components/ui/hover-card.md +28 -6
- package/docs/components/ui/icon.md +10 -9
- package/docs/components/ui/input-group.md +9 -9
- package/docs/components/ui/input.md +30 -33
- package/docs/components/ui/kbd.md +10 -9
- package/docs/components/ui/label.md +6 -6
- package/docs/components/ui/pagination.md +3 -3
- package/docs/components/ui/popover.md +1 -0
- package/docs/components/ui/progress.md +3 -3
- package/docs/components/ui/radio-group.md +18 -6
- package/docs/components/ui/scroll-area.md +4 -4
- package/docs/components/ui/select.md +14 -12
- package/docs/components/ui/selectable-card.md +204 -0
- package/docs/components/ui/separator.md +4 -4
- package/docs/components/ui/sheet.md +21 -3
- package/docs/components/ui/slider.md +3 -3
- package/docs/components/ui/switch.md +7 -7
- package/docs/components/ui/table.md +7 -4
- package/docs/components/ui/tabs-underline.md +36 -36
- package/docs/components/ui/tabs.md +6 -4
- package/docs/components/ui/textarea.md +6 -4
- package/docs/components/ui/timeline.md +214 -0
- package/docs/components/ui/toggle.md +1 -1
- package/docs/components/ui/tooltip.md +3 -3
- package/llm.txt +7 -4
- package/package.json +13 -1
- package/dist/button-BnUlAtuD.js +0 -132
- package/dist/button-CFJs0esR.cjs +0 -63
- package/dist/checkbox-3RIZX2HF.cjs +0 -22
- package/dist/combobox-MkeJiTXj.js +0 -637
- package/dist/combobox-jJRxvUsB.cjs +0 -40
- package/dist/input-BCiOr4Fy.js +0 -44
- package/dist/input-Bz5k4w94.cjs +0 -22
- package/dist/separator-CCGaTo09.cjs +0 -7
- package/dist/textarea-BRCnIxdB.js +0 -33
- package/dist/textarea-DkFUS_oS.cjs +0 -14
|
@@ -25,7 +25,7 @@ import { Kbd, KbdGroup } from "@adamosuiteservices/ui/kbd";
|
|
|
25
25
|
</KbdGroup>
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
**
|
|
28
|
+
**Components**: 2 (Kbd, KbdGroup)
|
|
29
29
|
|
|
30
30
|
## Props
|
|
31
31
|
|
|
@@ -41,7 +41,9 @@ import { Kbd, KbdGroup } from "@adamosuiteservices/ui/kbd";
|
|
|
41
41
|
| Prop | Type | Description |
|
|
42
42
|
| ----------- | -------- | ------------------------ |
|
|
43
43
|
| `className` | `string` | Additional CSS classes |
|
|
44
|
-
| ...props | - | All native `<
|
|
44
|
+
| ...props | - | All native `<kbd>` props |
|
|
45
|
+
|
|
46
|
+
**Note**: Renders as a `<kbd>` element (semantic)
|
|
45
47
|
|
|
46
48
|
## Usage patterns
|
|
47
49
|
|
|
@@ -328,10 +330,10 @@ import { Icon } from "@adamosuiteservices/ui/icon";
|
|
|
328
330
|
|
|
329
331
|
### Kbd styles
|
|
330
332
|
|
|
331
|
-
- **Background**: `bg-
|
|
332
|
-
- **Color**: `text-
|
|
333
|
+
- **Background**: `bg-accent`
|
|
334
|
+
- **Color**: `text-accent-foreground`
|
|
333
335
|
- **Height**: `h-5` (~20px)
|
|
334
|
-
- **Min Width**: `min-w-5` (square
|
|
336
|
+
- **Min Width**: `min-w-5` (square minimum)
|
|
335
337
|
- **Padding**: `px-1`
|
|
336
338
|
- **Font**: `font-sans text-xs font-medium`
|
|
337
339
|
- **Border**: `rounded-sm`
|
|
@@ -348,9 +350,8 @@ import { Icon } from "@adamosuiteservices/ui/icon";
|
|
|
348
350
|
|
|
349
351
|
When inside Tooltip:
|
|
350
352
|
|
|
351
|
-
- **Background**: `bg-
|
|
352
|
-
- **Color**: `text-
|
|
353
|
-
- **Dark mode**: `dark:bg-background/10`
|
|
353
|
+
- **Background**: `bg-neutrals-0/20` (semi-transparent white)
|
|
354
|
+
- **Color**: `text-neutrals-0` (white)
|
|
354
355
|
|
|
355
356
|
## Common symbols
|
|
356
357
|
|
|
@@ -425,7 +426,7 @@ When inside Tooltip:
|
|
|
425
426
|
**Not visible in Tooltip**: Tooltip styles apply automatically
|
|
426
427
|
**Inconsistent spacing**: KbdGroup has `gap-1`, adjust with className if needed
|
|
427
428
|
**Selectable**: Verify it has `select-none` applied
|
|
428
|
-
**Background not visible**: Verify theme and color `bg-
|
|
429
|
+
**Background not visible**: Verify theme and color `bg-accent`
|
|
429
430
|
**Too tall**: Fixed height `h-5`, don't change without adjusting padding
|
|
430
431
|
|
|
431
432
|
## References
|
|
@@ -19,7 +19,7 @@ import { Label } from "@adamosuiteservices/ui/label";
|
|
|
19
19
|
<Input id="email" type="email" />
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
**
|
|
22
|
+
**Components**: 1 (Label)
|
|
23
23
|
|
|
24
24
|
## Props
|
|
25
25
|
|
|
@@ -273,11 +273,11 @@ import { Checkbox } from "@adamosuiteservices/ui/checkbox";
|
|
|
273
273
|
## Base styles
|
|
274
274
|
|
|
275
275
|
- **Display**: `flex items-center gap-2`
|
|
276
|
-
- **Font**: `text-xs font-
|
|
276
|
+
- **Font**: `text-xs font-normal`
|
|
277
277
|
- **Line height**: `leading-none`
|
|
278
278
|
- **Select**: `select-none` (not selectable)
|
|
279
|
-
- **Peer disabled**: `peer-disabled:cursor-not-allowed peer-disabled:
|
|
280
|
-
- **Group disabled**: `group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:
|
|
279
|
+
- **Peer disabled**: `peer-disabled:cursor-not-allowed peer-disabled:text-disabled-foreground`
|
|
280
|
+
- **Group disabled**: `group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:text-disabled-foreground`
|
|
281
281
|
|
|
282
282
|
## States
|
|
283
283
|
|
|
@@ -290,7 +290,7 @@ When the associated input (`peer`) is disabled:
|
|
|
290
290
|
<Label htmlFor="disabled">Disabled field</Label>
|
|
291
291
|
```
|
|
292
292
|
|
|
293
|
-
→ Label
|
|
293
|
+
→ Label automatically applies `text-disabled-foreground` and `cursor-not-allowed`
|
|
294
294
|
|
|
295
295
|
### Disabled via group
|
|
296
296
|
|
|
@@ -303,7 +303,7 @@ When the container has `data-disabled`:
|
|
|
303
303
|
</div>
|
|
304
304
|
```
|
|
305
305
|
|
|
306
|
-
→ Label
|
|
306
|
+
→ Label automatically applies `text-disabled-foreground` and `pointer-events-none`
|
|
307
307
|
|
|
308
308
|
## Accessibility
|
|
309
309
|
|
|
@@ -537,8 +537,8 @@ function App() {
|
|
|
537
537
|
|
|
538
538
|
### PaginationLink
|
|
539
539
|
|
|
540
|
-
- **Active**: `isActive` →
|
|
541
|
-
- **Inactive**: variant
|
|
540
|
+
- **Active**: `isActive` → `bg-accent` applied, `aria-current="page"`
|
|
541
|
+
- **Inactive**: no background, variant `link-neutral`
|
|
542
542
|
|
|
543
543
|
### Disabled (previous/next)
|
|
544
544
|
|
|
@@ -562,7 +562,7 @@ className = "pointer-events-none opacity-50";
|
|
|
562
562
|
### PaginationLink
|
|
563
563
|
|
|
564
564
|
- **Size default**: `size="icon"` (h-9 w-9)
|
|
565
|
-
- **
|
|
565
|
+
- **Variant**: `link-neutral` for all states; active adds `bg-accent`
|
|
566
566
|
|
|
567
567
|
### PaginationPrevious/Next
|
|
568
568
|
|
|
@@ -18,7 +18,7 @@ import { Progress } from "@adamosuiteservices/ui/progress";
|
|
|
18
18
|
<Progress value={33} />
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
**
|
|
21
|
+
**Components**: 1 (Progress)
|
|
22
22
|
|
|
23
23
|
## Props
|
|
24
24
|
|
|
@@ -146,8 +146,8 @@ function App() {
|
|
|
146
146
|
|
|
147
147
|
- **Height**: `h-2` default
|
|
148
148
|
- **Border radius**: `rounded-full`
|
|
149
|
-
- **Transition**: `transition-all`
|
|
150
|
-
- **Transform**: `translateX`
|
|
149
|
+
- **Transition**: `transition-all` on indicator
|
|
150
|
+
- **Transform**: `translateX` for animation
|
|
151
151
|
|
|
152
152
|
### Variant styles
|
|
153
153
|
|
|
@@ -27,7 +27,7 @@ import { RadioGroup, RadioGroupItem } from "@adamosuiteservices/ui/radio-group";
|
|
|
27
27
|
</RadioGroup>
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
**
|
|
30
|
+
**Components**: 2 (RadioGroup, RadioGroupItem)
|
|
31
31
|
|
|
32
32
|
## Props
|
|
33
33
|
|
|
@@ -56,6 +56,17 @@ import { RadioGroup, RadioGroupItem } from "@adamosuiteservices/ui/radio-group";
|
|
|
56
56
|
|
|
57
57
|
**Note**: Accepts all Radix UI RadioGroup.Item props
|
|
58
58
|
|
|
59
|
+
## States
|
|
60
|
+
|
|
61
|
+
| State | Styles |
|
|
62
|
+
| -------- | ------------------------------------------------------------------------------- |
|
|
63
|
+
| Default | `border-medium-border bg-background` |
|
|
64
|
+
| Hover | `bg-muted` |
|
|
65
|
+
| Focus | `border-primary ring-4 ring-primary/10` |
|
|
66
|
+
| Checked | `border-primary` + white bg + primary dot (`text-[10px] text-primary`) |
|
|
67
|
+
| Disabled | `bg-accent border-medium-border opacity-100 cursor-not-allowed` |
|
|
68
|
+
| Invalid | `border-destructive` (ring only on focus-visible: `ring-4 ring-destructive/10`) |
|
|
69
|
+
|
|
59
70
|
## Usage patterns
|
|
60
71
|
|
|
61
72
|
### Basic
|
|
@@ -274,11 +285,12 @@ function App() {
|
|
|
274
285
|
## Base styles
|
|
275
286
|
|
|
276
287
|
- **Size**: `size-5` (20px)
|
|
277
|
-
- **Border**: `border-
|
|
278
|
-
- **Checked**: Icon `circle` with `text-primary`
|
|
279
|
-
- **Focus**: `ring-
|
|
280
|
-
- **Invalid**: `border-destructive` with `ring-destructive/
|
|
281
|
-
- **
|
|
288
|
+
- **Border**: `border-medium-border`, no shadow
|
|
289
|
+
- **Checked**: Icon `circle` (filled) with `text-primary`, `border-primary`
|
|
290
|
+
- **Focus**: `border-primary ring-4 ring-primary/10`
|
|
291
|
+
- **Invalid**: `border-destructive` with `ring-4 ring-destructive/10` (on focus)
|
|
292
|
+
- **Disabled**: `bg-accent border-medium-border opacity-100`
|
|
293
|
+
- **Spacing**: `gap-3` default between items (RadioGroup uses `grid gap-3`)
|
|
282
294
|
|
|
283
295
|
## Accessibility
|
|
284
296
|
|
|
@@ -324,10 +324,10 @@ You can customize the scrollbar using Tailwind classes:
|
|
|
324
324
|
|
|
325
325
|
The following `data-slot` attributes are available for CSS targeting:
|
|
326
326
|
|
|
327
|
-
- `scroll-area` -
|
|
328
|
-
- `scroll-area-viewport` -
|
|
329
|
-
- `scroll-area-scrollbar` - Scrollbar (vertical
|
|
330
|
-
- `scroll-area-thumb` -
|
|
327
|
+
- `scroll-area` - Main container
|
|
328
|
+
- `scroll-area-viewport` - Content viewport
|
|
329
|
+
- `scroll-area-scrollbar` - Scrollbar (vertical or horizontal)
|
|
330
|
+
- `scroll-area-thumb` - Scrollbar thumb
|
|
331
331
|
|
|
332
332
|
### Usage example with data-slot
|
|
333
333
|
|
|
@@ -317,9 +317,7 @@ function App() {
|
|
|
317
317
|
</Select>
|
|
318
318
|
```
|
|
319
319
|
|
|
320
|
-
## Use cases
|
|
321
|
-
|
|
322
|
-
```tsx## Use cases
|
|
320
|
+
## Use cases
|
|
323
321
|
|
|
324
322
|
**Simple selection**: Choose one option from a long list
|
|
325
323
|
**Forms**: Country, state, category, language
|
|
@@ -330,16 +328,17 @@ function App() {
|
|
|
330
328
|
## Base styles
|
|
331
329
|
|
|
332
330
|
- **Trigger height**: `h-10` (default, 40px), `h-9` (sm, 36px)
|
|
333
|
-
- **Item height**: `h-
|
|
334
|
-
- **Padding**: Trigger uses `px-3`
|
|
335
|
-
- **Item padding**: `
|
|
336
|
-
- **
|
|
331
|
+
- **Item height**: `h-11` (44px)
|
|
332
|
+
- **Padding**: Trigger uses `px-3`
|
|
333
|
+
- **Item padding**: `pl-4 pr-10`
|
|
334
|
+
- **Item gap**: `gap-3`
|
|
335
|
+
- **Separators**: `border-b border-divider` between items, removed on last item
|
|
337
336
|
- **Border radius**: Items have rounded corners on first (top) and last (bottom) to match container
|
|
338
|
-
- **
|
|
339
|
-
- **Focus**: `ring-
|
|
340
|
-
- **Content**: `bg-popover` with `shadow-
|
|
341
|
-
- **Item hover**: `bg-
|
|
342
|
-
- **Check icon**: Icon `check` with `text-
|
|
337
|
+
- **Trigger border**: `border-input`, no shadow
|
|
338
|
+
- **Focus (trigger)**: `border-primary-300 ring-4 ring-primary/10`
|
|
339
|
+
- **Content**: `bg-popover` with `shadow-xs` and `border`
|
|
340
|
+
- **Item focus/hover**: `bg-muted text-foreground`
|
|
341
|
+
- **Check icon**: Icon `check` with `text-xl text-success` on selected item, positioned absolute right
|
|
343
342
|
|
|
344
343
|
## Accessibility
|
|
345
344
|
|
|
@@ -371,4 +370,7 @@ function App() {
|
|
|
371
370
|
|
|
372
371
|
- **Radix UI Select**: <https://www.radix-ui.com/primitives/docs/components/select>
|
|
373
372
|
- **shadcn/ui Select**: <https://ui.shadcn.com/docs/components/select>
|
|
373
|
+
|
|
374
|
+
```
|
|
375
|
+
|
|
374
376
|
```
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Selectable card component
|
|
2
|
+
|
|
3
|
+
A pressable card that can be selected or deselected. Supports standalone toggle mode and group selection mode, with full disabled state propagation from `<fieldset disabled>`.
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
`SelectableCard` is a `<button>` styled as a card with `aria-pressed` semantics. It works standalone as a toggle, or inside `SelectableCardGroup` for single-selection radio-like behaviour. `SelectableCardTitle` and `SelectableCardDescription` are typographic sub-components that inherit the disabled state automatically.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Standalone toggle mode (no group needed)
|
|
12
|
+
- Group mode via `SelectableCardGroup` — single-selection, controlled or uncontrolled
|
|
13
|
+
- `aria-pressed` for correct screen reader announcement
|
|
14
|
+
- Selected state: primary gradient background + primary border
|
|
15
|
+
- Disabled state propagates from `<fieldset disabled>` via `in-[fieldset:disabled]` selectors
|
|
16
|
+
- `SelectableCardTitle` and `SelectableCardDescription` dim automatically when the card is disabled via `group-disabled:`
|
|
17
|
+
|
|
18
|
+
## Import
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import {
|
|
22
|
+
SelectableCard,
|
|
23
|
+
SelectableCardGroup,
|
|
24
|
+
SelectableCardTitle,
|
|
25
|
+
SelectableCardDescription,
|
|
26
|
+
type SelectableCardProps,
|
|
27
|
+
type SelectableCardGroupProps,
|
|
28
|
+
type SelectableCardTitleProps,
|
|
29
|
+
type SelectableCardDescriptionProps,
|
|
30
|
+
} from "@adamosuiteservices/ui/selectable-card";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Basic usage
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
<SelectableCard>
|
|
37
|
+
<SelectableCardTitle>Standard</SelectableCardTitle>
|
|
38
|
+
<SelectableCardDescription>
|
|
39
|
+
Up to 5 users and basic features.
|
|
40
|
+
</SelectableCardDescription>
|
|
41
|
+
</SelectableCard>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Standalone toggle
|
|
45
|
+
|
|
46
|
+
The card manages its own selection state internally when neither `selected` nor a group is provided:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<SelectableCard>
|
|
50
|
+
<SelectableCardTitle>Enable notifications</SelectableCardTitle>
|
|
51
|
+
</SelectableCard>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Pass `selected` to control it externally:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
const [selected, setSelected] = useState(false);
|
|
58
|
+
|
|
59
|
+
<SelectableCard selected={selected} onClick={() => setSelected((s) => !s)}>
|
|
60
|
+
<SelectableCardTitle>Enable notifications</SelectableCardTitle>
|
|
61
|
+
</SelectableCard>;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Group selection
|
|
65
|
+
|
|
66
|
+
Wrap cards in `SelectableCardGroup` for single-selection behaviour. Each card requires a unique `value` prop:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const [value, setValue] = useState("pro");
|
|
70
|
+
|
|
71
|
+
<SelectableCardGroup value={value} onValueChange={setValue}>
|
|
72
|
+
<SelectableCard value="standard">
|
|
73
|
+
<SelectableCardTitle>Standard</SelectableCardTitle>
|
|
74
|
+
<SelectableCardDescription>Up to 5 users.</SelectableCardDescription>
|
|
75
|
+
</SelectableCard>
|
|
76
|
+
<SelectableCard value="pro">
|
|
77
|
+
<SelectableCardTitle>Pro</SelectableCardTitle>
|
|
78
|
+
<SelectableCardDescription>Unlimited users.</SelectableCardDescription>
|
|
79
|
+
</SelectableCard>
|
|
80
|
+
</SelectableCardGroup>;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Uncontrolled group (manages selection internally):
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
<SelectableCardGroup defaultValue="pro">
|
|
87
|
+
<SelectableCard value="standard">...</SelectableCard>
|
|
88
|
+
<SelectableCard value="pro">...</SelectableCard>
|
|
89
|
+
</SelectableCardGroup>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## With icon and typography
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
<SelectableCard>
|
|
96
|
+
<div className="adm:flex adm:flex-col adm:gap-2">
|
|
97
|
+
<SelectableCardTitle>Standard plan</SelectableCardTitle>
|
|
98
|
+
<div className="adm:flex adm:items-center adm:gap-2 adm:pl-2">
|
|
99
|
+
<Icon symbol="credit_card" className="adm:text-2xl" />
|
|
100
|
+
<SelectableCardDescription>
|
|
101
|
+
Up to 5 users and basic features.
|
|
102
|
+
</SelectableCardDescription>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</SelectableCard>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Inside a field
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
<Field>
|
|
112
|
+
<FieldLegend variant="label">Choose a plan</FieldLegend>
|
|
113
|
+
<SelectableCardGroup value={value} onValueChange={setValue}>
|
|
114
|
+
<SelectableCard value="standard">...</SelectableCard>
|
|
115
|
+
<SelectableCard value="pro">...</SelectableCard>
|
|
116
|
+
</SelectableCardGroup>
|
|
117
|
+
</Field>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Props
|
|
121
|
+
|
|
122
|
+
### SelectableCard
|
|
123
|
+
|
|
124
|
+
| Prop | Type | Default | Description |
|
|
125
|
+
| ----------- | ---------- | ------- | ------------------------------------------------------- |
|
|
126
|
+
| `value` | `string` | — | Required when used inside `SelectableCardGroup` |
|
|
127
|
+
| `selected` | `boolean` | — | Controlled selected state (standalone, outside a group) |
|
|
128
|
+
| `disabled` | `boolean` | — | Disables the card and applies disabled visual styles |
|
|
129
|
+
| `onClick` | `function` | — | Standard button click handler |
|
|
130
|
+
| `className` | `string` | — | Additional CSS classes |
|
|
131
|
+
|
|
132
|
+
Accepts all `<button>` props.
|
|
133
|
+
|
|
134
|
+
### SelectableCardGroup
|
|
135
|
+
|
|
136
|
+
| Prop | Type | Default | Description |
|
|
137
|
+
| --------------- | ------------------------- | ------- | ------------------------------------------- |
|
|
138
|
+
| `value` | `string` | — | Controlled selected value |
|
|
139
|
+
| `defaultValue` | `string` | — | Initial value for uncontrolled mode |
|
|
140
|
+
| `onValueChange` | `(value: string) => void` | — | Called when the selected card changes |
|
|
141
|
+
| `disabled` | `boolean` | — | Disables all cards in the group |
|
|
142
|
+
| `className` | `string` | — | Additional CSS classes on the group wrapper |
|
|
143
|
+
|
|
144
|
+
### SelectableCardTitle
|
|
145
|
+
|
|
146
|
+
Small label above the main content (xs, normal weight, secondary color). Accepts all `<p>` props.
|
|
147
|
+
|
|
148
|
+
### SelectableCardDescription
|
|
149
|
+
|
|
150
|
+
Main content text (sm, semibold, foreground color). Accepts all `<p>` props.
|
|
151
|
+
|
|
152
|
+
## Examples
|
|
153
|
+
|
|
154
|
+
### Disabled state
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<SelectableCard disabled>
|
|
158
|
+
<SelectableCardTitle>Standard plan</SelectableCardTitle>
|
|
159
|
+
<SelectableCardDescription>
|
|
160
|
+
Unavailable in your region.
|
|
161
|
+
</SelectableCardDescription>
|
|
162
|
+
</SelectableCard>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Group with disabled card
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<SelectableCardGroup value={value} onValueChange={setValue}>
|
|
169
|
+
<SelectableCard value="standard">...</SelectableCard>
|
|
170
|
+
<SelectableCard value="enterprise" disabled>
|
|
171
|
+
...
|
|
172
|
+
</SelectableCard>
|
|
173
|
+
</SelectableCardGroup>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Inside a disabled fieldset
|
|
177
|
+
|
|
178
|
+
All cards inherit the disabled state without any extra props:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
<FieldSet disabled>
|
|
182
|
+
<FieldLegend>Choose a plan</FieldLegend>
|
|
183
|
+
<SelectableCardGroup defaultValue="pro">
|
|
184
|
+
<SelectableCard value="standard">...</SelectableCard>
|
|
185
|
+
<SelectableCard value="pro">...</SelectableCard>
|
|
186
|
+
</SelectableCardGroup>
|
|
187
|
+
</FieldSet>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Implementation notes
|
|
191
|
+
|
|
192
|
+
- `SelectableCard` uses `data-state="selected" | "unselected"` and `aria-pressed` for both styling and accessibility.
|
|
193
|
+
- When inside a `SelectableCardGroup`, the card reads from context — `group.value === value` determines selection.
|
|
194
|
+
- When standalone with no `selected` prop, the card manages `internalSelected` state internally.
|
|
195
|
+
- `SelectableCardTitle` and `SelectableCardDescription` use `adm:group-disabled:text-disabled-foreground` — the `adm:group` class on the parent `<button>` enables this inheritance.
|
|
196
|
+
- Disabled via `<fieldset disabled>` uses `in-[fieldset:disabled]` selectors, which do not set the native `disabled` attribute on the button — `pointer-events-none` is applied instead.
|
|
197
|
+
- Selected background is a horizontal gradient: `from-primary-50 to-white`.
|
|
198
|
+
|
|
199
|
+
## Accessibility
|
|
200
|
+
|
|
201
|
+
- `aria-pressed` correctly communicates toggle state to screen readers.
|
|
202
|
+
- `disabled` cards are focusable by default in some browsers — use `<fieldset disabled>` at the group level to prevent all interaction cleanly.
|
|
203
|
+
- Use `SelectableCardGroup` inside a `<fieldset>` with a `<legend>` (via `FieldLegend`) so screen readers announce the group label.
|
|
204
|
+
- The card content is free-form — ensure it is descriptive enough to understand the option without visual context.
|
|
@@ -148,7 +148,7 @@ const items = [
|
|
|
148
148
|
```tsx
|
|
149
149
|
<Separator className="bg-muted" /> {/* Subtle */}
|
|
150
150
|
<Separator className="bg-primary h-0.5" /> {/* Accent */}
|
|
151
|
-
<Separator className="bg-
|
|
151
|
+
<Separator className="bg-divider" /> {/* Default */}
|
|
152
152
|
```
|
|
153
153
|
|
|
154
154
|
## Use cases
|
|
@@ -166,13 +166,13 @@ const items = [
|
|
|
166
166
|
|
|
167
167
|
- **Height**: `h-px` (1px)
|
|
168
168
|
- **Width**: `w-full`
|
|
169
|
-
- **Color**: `bg-
|
|
169
|
+
- **Color**: `bg-divider`
|
|
170
170
|
|
|
171
171
|
### Vertical styles
|
|
172
172
|
|
|
173
173
|
- **Width**: `w-px` (1px)
|
|
174
174
|
- **Height**: `h-full`
|
|
175
|
-
- **Color**: `bg-
|
|
175
|
+
- **Color**: `bg-divider`
|
|
176
176
|
|
|
177
177
|
## Accessibility
|
|
178
178
|
|
|
@@ -203,7 +203,7 @@ const items = [
|
|
|
203
203
|
|
|
204
204
|
## Troubleshooting
|
|
205
205
|
|
|
206
|
-
**Not visible**: Verify `bg-
|
|
206
|
+
**Not visible**: Verify `bg-divider` or custom color applied
|
|
207
207
|
**Too tall/wide**: Horizontal uses `h-px`, vertical uses `w-px`
|
|
208
208
|
**Doesn't divide vertically**: Verify `orientation="vertical"` and container height
|
|
209
209
|
**Inconsistent spacing**: Use `my-*` or `mx-*` for uniform spacing
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
|
|
61
61
|
### From right (default)
|
|
62
62
|
|
|
63
|
-
Width: `w-11/12` on mobile, `max-w-
|
|
63
|
+
Width: `w-11/12` on mobile, `max-w-xl` on desktop. Border radius: `rounded-2xl`. Individual sections (Header/Footer) have `p-8` (32px) padding.
|
|
64
64
|
|
|
65
65
|
```tsx
|
|
66
66
|
<Sheet>
|
|
@@ -137,7 +137,7 @@ Width: `w-11/12` on mobile, `max-w-sm` on desktop. Border radius: `rounded-2xl`.
|
|
|
137
137
|
|
|
138
138
|
### SheetBody
|
|
139
139
|
|
|
140
|
-
Container for the main sheet content with
|
|
140
|
+
Container for the main sheet content with horizontal padding.
|
|
141
141
|
|
|
142
142
|
```tsx
|
|
143
143
|
<SheetBody>
|
|
@@ -149,10 +149,28 @@ Container for the main sheet content with 32px horizontal padding (`px-8`).
|
|
|
149
149
|
|
|
150
150
|
**Default styles**: `px-8` (32px horizontal padding)
|
|
151
151
|
|
|
152
|
+
### SheetHeader
|
|
153
|
+
|
|
154
|
+
Header section with padding.
|
|
155
|
+
|
|
156
|
+
**Default styles**: `p-8` (32px padding), `flex flex-col gap-2`
|
|
157
|
+
|
|
158
|
+
### SheetFooter
|
|
159
|
+
|
|
160
|
+
Footer section with padding, typically for action buttons.
|
|
161
|
+
|
|
162
|
+
**Default styles**: `p-8` (32px padding), `mt-auto flex flex-col gap-2`
|
|
163
|
+
|
|
164
|
+
### SheetTitle
|
|
165
|
+
|
|
166
|
+
Sheet title with semantic heading.
|
|
167
|
+
|
|
168
|
+
**Default styles**: `text-sm leading-5 font-bold text-foreground`
|
|
169
|
+
|
|
152
170
|
## Spacing
|
|
153
171
|
|
|
154
172
|
- **Content padding**: SheetHeader, SheetBody, SheetFooter use `p-8` or `px-8` (32px)
|
|
155
|
-
- **Gap between sections**: `gap-
|
|
173
|
+
- **Gap between sections**: `gap-4` (16px) between SheetHeader, SheetBody, and SheetFooter
|
|
156
174
|
|
|
157
175
|
## Use cases
|
|
158
176
|
|
|
@@ -308,7 +308,7 @@ function ColorPicker() {
|
|
|
308
308
|
}
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
-
###
|
|
311
|
+
### With rainbow gradient
|
|
312
312
|
|
|
313
313
|
```tsx
|
|
314
314
|
function RainbowSlider() {
|
|
@@ -329,8 +329,8 @@ function RainbowSlider() {
|
|
|
329
329
|
- **Track height**: `h-1.5` (horizontal), `w-1.5` (vertical)
|
|
330
330
|
- **Track bg**: `bg-muted` (or custom gradient with `colorSlide` prop)
|
|
331
331
|
- **Range bg**: `bg-primary` (transparent when using `colorSlide`)
|
|
332
|
-
- **Thumb**: `size-4` with `border-primary`, `bg-
|
|
333
|
-
- **Thumb hover/focus**: `ring-4
|
|
332
|
+
- **Thumb**: `size-4` with `border-primary`, `bg-neutrals-0`, `shadow-sm`
|
|
333
|
+
- **Thumb hover/focus**: `ring-4 ring-ring/50` on hover and focus-visible
|
|
334
334
|
- **Vertical**: `min-h-44` default, `flex-col`
|
|
335
335
|
- **Full gradient**: Rainbow of 6 colors (red → yellow → green → cyan → blue → red)
|
|
336
336
|
- **Custom gradient**: Linear gradient between two specified colors
|
|
@@ -359,19 +359,19 @@ function FeatureToggles() {
|
|
|
359
359
|
|
|
360
360
|
## Use cases
|
|
361
361
|
|
|
362
|
-
**Settings**: On/off toggles
|
|
363
|
-
**Feature flags**:
|
|
364
|
-
**Notifications**:
|
|
365
|
-
**Privacy**:
|
|
362
|
+
**Settings**: On/off toggles for configuration
|
|
363
|
+
**Feature flags**: Enable/disable features
|
|
364
|
+
**Notifications**: Enable/disable notifications
|
|
365
|
+
**Privacy**: Privacy and permissions controls
|
|
366
366
|
**Device controls**: Wi-Fi, Bluetooth, Airplane mode
|
|
367
|
-
**Filters**:
|
|
367
|
+
**Filters**: Show/hide content
|
|
368
368
|
|
|
369
369
|
## Base styles
|
|
370
370
|
|
|
371
371
|
- **Size**: `h-5 w-8`
|
|
372
372
|
- **Checked bg**: `bg-primary`
|
|
373
373
|
- **Unchecked bg**: `bg-input` (dark: `bg-input/80`)
|
|
374
|
-
- **Thumb**: `size-4` with `bg-
|
|
374
|
+
- **Thumb**: `size-4` with `bg-neutrals-0` (always white)
|
|
375
375
|
- **Thumb checked**: `translate-x-[calc(100%-2px)]`
|
|
376
376
|
- **Thumb unchecked**: `translate-x-0`
|
|
377
377
|
- **Focus**: `ring-ring/50` with `ring-[3px]`
|
|
@@ -392,7 +392,7 @@ function FeatureToggles() {
|
|
|
392
392
|
- **Data states**: `data-state="checked|unchecked"` for styles
|
|
393
393
|
- **Controlled**: Use `checked` + `onCheckedChange`
|
|
394
394
|
- **Uncontrolled**: Use `defaultChecked`
|
|
395
|
-
- **
|
|
395
|
+
- **Thumb color**: Always white (`bg-neutrals-0`) for consistent contrast
|
|
396
396
|
|
|
397
397
|
## Troubleshooting
|
|
398
398
|
|
|
@@ -173,10 +173,13 @@ const invoices = [
|
|
|
173
173
|
|
|
174
174
|
## Base styles
|
|
175
175
|
|
|
176
|
-
- **Container**: `rounded-
|
|
177
|
-
- **Head**: `bg-muted
|
|
178
|
-
- **Row
|
|
179
|
-
- **Cell**: `p-4 text-sm text-
|
|
176
|
+
- **Container**: `rounded-2xl border` with `overflow-x-auto`
|
|
177
|
+
- **Head**: `h-16 p-4 bg-muted text-foreground text-xs font-semibold uppercase`
|
|
178
|
+
- **Row**: `h-16 border-b border-divider` with `hover:bg-muted/50`
|
|
179
|
+
- **Cell**: `p-4 text-sm text-foreground`
|
|
180
|
+
- **Footer**: `bg-muted`
|
|
181
|
+
|
|
182
|
+
**Note**: Table uses `border-divider` for internal row separators (lighter than `border`). Headers and cells use `text-foreground` instead of `text-muted-foreground` to match Figma design.
|
|
180
183
|
|
|
181
184
|
## References
|
|
182
185
|
|