@stevederico/skateboard-ui 3.11.0 → 4.0.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/CHANGELOG.md +17 -0
- package/README.md +37 -31
- package/dist/shadcn/ui/accordion.d.ts +1 -6
- package/dist/shadcn/ui/accordion.js +3 -17
- package/dist/shadcn/ui/alert-dialog.d.ts +1 -18
- package/dist/shadcn/ui/alert-dialog.js +3 -43
- package/dist/shadcn/ui/alert.d.ts +1 -13
- package/dist/shadcn/ui/alert.js +3 -28
- package/dist/shadcn/ui/aspect-ratio.d.ts +1 -4
- package/dist/shadcn/ui/aspect-ratio.js +3 -8
- package/dist/shadcn/ui/avatar.d.ts +1 -11
- package/dist/shadcn/ui/avatar.js +3 -24
- package/dist/shadcn/ui/badge.d.ts +1 -14
- package/dist/shadcn/ui/badge.js +3 -33
- package/dist/shadcn/ui/breadcrumb.d.ts +1 -10
- package/dist/shadcn/ui/breadcrumb.js +3 -37
- package/dist/shadcn/ui/button-group.d.ts +1 -13
- package/dist/shadcn/ui/button-group.js +3 -36
- package/dist/shadcn/ui/button.d.ts +1 -34
- package/dist/shadcn/ui/button.js +3 -48
- package/dist/shadcn/ui/calendar.d.ts +1 -13
- package/dist/shadcn/ui/calendar.js +3 -75
- package/dist/shadcn/ui/card.d.ts +1 -11
- package/dist/shadcn/ui/card.js +3 -25
- package/dist/shadcn/ui/checkbox.d.ts +1 -3
- package/dist/shadcn/ui/checkbox.js +3 -9
- package/dist/shadcn/ui/collapsible.d.ts +1 -5
- package/dist/shadcn/ui/collapsible.js +3 -13
- package/dist/shadcn/ui/command.d.ts +1 -19
- package/dist/shadcn/ui/command.js +3 -35
- package/dist/shadcn/ui/context-menu.d.ts +1 -29
- package/dist/shadcn/ui/context-menu.js +3 -52
- package/dist/shadcn/ui/dialog.d.ts +1 -17
- package/dist/shadcn/ui/dialog.js +3 -38
- package/dist/shadcn/ui/drawer.d.ts +1 -13
- package/dist/shadcn/ui/drawer.js +3 -196
- package/dist/shadcn/ui/dropdown-menu.d.ts +1 -29
- package/dist/shadcn/ui/dropdown-menu.js +3 -52
- package/dist/shadcn/ui/empty.d.ts +1 -14
- package/dist/shadcn/ui/empty.js +3 -33
- package/dist/shadcn/ui/field.d.ts +1 -28
- package/dist/shadcn/ui/field.js +3 -68
- package/dist/shadcn/ui/hover-card.d.ts +1 -5
- package/dist/shadcn/ui/hover-card.js +3 -14
- package/dist/shadcn/ui/input-group.d.ts +1 -28
- package/dist/shadcn/ui/input-group.js +3 -58
- package/dist/shadcn/ui/input.d.ts +1 -3
- package/dist/shadcn/ui/input.js +3 -8
- package/dist/shadcn/ui/item.d.ts +1 -34
- package/dist/shadcn/ui/item.js +3 -79
- package/dist/shadcn/ui/kbd.d.ts +1 -3
- package/dist/shadcn/ui/kbd.js +3 -9
- package/dist/shadcn/ui/label.d.ts +1 -3
- package/dist/shadcn/ui/label.js +3 -8
- package/dist/shadcn/ui/menubar.d.ts +1 -29
- package/dist/shadcn/ui/menubar.js +3 -57
- package/dist/shadcn/ui/navigation-menu.d.ts +1 -13
- package/dist/shadcn/ui/navigation-menu.js +3 -31
- package/dist/shadcn/ui/pagination.d.ts +1 -17
- package/dist/shadcn/ui/pagination.js +3 -27
- package/dist/shadcn/ui/popover.d.ts +1 -9
- package/dist/shadcn/ui/popover.js +3 -24
- package/dist/shadcn/ui/progress.d.ts +1 -7
- package/dist/shadcn/ui/progress.js +3 -20
- package/dist/shadcn/ui/radio-group.d.ts +1 -5
- package/dist/shadcn/ui/radio-group.js +3 -12
- package/dist/shadcn/ui/scroll-area.d.ts +1 -5
- package/dist/shadcn/ui/scroll-area.js +3 -12
- package/dist/shadcn/ui/select.d.ts +1 -15
- package/dist/shadcn/ui/select.js +3 -35
- package/dist/shadcn/ui/separator.d.ts +1 -3
- package/dist/shadcn/ui/separator.js +3 -8
- package/dist/shadcn/ui/sheet.d.ts +1 -14
- package/dist/shadcn/ui/sheet.js +3 -38
- package/dist/shadcn/ui/sidebar.d.ts +1 -70
- package/dist/shadcn/ui/sidebar.js +3 -256
- package/dist/shadcn/ui/skeleton.d.ts +1 -2
- package/dist/shadcn/ui/skeleton.js +3 -6
- package/dist/shadcn/ui/slider.d.ts +1 -3
- package/dist/shadcn/ui/slider.js +3 -12
- package/dist/shadcn/ui/spinner.d.ts +1 -2
- package/dist/shadcn/ui/spinner.js +3 -7
- package/dist/shadcn/ui/switch.d.ts +1 -5
- package/dist/shadcn/ui/switch.js +3 -8
- package/dist/shadcn/ui/table.d.ts +1 -10
- package/dist/shadcn/ui/table.js +3 -29
- package/dist/shadcn/ui/tabs.d.ts +1 -13
- package/dist/shadcn/ui/tabs.js +3 -29
- package/dist/shadcn/ui/textarea.d.ts +1 -3
- package/dist/shadcn/ui/textarea.js +3 -7
- package/dist/shadcn/ui/toggle-group.d.ts +1 -11
- package/dist/shadcn/ui/toggle-group.js +3 -25
- package/dist/shadcn/ui/toggle.d.ts +1 -15
- package/dist/shadcn/ui/toggle.js +3 -26
- package/dist/shadcn/ui/tooltip.d.ts +1 -6
- package/dist/shadcn/ui/tooltip.js +3 -17
- package/dist/ui/accordion.d.ts +21 -0
- package/dist/ui/accordion.js +67 -0
- package/dist/ui/alert-dialog.d.ts +32 -0
- package/dist/ui/alert-dialog.js +102 -0
- package/dist/ui/alert.d.ts +13 -0
- package/dist/ui/alert.js +28 -0
- package/dist/ui/aspect-ratio.d.ts +5 -0
- package/dist/ui/aspect-ratio.js +9 -0
- package/dist/ui/avatar.d.ts +14 -0
- package/dist/ui/avatar.js +49 -0
- package/dist/ui/badge.d.ts +22 -0
- package/dist/ui/badge.js +26 -0
- package/dist/ui/breadcrumb.d.ts +13 -0
- package/dist/ui/breadcrumb.js +29 -0
- package/dist/ui/button-group.d.ts +21 -0
- package/dist/ui/button-group.js +29 -0
- package/dist/ui/button.d.ts +38 -0
- package/dist/ui/button.js +49 -0
- package/dist/ui/calendar.d.ts +13 -0
- package/dist/ui/calendar.js +75 -0
- package/dist/ui/card.d.ts +11 -0
- package/dist/ui/card.js +25 -0
- package/dist/ui/checkbox.d.ts +17 -0
- package/dist/ui/checkbox.js +25 -0
- package/dist/ui/collapsible.d.ts +11 -0
- package/dist/ui/collapsible.js +40 -0
- package/dist/ui/command.d.ts +19 -0
- package/dist/ui/command.js +35 -0
- package/dist/ui/context-menu.d.ts +53 -0
- package/dist/ui/context-menu.js +345 -0
- package/dist/ui/dialog.d.ts +40 -0
- package/dist/ui/dialog.js +109 -0
- package/dist/ui/drawer.d.ts +36 -0
- package/dist/ui/drawer.js +234 -0
- package/dist/ui/dropdown-menu.d.ts +61 -0
- package/dist/ui/dropdown-menu.js +323 -0
- package/dist/ui/empty.d.ts +14 -0
- package/dist/ui/empty.js +33 -0
- package/dist/ui/field.d.ts +28 -0
- package/dist/ui/field.js +68 -0
- package/dist/ui/hover-card.d.ts +32 -0
- package/dist/ui/hover-card.js +119 -0
- package/dist/ui/input-group.d.ts +28 -0
- package/dist/ui/input-group.js +58 -0
- package/dist/ui/input.d.ts +3 -0
- package/dist/ui/input.js +7 -0
- package/dist/ui/item.d.ts +41 -0
- package/dist/ui/item.js +69 -0
- package/dist/ui/kbd.d.ts +4 -0
- package/dist/ui/kbd.js +10 -0
- package/dist/ui/label.d.ts +3 -0
- package/dist/ui/label.js +8 -0
- package/dist/ui/menubar.d.ts +59 -0
- package/dist/ui/menubar.js +384 -0
- package/dist/ui/navigation-menu.d.ts +24 -0
- package/dist/ui/navigation-menu.js +134 -0
- package/dist/ui/pagination.d.ts +17 -0
- package/dist/ui/pagination.js +36 -0
- package/dist/ui/popover.d.ts +25 -0
- package/dist/ui/popover.js +68 -0
- package/dist/ui/portal.d.ts +7 -0
- package/dist/ui/portal.js +12 -0
- package/dist/ui/progress.d.ts +15 -0
- package/dist/ui/progress.js +36 -0
- package/dist/ui/radio-group.d.ts +17 -0
- package/dist/ui/radio-group.js +54 -0
- package/dist/ui/scroll-area.d.ts +9 -0
- package/dist/ui/scroll-area.js +72 -0
- package/dist/ui/select.d.ts +37 -0
- package/dist/ui/select.js +216 -0
- package/dist/ui/separator.d.ts +14 -0
- package/dist/ui/separator.js +13 -0
- package/dist/ui/sheet.d.ts +31 -0
- package/dist/ui/sheet.js +121 -0
- package/dist/ui/sidebar.d.ts +86 -0
- package/dist/ui/sidebar.js +211 -0
- package/dist/ui/skeleton.d.ts +3 -0
- package/dist/ui/skeleton.js +7 -0
- package/dist/ui/slider.d.ts +18 -0
- package/dist/ui/slider.js +94 -0
- package/dist/ui/slot.d.ts +27 -0
- package/dist/ui/slot.js +62 -0
- package/dist/ui/spinner.d.ts +3 -0
- package/dist/ui/spinner.js +8 -0
- package/dist/ui/switch.d.ts +17 -0
- package/dist/ui/switch.js +23 -0
- package/dist/ui/table.d.ts +10 -0
- package/dist/ui/table.js +29 -0
- package/dist/ui/tabs.d.ts +29 -0
- package/dist/ui/tabs.js +82 -0
- package/dist/ui/textarea.d.ts +3 -0
- package/dist/ui/textarea.js +7 -0
- package/dist/ui/toggle-group.d.ts +23 -0
- package/dist/ui/toggle-group.js +52 -0
- package/dist/ui/toggle.d.ts +25 -0
- package/dist/ui/toggle.js +41 -0
- package/dist/ui/tooltip.d.ts +25 -0
- package/dist/ui/tooltip.js +90 -0
- package/dist/ui/use-controllable-state.d.ts +10 -0
- package/dist/ui/use-controllable-state.js +17 -0
- package/dist/ui/use-dismiss.d.ts +10 -0
- package/dist/ui/use-dismiss.js +51 -0
- package/dist/ui/use-floating.d.ts +38 -0
- package/dist/ui/use-floating.js +128 -0
- package/dist/ui/use-presence.d.ts +8 -0
- package/dist/ui/use-presence.js +48 -0
- package/package.json +6 -1
- package/dist/shadcn/lib/base-ui/LICENSE +0 -21
- package/dist/shadcn/lib/base-ui/_chunk-000kmre8.js +0 -150
- package/dist/shadcn/lib/base-ui/_chunk-1vw45v38.js +0 -64
- package/dist/shadcn/lib/base-ui/_chunk-23rx7haq.js +0 -81
- package/dist/shadcn/lib/base-ui/_chunk-242gh8ph.js +0 -230
- package/dist/shadcn/lib/base-ui/_chunk-26cc610z.js +0 -6
- package/dist/shadcn/lib/base-ui/_chunk-2z044bba.js +0 -5890
- package/dist/shadcn/lib/base-ui/_chunk-3cpd1vjz.js +0 -13
- package/dist/shadcn/lib/base-ui/_chunk-3enq1vat.js +0 -82
- package/dist/shadcn/lib/base-ui/_chunk-3xpke33f.js +0 -23
- package/dist/shadcn/lib/base-ui/_chunk-451nqgsa.js +0 -6
- package/dist/shadcn/lib/base-ui/_chunk-4maf6pas.js +0 -11
- package/dist/shadcn/lib/base-ui/_chunk-4zhfq4d3.js +0 -16
- package/dist/shadcn/lib/base-ui/_chunk-5gaqyne5.js +0 -21
- package/dist/shadcn/lib/base-ui/_chunk-5tt5hk59.js +0 -4
- package/dist/shadcn/lib/base-ui/_chunk-5tze5c8q.js +0 -13
- package/dist/shadcn/lib/base-ui/_chunk-5xmdvndx.js +0 -225
- package/dist/shadcn/lib/base-ui/_chunk-6adaer33.js +0 -435
- package/dist/shadcn/lib/base-ui/_chunk-6ejf1z1r.js +0 -9
- package/dist/shadcn/lib/base-ui/_chunk-6kqramh9.js +0 -27
- package/dist/shadcn/lib/base-ui/_chunk-7b9dc493.js +0 -14
- package/dist/shadcn/lib/base-ui/_chunk-8a9vv8am.js +0 -89
- package/dist/shadcn/lib/base-ui/_chunk-8ctgmf06.js +0 -129
- package/dist/shadcn/lib/base-ui/_chunk-8ganmsbg.js +0 -54
- package/dist/shadcn/lib/base-ui/_chunk-8xaqxgck.js +0 -15
- package/dist/shadcn/lib/base-ui/_chunk-95tf2rxq.js +0 -62
- package/dist/shadcn/lib/base-ui/_chunk-9x63vfqj.js +0 -70
- package/dist/shadcn/lib/base-ui/_chunk-ase0ydtt.js +0 -9
- package/dist/shadcn/lib/base-ui/_chunk-b0nc8wq7.js +0 -34
- package/dist/shadcn/lib/base-ui/_chunk-b5ya6xds.js +0 -10
- package/dist/shadcn/lib/base-ui/_chunk-b6dkjkbw.js +0 -43
- package/dist/shadcn/lib/base-ui/_chunk-c2bz952e.js +0 -19
- package/dist/shadcn/lib/base-ui/_chunk-cdgfsr3q.js +0 -15
- package/dist/shadcn/lib/base-ui/_chunk-cdj8cpx5.js +0 -347
- package/dist/shadcn/lib/base-ui/_chunk-cgptgywc.js +0 -104
- package/dist/shadcn/lib/base-ui/_chunk-cwvtvwc7.js +0 -35
- package/dist/shadcn/lib/base-ui/_chunk-dan0mva4.js +0 -23
- package/dist/shadcn/lib/base-ui/_chunk-dzvjwv25.js +0 -0
- package/dist/shadcn/lib/base-ui/_chunk-e13rsb6b.js +0 -184
- package/dist/shadcn/lib/base-ui/_chunk-e56mpvk1.js +0 -118
- package/dist/shadcn/lib/base-ui/_chunk-e6k2ecs7.js +0 -48
- package/dist/shadcn/lib/base-ui/_chunk-ebyxgtb4.js +0 -29
- package/dist/shadcn/lib/base-ui/_chunk-f2wttwrf.js +0 -39
- package/dist/shadcn/lib/base-ui/_chunk-fdzctasg.js +0 -38
- package/dist/shadcn/lib/base-ui/_chunk-ffpjy0ta.js +0 -39
- package/dist/shadcn/lib/base-ui/_chunk-fqry7pew.js +0 -603
- package/dist/shadcn/lib/base-ui/_chunk-ghn1tzt8.js +0 -84
- package/dist/shadcn/lib/base-ui/_chunk-gy0bpkmx.js +0 -12
- package/dist/shadcn/lib/base-ui/_chunk-hm5h9vsk.js +0 -16
- package/dist/shadcn/lib/base-ui/_chunk-htdj1jps.js +0 -833
- package/dist/shadcn/lib/base-ui/_chunk-j29xjete.js +0 -146
- package/dist/shadcn/lib/base-ui/_chunk-j3qkyd10.js +0 -50
- package/dist/shadcn/lib/base-ui/_chunk-ktvsd5k6.js +0 -2386
- package/dist/shadcn/lib/base-ui/_chunk-kw8nnq00.js +0 -546
- package/dist/shadcn/lib/base-ui/_chunk-m307wpdj.js +0 -18
- package/dist/shadcn/lib/base-ui/_chunk-mnd0j7v9.js +0 -15
- package/dist/shadcn/lib/base-ui/_chunk-n11h505c.js +0 -32
- package/dist/shadcn/lib/base-ui/_chunk-p0e2qacz.js +0 -26
- package/dist/shadcn/lib/base-ui/_chunk-pv7b791x.js +0 -106
- package/dist/shadcn/lib/base-ui/_chunk-q5cg71p7.js +0 -83
- package/dist/shadcn/lib/base-ui/_chunk-qbezxj1g.js +0 -385
- package/dist/shadcn/lib/base-ui/_chunk-qmsqz6nt.js +0 -15
- package/dist/shadcn/lib/base-ui/_chunk-rrh8rt4v.js +0 -65
- package/dist/shadcn/lib/base-ui/_chunk-s5pwkz8v.js +0 -25
- package/dist/shadcn/lib/base-ui/_chunk-svxv97ph.js +0 -218
- package/dist/shadcn/lib/base-ui/_chunk-t7ppm3t0.js +0 -68
- package/dist/shadcn/lib/base-ui/_chunk-vg16xxmb.js +0 -52
- package/dist/shadcn/lib/base-ui/_chunk-vgkfmtbe.js +0 -21
- package/dist/shadcn/lib/base-ui/_chunk-watha94s.js +0 -14
- package/dist/shadcn/lib/base-ui/_chunk-wdqynnjf.js +0 -35
- package/dist/shadcn/lib/base-ui/_chunk-wx2nxg0p.js +0 -15
- package/dist/shadcn/lib/base-ui/_chunk-x11e1k9r.js +0 -0
- package/dist/shadcn/lib/base-ui/_chunk-x8xehj6d.js +0 -302
- package/dist/shadcn/lib/base-ui/_chunk-xcqbtm2f.js +0 -28
- package/dist/shadcn/lib/base-ui/_chunk-ytnp24gq.js +0 -328
- package/dist/shadcn/lib/base-ui/_chunk-yzr7eg4b.js +0 -6
- package/dist/shadcn/lib/base-ui/_chunk-zk4mtm9m.js +0 -9
- package/dist/shadcn/lib/base-ui/accordion.d.ts +0 -447
- package/dist/shadcn/lib/base-ui/accordion.js +0 -630
- package/dist/shadcn/lib/base-ui/alert-dialog.d.ts +0 -1467
- package/dist/shadcn/lib/base-ui/alert-dialog.js +0 -98
- package/dist/shadcn/lib/base-ui/avatar.d.ts +0 -123
- package/dist/shadcn/lib/base-ui/avatar.js +0 -235
- package/dist/shadcn/lib/base-ui/button.d.ts +0 -84
- package/dist/shadcn/lib/base-ui/button.js +0 -51
- package/dist/shadcn/lib/base-ui/checkbox.d.ts +0 -341
- package/dist/shadcn/lib/base-ui/checkbox.js +0 -501
- package/dist/shadcn/lib/base-ui/collapsible.d.ts +0 -291
- package/dist/shadcn/lib/base-ui/collapsible.js +0 -264
- package/dist/shadcn/lib/base-ui/context-menu.d.ts +0 -2213
- package/dist/shadcn/lib/base-ui/context-menu.js +0 -323
- package/dist/shadcn/lib/base-ui/dialog.d.ts +0 -1448
- package/dist/shadcn/lib/base-ui/dialog.js +0 -79
- package/dist/shadcn/lib/base-ui/input.d.ts +0 -506
- package/dist/shadcn/lib/base-ui/input.js +0 -1027
- package/dist/shadcn/lib/base-ui/menu.d.ts +0 -2275
- package/dist/shadcn/lib/base-ui/menu.js +0 -60
- package/dist/shadcn/lib/base-ui/menubar.d.ts +0 -48
- package/dist/shadcn/lib/base-ui/menubar.js +0 -156
- package/dist/shadcn/lib/base-ui/merge-props.d.ts +0 -70
- package/dist/shadcn/lib/base-ui/merge-props.js +0 -15
- package/dist/shadcn/lib/base-ui/navigation-menu.d.ts +0 -825
- package/dist/shadcn/lib/base-ui/navigation-menu.js +0 -1849
- package/dist/shadcn/lib/base-ui/popover.d.ts +0 -1743
- package/dist/shadcn/lib/base-ui/popover.js +0 -1089
- package/dist/shadcn/lib/base-ui/preview-card.d.ts +0 -1608
- package/dist/shadcn/lib/base-ui/preview-card.js +0 -919
- package/dist/shadcn/lib/base-ui/progress.d.ts +0 -172
- package/dist/shadcn/lib/base-ui/progress.js +0 -272
- package/dist/shadcn/lib/base-ui/radio-group.d.ts +0 -260
- package/dist/shadcn/lib/base-ui/radio-group.js +0 -239
- package/dist/shadcn/lib/base-ui/radio.d.ts +0 -176
- package/dist/shadcn/lib/base-ui/radio.js +0 -387
- package/dist/shadcn/lib/base-ui/scroll-area.d.ts +0 -241
- package/dist/shadcn/lib/base-ui/scroll-area.js +0 -1055
- package/dist/shadcn/lib/base-ui/select.d.ts +0 -1266
- package/dist/shadcn/lib/base-ui/select.js +0 -2450
- package/dist/shadcn/lib/base-ui/separator.d.ts +0 -76
- package/dist/shadcn/lib/base-ui/separator.js +0 -11
- package/dist/shadcn/lib/base-ui/slider.d.ts +0 -551
- package/dist/shadcn/lib/base-ui/slider.js +0 -1583
- package/dist/shadcn/lib/base-ui/switch.d.ts +0 -313
- package/dist/shadcn/lib/base-ui/switch.js +0 -326
- package/dist/shadcn/lib/base-ui/tabs.d.ts +0 -406
- package/dist/shadcn/lib/base-ui/tabs.js +0 -915
- package/dist/shadcn/lib/base-ui/toggle-group.d.ts +0 -235
- package/dist/shadcn/lib/base-ui/toggle-group.js +0 -145
- package/dist/shadcn/lib/base-ui/toggle.d.ts +0 -224
- package/dist/shadcn/lib/base-ui/toggle.js +0 -127
- package/dist/shadcn/lib/base-ui/tooltip.d.ts +0 -1656
- package/dist/shadcn/lib/base-ui/tooltip.js +0 -920
- package/dist/shadcn/lib/base-ui/use-render.d.ts +0 -87
- package/dist/shadcn/lib/base-ui/use-render.js +0 -15
package/dist/ui/slot.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
3
|
+
/**
|
|
4
|
+
* Minimal `asChild` Slot — self-contained replacement for Radix Slot / Base UI's
|
|
5
|
+
* `render` prop. Merges this slot's props onto its single child element:
|
|
6
|
+
* `className` is class-merged, refs are composed, and the child's own props win
|
|
7
|
+
* on any other collision (the child is the concrete element).
|
|
8
|
+
*
|
|
9
|
+
* This is the only behavioral helper the self-contained `ui/` tier depends on;
|
|
10
|
+
* it carries no primitive framework. React 19 ref-as-prop, no forwardRef.
|
|
11
|
+
*/
|
|
12
|
+
function mergeRefs(...refs) {
|
|
13
|
+
return (node) => {
|
|
14
|
+
for (const ref of refs) {
|
|
15
|
+
if (typeof ref === "function")
|
|
16
|
+
ref(node);
|
|
17
|
+
else if (ref)
|
|
18
|
+
ref.current = node;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function Slot({ children, className, style, ref, ...props }) {
|
|
23
|
+
const child = React.Children.only(children);
|
|
24
|
+
const childProps = child.props;
|
|
25
|
+
// Child props win on plain values, but event handlers (on*) are COMPOSED so
|
|
26
|
+
// the slot-injected behavior (open/close/etc.) runs alongside the child's own
|
|
27
|
+
// handler — matching Radix Slot / Base UI mergeProps instead of clobbering it.
|
|
28
|
+
const merged = { ...props, ...childProps };
|
|
29
|
+
for (const key of Object.keys(props)) {
|
|
30
|
+
const slotHandler = props[key];
|
|
31
|
+
const childHandler = childProps[key];
|
|
32
|
+
if (key.startsWith("on") &&
|
|
33
|
+
typeof slotHandler === "function" &&
|
|
34
|
+
typeof childHandler === "function") {
|
|
35
|
+
merged[key] = (...args) => {
|
|
36
|
+
;
|
|
37
|
+
slotHandler(...args);
|
|
38
|
+
const event = args[0];
|
|
39
|
+
if (!event?.defaultPrevented) {
|
|
40
|
+
;
|
|
41
|
+
childHandler(...args);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
merged.className = cn(className, childProps.className);
|
|
47
|
+
merged.style = { ...style, ...childProps.style };
|
|
48
|
+
merged.ref = mergeRefs(childProps.ref, ref);
|
|
49
|
+
return React.cloneElement(child, merged);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Base UI `render={<El/>}` compatibility. The old shadcn tier passed a React
|
|
53
|
+
* element to `render` to control the rendered element; here that maps onto the
|
|
54
|
+
* `asChild` + Slot mechanism. Returns whether to use the Slot and what child to
|
|
55
|
+
* render through it, so `render={<Button/>}` keeps working on the new components.
|
|
56
|
+
*/
|
|
57
|
+
function resolveRender(asChild, render, children) {
|
|
58
|
+
if (React.isValidElement(render))
|
|
59
|
+
return { useSlot: true, slotChild: render };
|
|
60
|
+
return { useSlot: !!asChild, slotChild: children };
|
|
61
|
+
}
|
|
62
|
+
export { Slot, mergeRefs, resolveRender };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
4
|
+
import { Loader2Icon } from "../icons/index.js";
|
|
5
|
+
function Spinner({ className, ...props }) {
|
|
6
|
+
return (_jsx(Loader2Icon, { role: "status", "aria-label": "Loading", className: cn("size-4 animate-spin", className), ...props }));
|
|
7
|
+
}
|
|
8
|
+
export { Spinner };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface SwitchProps extends Omit<React.ComponentProps<"button">, "onChange" | "value"> {
|
|
3
|
+
size?: "sm" | "default";
|
|
4
|
+
checked?: boolean;
|
|
5
|
+
defaultChecked?: boolean;
|
|
6
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
7
|
+
/** When set, a hidden checkbox of this name mirrors the state for form posts. */
|
|
8
|
+
name?: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Self-contained switch: a `role="switch"` button with controlled/uncontrolled
|
|
13
|
+
* checked state. Emits `data-checked`/`data-unchecked`/`data-disabled` so the
|
|
14
|
+
* shared classes apply. Pass `name` to include a hidden checkbox for forms.
|
|
15
|
+
*/
|
|
16
|
+
declare function Switch({ className, size, checked, defaultChecked, onCheckedChange, disabled, name, value, onClick, ...props }: SwitchProps): React.JSX.Element;
|
|
17
|
+
export { Switch };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
5
|
+
import { useControllableState } from "./use-controllable-state.js";
|
|
6
|
+
/**
|
|
7
|
+
* Self-contained switch: a `role="switch"` button with controlled/uncontrolled
|
|
8
|
+
* checked state. Emits `data-checked`/`data-unchecked`/`data-disabled` so the
|
|
9
|
+
* shared classes apply. Pass `name` to include a hidden checkbox for forms.
|
|
10
|
+
*/
|
|
11
|
+
function Switch({ className, size = "default", checked, defaultChecked = false, onCheckedChange, disabled, name, value = "on", onClick, ...props }) {
|
|
12
|
+
const [on, setOn] = useControllableState({
|
|
13
|
+
value: checked,
|
|
14
|
+
defaultValue: defaultChecked,
|
|
15
|
+
onChange: onCheckedChange,
|
|
16
|
+
});
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", role: "switch", "aria-checked": on, disabled: disabled, "data-slot": "switch", "data-size": size, "data-state": on ? "checked" : "unchecked", "data-checked": on ? "" : undefined, "data-unchecked": on ? undefined : "", "data-disabled": disabled ? "" : undefined, className: cn("cursor-pointer peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50", className), onClick: (e) => {
|
|
18
|
+
onClick?.(e);
|
|
19
|
+
if (!e.defaultPrevented)
|
|
20
|
+
setOn(!on);
|
|
21
|
+
}, ...props, children: _jsx("span", { "data-slot": "switch-thumb", "data-checked": on ? "" : undefined, "data-unchecked": on ? undefined : "", className: "pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground" }) }), name ? (_jsx("input", { type: "checkbox", "aria-hidden": true, tabIndex: -1, name: name, value: value, checked: on, disabled: disabled, readOnly: true, className: "sr-only" })) : null] }));
|
|
22
|
+
}
|
|
23
|
+
export { Switch };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
declare function Table({ className, ...props }: React.ComponentProps<"table">): React.JSX.Element;
|
|
3
|
+
declare function TableHeader({ className, ...props }: React.ComponentProps<"thead">): React.JSX.Element;
|
|
4
|
+
declare function TableBody({ className, ...props }: React.ComponentProps<"tbody">): React.JSX.Element;
|
|
5
|
+
declare function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">): React.JSX.Element;
|
|
6
|
+
declare function TableRow({ className, ...props }: React.ComponentProps<"tr">): React.JSX.Element;
|
|
7
|
+
declare function TableHead({ className, ...props }: React.ComponentProps<"th">): React.JSX.Element;
|
|
8
|
+
declare function TableCell({ className, ...props }: React.ComponentProps<"td">): React.JSX.Element;
|
|
9
|
+
declare function TableCaption({ className, ...props }: React.ComponentProps<"caption">): React.JSX.Element;
|
|
10
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, };
|
package/dist/ui/table.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
5
|
+
function Table({ className, ...props }) {
|
|
6
|
+
return (_jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: _jsx("table", { "data-slot": "table", className: cn("w-full caption-bottom text-sm", className), ...props }) }));
|
|
7
|
+
}
|
|
8
|
+
function TableHeader({ className, ...props }) {
|
|
9
|
+
return (_jsx("thead", { "data-slot": "table-header", className: cn("[&_tr]:border-b", className), ...props }));
|
|
10
|
+
}
|
|
11
|
+
function TableBody({ className, ...props }) {
|
|
12
|
+
return (_jsx("tbody", { "data-slot": "table-body", className: cn("[&_tr:last-child]:border-0", className), ...props }));
|
|
13
|
+
}
|
|
14
|
+
function TableFooter({ className, ...props }) {
|
|
15
|
+
return (_jsx("tfoot", { "data-slot": "table-footer", className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props }));
|
|
16
|
+
}
|
|
17
|
+
function TableRow({ className, ...props }) {
|
|
18
|
+
return (_jsx("tr", { "data-slot": "table-row", className: cn("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted", className), ...props }));
|
|
19
|
+
}
|
|
20
|
+
function TableHead({ className, ...props }) {
|
|
21
|
+
return (_jsx("th", { "data-slot": "table-head", className: cn("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0", className), ...props }));
|
|
22
|
+
}
|
|
23
|
+
function TableCell({ className, ...props }) {
|
|
24
|
+
return (_jsx("td", { "data-slot": "table-cell", className: cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className), ...props }));
|
|
25
|
+
}
|
|
26
|
+
function TableCaption({ className, ...props }) {
|
|
27
|
+
return (_jsx("caption", { "data-slot": "table-caption", className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
|
|
28
|
+
}
|
|
29
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "../shadcn/lib/cva.js";
|
|
3
|
+
export interface TabsProps extends Omit<React.ComponentProps<"div">, "onChange" | "defaultValue"> {
|
|
4
|
+
value?: string;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
onValueChange?: (value: string) => void;
|
|
7
|
+
orientation?: "horizontal" | "vertical";
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Self-contained tabs. Controlled/uncontrolled active value; the list provides
|
|
11
|
+
* roving arrow-key navigation with automatic activation (WAI-ARIA tabs pattern).
|
|
12
|
+
*/
|
|
13
|
+
declare function Tabs({ className, value, defaultValue, onValueChange, orientation, ...props }: TabsProps): React.JSX.Element;
|
|
14
|
+
declare const tabsListVariants: (props?: import("../shadcn/lib/cva.js").CvaProps<{
|
|
15
|
+
variant: {
|
|
16
|
+
default: string;
|
|
17
|
+
line: string;
|
|
18
|
+
};
|
|
19
|
+
}> | undefined) => string;
|
|
20
|
+
declare function TabsList({ className, variant, onKeyDown, ...props }: React.ComponentProps<"div"> & VariantProps<typeof tabsListVariants>): React.JSX.Element;
|
|
21
|
+
export interface TabsTriggerProps extends Omit<React.ComponentProps<"button">, "value"> {
|
|
22
|
+
value: string;
|
|
23
|
+
}
|
|
24
|
+
declare function TabsTrigger({ className, value, onClick, ...props }: TabsTriggerProps): React.JSX.Element;
|
|
25
|
+
export interface TabsContentProps extends Omit<React.ComponentProps<"div">, "value"> {
|
|
26
|
+
value: string;
|
|
27
|
+
}
|
|
28
|
+
declare function TabsContent({ className, value, ...props }: TabsContentProps): React.JSX.Element;
|
|
29
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
|
package/dist/ui/tabs.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cva } from "../shadcn/lib/cva.js";
|
|
5
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
6
|
+
import { useControllableState } from "./use-controllable-state.js";
|
|
7
|
+
const TabsContext = React.createContext(null);
|
|
8
|
+
function useTabs() {
|
|
9
|
+
const ctx = React.useContext(TabsContext);
|
|
10
|
+
if (!ctx)
|
|
11
|
+
throw new Error("Tabs parts must be used within <Tabs>");
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
// Sanitize a tab value for use in an element id — spaces/special chars would
|
|
15
|
+
// break the aria-controls / aria-labelledby IDREF association.
|
|
16
|
+
const idify = (v) => v.replace(/[^\w-]/g, "_");
|
|
17
|
+
/**
|
|
18
|
+
* Self-contained tabs. Controlled/uncontrolled active value; the list provides
|
|
19
|
+
* roving arrow-key navigation with automatic activation (WAI-ARIA tabs pattern).
|
|
20
|
+
*/
|
|
21
|
+
function Tabs({ className, value, defaultValue, onValueChange, orientation = "horizontal", ...props }) {
|
|
22
|
+
const [active, setActive] = useControllableState({
|
|
23
|
+
value,
|
|
24
|
+
defaultValue,
|
|
25
|
+
onChange: onValueChange,
|
|
26
|
+
});
|
|
27
|
+
const idBase = React.useId();
|
|
28
|
+
return (_jsx(TabsContext.Provider, { value: { value: active, setValue: setActive, orientation, idBase }, children: _jsx("div", { "data-slot": "tabs", "data-orientation": orientation, className: cn("group/tabs flex gap-2 data-horizontal:flex-col", className), ...props }) }));
|
|
29
|
+
}
|
|
30
|
+
const tabsListVariants = cva("group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none", {
|
|
31
|
+
variants: {
|
|
32
|
+
variant: {
|
|
33
|
+
default: "bg-muted",
|
|
34
|
+
line: "gap-1 bg-transparent",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
defaultVariants: {
|
|
38
|
+
variant: "default",
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
function TabsList({ className, variant = "default", onKeyDown, ...props }) {
|
|
42
|
+
const { orientation } = useTabs();
|
|
43
|
+
return (_jsx("div", { role: "tablist", "aria-orientation": orientation, "data-slot": "tabs-list", "data-variant": variant, className: cn(tabsListVariants({ variant }), className), onKeyDown: (e) => {
|
|
44
|
+
onKeyDown?.(e);
|
|
45
|
+
if (e.defaultPrevented)
|
|
46
|
+
return;
|
|
47
|
+
const tabs = Array.from(e.currentTarget.querySelectorAll('[role="tab"]:not([disabled]):not([data-disabled])'));
|
|
48
|
+
const current = tabs.indexOf(document.activeElement);
|
|
49
|
+
if (current < 0)
|
|
50
|
+
return;
|
|
51
|
+
const horizontal = orientation !== "vertical";
|
|
52
|
+
let next = -1;
|
|
53
|
+
if ((horizontal && e.key === "ArrowRight") || (!horizontal && e.key === "ArrowDown"))
|
|
54
|
+
next = (current + 1) % tabs.length;
|
|
55
|
+
else if ((horizontal && e.key === "ArrowLeft") || (!horizontal && e.key === "ArrowUp"))
|
|
56
|
+
next = (current - 1 + tabs.length) % tabs.length;
|
|
57
|
+
else if (e.key === "Home")
|
|
58
|
+
next = 0;
|
|
59
|
+
else if (e.key === "End")
|
|
60
|
+
next = tabs.length - 1;
|
|
61
|
+
if (next >= 0) {
|
|
62
|
+
e.preventDefault();
|
|
63
|
+
tabs[next].focus();
|
|
64
|
+
tabs[next].click();
|
|
65
|
+
}
|
|
66
|
+
}, ...props }));
|
|
67
|
+
}
|
|
68
|
+
function TabsTrigger({ className, value, onClick, ...props }) {
|
|
69
|
+
const { value: active, setValue, idBase } = useTabs();
|
|
70
|
+
const selected = active === value;
|
|
71
|
+
return (_jsx("button", { type: "button", role: "tab", id: `${idBase}-tab-${idify(value)}`, "aria-selected": selected, "aria-controls": `${idBase}-panel-${idify(value)}`, tabIndex: selected ? 0 : -1, "data-slot": "tabs-trigger", "data-active": selected ? "" : undefined, className: cn("cursor-pointer relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent", "data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground", "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100", className), onClick: (e) => {
|
|
72
|
+
onClick?.(e);
|
|
73
|
+
if (!e.defaultPrevented)
|
|
74
|
+
setValue(value);
|
|
75
|
+
}, ...props }));
|
|
76
|
+
}
|
|
77
|
+
function TabsContent({ className, value, ...props }) {
|
|
78
|
+
const { value: active, idBase } = useTabs();
|
|
79
|
+
const selected = active === value;
|
|
80
|
+
return (_jsx("div", { role: "tabpanel", id: `${idBase}-panel-${idify(value)}`, "aria-labelledby": `${idBase}-tab-${idify(value)}`, hidden: !selected, tabIndex: 0, "data-slot": "tabs-content", className: cn("flex-1 text-sm outline-none", className), ...props }));
|
|
81
|
+
}
|
|
82
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
4
|
+
function Textarea({ className, ...props }) {
|
|
5
|
+
return (_jsx("textarea", { "data-slot": "textarea", className: cn("flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className), ...props }));
|
|
6
|
+
}
|
|
7
|
+
export { Textarea };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "../shadcn/lib/cva.js";
|
|
3
|
+
import { toggleVariants } from "./toggle.js";
|
|
4
|
+
export interface ToggleGroupProps extends Omit<React.ComponentProps<"div">, "onChange">, VariantProps<typeof toggleVariants> {
|
|
5
|
+
value?: string[];
|
|
6
|
+
defaultValue?: string[];
|
|
7
|
+
onValueChange?: (value: string[]) => void;
|
|
8
|
+
/** Allow more than one item selected at once. */
|
|
9
|
+
toggleMultiple?: boolean;
|
|
10
|
+
spacing?: number;
|
|
11
|
+
orientation?: "horizontal" | "vertical";
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Self-contained toggle group: manages single- or multi-select state across its
|
|
15
|
+
* items via context. Keyboard: native button focus order + Space/Enter (roving
|
|
16
|
+
* arrow nav is intentionally omitted from this tier).
|
|
17
|
+
*/
|
|
18
|
+
declare function ToggleGroup({ className, variant, size, spacing, orientation, value, defaultValue, onValueChange, toggleMultiple, children, ...props }: ToggleGroupProps): React.JSX.Element;
|
|
19
|
+
export interface ToggleGroupItemProps extends Omit<React.ComponentProps<"button">, "value">, VariantProps<typeof toggleVariants> {
|
|
20
|
+
value: string;
|
|
21
|
+
}
|
|
22
|
+
declare function ToggleGroupItem({ className, children, variant, size, value, onClick, ...props }: ToggleGroupItemProps): React.JSX.Element;
|
|
23
|
+
export { ToggleGroup, ToggleGroupItem };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {} from "../shadcn/lib/cva.js";
|
|
5
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
6
|
+
import { toggleVariants } from "./toggle.js";
|
|
7
|
+
import { useControllableState } from "./use-controllable-state.js";
|
|
8
|
+
const ToggleGroupContext = React.createContext({
|
|
9
|
+
size: "default",
|
|
10
|
+
variant: "default",
|
|
11
|
+
spacing: 2,
|
|
12
|
+
orientation: "horizontal",
|
|
13
|
+
value: [],
|
|
14
|
+
toggle: () => { },
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Self-contained toggle group: manages single- or multi-select state across its
|
|
18
|
+
* items via context. Keyboard: native button focus order + Space/Enter (roving
|
|
19
|
+
* arrow nav is intentionally omitted from this tier).
|
|
20
|
+
*/
|
|
21
|
+
function ToggleGroup({ className, variant, size, spacing = 2, orientation = "horizontal", value, defaultValue = [], onValueChange, toggleMultiple = false, children, ...props }) {
|
|
22
|
+
const [selected, setSelected] = useControllableState({
|
|
23
|
+
value,
|
|
24
|
+
defaultValue,
|
|
25
|
+
onChange: onValueChange,
|
|
26
|
+
});
|
|
27
|
+
const toggle = React.useCallback((item) => {
|
|
28
|
+
const has = selected.includes(item);
|
|
29
|
+
const next = toggleMultiple
|
|
30
|
+
? has
|
|
31
|
+
? selected.filter((v) => v !== item)
|
|
32
|
+
: [...selected, item]
|
|
33
|
+
: has
|
|
34
|
+
? []
|
|
35
|
+
: [item];
|
|
36
|
+
setSelected(next);
|
|
37
|
+
}, [selected, toggleMultiple, setSelected]);
|
|
38
|
+
return (_jsx("div", { role: "group", "data-slot": "toggle-group", "data-variant": variant, "data-size": size, "data-spacing": spacing, "data-orientation": orientation, style: { "--gap": spacing }, className: cn("group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=0]:data-[variant=outline]:shadow-xs data-vertical:flex-col data-vertical:items-stretch", className), ...props, children: _jsx(ToggleGroupContext.Provider, { value: { variant, size, spacing, orientation, value: selected, toggle }, children: children }) }));
|
|
39
|
+
}
|
|
40
|
+
function ToggleGroupItem({ className, children, variant = "default", size = "default", value, onClick, ...props }) {
|
|
41
|
+
const context = React.useContext(ToggleGroupContext);
|
|
42
|
+
const pressed = context.value.includes(value);
|
|
43
|
+
return (_jsx("button", { type: "button", "data-slot": "toggle-group-item", "data-state": pressed ? "on" : "off", "aria-pressed": pressed, "data-variant": context.variant || variant, "data-size": context.size || size, "data-spacing": context.spacing, className: cn("shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 group-data-[spacing=0]/toggle-group:shadow-none focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-md group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-md group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-md group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-md data-[state=on]:bg-muted group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t", toggleVariants({
|
|
44
|
+
variant: context.variant || variant,
|
|
45
|
+
size: context.size || size,
|
|
46
|
+
}), className), onClick: (e) => {
|
|
47
|
+
onClick?.(e);
|
|
48
|
+
if (!e.defaultPrevented)
|
|
49
|
+
context.toggle(value);
|
|
50
|
+
}, ...props, children: children }));
|
|
51
|
+
}
|
|
52
|
+
export { ToggleGroup, ToggleGroupItem };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "../shadcn/lib/cva.js";
|
|
3
|
+
declare const toggleVariants: (props?: import("../shadcn/lib/cva.js").CvaProps<{
|
|
4
|
+
variant: {
|
|
5
|
+
default: string;
|
|
6
|
+
outline: string;
|
|
7
|
+
};
|
|
8
|
+
size: {
|
|
9
|
+
default: string;
|
|
10
|
+
sm: string;
|
|
11
|
+
lg: string;
|
|
12
|
+
};
|
|
13
|
+
}> | undefined) => string;
|
|
14
|
+
export interface ToggleProps extends Omit<React.ComponentProps<"button">, "onChange">, VariantProps<typeof toggleVariants> {
|
|
15
|
+
pressed?: boolean;
|
|
16
|
+
defaultPressed?: boolean;
|
|
17
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Self-contained two-state toggle button. Controlled via `pressed`/
|
|
21
|
+
* `onPressedChange` or uncontrolled via `defaultPressed`. Emits `aria-pressed`
|
|
22
|
+
* and `data-state` so the shared toggle classes apply.
|
|
23
|
+
*/
|
|
24
|
+
declare function Toggle({ className, variant, size, pressed, defaultPressed, onPressedChange, onClick, ...props }: ToggleProps): React.JSX.Element;
|
|
25
|
+
export { Toggle, toggleVariants };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cva } from "../shadcn/lib/cva.js";
|
|
5
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
6
|
+
import { useControllableState } from "./use-controllable-state.js";
|
|
7
|
+
const toggleVariants = cva("cursor-pointer group/toggle inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: "bg-transparent",
|
|
11
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-muted",
|
|
12
|
+
},
|
|
13
|
+
size: {
|
|
14
|
+
default: "h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
15
|
+
sm: "h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5",
|
|
16
|
+
lg: "h-10 min-w-10 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: {
|
|
20
|
+
variant: "default",
|
|
21
|
+
size: "default",
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* Self-contained two-state toggle button. Controlled via `pressed`/
|
|
26
|
+
* `onPressedChange` or uncontrolled via `defaultPressed`. Emits `aria-pressed`
|
|
27
|
+
* and `data-state` so the shared toggle classes apply.
|
|
28
|
+
*/
|
|
29
|
+
function Toggle({ className, variant = "default", size = "default", pressed, defaultPressed = false, onPressedChange, onClick, ...props }) {
|
|
30
|
+
const [on, setOn] = useControllableState({
|
|
31
|
+
value: pressed,
|
|
32
|
+
defaultValue: defaultPressed,
|
|
33
|
+
onChange: onPressedChange,
|
|
34
|
+
});
|
|
35
|
+
return (_jsx("button", { type: "button", "data-slot": "toggle", "data-state": on ? "on" : "off", "aria-pressed": on, className: cn(toggleVariants({ variant, size, className })), onClick: (e) => {
|
|
36
|
+
onClick?.(e);
|
|
37
|
+
if (!e.defaultPrevented)
|
|
38
|
+
setOn(!on);
|
|
39
|
+
}, ...props }));
|
|
40
|
+
}
|
|
41
|
+
export { Toggle, toggleVariants };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type Side, type Align } from "./use-floating.js";
|
|
3
|
+
declare function TooltipProvider({ delay, children, }: {
|
|
4
|
+
delay?: number;
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
}): React.JSX.Element;
|
|
7
|
+
export interface TooltipProps {
|
|
8
|
+
delay?: number;
|
|
9
|
+
defaultOpen?: boolean;
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
declare function Tooltip({ delay, defaultOpen, children }: TooltipProps): React.JSX.Element;
|
|
13
|
+
declare function TooltipTrigger({ asChild, render, nativeButton: _nativeButton, children, onMouseEnter, onMouseLeave, onFocus, onBlur, ...props }: React.ComponentProps<"button"> & {
|
|
14
|
+
asChild?: boolean;
|
|
15
|
+
render?: React.ReactElement;
|
|
16
|
+
nativeButton?: boolean;
|
|
17
|
+
}): React.JSX.Element;
|
|
18
|
+
export interface TooltipContentProps extends React.ComponentProps<"div"> {
|
|
19
|
+
side?: Side;
|
|
20
|
+
align?: Align;
|
|
21
|
+
sideOffset?: number;
|
|
22
|
+
alignOffset?: number;
|
|
23
|
+
}
|
|
24
|
+
declare function TooltipContent({ className, style, ref, side, sideOffset, align, alignOffset, children, ...props }: TooltipContentProps): React.JSX.Element | null;
|
|
25
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
5
|
+
import { Slot, mergeRefs, resolveRender } from "./slot.js";
|
|
6
|
+
import { Portal } from "./portal.js";
|
|
7
|
+
import { useFloating } from "./use-floating.js";
|
|
8
|
+
import { usePresence } from "./use-presence.js";
|
|
9
|
+
const TooltipContext = React.createContext(null);
|
|
10
|
+
function useTooltip() {
|
|
11
|
+
const ctx = React.useContext(TooltipContext);
|
|
12
|
+
if (!ctx)
|
|
13
|
+
throw new Error("Tooltip parts must be used within <Tooltip>");
|
|
14
|
+
return ctx;
|
|
15
|
+
}
|
|
16
|
+
const DelayContext = React.createContext(0);
|
|
17
|
+
function TooltipProvider({ delay = 0, children, }) {
|
|
18
|
+
return _jsx(DelayContext.Provider, { value: delay, children: children });
|
|
19
|
+
}
|
|
20
|
+
function Tooltip({ delay, defaultOpen = false, children }) {
|
|
21
|
+
const providerDelay = React.useContext(DelayContext);
|
|
22
|
+
const openDelay = delay ?? providerDelay;
|
|
23
|
+
const [open, setOpen] = React.useState(defaultOpen);
|
|
24
|
+
const triggerRef = React.useRef(null);
|
|
25
|
+
const contentId = React.useId();
|
|
26
|
+
const timer = React.useRef(undefined);
|
|
27
|
+
const show = React.useCallback(() => {
|
|
28
|
+
window.clearTimeout(timer.current);
|
|
29
|
+
if (openDelay > 0) {
|
|
30
|
+
timer.current = window.setTimeout(() => setOpen(true), openDelay);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
setOpen(true);
|
|
34
|
+
}
|
|
35
|
+
}, [openDelay]);
|
|
36
|
+
const hide = React.useCallback(() => {
|
|
37
|
+
window.clearTimeout(timer.current);
|
|
38
|
+
setOpen(false);
|
|
39
|
+
}, []);
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
if (!open)
|
|
42
|
+
return;
|
|
43
|
+
const onKey = (e) => {
|
|
44
|
+
if (e.key === "Escape")
|
|
45
|
+
hide();
|
|
46
|
+
};
|
|
47
|
+
document.addEventListener("keydown", onKey);
|
|
48
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
49
|
+
}, [open, hide]);
|
|
50
|
+
return (_jsx(TooltipContext.Provider, { value: { open, show, hide, triggerRef, contentId }, children: children }));
|
|
51
|
+
}
|
|
52
|
+
function TooltipTrigger({ asChild = false, render, nativeButton: _nativeButton, children, onMouseEnter, onMouseLeave, onFocus, onBlur, ...props }) {
|
|
53
|
+
const { open, show, hide, triggerRef, contentId } = useTooltip();
|
|
54
|
+
const { useSlot, slotChild } = resolveRender(asChild, render, children);
|
|
55
|
+
const Comp = useSlot ? Slot : "button";
|
|
56
|
+
return (_jsx(Comp, { ref: triggerRef, type: useSlot ? undefined : "button", "data-slot": "tooltip-trigger", "aria-describedby": open ? contentId : undefined, "data-state": open ? "open" : "closed", onMouseEnter: (e) => {
|
|
57
|
+
onMouseEnter?.(e);
|
|
58
|
+
show();
|
|
59
|
+
}, onMouseLeave: (e) => {
|
|
60
|
+
onMouseLeave?.(e);
|
|
61
|
+
hide();
|
|
62
|
+
}, onFocus: (e) => {
|
|
63
|
+
onFocus?.(e);
|
|
64
|
+
show();
|
|
65
|
+
}, onBlur: (e) => {
|
|
66
|
+
onBlur?.(e);
|
|
67
|
+
hide();
|
|
68
|
+
}, ...props, children: slotChild }));
|
|
69
|
+
}
|
|
70
|
+
function TooltipContent({ className, style, ref, side = "top", sideOffset = 4, align = "center", alignOffset = 0, children, ...props }) {
|
|
71
|
+
const { open, contentId, triggerRef } = useTooltip();
|
|
72
|
+
const [mounted, presenceRef] = usePresence(open);
|
|
73
|
+
const { floatingRef, pos } = useFloating(triggerRef, mounted, {
|
|
74
|
+
side,
|
|
75
|
+
align,
|
|
76
|
+
sideOffset,
|
|
77
|
+
alignOffset,
|
|
78
|
+
});
|
|
79
|
+
if (!mounted)
|
|
80
|
+
return null;
|
|
81
|
+
return (_jsx(Portal, { children: _jsx("div", { ref: mergeRefs(floatingRef, presenceRef, ref), id: contentId, role: "tooltip", "data-slot": "tooltip-content", "data-state": open ? "open" : "closed", "data-open": open ? "" : undefined, "data-closed": open ? undefined : "", "data-side": pos?.side ?? side, style: {
|
|
82
|
+
...style,
|
|
83
|
+
position: "fixed",
|
|
84
|
+
left: pos?.x ?? 0,
|
|
85
|
+
top: pos?.y ?? 0,
|
|
86
|
+
visibility: pos ? "visible" : "hidden",
|
|
87
|
+
["--transform-origin"]: pos?.transformOrigin ?? "center",
|
|
88
|
+
}, className: cn("z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props, children: children }) }));
|
|
89
|
+
}
|
|
90
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controlled/uncontrolled state in one hook. If `value` is provided the state is
|
|
3
|
+
* controlled (the hook just forwards it and calls `onChange`); otherwise it owns
|
|
4
|
+
* the state internally, seeded by `defaultValue`. Self-contained, no deps.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useControllableState<T>({ value, defaultValue, onChange, }: {
|
|
7
|
+
value?: T;
|
|
8
|
+
defaultValue: T;
|
|
9
|
+
onChange?: (value: T) => void;
|
|
10
|
+
}): [T, (next: T) => void];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Controlled/uncontrolled state in one hook. If `value` is provided the state is
|
|
4
|
+
* controlled (the hook just forwards it and calls `onChange`); otherwise it owns
|
|
5
|
+
* the state internally, seeded by `defaultValue`. Self-contained, no deps.
|
|
6
|
+
*/
|
|
7
|
+
export function useControllableState({ value, defaultValue, onChange, }) {
|
|
8
|
+
const [uncontrolled, setUncontrolled] = React.useState(defaultValue);
|
|
9
|
+
const isControlled = value !== undefined;
|
|
10
|
+
const state = isControlled ? value : uncontrolled;
|
|
11
|
+
const setState = React.useCallback((next) => {
|
|
12
|
+
if (!isControlled)
|
|
13
|
+
setUncontrolled(next);
|
|
14
|
+
onChange?.(next);
|
|
15
|
+
}, [isControlled, onChange]);
|
|
16
|
+
return [state, setState];
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Close an open layer on Escape or on a pointer press outside all of the given
|
|
4
|
+
* elements (e.g. the popup and its trigger). The listeners are only attached
|
|
5
|
+
* while `open`, and because the effect runs after the click that opened the
|
|
6
|
+
* layer, that same click never re-closes it. Escape is stacked: only the
|
|
7
|
+
* top layer closes, and the keydown is prevented/stopped so a native `<dialog>`
|
|
8
|
+
* ancestor's Escape-to-close doesn't also fire.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useDismiss(open: boolean, onDismiss: () => void, refs: Array<React.RefObject<HTMLElement | null>>): void;
|