@stevederico/skateboard-ui 3.12.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 +12 -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 -53
- 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
|
@@ -0,0 +1,384 @@
|
|
|
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 { 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
|
+
import { ChevronRightIcon, CheckIcon } from "../icons/index.js";
|
|
10
|
+
const MenubarRootContext = React.createContext(null);
|
|
11
|
+
function useMenubarRoot() {
|
|
12
|
+
const ctx = React.useContext(MenubarRootContext);
|
|
13
|
+
if (!ctx)
|
|
14
|
+
throw new Error("Menubar parts must be used within <Menubar>");
|
|
15
|
+
return ctx;
|
|
16
|
+
}
|
|
17
|
+
const MenuContext = React.createContext(null);
|
|
18
|
+
function useMenu() {
|
|
19
|
+
const ctx = React.useContext(MenuContext);
|
|
20
|
+
if (!ctx)
|
|
21
|
+
throw new Error("Menu parts must be used within <MenubarMenu>");
|
|
22
|
+
return ctx;
|
|
23
|
+
}
|
|
24
|
+
function itemsOf(container) {
|
|
25
|
+
return Array.from(container.querySelectorAll(':scope > [role^="menuitem"]:not([data-disabled]), :scope > [data-slot="menubar-group"] > [role^="menuitem"]:not([data-disabled]), :scope > [data-slot="menubar-radio-group"] > [role^="menuitem"]:not([data-disabled])'));
|
|
26
|
+
}
|
|
27
|
+
function moveFocus(container, dir) {
|
|
28
|
+
const items = itemsOf(container);
|
|
29
|
+
if (!items.length)
|
|
30
|
+
return;
|
|
31
|
+
const idx = items.indexOf(document.activeElement);
|
|
32
|
+
let next = 0;
|
|
33
|
+
if (dir === "first")
|
|
34
|
+
next = 0;
|
|
35
|
+
else if (dir === "last")
|
|
36
|
+
next = items.length - 1;
|
|
37
|
+
else if (dir === "next")
|
|
38
|
+
next = idx < 0 ? 0 : (idx + 1) % items.length;
|
|
39
|
+
else
|
|
40
|
+
next = idx < 0 ? items.length - 1 : (idx - 1 + items.length) % items.length;
|
|
41
|
+
items[next]?.focus();
|
|
42
|
+
}
|
|
43
|
+
function Menubar({ className, ...props }) {
|
|
44
|
+
const [value, setValue] = React.useState(null);
|
|
45
|
+
const [active, setActive] = React.useState(false);
|
|
46
|
+
return (_jsx(MenubarRootContext.Provider, { value: { value, setValue, active, setActive }, children: _jsx("div", { role: "menubar", "data-slot": "menubar", className: cn("flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs", className), ...props }) }));
|
|
47
|
+
}
|
|
48
|
+
function MenubarMenu({ value: valueProp, children, }) {
|
|
49
|
+
const root = useMenubarRoot();
|
|
50
|
+
const generatedId = React.useId();
|
|
51
|
+
const value = valueProp ?? generatedId;
|
|
52
|
+
const triggerRef = React.useRef(null);
|
|
53
|
+
const contentId = React.useId();
|
|
54
|
+
const layers = React.useRef(new Set());
|
|
55
|
+
const open = root.value === value;
|
|
56
|
+
const setOpen = React.useCallback((next) => {
|
|
57
|
+
if (next) {
|
|
58
|
+
root.setValue(value);
|
|
59
|
+
root.setActive(true);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
if (root.value === value)
|
|
63
|
+
root.setValue(null);
|
|
64
|
+
root.setActive(false);
|
|
65
|
+
}
|
|
66
|
+
}, [root, value]);
|
|
67
|
+
return (_jsx(MenuContext.Provider, { value: { value, open, setOpen, triggerRef, contentId, layers }, children: children }));
|
|
68
|
+
}
|
|
69
|
+
function MenubarPortal({ children }) {
|
|
70
|
+
return _jsx(_Fragment, { children: children });
|
|
71
|
+
}
|
|
72
|
+
function MenubarGroup({ className, ...props }) {
|
|
73
|
+
return _jsx("div", { role: "group", "data-slot": "menubar-group", className: className, ...props });
|
|
74
|
+
}
|
|
75
|
+
function MenubarTrigger({ asChild = false, render, nativeButton: _nativeButton, children, className, onClick, onKeyDown, onMouseEnter, ...props }) {
|
|
76
|
+
const root = useMenubarRoot();
|
|
77
|
+
const { value, open, setOpen, triggerRef, contentId } = useMenu();
|
|
78
|
+
const { useSlot, slotChild } = resolveRender(asChild, render, children);
|
|
79
|
+
const Comp = useSlot ? Slot : "button";
|
|
80
|
+
return (_jsx(Comp, { ref: triggerRef, type: useSlot ? undefined : "button", "data-slot": "menubar-trigger", "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": open ? contentId : undefined, "data-state": open ? "open" : "closed", className: cn("cursor-pointer flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none hover:bg-muted aria-expanded:bg-muted", className), onClick: (e) => {
|
|
81
|
+
onClick?.(e);
|
|
82
|
+
if (!e.defaultPrevented)
|
|
83
|
+
setOpen(!open);
|
|
84
|
+
}, onMouseEnter: (e) => {
|
|
85
|
+
onMouseEnter?.(e);
|
|
86
|
+
// When the bar is engaged, hovering a sibling trigger switches the
|
|
87
|
+
// open menu to this one without requiring another click.
|
|
88
|
+
if (!e.defaultPrevented && root.active && root.value !== value) {
|
|
89
|
+
root.setValue(value);
|
|
90
|
+
}
|
|
91
|
+
}, onKeyDown: (e) => {
|
|
92
|
+
onKeyDown?.(e);
|
|
93
|
+
if (e.defaultPrevented)
|
|
94
|
+
return;
|
|
95
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
96
|
+
e.preventDefault();
|
|
97
|
+
setOpen(true);
|
|
98
|
+
}
|
|
99
|
+
else if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
|
|
100
|
+
// Move focus along the bar to the sibling trigger.
|
|
101
|
+
const bar = e.currentTarget.closest('[role="menubar"]');
|
|
102
|
+
if (!bar)
|
|
103
|
+
return;
|
|
104
|
+
const triggers = Array.from(bar.querySelectorAll('[data-slot="menubar-trigger"]'));
|
|
105
|
+
const idx = triggers.indexOf(e.currentTarget);
|
|
106
|
+
if (idx < 0)
|
|
107
|
+
return;
|
|
108
|
+
e.preventDefault();
|
|
109
|
+
const delta = e.key === "ArrowRight" ? 1 : -1;
|
|
110
|
+
const target = triggers[(idx + delta + triggers.length) % triggers.length];
|
|
111
|
+
target?.focus();
|
|
112
|
+
if (root.active)
|
|
113
|
+
target?.click();
|
|
114
|
+
}
|
|
115
|
+
}, ...props, children: slotChild }));
|
|
116
|
+
}
|
|
117
|
+
function MenubarContent({ align = "start", alignOffset = -4, side = "bottom", sideOffset = 8, className, children, onKeyDown, ...props }) {
|
|
118
|
+
const root = useMenubarRoot();
|
|
119
|
+
const { open, setOpen, triggerRef, contentId, layers } = useMenu();
|
|
120
|
+
const [mounted, presenceRef] = usePresence(open);
|
|
121
|
+
const { floatingRef, pos } = useFloating(triggerRef, mounted, {
|
|
122
|
+
side,
|
|
123
|
+
align,
|
|
124
|
+
sideOffset,
|
|
125
|
+
alignOffset,
|
|
126
|
+
});
|
|
127
|
+
const containerRef = React.useRef(null);
|
|
128
|
+
React.useEffect(() => {
|
|
129
|
+
const node = containerRef.current;
|
|
130
|
+
if (!node)
|
|
131
|
+
return;
|
|
132
|
+
layers.current.add(node);
|
|
133
|
+
return () => {
|
|
134
|
+
layers.current.delete(node);
|
|
135
|
+
};
|
|
136
|
+
}, [mounted, layers]);
|
|
137
|
+
// Focus the first item once the popup is actually visible — a
|
|
138
|
+
// visibility:hidden element can't take focus, so retry each frame until it is.
|
|
139
|
+
const didFocus = React.useRef(false);
|
|
140
|
+
React.useEffect(() => {
|
|
141
|
+
if (!open) {
|
|
142
|
+
didFocus.current = false;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
let raf = 0;
|
|
146
|
+
const tryFocus = () => {
|
|
147
|
+
const c = containerRef.current;
|
|
148
|
+
if (c && getComputedStyle(c).visibility !== "hidden") {
|
|
149
|
+
didFocus.current = true;
|
|
150
|
+
moveFocus(c, "first");
|
|
151
|
+
}
|
|
152
|
+
else if (!didFocus.current) {
|
|
153
|
+
raf = requestAnimationFrame(tryFocus);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
raf = requestAnimationFrame(tryFocus);
|
|
157
|
+
return () => cancelAnimationFrame(raf);
|
|
158
|
+
}, [open]);
|
|
159
|
+
React.useEffect(() => {
|
|
160
|
+
if (!open)
|
|
161
|
+
return;
|
|
162
|
+
const onPointerDown = (e) => {
|
|
163
|
+
const t = e.target;
|
|
164
|
+
if (triggerRef.current?.contains(t))
|
|
165
|
+
return;
|
|
166
|
+
for (const layer of layers.current)
|
|
167
|
+
if (layer.contains(t))
|
|
168
|
+
return;
|
|
169
|
+
setOpen(false);
|
|
170
|
+
};
|
|
171
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
172
|
+
return () => {
|
|
173
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
174
|
+
};
|
|
175
|
+
}, [open, setOpen, triggerRef, layers]);
|
|
176
|
+
if (!mounted)
|
|
177
|
+
return null;
|
|
178
|
+
return (_jsx(Portal, { children: _jsx("div", { ref: mergeRefs(floatingRef, presenceRef, containerRef), id: contentId, role: "menu", "aria-orientation": "vertical", tabIndex: -1, "data-slot": "menubar-content", "data-state": open ? "open" : "closed", "data-open": open ? "" : undefined, "data-closed": open ? undefined : "", "data-side": pos?.side ?? side, style: {
|
|
179
|
+
position: "fixed",
|
|
180
|
+
left: pos?.x ?? 0,
|
|
181
|
+
top: pos?.y ?? 0,
|
|
182
|
+
visibility: pos ? "visible" : "hidden",
|
|
183
|
+
["--transform-origin"]: pos?.transformOrigin ?? "center",
|
|
184
|
+
}, onPointerMove: (e) => {
|
|
185
|
+
const item = e.target.closest('[role^="menuitem"]:not([data-disabled])');
|
|
186
|
+
if (item && item !== document.activeElement)
|
|
187
|
+
item.focus();
|
|
188
|
+
}, onKeyDown: (e) => {
|
|
189
|
+
onKeyDown?.(e);
|
|
190
|
+
if (e.defaultPrevented)
|
|
191
|
+
return;
|
|
192
|
+
const c = containerRef.current;
|
|
193
|
+
if (e.key === "ArrowDown")
|
|
194
|
+
(e.preventDefault(), moveFocus(c, "next"));
|
|
195
|
+
else if (e.key === "ArrowUp")
|
|
196
|
+
(e.preventDefault(), moveFocus(c, "prev"));
|
|
197
|
+
else if (e.key === "Home")
|
|
198
|
+
(e.preventDefault(), moveFocus(c, "first"));
|
|
199
|
+
else if (e.key === "End")
|
|
200
|
+
(e.preventDefault(), moveFocus(c, "last"));
|
|
201
|
+
else if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
|
|
202
|
+
// Switch to the adjacent menu in the bar, keeping it open.
|
|
203
|
+
const trigger = triggerRef.current;
|
|
204
|
+
const bar = trigger?.closest('[role="menubar"]');
|
|
205
|
+
if (!bar)
|
|
206
|
+
return;
|
|
207
|
+
const triggers = Array.from(bar.querySelectorAll('[data-slot="menubar-trigger"]'));
|
|
208
|
+
const idx = triggers.indexOf(trigger);
|
|
209
|
+
if (idx < 0)
|
|
210
|
+
return;
|
|
211
|
+
e.preventDefault();
|
|
212
|
+
const delta = e.key === "ArrowRight" ? 1 : -1;
|
|
213
|
+
triggers[(idx + delta + triggers.length) % triggers.length]?.click();
|
|
214
|
+
}
|
|
215
|
+
else if (e.key === "Escape") {
|
|
216
|
+
e.preventDefault();
|
|
217
|
+
setOpen(false);
|
|
218
|
+
triggerRef.current?.focus();
|
|
219
|
+
}
|
|
220
|
+
else if (e.key === "Tab") {
|
|
221
|
+
root.setValue(null);
|
|
222
|
+
root.setActive(false);
|
|
223
|
+
}
|
|
224
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
225
|
+
const active = document.activeElement;
|
|
226
|
+
if (active && c.contains(active) && active.getAttribute("role")?.startsWith("menuitem")) {
|
|
227
|
+
e.preventDefault();
|
|
228
|
+
active.click();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}, className: cn("z-50 min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none 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 }) }));
|
|
232
|
+
}
|
|
233
|
+
function MenubarLabel({ className, inset, ...props }) {
|
|
234
|
+
return (_jsx("div", { "data-slot": "menubar-label", "data-inset": inset ? "" : undefined, className: cn("px-2 py-1.5 text-sm font-medium data-inset:pl-8", className), ...props }));
|
|
235
|
+
}
|
|
236
|
+
function MenubarItem({ className, inset, variant = "default", disabled, onSelect, onClick, ...props }) {
|
|
237
|
+
const { setOpen } = useMenu();
|
|
238
|
+
return (_jsx("div", { role: "menuitem", tabIndex: -1, "aria-disabled": disabled || undefined, "data-slot": "menubar-item", "data-inset": inset ? "" : undefined, "data-variant": variant, "data-disabled": disabled ? "" : undefined, className: cn("group/menubar-item relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive!", className), onClick: (e) => {
|
|
239
|
+
if (disabled)
|
|
240
|
+
return;
|
|
241
|
+
onClick?.(e);
|
|
242
|
+
if (e.defaultPrevented)
|
|
243
|
+
return;
|
|
244
|
+
onSelect?.();
|
|
245
|
+
setOpen(false);
|
|
246
|
+
}, ...props }));
|
|
247
|
+
}
|
|
248
|
+
const RadioGroupContext = React.createContext({});
|
|
249
|
+
function MenubarCheckboxItem({ className, children, checked, onCheckedChange, disabled, inset, onClick, ...props }) {
|
|
250
|
+
return (_jsxs("div", { role: "menuitemcheckbox", tabIndex: -1, "aria-checked": !!checked, "aria-disabled": disabled || undefined, "data-slot": "menubar-checkbox-item", "data-disabled": disabled ? "" : undefined, "data-inset": inset ? "" : undefined, className: cn("relative flex cursor-pointer items-center gap-2 rounded-md py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), onClick: (e) => {
|
|
251
|
+
if (disabled)
|
|
252
|
+
return;
|
|
253
|
+
onClick?.(e);
|
|
254
|
+
if (!e.defaultPrevented)
|
|
255
|
+
onCheckedChange?.(!checked);
|
|
256
|
+
}, ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-2 flex size-4 items-center justify-center", "data-slot": "menubar-checkbox-item-indicator", children: checked ? _jsx(CheckIcon, {}) : null }), children] }));
|
|
257
|
+
}
|
|
258
|
+
function MenubarRadioGroup({ value, onValueChange, ...props }) {
|
|
259
|
+
return (_jsx(RadioGroupContext.Provider, { value: { value, onValueChange }, children: _jsx("div", { role: "group", "data-slot": "menubar-radio-group", ...props }) }));
|
|
260
|
+
}
|
|
261
|
+
function MenubarRadioItem({ className, children, value, disabled, inset, onClick, ...props }) {
|
|
262
|
+
const { value: groupValue, onValueChange } = React.useContext(RadioGroupContext);
|
|
263
|
+
const checked = groupValue === value;
|
|
264
|
+
return (_jsxs("div", { role: "menuitemradio", tabIndex: -1, "aria-checked": checked, "aria-disabled": disabled || undefined, "data-slot": "menubar-radio-item", "data-disabled": disabled ? "" : undefined, "data-inset": inset ? "" : undefined, className: cn("relative flex cursor-pointer items-center gap-2 rounded-md py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), onClick: (e) => {
|
|
265
|
+
if (disabled)
|
|
266
|
+
return;
|
|
267
|
+
onClick?.(e);
|
|
268
|
+
if (!e.defaultPrevented)
|
|
269
|
+
onValueChange?.(value);
|
|
270
|
+
}, ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-2 flex size-4 items-center justify-center", "data-slot": "menubar-radio-item-indicator", children: checked ? _jsx(CheckIcon, {}) : null }), children] }));
|
|
271
|
+
}
|
|
272
|
+
function MenubarSeparator({ className, ...props }) {
|
|
273
|
+
return (_jsx("div", { role: "separator", "data-slot": "menubar-separator", className: cn("-mx-1 my-1 h-px bg-border", className), ...props }));
|
|
274
|
+
}
|
|
275
|
+
function MenubarShortcut({ className, ...props }) {
|
|
276
|
+
return (_jsx("span", { "data-slot": "menubar-shortcut", className: cn("ml-auto text-xs tracking-widest text-muted-foreground group-focus/menubar-item:text-accent-foreground", className), ...props }));
|
|
277
|
+
}
|
|
278
|
+
const SubContext = React.createContext(null);
|
|
279
|
+
function useSub() {
|
|
280
|
+
const ctx = React.useContext(SubContext);
|
|
281
|
+
if (!ctx)
|
|
282
|
+
throw new Error("Submenu parts must be used within <MenubarSub>");
|
|
283
|
+
return ctx;
|
|
284
|
+
}
|
|
285
|
+
function MenubarSub({ defaultOpen = false, children, }) {
|
|
286
|
+
const [open, setOpen] = React.useState(defaultOpen);
|
|
287
|
+
const triggerRef = React.useRef(null);
|
|
288
|
+
return (_jsx(SubContext.Provider, { value: { open, setOpen, triggerRef }, children: children }));
|
|
289
|
+
}
|
|
290
|
+
function MenubarSubTrigger({ className, inset, children, onClick, onKeyDown, onMouseEnter, ...props }) {
|
|
291
|
+
const { open, setOpen, triggerRef } = useSub();
|
|
292
|
+
return (_jsxs("div", { ref: triggerRef, role: "menuitem", tabIndex: -1, "aria-haspopup": "menu", "aria-expanded": open, "data-slot": "menubar-sub-trigger", "data-inset": inset ? "" : undefined, "data-popup-open": open ? "" : undefined, "data-open": open ? "" : undefined, className: cn("flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-8 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), onMouseEnter: (e) => {
|
|
293
|
+
onMouseEnter?.(e);
|
|
294
|
+
setOpen(true);
|
|
295
|
+
}, onClick: (e) => {
|
|
296
|
+
onClick?.(e);
|
|
297
|
+
if (!e.defaultPrevented)
|
|
298
|
+
setOpen(!open);
|
|
299
|
+
}, onKeyDown: (e) => {
|
|
300
|
+
onKeyDown?.(e);
|
|
301
|
+
if (e.defaultPrevented)
|
|
302
|
+
return;
|
|
303
|
+
if (e.key === "ArrowRight" || e.key === "Enter" || e.key === " ") {
|
|
304
|
+
e.preventDefault();
|
|
305
|
+
setOpen(true);
|
|
306
|
+
}
|
|
307
|
+
}, ...props, children: [children, _jsx(ChevronRightIcon, { className: "ml-auto" })] }));
|
|
308
|
+
}
|
|
309
|
+
function MenubarSubContent({ className, children, onKeyDown, ...props }) {
|
|
310
|
+
const { open, setOpen, triggerRef } = useSub();
|
|
311
|
+
const { layers } = useMenu();
|
|
312
|
+
const [mounted, presenceRef] = usePresence(open);
|
|
313
|
+
const { floatingRef, pos } = useFloating(triggerRef, mounted, {
|
|
314
|
+
side: "right",
|
|
315
|
+
align: "start",
|
|
316
|
+
sideOffset: 0,
|
|
317
|
+
alignOffset: -3,
|
|
318
|
+
});
|
|
319
|
+
const containerRef = React.useRef(null);
|
|
320
|
+
React.useEffect(() => {
|
|
321
|
+
const node = containerRef.current;
|
|
322
|
+
if (!node)
|
|
323
|
+
return;
|
|
324
|
+
layers.current.add(node);
|
|
325
|
+
return () => {
|
|
326
|
+
layers.current.delete(node);
|
|
327
|
+
};
|
|
328
|
+
}, [mounted, layers]);
|
|
329
|
+
const didFocus = React.useRef(false);
|
|
330
|
+
React.useEffect(() => {
|
|
331
|
+
if (!open) {
|
|
332
|
+
didFocus.current = false;
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
let raf = 0;
|
|
336
|
+
const tryFocus = () => {
|
|
337
|
+
const c = containerRef.current;
|
|
338
|
+
if (c && getComputedStyle(c).visibility !== "hidden") {
|
|
339
|
+
didFocus.current = true;
|
|
340
|
+
moveFocus(c, "first");
|
|
341
|
+
}
|
|
342
|
+
else if (!didFocus.current) {
|
|
343
|
+
raf = requestAnimationFrame(tryFocus);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
raf = requestAnimationFrame(tryFocus);
|
|
347
|
+
return () => cancelAnimationFrame(raf);
|
|
348
|
+
}, [open]);
|
|
349
|
+
if (!mounted)
|
|
350
|
+
return null;
|
|
351
|
+
return (_jsx(Portal, { children: _jsx("div", { ref: mergeRefs(floatingRef, presenceRef, containerRef), role: "menu", tabIndex: -1, "data-slot": "menubar-sub-content", "data-state": open ? "open" : "closed", "data-open": open ? "" : undefined, "data-closed": open ? undefined : "", "data-side": pos?.side ?? "right", style: {
|
|
352
|
+
position: "fixed",
|
|
353
|
+
left: pos?.x ?? 0,
|
|
354
|
+
top: pos?.y ?? 0,
|
|
355
|
+
visibility: pos ? "visible" : "hidden",
|
|
356
|
+
["--transform-origin"]: pos?.transformOrigin ?? "center",
|
|
357
|
+
}, onPointerMove: (e) => {
|
|
358
|
+
const item = e.target.closest('[role^="menuitem"]:not([data-disabled])');
|
|
359
|
+
if (item && item !== document.activeElement)
|
|
360
|
+
item.focus();
|
|
361
|
+
}, onKeyDown: (e) => {
|
|
362
|
+
onKeyDown?.(e);
|
|
363
|
+
if (e.defaultPrevented)
|
|
364
|
+
return;
|
|
365
|
+
const c = containerRef.current;
|
|
366
|
+
if (e.key === "ArrowDown")
|
|
367
|
+
(e.preventDefault(), moveFocus(c, "next"));
|
|
368
|
+
else if (e.key === "ArrowUp")
|
|
369
|
+
(e.preventDefault(), moveFocus(c, "prev"));
|
|
370
|
+
else if (e.key === "ArrowLeft" || e.key === "Escape") {
|
|
371
|
+
e.preventDefault();
|
|
372
|
+
setOpen(false);
|
|
373
|
+
triggerRef.current?.focus();
|
|
374
|
+
}
|
|
375
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
376
|
+
const active = document.activeElement;
|
|
377
|
+
if (active && c.contains(active)) {
|
|
378
|
+
e.preventDefault();
|
|
379
|
+
active.click();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}, className: cn("z-50 min-w-32 origin-(--transform-origin) overflow-hidden rounded-md bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 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 }) }));
|
|
383
|
+
}
|
|
384
|
+
export { Menubar, MenubarPortal, MenubarMenu, MenubarTrigger, MenubarContent, MenubarGroup, MenubarSeparator, MenubarLabel, MenubarItem, MenubarShortcut, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent, };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
declare function NavigationMenu({ className, children, onMouseLeave, ...props }: React.ComponentProps<"nav">): React.JSX.Element;
|
|
3
|
+
declare function NavigationMenuList({ className, ...props }: React.ComponentProps<"ul">): React.JSX.Element;
|
|
4
|
+
declare function NavigationMenuItem({ className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
|
|
5
|
+
declare const navigationMenuTriggerStyle: (props?: import("../shadcn/lib/cva.js").CvaProps<{
|
|
6
|
+
[x: string]: Record<string, string>;
|
|
7
|
+
}> | undefined) => string;
|
|
8
|
+
declare function NavigationMenuTrigger({ className, children, onMouseEnter, onFocus, onClick, ...props }: React.ComponentProps<"button">): React.JSX.Element;
|
|
9
|
+
declare function NavigationMenuContent({ className, children, onMouseEnter, ...props }: React.ComponentProps<"div">): React.JSX.Element | null;
|
|
10
|
+
declare function NavigationMenuLink({ className, active, ...props }: React.ComponentProps<"a"> & {
|
|
11
|
+
active?: boolean;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* No-op kept only to preserve the import name. The base-ui version renders an
|
|
15
|
+
* arrow indicator tied to the shared viewport; this simpler menu floats each
|
|
16
|
+
* content panel independently, so there is nothing to indicate.
|
|
17
|
+
*/
|
|
18
|
+
declare function NavigationMenuIndicator(_props: React.ComponentProps<"div">): React.ReactElement | null;
|
|
19
|
+
/**
|
|
20
|
+
* No-op kept only to preserve the import name. Positioning is handled inline by
|
|
21
|
+
* NavigationMenuContent via useFloating, so no separate positioner is needed.
|
|
22
|
+
*/
|
|
23
|
+
declare function NavigationMenuPositioner(_props: React.ComponentProps<"div">): React.ReactElement | null;
|
|
24
|
+
export { NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle, NavigationMenuPositioner, };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } 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 { Portal } from "./portal.js";
|
|
7
|
+
import { useFloating } from "./use-floating.js";
|
|
8
|
+
import { usePresence } from "./use-presence.js";
|
|
9
|
+
import { useControllableState } from "./use-controllable-state.js";
|
|
10
|
+
import { ChevronDownIcon } from "../icons/index.js";
|
|
11
|
+
const NavigationMenuContext = React.createContext(null);
|
|
12
|
+
function useNavigationMenu() {
|
|
13
|
+
const ctx = React.useContext(NavigationMenuContext);
|
|
14
|
+
if (!ctx)
|
|
15
|
+
throw new Error("NavigationMenu parts must be used within <NavigationMenu>");
|
|
16
|
+
return ctx;
|
|
17
|
+
}
|
|
18
|
+
const NavigationMenuItemContext = React.createContext(null);
|
|
19
|
+
function useNavigationMenuItem() {
|
|
20
|
+
const ctx = React.useContext(NavigationMenuItemContext);
|
|
21
|
+
if (!ctx)
|
|
22
|
+
throw new Error("NavigationMenu trigger/content must be used within <NavigationMenuItem>");
|
|
23
|
+
return ctx;
|
|
24
|
+
}
|
|
25
|
+
function NavigationMenu({ className, children, onMouseLeave, ...props }) {
|
|
26
|
+
const [value, setValue] = useControllableState({
|
|
27
|
+
defaultValue: null,
|
|
28
|
+
});
|
|
29
|
+
const closeTimer = React.useRef(null);
|
|
30
|
+
const cancelClose = React.useCallback(() => {
|
|
31
|
+
if (closeTimer.current !== null) {
|
|
32
|
+
window.clearTimeout(closeTimer.current);
|
|
33
|
+
closeTimer.current = null;
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
36
|
+
const scheduleClose = React.useCallback(() => {
|
|
37
|
+
cancelClose();
|
|
38
|
+
closeTimer.current = window.setTimeout(() => setValue(null), 150);
|
|
39
|
+
}, [cancelClose, setValue]);
|
|
40
|
+
const open = React.useCallback((v) => {
|
|
41
|
+
cancelClose();
|
|
42
|
+
setValue(v);
|
|
43
|
+
}, [cancelClose, setValue]);
|
|
44
|
+
React.useEffect(() => () => cancelClose(), [cancelClose]);
|
|
45
|
+
React.useEffect(() => {
|
|
46
|
+
if (value === null)
|
|
47
|
+
return;
|
|
48
|
+
const onKeyDown = (e) => {
|
|
49
|
+
if (e.key === "Escape")
|
|
50
|
+
setValue(null);
|
|
51
|
+
};
|
|
52
|
+
document.addEventListener("keydown", onKeyDown);
|
|
53
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
54
|
+
}, [value, setValue]);
|
|
55
|
+
return (_jsx(NavigationMenuContext.Provider, { value: { value, setValue, open, scheduleClose, cancelClose }, children: _jsx("nav", { "data-slot": "navigation-menu", "data-orientation": "horizontal", className: cn("group/navigation-menu relative flex max-w-max flex-1 items-center justify-center", className), onMouseEnter: cancelClose, onMouseLeave: (e) => {
|
|
56
|
+
onMouseLeave?.(e);
|
|
57
|
+
if (!e.defaultPrevented)
|
|
58
|
+
scheduleClose();
|
|
59
|
+
}, ...props, children: children }) }));
|
|
60
|
+
}
|
|
61
|
+
function NavigationMenuList({ className, ...props }) {
|
|
62
|
+
return (_jsx("ul", { "data-slot": "navigation-menu-list", className: cn("group flex flex-1 list-none items-center justify-center gap-0", className), ...props }));
|
|
63
|
+
}
|
|
64
|
+
function NavigationMenuItem({ className, ...props }) {
|
|
65
|
+
const value = React.useId();
|
|
66
|
+
const triggerRef = React.useRef(null);
|
|
67
|
+
return (_jsx(NavigationMenuItemContext.Provider, { value: { value, triggerRef }, children: _jsx("li", { "data-slot": "navigation-menu-item", className: cn("relative", className), ...props }) }));
|
|
68
|
+
}
|
|
69
|
+
const navigationMenuTriggerStyle = cva("cursor-pointer group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted data-open:bg-muted/50 data-open:hover:bg-muted data-open:focus:bg-muted");
|
|
70
|
+
function NavigationMenuTrigger({ className, children, onMouseEnter, onFocus, onClick, ...props }) {
|
|
71
|
+
const { value, setValue, open } = useNavigationMenu();
|
|
72
|
+
const { value: itemValue, triggerRef } = useNavigationMenuItem();
|
|
73
|
+
const isOpen = value === itemValue;
|
|
74
|
+
return (_jsxs("button", { ref: triggerRef, type: "button", "data-slot": "navigation-menu-trigger", "aria-expanded": isOpen, "data-state": isOpen ? "open" : "closed", "data-popup-open": isOpen ? "" : undefined, "data-open": isOpen ? "" : undefined, className: cn(navigationMenuTriggerStyle(), "group", className), onMouseEnter: (e) => {
|
|
75
|
+
onMouseEnter?.(e);
|
|
76
|
+
if (!e.defaultPrevented)
|
|
77
|
+
open(itemValue);
|
|
78
|
+
}, onFocus: (e) => {
|
|
79
|
+
onFocus?.(e);
|
|
80
|
+
if (!e.defaultPrevented)
|
|
81
|
+
open(itemValue);
|
|
82
|
+
}, onClick: (e) => {
|
|
83
|
+
onClick?.(e);
|
|
84
|
+
if (!e.defaultPrevented)
|
|
85
|
+
setValue(isOpen ? null : itemValue);
|
|
86
|
+
}, ...props, children: [children, " ", _jsx(ChevronDownIcon, { className: "relative top-px ml-1 size-3 transition duration-300 group-data-open:rotate-180", "aria-hidden": "true" })] }));
|
|
87
|
+
}
|
|
88
|
+
function NavigationMenuContent({ className, children, onMouseEnter, ...props }) {
|
|
89
|
+
const { value, cancelClose, scheduleClose } = useNavigationMenu();
|
|
90
|
+
const { value: itemValue, triggerRef } = useNavigationMenuItem();
|
|
91
|
+
const isOpen = value === itemValue;
|
|
92
|
+
const [mounted, presenceRef] = usePresence(isOpen);
|
|
93
|
+
const { floatingRef, pos } = useFloating(triggerRef, mounted, {
|
|
94
|
+
side: "bottom",
|
|
95
|
+
align: "start",
|
|
96
|
+
sideOffset: 8,
|
|
97
|
+
alignOffset: 0,
|
|
98
|
+
});
|
|
99
|
+
const setRef = React.useCallback((node) => {
|
|
100
|
+
floatingRef.current = node;
|
|
101
|
+
presenceRef.current = node;
|
|
102
|
+
}, [floatingRef, presenceRef]);
|
|
103
|
+
if (!mounted)
|
|
104
|
+
return null;
|
|
105
|
+
return (_jsx(Portal, { children: _jsx("div", { ref: setRef, "data-slot": "navigation-menu-content", "data-state": isOpen ? "open" : "closed", "data-open": isOpen ? "" : undefined, "data-closed": isOpen ? undefined : "", "data-side": pos?.side ?? "bottom", style: {
|
|
106
|
+
position: "fixed",
|
|
107
|
+
left: pos?.x ?? 0,
|
|
108
|
+
top: pos?.y ?? 0,
|
|
109
|
+
visibility: pos ? "visible" : "hidden",
|
|
110
|
+
["--transform-origin"]: pos?.transformOrigin ?? "center",
|
|
111
|
+
}, onMouseEnter: (e) => {
|
|
112
|
+
onMouseEnter?.(e);
|
|
113
|
+
cancelClose();
|
|
114
|
+
}, onMouseLeave: scheduleClose, className: cn("z-50 w-auto origin-(--transform-origin) rounded-md bg-popover p-2 text-popover-foreground shadow ring-1 ring-foreground/10 duration-200 outline-none 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 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none", className), ...props, children: children }) }));
|
|
115
|
+
}
|
|
116
|
+
function NavigationMenuLink({ className, active, ...props }) {
|
|
117
|
+
return (_jsx("a", { "data-slot": "navigation-menu-link", "data-active": active ? "true" : undefined, className: cn("cursor-pointer flex items-center gap-1.5 rounded-md p-2 text-sm transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 in-data-[slot=navigation-menu-content]:rounded-sm data-[active=true]:bg-muted/50 data-[active=true]:hover:bg-muted data-[active=true]:focus:bg-muted [&_svg:not([class*='size-'])]:size-4", className), ...props }));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* No-op kept only to preserve the import name. The base-ui version renders an
|
|
121
|
+
* arrow indicator tied to the shared viewport; this simpler menu floats each
|
|
122
|
+
* content panel independently, so there is nothing to indicate.
|
|
123
|
+
*/
|
|
124
|
+
function NavigationMenuIndicator(_props) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* No-op kept only to preserve the import name. Positioning is handled inline by
|
|
129
|
+
* NavigationMenuContent via useFloating, so no separate positioner is needed.
|
|
130
|
+
*/
|
|
131
|
+
function NavigationMenuPositioner(_props) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
export { NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle, NavigationMenuPositioner, };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Button } from "./button.js";
|
|
3
|
+
declare function Pagination({ className, ...props }: React.ComponentProps<"nav">): React.JSX.Element;
|
|
4
|
+
declare function PaginationContent({ className, ...props }: React.ComponentProps<"ul">): React.JSX.Element;
|
|
5
|
+
declare function PaginationItem({ ...props }: React.ComponentProps<"li">): React.JSX.Element;
|
|
6
|
+
type PaginationLinkProps = {
|
|
7
|
+
isActive?: boolean;
|
|
8
|
+
} & Pick<React.ComponentProps<typeof Button>, "size"> & React.ComponentProps<"a">;
|
|
9
|
+
declare function PaginationLink({ className, isActive, size, onKeyDown, ...props }: PaginationLinkProps): React.JSX.Element;
|
|
10
|
+
declare function PaginationPrevious({ className, text, ...props }: React.ComponentProps<typeof PaginationLink> & {
|
|
11
|
+
text?: string;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
declare function PaginationNext({ className, text, ...props }: React.ComponentProps<typeof PaginationLink> & {
|
|
14
|
+
text?: string;
|
|
15
|
+
}): React.JSX.Element;
|
|
16
|
+
declare function PaginationEllipsis({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
|
|
17
|
+
export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../shadcn/lib/utils.js";
|
|
4
|
+
import { Button } from "./button.js";
|
|
5
|
+
import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon, } from "../icons/index.js";
|
|
6
|
+
function Pagination({ className, ...props }) {
|
|
7
|
+
return (_jsx("nav", { role: "navigation", "aria-label": "pagination", "data-slot": "pagination", className: cn("mx-auto flex w-full justify-center", className), ...props }));
|
|
8
|
+
}
|
|
9
|
+
function PaginationContent({ className, ...props }) {
|
|
10
|
+
return (_jsx("ul", { "data-slot": "pagination-content", className: cn("flex items-center gap-1", className), ...props }));
|
|
11
|
+
}
|
|
12
|
+
function PaginationItem({ ...props }) {
|
|
13
|
+
return _jsx("li", { "data-slot": "pagination-item", ...props });
|
|
14
|
+
}
|
|
15
|
+
function PaginationLink({ className, isActive, size = "icon", onKeyDown, ...props }) {
|
|
16
|
+
// An <a> without href is not focusable or Enter/Space-activatable, so for
|
|
17
|
+
// SPA usage (onClick, no href) add button semantics + keyboard activation.
|
|
18
|
+
const isRealLink = props.href != null;
|
|
19
|
+
return (_jsx(Button, { asChild: true, variant: isActive ? "outline" : "ghost", size: size, className: cn("cursor-pointer", className), children: _jsx("a", { "aria-current": isActive ? "page" : undefined, "data-slot": "pagination-link", "data-active": isActive, role: isRealLink ? undefined : "button", tabIndex: isRealLink ? undefined : 0, onKeyDown: (e) => {
|
|
20
|
+
onKeyDown?.(e);
|
|
21
|
+
if (!isRealLink && !e.defaultPrevented && (e.key === "Enter" || e.key === " ")) {
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
e.currentTarget.click();
|
|
24
|
+
}
|
|
25
|
+
}, ...props }) }));
|
|
26
|
+
}
|
|
27
|
+
function PaginationPrevious({ className, text = "Previous", ...props }) {
|
|
28
|
+
return (_jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn("pl-2!", className), ...props, children: [_jsx(ChevronLeftIcon, {}), _jsx("span", { className: "hidden sm:block", children: text })] }));
|
|
29
|
+
}
|
|
30
|
+
function PaginationNext({ className, text = "Next", ...props }) {
|
|
31
|
+
return (_jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn("pr-2!", className), ...props, children: [_jsx("span", { className: "hidden sm:block", children: text }), _jsx(ChevronRightIcon, {})] }));
|
|
32
|
+
}
|
|
33
|
+
function PaginationEllipsis({ className, ...props }) {
|
|
34
|
+
return (_jsxs("span", { "aria-hidden": true, "data-slot": "pagination-ellipsis", className: cn("flex size-9 items-center justify-center [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [_jsx(MoreHorizontalIcon, {}), _jsx("span", { className: "sr-only", children: "More pages" })] }));
|
|
35
|
+
}
|
|
36
|
+
export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type Side, type Align } from "./use-floating.js";
|
|
3
|
+
export interface PopoverProps {
|
|
4
|
+
open?: boolean;
|
|
5
|
+
defaultOpen?: boolean;
|
|
6
|
+
onOpenChange?: (open: boolean) => void;
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
declare function Popover({ open, defaultOpen, onOpenChange, children }: PopoverProps): React.JSX.Element;
|
|
10
|
+
declare function PopoverTrigger({ asChild, render, nativeButton: _nativeButton, children, onClick, ...props }: React.ComponentProps<"button"> & {
|
|
11
|
+
asChild?: boolean;
|
|
12
|
+
render?: React.ReactElement;
|
|
13
|
+
nativeButton?: boolean;
|
|
14
|
+
}): React.JSX.Element;
|
|
15
|
+
export interface PopoverContentProps extends React.ComponentProps<"div"> {
|
|
16
|
+
side?: Side;
|
|
17
|
+
align?: Align;
|
|
18
|
+
sideOffset?: number;
|
|
19
|
+
alignOffset?: number;
|
|
20
|
+
}
|
|
21
|
+
declare function PopoverContent({ className, style, ref, align, alignOffset, side, sideOffset, ...props }: PopoverContentProps): React.JSX.Element | null;
|
|
22
|
+
declare function PopoverHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
23
|
+
declare function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">): React.JSX.Element;
|
|
24
|
+
declare function PopoverDescription({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
|
|
25
|
+
export { Popover, PopoverTrigger, PopoverContent, PopoverHeader, PopoverTitle, PopoverDescription, };
|