@justanarthur/modo-ui 0.6.0-canary.9 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -164
- package/dist/base.css +4 -141
- package/dist/blocks/sidebar-app/index.js +26 -40
- package/dist/components/AI/input-message/index.js +16 -23
- package/dist/components/AI/thinking-indicator/index.js +6 -9
- package/dist/components/accordion/index.d.ts +11 -39
- package/dist/components/accordion/index.js +13 -18
- package/dist/components/badge/index.d.ts +11 -18
- package/dist/components/badge/index.js +7 -12
- package/dist/components/button/index.d.ts +17 -53
- package/dist/components/button/index.js +6 -11
- package/dist/components/card/index.d.ts +9 -32
- package/dist/components/card/index.js +11 -17
- package/dist/components/copy/index.d.ts +8 -41
- package/dist/components/copy/index.js +9 -15
- package/dist/components/inputs/checkbox/index.d.ts +9 -28
- package/dist/components/inputs/checkbox/index.js +13 -18
- package/dist/components/inputs/color-picker/index.d.ts +14 -22
- package/dist/components/inputs/color-picker/index.js +18 -26
- package/dist/components/inputs/combobox/index.d.ts +20 -85
- package/dist/components/inputs/combobox/index.js +18 -27
- package/dist/components/inputs/date-time/calendar/index.d.ts +18 -24
- package/dist/components/inputs/date-time/calendar/index.js +11 -15
- package/dist/components/inputs/date-time/date-picker/index.d.ts +16 -105
- package/dist/components/inputs/date-time/date-picker/index.js +25 -35
- package/dist/components/inputs/date-time/date-range-picker/index.d.ts +12 -106
- package/dist/components/inputs/date-time/date-range-picker/index.js +24 -35
- package/dist/components/inputs/date-time/duration-picker/index.d.ts +13 -66
- package/dist/components/inputs/date-time/duration-picker/index.js +24 -33
- package/dist/components/inputs/date-time/month-picker/index.d.ts +10 -60
- package/dist/components/inputs/date-time/month-picker/index.js +23 -32
- package/dist/components/inputs/date-time/time-picker/index.d.ts +10 -58
- package/dist/components/inputs/date-time/time-picker/index.js +24 -33
- package/dist/components/inputs/input/index.d.ts +13 -95
- package/dist/components/inputs/input/index.js +9 -18
- package/dist/components/inputs/radio/index.d.ts +5 -20
- package/dist/components/inputs/radio/index.js +12 -16
- package/dist/components/inputs/search/index.d.ts +3 -3
- package/dist/components/inputs/search/index.js +18 -26
- package/dist/components/inputs/select/index.d.ts +23 -99
- package/dist/components/inputs/select/index.js +14 -29
- package/dist/components/inputs/slider/index.d.ts +0 -9
- package/dist/components/inputs/slider/index.js +5 -8
- package/dist/components/inputs/switch/index.d.ts +2 -8
- package/dist/components/inputs/switch/index.js +12 -15
- package/dist/components/inputs/textarea/index.d.ts +1 -20
- package/dist/components/inputs/textarea/index.js +6 -9
- package/dist/components/navigation/sidebar/index.d.ts +21 -44
- package/dist/components/navigation/sidebar/index.js +31 -42
- package/dist/components/navigation/tabs/index.d.ts +2 -8
- package/dist/components/navigation/tabs/index.js +10 -15
- package/dist/components/navigation/tabs-subtle/index.js +10 -13
- package/dist/components/overlays/alert-dialog/index.d.ts +16 -135
- package/dist/components/overlays/alert-dialog/index.js +13 -23
- package/dist/components/overlays/command/index.d.ts +20 -25
- package/dist/components/overlays/command/index.js +17 -25
- package/dist/components/overlays/context-menu/index.d.ts +17 -39
- package/dist/components/overlays/context-menu/index.js +18 -29
- package/dist/components/overlays/dialog/index.d.ts +16 -42
- package/dist/components/overlays/dialog/index.js +12 -20
- package/dist/components/overlays/dropdown/index.d.ts +34 -304
- package/dist/components/overlays/dropdown/index.js +17 -44
- package/dist/components/overlays/popover/index.d.ts +12 -38
- package/dist/components/overlays/popover/index.js +9 -13
- package/dist/components/overlays/preview-card/index.js +8 -12
- package/dist/components/overlays/sheet/index.d.ts +8 -25
- package/dist/components/overlays/sheet/index.js +13 -19
- package/dist/components/overlays/toast/index.d.ts +50 -209
- package/dist/components/overlays/toast/index.js +10 -23
- package/dist/components/overlays/tooltip/index.d.ts +21 -123
- package/dist/components/overlays/tooltip/index.js +6 -16
- package/dist/components/table/index.d.ts +8 -63
- package/dist/components/table/index.js +9 -20
- package/dist/index.d.ts +1048 -2999
- package/dist/index.js +82 -231
- package/dist/preset.d.ts +0 -22
- package/dist/preset.js +2 -24
- package/dist/primitives/code/index.js +5 -8
- package/dist/primitives/craft/index.js +6 -10
- package/dist/primitives/fluid-hover/index.js +8 -10
- package/dist/primitives/morph/index.js +10 -16
- package/dist/primitives/motion/index.js +8 -11
- package/dist/primitives/scroll-area/index.js +3 -5
- package/dist/primitives/sizes/index.js +4 -6
- package/dist/primitives/surface/index.js +4 -6
- package/dist/shared/{components-c7rwx0ap.js → components-0q0sqfh4.js} +49 -27
- package/dist/shared/components-0sn7ypjw.js +61 -0
- package/dist/shared/{components-vc864c51.js → components-11da9ajg.js} +5 -8
- package/dist/shared/components-1434p1mh.js +123 -0
- package/dist/shared/{components-c74gf16d.js → components-1z6tdadk.js} +24 -40
- package/dist/shared/{components-bae8sbjx.js → components-27nnvrwe.js} +14 -15
- package/dist/shared/{components-qh1cvj6p.js → components-2dxkv6zm.js} +7 -8
- package/dist/shared/{components-y0kfy2g4.js → components-2ecg8svx.js} +152 -234
- package/dist/shared/{components-c5w5zk0s.js → components-2ph6t61s.js} +34 -37
- package/dist/shared/{components-4j3t39dd.js → components-39jq9va1.js} +24 -29
- package/dist/shared/components-3ky44908.js +9 -0
- package/dist/shared/{components-syynwm1r.js → components-3mkepka5.js} +25 -28
- package/dist/shared/{components-wgtjt2af.js → components-4700p9kz.js} +22 -24
- package/dist/shared/{components-yhgq0qxx.js → components-59efxjd9.js} +12 -13
- package/dist/shared/{components-91zw3d9f.js → components-5vgpnxgy.js} +27 -51
- package/dist/shared/{components-kz5q11pp.js → components-5xc2j8jz.js} +18 -19
- package/dist/shared/{components-zkk3fmw8.js → components-6p8tfcd6.js} +29 -57
- package/dist/shared/{components-4nck8acq.js → components-7r3etddy.js} +54 -19
- package/dist/shared/{components-svkt577j.js → components-8snj490h.js} +32 -78
- package/dist/shared/{components-ctqmge8t.js → components-b0eac83j.js} +30 -9
- package/dist/shared/{components-9sttq78t.js → components-b2wyq2cq.js} +59 -41
- package/dist/shared/{components-pv1dyrtn.js → components-b3c5et5b.js} +38 -49
- package/dist/shared/{components-rrbpmfx4.js → components-c6s6b43g.js} +2 -3
- package/dist/shared/{components-pwayrkw9.js → components-chacnk61.js} +19 -19
- package/dist/shared/{components-71nbt03m.js → components-cv16mryv.js} +7 -26
- package/dist/shared/{components-hgv6tygd.js → components-d6xtjht3.js} +30 -35
- package/dist/shared/{components-z8fedth5.js → components-dk0gjr5a.js} +18 -19
- package/dist/shared/{components-cet3jpa0.js → components-fzrq6tr3.js} +34 -37
- package/dist/shared/{components-cnead5qm.js → components-gc5vtq2f.js} +30 -66
- package/dist/shared/components-gf5s6ap9.js +42 -0
- package/dist/shared/{components-0h78g3b5.js → components-gz8zf3ec.js} +55 -56
- package/dist/shared/{components-mattt5jp.js → components-h2ajmhwn.js} +35 -107
- package/dist/shared/{components-m06yq8wk.js → components-hqeq3w9q.js} +23 -38
- package/dist/shared/{components-7qx17na9.js → components-hw9yk32z.js} +24 -36
- package/dist/shared/components-hyq23phv.js +310 -0
- package/dist/shared/{components-9jmjnkqd.js → components-jbbmdr74.js} +22 -41
- package/dist/shared/{components-dcc02hs2.js → components-jjw69c4c.js} +4 -7
- package/dist/shared/{components-303jf96s.js → components-jthe1pwb.js} +420 -139
- package/dist/shared/{components-dtca4s6b.js → components-jwst3vtj.js} +76 -224
- package/dist/shared/{components-dc5q749x.js → components-kvr7f9hy.js} +10 -19
- package/dist/shared/{components-s8yqk2dc.js → components-kwa6mrf9.js} +11 -46
- package/dist/shared/{components-de99ykt7.js → components-men63rwj.js} +2 -3
- package/dist/shared/{components-qx27excf.js → components-mjthm1kf.js} +9 -13
- package/dist/shared/{components-1e64t8aj.js → components-n42c79bz.js} +22 -23
- package/dist/shared/{components-tz1fv35x.js → components-n7mjr357.js} +2 -3
- package/dist/shared/components-ng72k97e.js +128 -0
- package/dist/shared/{components-w2jqa6hx.js → components-pbmqctfa.js} +65 -169
- package/dist/shared/{components-px2zm7dc.js → components-q5xj5c16.js} +8 -9
- package/dist/shared/components-raknhppb.js +64 -0
- package/dist/shared/{components-2a7hcand.js → components-rr7a6ja9.js} +27 -59
- package/dist/shared/{components-005jt2nz.js → components-s083f38z.js} +34 -164
- package/dist/shared/components-s5ngg32c.js +267 -0
- package/dist/shared/components-sn1rxx1d.js +143 -0
- package/dist/shared/{components-r8eqs7gz.js → components-ta7shw28.js} +4 -4
- package/dist/shared/{components-9as3rf68.js → components-vc7vq5nz.js} +3 -6
- package/dist/shared/{components-ft3zdc79.js → components-vfbhxf5r.js} +5 -6
- package/dist/shared/components-vynjtrk6.js +19 -0
- package/dist/shared/{components-p0fm0bab.js → components-w1r67ag9.js} +149 -294
- package/dist/shared/{components-xd3emmy4.js → components-w90endve.js} +72 -71
- package/dist/shared/{components-t5pk5nmc.js → components-wvp1m52g.js} +102 -149
- package/dist/shared/components-wy9jpqny.js +146 -0
- package/dist/shared/{components-yxmxn2jp.js → components-y9y0g8er.js} +28 -52
- package/dist/shared/components-ypp01w3p.js +986 -0
- package/dist/shared/{components-czdvj1a8.js → components-zfnmn5d4.js} +36 -82
- package/dist/shared/{components-jqpefjsn.js → components-zrkzcayz.js} +6 -54
- package/dist/shared/{components-vf45j12c.js → components-zx6b6yby.js} +18 -4
- package/dist/styles.css +32 -320
- package/dist/tailwind.css +0 -16
- package/dist/tokens.css +0 -67
- package/package.json +4 -227
- package/DESIGN.md +0 -623
- package/blocks/sidebar-app/examples.mdx +0 -33
- package/blocks/sidebar-app/index.tsx +0 -218
- package/blocks/sidebar-app/inset-topbar.tsx +0 -25
- package/blocks/sidebar-app/menu-grid.ts +0 -26
- package/blocks/sidebar-app/nav-data.ts +0 -36
- package/blocks/sidebar-app/search-field.tsx +0 -48
- package/blocks/sidebar-app/user-footer.tsx +0 -67
- package/blocks/sidebar-app/workspace-header.tsx +0 -129
- package/components/AI/input-message/examples.mdx +0 -130
- package/components/AI/input-message/file-thumbnail.tsx +0 -173
- package/components/AI/input-message/index.tsx +0 -1385
- package/components/AI/thinking-indicator/examples.mdx +0 -27
- package/components/AI/thinking-indicator/index.tsx +0 -210
- package/components/accordion/examples.mdx +0 -233
- package/components/accordion/index.tsx +0 -1071
- package/components/avatar/examples.mdx +0 -95
- package/components/avatar/index.tsx +0 -129
- package/components/badge/change-demo.tsx +0 -29
- package/components/badge/examples.mdx +0 -124
- package/components/badge/index.tsx +0 -225
- package/components/badge/variants.ts +0 -73
- package/components/button/examples.mdx +0 -168
- package/components/button/index.tsx +0 -424
- package/components/button/loading-demo.tsx +0 -25
- package/components/button/variants.ts +0 -168
- package/components/card/examples.mdx +0 -251
- package/components/card/index.tsx +0 -1070
- package/components/copy/examples.mdx +0 -125
- package/components/copy/index.tsx +0 -662
- package/components/inputs/checkbox/examples.mdx +0 -87
- package/components/inputs/checkbox/index.tsx +0 -611
- package/components/inputs/checkbox/select-all-demo.tsx +0 -48
- package/components/inputs/color-picker/examples.mdx +0 -111
- package/components/inputs/color-picker/index.tsx +0 -1981
- package/components/inputs/color-picker/variants.ts +0 -401
- package/components/inputs/combobox/examples.mdx +0 -366
- package/components/inputs/combobox/index.tsx +0 -1527
- package/components/inputs/combobox/remote-demo.tsx +0 -105
- package/components/inputs/date-time/calendar/examples.mdx +0 -45
- package/components/inputs/date-time/calendar/index.tsx +0 -370
- package/components/inputs/date-time/calendar/use-month-window.ts +0 -173
- package/components/inputs/date-time/date-picker/examples.mdx +0 -243
- package/components/inputs/date-time/date-picker/index.tsx +0 -476
- package/components/inputs/date-time/date-picker/masked-date-input.tsx +0 -348
- package/components/inputs/date-time/date-range-picker/examples.mdx +0 -93
- package/components/inputs/date-time/date-range-picker/index.tsx +0 -525
- package/components/inputs/date-time/duration-picker/examples.mdx +0 -40
- package/components/inputs/date-time/duration-picker/index.tsx +0 -253
- package/components/inputs/date-time/month-picker/examples.mdx +0 -45
- package/components/inputs/date-time/month-picker/index.tsx +0 -254
- package/components/inputs/date-time/picker-shell.tsx +0 -581
- package/components/inputs/date-time/time-columns.tsx +0 -94
- package/components/inputs/date-time/time-picker/examples.mdx +0 -57
- package/components/inputs/date-time/time-picker/index.tsx +0 -227
- package/components/inputs/field/examples.mdx +0 -117
- package/components/inputs/field/index.tsx +0 -268
- package/components/inputs/file-dropzone/examples.mdx +0 -83
- package/components/inputs/file-dropzone/file-row.tsx +0 -201
- package/components/inputs/file-dropzone/index.tsx +0 -316
- package/components/inputs/file-dropzone/upload-demo.tsx +0 -67
- package/components/inputs/file-dropzone/variants.ts +0 -94
- package/components/inputs/input/examples.mdx +0 -166
- package/components/inputs/input/index.tsx +0 -494
- package/components/inputs/input/password-demo.tsx +0 -30
- package/components/inputs/label/examples.mdx +0 -67
- package/components/inputs/label/index.tsx +0 -85
- package/components/inputs/number-input/examples.mdx +0 -69
- package/components/inputs/number-input/index.tsx +0 -221
- package/components/inputs/radio/examples.mdx +0 -77
- package/components/inputs/radio/index.tsx +0 -636
- package/components/inputs/search/examples.mdx +0 -74
- package/components/inputs/search/index.tsx +0 -333
- package/components/inputs/select/examples.mdx +0 -296
- package/components/inputs/select/index.tsx +0 -1044
- package/components/inputs/select/variants.ts +0 -32
- package/components/inputs/slider/examples.mdx +0 -153
- package/components/inputs/slider/index.tsx +0 -1867
- package/components/inputs/switch/examples.mdx +0 -96
- package/components/inputs/switch/index.tsx +0 -504
- package/components/inputs/textarea/examples.mdx +0 -126
- package/components/inputs/textarea/index.tsx +0 -207
- package/components/navigation/navigation-menu/examples.mdx +0 -136
- package/components/navigation/navigation-menu/index.tsx +0 -704
- package/components/navigation/pagination/examples.mdx +0 -74
- package/components/navigation/pagination/index.tsx +0 -401
- package/components/navigation/sidebar/examples.mdx +0 -325
- package/components/navigation/sidebar/index.tsx +0 -453
- package/components/navigation/sidebar/sidebar-core.tsx +0 -1408
- package/components/navigation/sidebar/sidebar-menu.tsx +0 -1495
- package/components/navigation/sidebar/sidebar.css +0 -74
- package/components/navigation/sidebar/variants.ts +0 -55
- package/components/navigation/tabs/examples.mdx +0 -89
- package/components/navigation/tabs/index.tsx +0 -494
- package/components/navigation/tabs-subtle/examples.mdx +0 -49
- package/components/navigation/tabs-subtle/index.tsx +0 -512
- package/components/overlays/alert-dialog/examples.mdx +0 -123
- package/components/overlays/alert-dialog/index.tsx +0 -276
- package/components/overlays/alert-dialog/pending-demo.tsx +0 -36
- package/components/overlays/command/examples.mdx +0 -113
- package/components/overlays/command/index.tsx +0 -425
- package/components/overlays/context-menu/examples.mdx +0 -56
- package/components/overlays/context-menu/index.tsx +0 -279
- package/components/overlays/dialog/examples.mdx +0 -165
- package/components/overlays/dialog/index.tsx +0 -451
- package/components/overlays/dropdown/dropdown-search.tsx +0 -395
- package/components/overlays/dropdown/examples.mdx +0 -444
- package/components/overlays/dropdown/index.tsx +0 -1241
- package/components/overlays/dropdown/menu-item.tsx +0 -510
- package/components/overlays/dropdown/menu-parts.tsx +0 -725
- package/components/overlays/popover/anchored-demo.tsx +0 -59
- package/components/overlays/popover/examples.mdx +0 -203
- package/components/overlays/popover/index.tsx +0 -317
- package/components/overlays/preview-card/examples.mdx +0 -61
- package/components/overlays/preview-card/index.tsx +0 -204
- package/components/overlays/sheet/examples.mdx +0 -101
- package/components/overlays/sheet/index.tsx +0 -307
- package/components/overlays/toast/examples.mdx +0 -85
- package/components/overlays/toast/global-demo.tsx +0 -72
- package/components/overlays/toast/index.tsx +0 -544
- package/components/overlays/toast/manager.ts +0 -193
- package/components/overlays/tooltip/examples.mdx +0 -106
- package/components/overlays/tooltip/index.tsx +0 -539
- package/components/progress/examples.mdx +0 -59
- package/components/progress/index.tsx +0 -174
- package/components/progress/progress.css +0 -49
- package/components/progress/step-demo.tsx +0 -27
- package/components/table/examples.mdx +0 -188
- package/components/table/index.tsx +0 -535
- package/components/table/sort-demo.tsx +0 -61
- package/dist/components/avatar/index.d.ts +0 -46
- package/dist/components/avatar/index.js +0 -19
- package/dist/components/badge/variants.d.ts +0 -33
- package/dist/components/badge/variants.js +0 -10
- package/dist/components/button/variants.d.ts +0 -39
- package/dist/components/button/variants.js +0 -8
- package/dist/components/inputs/color-picker/variants.d.ts +0 -61
- package/dist/components/inputs/color-picker/variants.js +0 -28
- package/dist/components/inputs/field/index.d.ts +0 -116
- package/dist/components/inputs/field/index.js +0 -29
- package/dist/components/inputs/file-dropzone/index.d.ts +0 -167
- package/dist/components/inputs/file-dropzone/index.js +0 -33
- package/dist/components/inputs/file-dropzone/variants.d.ts +0 -35
- package/dist/components/inputs/file-dropzone/variants.js +0 -12
- package/dist/components/inputs/label/index.d.ts +0 -32
- package/dist/components/inputs/label/index.js +0 -11
- package/dist/components/inputs/number-input/index.d.ts +0 -87
- package/dist/components/inputs/number-input/index.js +0 -21
- package/dist/components/inputs/select/variants.d.ts +0 -5
- package/dist/components/inputs/select/variants.js +0 -6
- package/dist/components/navigation/navigation-menu/index.d.ts +0 -126
- package/dist/components/navigation/navigation-menu/index.js +0 -41
- package/dist/components/navigation/pagination/index.d.ts +0 -75
- package/dist/components/navigation/pagination/index.js +0 -41
- package/dist/components/navigation/sidebar/variants.d.ts +0 -25
- package/dist/components/navigation/sidebar/variants.js +0 -28
- package/dist/components/progress/index.d.ts +0 -56
- package/dist/components/progress/index.js +0 -15
- package/dist/docs/index.d.ts +0 -83
- package/dist/docs/index.js +0 -288
- package/dist/docs/vite.d.ts +0 -31
- package/dist/docs/vite.js +0 -45
- package/dist/lib/date-locale.d.ts +0 -26
- package/dist/lib/date-locale.js +0 -24
- package/dist/lib/field-classes.d.ts +0 -149
- package/dist/lib/field-classes.js +0 -41
- package/dist/lib/field-variants.d.ts +0 -47
- package/dist/lib/field-variants.js +0 -26
- package/dist/lib/fluid-hover-highlight.d.ts +0 -112
- package/dist/lib/fluid-hover-highlight.js +0 -17
- package/dist/lib/focus-ring.d.ts +0 -18
- package/dist/lib/focus-ring.js +0 -11
- package/dist/lib/goo-indicator.d.ts +0 -46
- package/dist/lib/goo-indicator.js +0 -14
- package/dist/lib/icon-context.d.ts +0 -30
- package/dist/lib/icon-context.js +0 -12
- package/dist/lib/inert.d.ts +0 -9
- package/dist/lib/inert.js +0 -8
- package/dist/lib/morph-layers.d.ts +0 -93
- package/dist/lib/morph-layers.js +0 -13
- package/dist/lib/morph-part.d.ts +0 -21
- package/dist/lib/morph-part.js +0 -12
- package/dist/lib/popup.d.ts +0 -20
- package/dist/lib/popup.js +0 -12
- package/dist/lib/reduced-motion.d.ts +0 -9
- package/dist/lib/reduced-motion.js +0 -6
- package/dist/lib/row-index.d.ts +0 -10
- package/dist/lib/row-index.js +0 -8
- package/dist/lib/row-order.d.ts +0 -28
- package/dist/lib/row-order.js +0 -10
- package/dist/lib/scroll-column.d.ts +0 -31
- package/dist/lib/scroll-column.js +0 -19
- package/dist/lib/shape-context.d.ts +0 -30
- package/dist/lib/shape-context.js +0 -13
- package/dist/lib/shape-radius.d.ts +0 -19
- package/dist/lib/shape-radius.js +0 -6
- package/dist/lib/size-context.d.ts +0 -94
- package/dist/lib/size-context.js +0 -20
- package/dist/lib/size-scale.d.ts +0 -79
- package/dist/lib/size-scale.js +0 -8
- package/dist/lib/slot.d.ts +0 -39
- package/dist/lib/slot.js +0 -14
- package/dist/lib/springs.d.ts +0 -44
- package/dist/lib/springs.js +0 -8
- package/dist/lib/surface-classes.d.ts +0 -19
- package/dist/lib/surface-classes.js +0 -10
- package/dist/lib/surface-context.d.ts +0 -9
- package/dist/lib/surface-context.js +0 -8
- package/dist/lib/use-controllable-state.d.ts +0 -2
- package/dist/lib/use-controllable-state.js +0 -6
- package/dist/lib/use-fluid-hover.d.ts +0 -138
- package/dist/lib/use-fluid-hover.js +0 -14
- package/dist/lib/use-is-mobile.d.ts +0 -2
- package/dist/lib/use-is-mobile.js +0 -6
- package/dist/lib/use-keyboard-nav-gate.d.ts +0 -20
- package/dist/lib/use-keyboard-nav-gate.js +0 -7
- package/dist/lib/use-merge-split.d.ts +0 -47
- package/dist/lib/use-merge-split.js +0 -15
- package/dist/lib/use-morph.d.ts +0 -101
- package/dist/lib/use-morph.js +0 -20
- package/dist/lib/use-touch-primary.d.ts +0 -2
- package/dist/lib/use-touch-primary.js +0 -6
- package/dist/lib/utils.d.ts +0 -3
- package/dist/lib/utils.js +0 -6
- package/dist/primitives/separator/index.d.ts +0 -25
- package/dist/primitives/separator/index.js +0 -9
- package/dist/primitives/skeleton/index.d.ts +0 -35
- package/dist/primitives/skeleton/index.js +0 -13
- package/dist/shared/components-01w9qcfa.js +0 -277
- package/dist/shared/components-124epb7f.js +0 -53
- package/dist/shared/components-26snnbs9.js +0 -322
- package/dist/shared/components-2krsc300.js +0 -254
- package/dist/shared/components-2qbqqpgq.js +0 -1545
- package/dist/shared/components-34txk9rj.js +0 -35
- package/dist/shared/components-3h92d94m.js +0 -23
- package/dist/shared/components-4vfm04wq.js +0 -82
- package/dist/shared/components-54nq988h.js +0 -123
- package/dist/shared/components-7s7pykk5.js +0 -281
- package/dist/shared/components-868v7scv.js +0 -399
- package/dist/shared/components-8jrk5eye.js +0 -448
- package/dist/shared/components-adkarj8n.js +0 -35
- package/dist/shared/components-b1e239g3.js +0 -28
- package/dist/shared/components-b94t6qtj.js +0 -143
- package/dist/shared/components-bsqynhaj.js +0 -179
- package/dist/shared/components-c9yr4ed1.js +0 -44
- package/dist/shared/components-d3shbwqq.js +0 -95
- package/dist/shared/components-dhgk6mbt.js +0 -16
- package/dist/shared/components-drxrtnp2.js +0 -25
- package/dist/shared/components-f7h57m6t.js +0 -59
- package/dist/shared/components-g3eafs70.js +0 -337
- package/dist/shared/components-gx4h5rbb.js +0 -40
- package/dist/shared/components-gyt7my41.js +0 -328
- package/dist/shared/components-h6p86be3.js +0 -19
- package/dist/shared/components-h83az0bz.js +0 -33
- package/dist/shared/components-hdzrqqpx.js +0 -55
- package/dist/shared/components-krtx3m5b.js +0 -84
- package/dist/shared/components-kswxnm3h.js +0 -24
- package/dist/shared/components-mhza2wdn.js +0 -482
- package/dist/shared/components-mrbaxt8q.js +0 -62
- package/dist/shared/components-pt5ftm4p.js +0 -38
- package/dist/shared/components-rtadhd9j.js +0 -64
- package/dist/shared/components-tv7b8tet.js +0 -271
- package/dist/shared/components-tz4gaf1v.js +0 -23
- package/dist/shared/components-wbbckbw8.js +0 -34
- package/dist/shared/components-wknae3m4.js +0 -298
- package/dist/shared/components-xdqmt6ed.js +0 -20
- package/dist/shared/components-xjkdvnbg.js +0 -107
- package/dist/shared/components-z3v0n0de.js +0 -11
- package/dist/tokens/colors.css +0 -230
- package/dist/tokens/motion.css +0 -40
- package/dist/tokens/radius.css +0 -10
- package/dist/tokens/spacing.css +0 -9
- package/dist/tokens/typography.css +0 -119
- package/docs/chrome.css +0 -120
- package/docs/chrome.tsx +0 -283
- package/docs/index.ts +0 -9
- package/docs/vite.ts +0 -85
- package/index.ts +0 -60
- package/lib/date-locale.ts +0 -195
- package/lib/field-classes.ts +0 -121
- package/lib/field-variants.ts +0 -117
- package/lib/fluid-hover-highlight.tsx +0 -139
- package/lib/focus-ring.tsx +0 -46
- package/lib/goo-indicator.tsx +0 -261
- package/lib/icon-context.tsx +0 -310
- package/lib/inert.ts +0 -22
- package/lib/morph-layers.tsx +0 -102
- package/lib/morph-part.tsx +0 -49
- package/lib/popup.ts +0 -52
- package/lib/reduced-motion.ts +0 -19
- package/lib/row-index.tsx +0 -29
- package/lib/row-order.tsx +0 -126
- package/lib/scroll-column.tsx +0 -273
- package/lib/shape-context.tsx +0 -138
- package/lib/shape-radius.ts +0 -67
- package/lib/size-context.tsx +0 -66
- package/lib/size-scale.ts +0 -115
- package/lib/slot.ts +0 -115
- package/lib/springs.ts +0 -62
- package/lib/surface-classes.ts +0 -58
- package/lib/surface-context.tsx +0 -21
- package/lib/use-controllable-state.ts +0 -44
- package/lib/use-fluid-hover.ts +0 -541
- package/lib/use-is-mobile.ts +0 -25
- package/lib/use-keyboard-nav-gate.ts +0 -45
- package/lib/use-merge-split.tsx +0 -209
- package/lib/use-morph.ts +0 -575
- package/lib/use-touch-primary.tsx +0 -43
- package/lib/utils.ts +0 -37
- package/preset.ts +0 -199
- package/primitives/code/examples.mdx +0 -27
- package/primitives/code/index.tsx +0 -80
- package/primitives/craft/demos.tsx +0 -173
- package/primitives/craft/examples.mdx +0 -142
- package/primitives/craft/index.tsx +0 -76
- package/primitives/fluid-hover/examples.mdx +0 -84
- package/primitives/fluid-hover/index.tsx +0 -316
- package/primitives/morph/examples.mdx +0 -139
- package/primitives/morph/index.tsx +0 -192
- package/primitives/motion/examples.mdx +0 -100
- package/primitives/motion/index.tsx +0 -160
- package/primitives/scroll-area/examples.mdx +0 -58
- package/primitives/scroll-area/index.tsx +0 -204
- package/primitives/separator/examples.mdx +0 -30
- package/primitives/separator/index.tsx +0 -53
- package/primitives/sizes/examples.mdx +0 -167
- package/primitives/sizes/index.tsx +0 -89
- package/primitives/skeleton/examples.mdx +0 -51
- package/primitives/skeleton/index.tsx +0 -72
- package/primitives/skeleton/skeleton.css +0 -15
- package/primitives/surface/examples.mdx +0 -173
- package/primitives/surface/index.tsx +0 -109
- package/primitives/surface/surface.css +0 -176
- /package/dist/shared/{components-3ey0hzpb.js → components-1v7rxytx.js} +0 -0
- /package/dist/shared/{components-jcnjay5g.js → components-ezxhrmer.js} +0 -0
|
@@ -1,510 +0,0 @@
|
|
|
1
|
-
// biome-ignore-all lint: vendored upstream code keeps its own patterns (see the header)
|
|
2
|
-
/*
|
|
3
|
-
* Ported from Fluid Functionalism — github.com/mickadesign/fluid-functionalism
|
|
4
|
-
* `registry/default/menu-item.tsx` @ b3587bdbd83fc66c2a6aae3817ffb856cb09260b
|
|
5
|
-
* MIT License © 2026 Micka Touillaud — fluidfunctionalism.com (notice: LICENSE.fluid-functionalism)
|
|
6
|
-
* Local modifications:
|
|
7
|
-
* - `"use client"` dropped; `framer-motion` → `motion/react`; `@/lib/*` and
|
|
8
|
-
* `@/hooks/*` imports rewritten to `../../../lib/*`.
|
|
9
|
-
* - Uncontrolled selection: when the surrounding panel owns the selection
|
|
10
|
-
* (`defaultCheckedIndex` / `defaultCheckedIndices` on Dropdown or
|
|
11
|
-
* Dropdown.Content, `selfManaged` in context), a row with no `checked` prop
|
|
12
|
-
* derives it from the panel and toggles the panel's state on activation —
|
|
13
|
-
* so a docs example can be interactive with no state of its own. An
|
|
14
|
-
* explicit `checked` still wins, and the controlled API is unchanged.
|
|
15
|
-
* - `sourceIndex`: the row's authored index, stamped by a filtering panel
|
|
16
|
-
* (`Dropdown.Search filter`) that re-indexed the visible rows. Selection is
|
|
17
|
-
* keyed on it, fluid hover on the re-indexed `index`.
|
|
18
|
-
* - Styling reads DS tokens (AGENTS.md styling): inline
|
|
19
|
-
* `fontVariationSettings` → `weight-*`; `duration-80|120|160` and
|
|
20
|
-
* tier-length JS durations → `duration-<tier>` / `spring.*`.
|
|
21
|
-
* - Inside a popup the row's activation travels as `onClick` in the render
|
|
22
|
-
* options, for the primitive, instead of sitting on the render element:
|
|
23
|
-
* Base UI's Enter/Space activation calls only the primitive's own `onClick`
|
|
24
|
-
* prop, so a keyboard pick used to close the menu without selecting.
|
|
25
|
-
* - Children-based rows (shadcn parity): `label` and `index` are optional.
|
|
26
|
-
* `children` stand in for the label (a string keeps the weight ghost; any
|
|
27
|
-
* other node is laid out as the row's own flex items, svgs sized to the
|
|
28
|
-
* ladder's icon); a row with no `index` takes its place in the panel's
|
|
29
|
-
* document order (`row-order.tsx`). `inset` pads a row to the icon column,
|
|
30
|
-
* `shortcut` adds a trailing `Dropdown.Shortcut`, `onSelect` receives a
|
|
31
|
-
* cancelable event (`preventDefault()` keeps the menu open), and the
|
|
32
|
-
* panel-owned selection only answers rows with an authored `index`.
|
|
33
|
-
* - `kind` / `value` (internal): `Dropdown.CheckboxItem` and
|
|
34
|
-
* `Dropdown.RadioItem` force the selection primitive and hand the radio its
|
|
35
|
-
* real value; their checked rows report to the panel (`reportChecked`) for
|
|
36
|
-
* the merged selection background.
|
|
37
|
-
* - `DropdownContextValue` gains `pin` (a submenu trigger keeps the panel's
|
|
38
|
-
* highlight while its submenu is open) and `reportChecked`.
|
|
39
|
-
* - `render` / `asChild` (`lib/slot.ts`): the row becomes the given element
|
|
40
|
-
* (a link, a router `Link`), keeping its own props and ref; its children are
|
|
41
|
-
* the row's content. In the inline panel Enter and Space click it once, so a
|
|
42
|
-
* link navigates.
|
|
43
|
-
* - `textValue`: the typeahead text of a row whose content is more than a
|
|
44
|
-
* string; it goes to the primitive's `label`.
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
import { AnimatePresence, motion } from 'motion/react'
|
|
48
|
-
import {
|
|
49
|
-
createContext,
|
|
50
|
-
createElement,
|
|
51
|
-
forwardRef,
|
|
52
|
-
type HTMLAttributes,
|
|
53
|
-
type ReactElement,
|
|
54
|
-
type ReactNode,
|
|
55
|
-
type Ref,
|
|
56
|
-
useContext,
|
|
57
|
-
useEffect,
|
|
58
|
-
useRef,
|
|
59
|
-
version,
|
|
60
|
-
} from 'react'
|
|
61
|
-
import type { IconComponent } from '../../../lib/icon-context'
|
|
62
|
-
import { useRowSlot } from '../../../lib/row-order'
|
|
63
|
-
import { shapeMap } from '../../../lib/shape-context'
|
|
64
|
-
import { useSize } from '../../../lib/size-context'
|
|
65
|
-
import { slotRender } from '../../../lib/slot'
|
|
66
|
-
import { spring } from '../../../lib/springs'
|
|
67
|
-
import { useRegisterFluidHoverItem } from '../../../lib/use-fluid-hover'
|
|
68
|
-
import { cn } from '../../../lib/utils'
|
|
69
|
-
|
|
70
|
-
// MenuItem is only used inside Dropdown, which opts out of the global pill
|
|
71
|
-
// shape — see index.tsx for the rationale.
|
|
72
|
-
const shape = shapeMap.rounded
|
|
73
|
-
|
|
74
|
-
const REACT_19 = parseInt(version, 10) >= 19
|
|
75
|
-
|
|
76
|
-
/** An element's ref: `props.ref` on React 19, where `element.ref` warns on access; `element.ref` before (where `props.ref` warns). */
|
|
77
|
-
function elementRef(element: ReactElement): Ref<HTMLElement> | undefined {
|
|
78
|
-
if (REACT_19) return (element.props as { ref?: Ref<HTMLElement> }).ref
|
|
79
|
-
return (element as ReactElement & { ref?: Ref<HTMLElement> }).ref
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// ---------------------------------------------------------------------------
|
|
83
|
-
// Dropdown context — the single shared context for every Dropdown build.
|
|
84
|
-
//
|
|
85
|
-
// It lives here rather than in the dropdown module so that (a) MenuItem stays
|
|
86
|
-
// primitive-free and self-contained, and (b) dropdowns built on different
|
|
87
|
-
// primitives (Radix, Base UI) can render side by side — each provides this
|
|
88
|
-
// same context object, so MenuItem resolves whichever provider actually
|
|
89
|
-
// wraps it. The dropdown module re-exports useDropdown from here, keeping
|
|
90
|
-
// its public API unchanged.
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
|
|
93
|
-
/** What MenuItem hands to the popup's primitive wrapper. `element` is the
|
|
94
|
-
* styled row div (visuals + fluid hover registration, no children); `children`
|
|
95
|
-
* is the row content (icon, label, check). The dropdown wraps them in its
|
|
96
|
-
* own Item / RadioItem primitive, so MenuItem itself stays primitive-free. */
|
|
97
|
-
export interface MenuItemRenderOptions {
|
|
98
|
-
/** Radio-style option (boolean `checked` on MenuItem) vs plain action item. */
|
|
99
|
-
radio: boolean
|
|
100
|
-
/** Checkbox-style option: a boolean `checked` inside a multiple-selection
|
|
101
|
-
* dropdown (`checkedIndices`). Takes precedence over `radio`. */
|
|
102
|
-
checkbox: boolean
|
|
103
|
-
/** The item's checked state (radio and checkbox items). */
|
|
104
|
-
checked?: boolean
|
|
105
|
-
/** The radio value: the item's index, or a `Dropdown.RadioItem`'s own value. */
|
|
106
|
-
value: unknown
|
|
107
|
-
disabled?: boolean
|
|
108
|
-
/** Typeahead text. Undefined for a children-based row: the primitive reads its text content. */
|
|
109
|
-
label?: string
|
|
110
|
-
closeOnClick: boolean
|
|
111
|
-
/** The row's activation. It goes on the primitive, not on `element`: Base
|
|
112
|
-
* UI's Enter/Space activation calls the primitive's own `onClick` prop and
|
|
113
|
-
* never sees a handler on the render element. */
|
|
114
|
-
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void
|
|
115
|
-
element: ReactElement
|
|
116
|
-
children: ReactNode
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export interface DropdownContextValue {
|
|
120
|
-
registerItem: (index: number, element: HTMLElement | null) => void
|
|
121
|
-
activeIndex: number | null
|
|
122
|
-
checkedIndex?: number
|
|
123
|
-
/** Multiple selection (`checkedIndices` on the dropdown): rows are
|
|
124
|
-
* checkbox items and activating one keeps the menu open by default. */
|
|
125
|
-
multiple?: boolean
|
|
126
|
-
checkedIndices?: number[]
|
|
127
|
-
/** True when items render inside a Menu popup (DropdownContent), where the
|
|
128
|
-
* primitive's Item / RadioItem own roles, roving highlight, typeahead,
|
|
129
|
-
* and activation. MenuItem switches its rendering accordingly. */
|
|
130
|
-
inMenu?: boolean
|
|
131
|
-
/** Popup-only: wraps a MenuItem's styled div in the dropdown's menu-item
|
|
132
|
-
* primitive. Absent in the inline Dropdown panel, where MenuItem renders
|
|
133
|
-
* its own ARIA menuitem div. */
|
|
134
|
-
renderMenuItem?: (opts: MenuItemRenderOptions) => ReactElement
|
|
135
|
-
/** Local addition. The panel owns its selection (`defaultCheckedIndex` /
|
|
136
|
-
* `defaultCheckedIndices`), so a row with no `checked` prop takes its
|
|
137
|
-
* checked state from `checkedIndex` / `checkedIndices` and toggles the
|
|
138
|
-
* panel on activation. */
|
|
139
|
-
selfManaged?: boolean
|
|
140
|
-
/** Local addition. Toggles the row at an AUTHORED index (see
|
|
141
|
-
* `sourceIndex`). Present with `selfManaged`. */
|
|
142
|
-
toggleIndex?: (sourceIndex: number) => void
|
|
143
|
-
/** Local addition. Keeps the highlight on a row while its submenu is open. */
|
|
144
|
-
pin?: (index: number, on: boolean) => void
|
|
145
|
-
/** Local addition. A value-checked row (`Dropdown.CheckboxItem`,
|
|
146
|
-
* `Dropdown.RadioItem`) reports itself for the merged selection background. */
|
|
147
|
-
reportChecked?: (index: number, on: boolean) => void
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export const DropdownContext = createContext<DropdownContextValue | null>(null)
|
|
151
|
-
|
|
152
|
-
export function useDropdown() {
|
|
153
|
-
const ctx = useContext(DropdownContext)
|
|
154
|
-
if (!ctx) throw new Error('useDropdown must be used within a Dropdown')
|
|
155
|
-
return ctx
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/** Null-safe context read for callers that render outside a provider. */
|
|
159
|
-
export function useDropdownMaybe() {
|
|
160
|
-
return useContext(DropdownContext)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/* `inset` swaps the row's padding for one that starts at the label column of
|
|
164
|
-
a row with an icon: the ladder's padding + icon + gap (8+16+8, 6+14+4). */
|
|
165
|
-
export const INSET_PX = { default: 'pl-8 pr-2', compact: 'pl-6 pr-1.5' } as const
|
|
166
|
-
/* Children-based rows lay their nodes out as the row's own flex items; a
|
|
167
|
-
bare svg among them takes the ladder's icon size. */
|
|
168
|
-
const FREEFORM_SVG = {
|
|
169
|
-
default: '[&>svg]:size-4 [&>svg]:shrink-0',
|
|
170
|
-
compact: '[&>svg]:size-3.5 [&>svg]:shrink-0',
|
|
171
|
-
} as const
|
|
172
|
-
|
|
173
|
-
interface MenuItemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {
|
|
174
|
-
/** Optional leading icon. When omitted, the row renders text-only with no
|
|
175
|
-
* reserved icon column. */
|
|
176
|
-
icon?: IconComponent
|
|
177
|
-
/** The row text, also its typeahead text and what a `Dropdown.Search filter` matches. Omit it to pass the row's content as `children`. */
|
|
178
|
-
label?: string
|
|
179
|
-
/** Position among the panel's rows, for the index-based selection (`checkedIndex`). Omitted, the row takes its place in document order. */
|
|
180
|
-
index?: number
|
|
181
|
-
/** The row's content when there is no `label`: text, or any nodes (an svg among them takes the icon size). */
|
|
182
|
-
children?: ReactNode
|
|
183
|
-
/** When a boolean, the item is a radio-style option (role="menuitemradio"
|
|
184
|
-
* with aria-checked). When undefined, it is a plain action item
|
|
185
|
-
* (role="menuitem"), unless the panel owns the selection — then the row
|
|
186
|
-
* reads its checked state off the panel and toggles it on activation. */
|
|
187
|
-
checked?: boolean
|
|
188
|
-
/** Called when the row is picked, by pointer or keyboard. Call `event.preventDefault()` to keep the menu open. */
|
|
189
|
-
onSelect?: (event: Event) => void
|
|
190
|
-
/** Dims the row; the pointer and the keyboard skip it. Defaults to `false`. */
|
|
191
|
-
disabled?: boolean
|
|
192
|
-
/** Popup-only (inside DropdownContent): whether activating the item closes
|
|
193
|
-
* the menu. Ignored in the inline Dropdown panel. Defaults to `true` (`false` in multiple selection). */
|
|
194
|
-
closeOnClick?: boolean
|
|
195
|
-
/** Indents the row to the label column of rows with an icon. Defaults to `false`. */
|
|
196
|
-
inset?: boolean
|
|
197
|
-
/** A keyboard shortcut shown muted at the row's end, e.g. `⌘K` (see Dropdown.Shortcut). */
|
|
198
|
-
shortcut?: ReactNode
|
|
199
|
-
/** Typeahead text for a row whose content is more than a string (an icon beside markup): the key a press matches while the menu is open. Defaults to `label`, else the row's text `children`. */
|
|
200
|
-
textValue?: string
|
|
201
|
-
/** The element that becomes the row, e.g. a link: `render={<a href="/docs" />}`. Its own props and ref are kept, the row's classes and handlers are added, and its children are the row's content. */
|
|
202
|
-
render?: ReactElement
|
|
203
|
-
/** Compose onto the single child instead of `render`: `<Dropdown.Item asChild><a href="/docs">Docs</a></Dropdown.Item>`. Defaults to `false`. */
|
|
204
|
-
asChild?: boolean
|
|
205
|
-
/** Internal: the row's authored index, stamped by a filtering panel that
|
|
206
|
-
* re-indexed the visible rows. Selection is keyed on it. */
|
|
207
|
-
sourceIndex?: number
|
|
208
|
-
/** Internal: the selection primitive a `Dropdown.CheckboxItem` / `Dropdown.RadioItem` forces. */
|
|
209
|
-
kind?: 'checkbox' | 'radio'
|
|
210
|
-
/** Internal: a `Dropdown.RadioItem`'s value. */
|
|
211
|
-
value?: unknown
|
|
212
|
-
/** Internal: keeps the panel's highlight on the row (a `Dropdown.SubTrigger` whose submenu is open). */
|
|
213
|
-
pinned?: boolean
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
interface DropdownShortcutProps extends HTMLAttributes<HTMLElement> {
|
|
217
|
-
/** The keys, e.g. `⇧⌘P`. */
|
|
218
|
-
children?: ReactNode
|
|
219
|
-
/** Extra classes. */
|
|
220
|
-
className?: string
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/** A muted caption at the end of a row: the row's keyboard shortcut. */
|
|
224
|
-
const DropdownShortcut = forwardRef<HTMLElement, DropdownShortcutProps>(({ className, ...props }, ref) => {
|
|
225
|
-
const compact = useSize().variant === 'compact'
|
|
226
|
-
return (
|
|
227
|
-
<kbd
|
|
228
|
-
ref={ref}
|
|
229
|
-
className={cn(
|
|
230
|
-
'ml-auto shrink-0 pl-4 font-sans text-muted-foreground',
|
|
231
|
-
compact ? 'text-caption-compact' : 'text-caption',
|
|
232
|
-
className,
|
|
233
|
-
)}
|
|
234
|
-
{...props}
|
|
235
|
-
/>
|
|
236
|
-
)
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
DropdownShortcut.displayName = 'DropdownShortcut'
|
|
240
|
-
|
|
241
|
-
const MenuItem = forwardRef<HTMLDivElement, MenuItemProps>(
|
|
242
|
-
(
|
|
243
|
-
{
|
|
244
|
-
icon: Icon,
|
|
245
|
-
label,
|
|
246
|
-
textValue,
|
|
247
|
-
render,
|
|
248
|
-
asChild,
|
|
249
|
-
index: indexProp,
|
|
250
|
-
children: childrenProp,
|
|
251
|
-
checked,
|
|
252
|
-
onSelect,
|
|
253
|
-
disabled,
|
|
254
|
-
closeOnClick,
|
|
255
|
-
inset,
|
|
256
|
-
shortcut,
|
|
257
|
-
sourceIndex,
|
|
258
|
-
kind,
|
|
259
|
-
value,
|
|
260
|
-
pinned,
|
|
261
|
-
className,
|
|
262
|
-
onClick,
|
|
263
|
-
...props
|
|
264
|
-
},
|
|
265
|
-
ref,
|
|
266
|
-
) => {
|
|
267
|
-
const internalRef = useRef<HTMLDivElement>(null)
|
|
268
|
-
const slot = slotRender(render, asChild, childrenProp)
|
|
269
|
-
// The slot element's own children are the row's content.
|
|
270
|
-
const children = slot ? (slot.props as { children?: ReactNode }).children : childrenProp
|
|
271
|
-
const hasMounted = useRef(false)
|
|
272
|
-
const {
|
|
273
|
-
registerItem,
|
|
274
|
-
activeIndex,
|
|
275
|
-
checkedIndex,
|
|
276
|
-
multiple,
|
|
277
|
-
checkedIndices,
|
|
278
|
-
renderMenuItem,
|
|
279
|
-
selfManaged,
|
|
280
|
-
toggleIndex,
|
|
281
|
-
reportChecked,
|
|
282
|
-
pin,
|
|
283
|
-
} = useDropdown()
|
|
284
|
-
const { index, firstRow } = useRowSlot(internalRef, indexProp)
|
|
285
|
-
// The panel's index-keyed selection answers only rows written with an index.
|
|
286
|
-
const authored = indexProp !== undefined
|
|
287
|
-
|
|
288
|
-
// Uncontrolled panels answer for rows that brought no `checked` of their
|
|
289
|
-
// own; a row that did keeps it.
|
|
290
|
-
const panelChecked = multiple ? (checkedIndices?.includes(indexProp ?? -1) ?? false) : checkedIndex === indexProp
|
|
291
|
-
const isChecked = checked ?? (selfManaged && authored ? panelChecked : undefined)
|
|
292
|
-
const isCheckbox = kind ? kind === 'checkbox' : !!multiple && typeof isChecked === 'boolean'
|
|
293
|
-
const isRadio = kind ? kind === 'radio' : !isCheckbox && typeof isChecked === 'boolean'
|
|
294
|
-
|
|
295
|
-
useRegisterFluidHoverItem(registerItem, index, internalRef)
|
|
296
|
-
|
|
297
|
-
useEffect(() => {
|
|
298
|
-
if (!kind || !isChecked || index === undefined || !reportChecked) return
|
|
299
|
-
reportChecked(index, true)
|
|
300
|
-
return () => reportChecked(index, false)
|
|
301
|
-
}, [kind, isChecked, index, reportChecked])
|
|
302
|
-
|
|
303
|
-
useEffect(() => {
|
|
304
|
-
if (!pinned || index === undefined || !pin) return
|
|
305
|
-
pin(index, true)
|
|
306
|
-
return () => pin(index, false)
|
|
307
|
-
}, [pinned, index, pin])
|
|
308
|
-
|
|
309
|
-
useEffect(() => {
|
|
310
|
-
hasMounted.current = true
|
|
311
|
-
}, [])
|
|
312
|
-
|
|
313
|
-
const isActive = index !== undefined && activeIndex === index
|
|
314
|
-
const skipAnimation = !hasMounted.current
|
|
315
|
-
const sizeClasses = useSize()
|
|
316
|
-
const text = label ?? (typeof children === 'string' ? children : undefined)
|
|
317
|
-
const freeform = label === undefined && text === undefined
|
|
318
|
-
const lit = isActive || isChecked
|
|
319
|
-
|
|
320
|
-
const slotRef = slot ? elementRef(slot) : undefined
|
|
321
|
-
const mergeRef = (node: HTMLDivElement | null) => {
|
|
322
|
-
;(internalRef as React.MutableRefObject<HTMLDivElement | null>).current = node
|
|
323
|
-
for (const target of [ref, slotRef]) {
|
|
324
|
-
if (typeof target === 'function') target(node)
|
|
325
|
-
else if (target) (target as React.MutableRefObject<HTMLDivElement | null>).current = node
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// The row element: a div, or the slot element with the row's props on top of its own.
|
|
330
|
-
// The caller's own props come last, as they always did.
|
|
331
|
-
const rowElement = (extra?: object) => {
|
|
332
|
-
const rowProps = {
|
|
333
|
-
ref: mergeRef,
|
|
334
|
-
'data-fluid-hover-index': index,
|
|
335
|
-
...(label !== undefined && { 'aria-label': label }),
|
|
336
|
-
...extra,
|
|
337
|
-
...props,
|
|
338
|
-
}
|
|
339
|
-
if (!slot) return <div {...rowProps} className={itemClassName} />
|
|
340
|
-
// Built without the slot's own children, which would win over the row's content in the primitive.
|
|
341
|
-
const { children: _content, ...slotProps } = slot.props as { children?: ReactNode; className?: string }
|
|
342
|
-
return createElement(slot.type, { ...slotProps, ...rowProps, className: cn(slotProps.className, itemClassName) })
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Selection is keyed on the authored index, which survives a filtering
|
|
346
|
-
// panel's re-indexing of the visible rows. Returns whether the consumer
|
|
347
|
-
// asked to keep the menu open.
|
|
348
|
-
const activate = () => {
|
|
349
|
-
const event = new Event('select', { cancelable: true })
|
|
350
|
-
onSelect?.(event)
|
|
351
|
-
if (selfManaged && authored && !kind) toggleIndex?.(sourceIndex ?? indexProp)
|
|
352
|
-
return event.defaultPrevented
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
const handleActivate = disabled
|
|
356
|
-
? undefined
|
|
357
|
-
: (e: React.MouseEvent<HTMLDivElement>) => {
|
|
358
|
-
onClick?.(e)
|
|
359
|
-
// Base UI's own close runs after this handler unless prevented.
|
|
360
|
-
if (activate()) (e as { preventBaseUIHandler?: () => void }).preventBaseUIHandler?.()
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const itemClassName = cn(
|
|
364
|
-
// Fixed height (was py-2 around a 19.5px line box ≈ 35.5px) so the
|
|
365
|
-
// text-box trim on the label doesn't shrink the row. shrink-0 because
|
|
366
|
-
// menu popups are max-height flex columns — without it a long list
|
|
367
|
-
// compresses rows to fit instead of scrolling.
|
|
368
|
-
`relative z-10 flex ${sizeClasses.control} shrink-0 items-center ${sizeClasses.gap} ${shape.item} ${inset ? INSET_PX[sizeClasses.variant] : sizeClasses.itemPx} cursor-pointer outline-none`,
|
|
369
|
-
freeform && [
|
|
370
|
-
sizeClasses.text,
|
|
371
|
-
FREEFORM_SVG[sizeClasses.variant],
|
|
372
|
-
'min-w-0 transition-[color,font-variation-settings] duration-fast',
|
|
373
|
-
lit ? 'text-foreground' : 'text-muted-foreground',
|
|
374
|
-
isChecked ? 'weight-semibold' : 'weight-normal',
|
|
375
|
-
],
|
|
376
|
-
disabled && 'opacity-50 pointer-events-none',
|
|
377
|
-
className,
|
|
378
|
-
)
|
|
379
|
-
|
|
380
|
-
const content = (
|
|
381
|
-
<>
|
|
382
|
-
{Icon && (
|
|
383
|
-
<span className="inline-grid">
|
|
384
|
-
<span className="col-start-1 row-start-1 invisible">
|
|
385
|
-
<Icon size={sizeClasses.icon} strokeWidth={2} />
|
|
386
|
-
</span>
|
|
387
|
-
<Icon
|
|
388
|
-
size={sizeClasses.icon}
|
|
389
|
-
strokeWidth={lit ? 2 : 1.5}
|
|
390
|
-
className={cn(
|
|
391
|
-
'col-start-1 row-start-1 transition-[color,stroke-width] duration-fast',
|
|
392
|
-
lit ? 'text-foreground' : 'text-muted-foreground',
|
|
393
|
-
)}
|
|
394
|
-
/>
|
|
395
|
-
</span>
|
|
396
|
-
)}
|
|
397
|
-
{text !== undefined && (
|
|
398
|
-
// Both stacked spans carry the text-box trim so the invisible bold
|
|
399
|
-
// sizer and the visible label keep identical boxes.
|
|
400
|
-
<span className={cn('inline-grid min-w-0 flex-1', sizeClasses.text)}>
|
|
401
|
-
<span
|
|
402
|
-
className="col-start-1 row-start-1 invisible truncate [text-box:trim-both_cap_alphabetic] weight-semibold"
|
|
403
|
-
aria-hidden="true"
|
|
404
|
-
>
|
|
405
|
-
{text}
|
|
406
|
-
</span>
|
|
407
|
-
<span
|
|
408
|
-
className={cn(
|
|
409
|
-
'col-start-1 row-start-1 truncate transition-[color,font-variation-settings] duration-fast [text-box:trim-both_cap_alphabetic]',
|
|
410
|
-
lit ? 'text-foreground' : 'text-muted-foreground',
|
|
411
|
-
isChecked ? 'weight-semibold' : 'weight-normal',
|
|
412
|
-
)}
|
|
413
|
-
>
|
|
414
|
-
{text}
|
|
415
|
-
</span>
|
|
416
|
-
</span>
|
|
417
|
-
)}
|
|
418
|
-
{label !== undefined || freeform ? children : null}
|
|
419
|
-
{shortcut != null && <DropdownShortcut>{shortcut}</DropdownShortcut>}
|
|
420
|
-
<AnimatePresence>
|
|
421
|
-
{isChecked && (
|
|
422
|
-
<motion.svg
|
|
423
|
-
key="check"
|
|
424
|
-
width={sizeClasses.icon}
|
|
425
|
-
height={sizeClasses.icon}
|
|
426
|
-
viewBox="0 0 24 24"
|
|
427
|
-
fill="none"
|
|
428
|
-
stroke="currentColor"
|
|
429
|
-
strokeWidth={2}
|
|
430
|
-
strokeLinecap="round"
|
|
431
|
-
strokeLinejoin="round"
|
|
432
|
-
className={cn('text-foreground shrink-0', freeform && shortcut == null && 'ml-auto')}
|
|
433
|
-
initial={{ opacity: 1 }}
|
|
434
|
-
animate={{ opacity: 1 }}
|
|
435
|
-
exit={{ opacity: 1 }}
|
|
436
|
-
>
|
|
437
|
-
<motion.path
|
|
438
|
-
d="M4 12L9 17L20 6"
|
|
439
|
-
initial={{ pathLength: skipAnimation ? 1 : 0 }}
|
|
440
|
-
animate={{
|
|
441
|
-
pathLength: 1,
|
|
442
|
-
transition: { duration: spring.fast.duration, ease: 'easeOut' },
|
|
443
|
-
}}
|
|
444
|
-
exit={{
|
|
445
|
-
pathLength: 0,
|
|
446
|
-
transition: { duration: 0.04, ease: 'easeIn' },
|
|
447
|
-
}}
|
|
448
|
-
/>
|
|
449
|
-
</motion.svg>
|
|
450
|
-
)}
|
|
451
|
-
</AnimatePresence>
|
|
452
|
-
</>
|
|
453
|
-
)
|
|
454
|
-
|
|
455
|
-
if (renderMenuItem) {
|
|
456
|
-
// Inside DropdownContent, the menu-item primitive (supplied by the
|
|
457
|
-
// surrounding DropdownContent through context) owns the role,
|
|
458
|
-
// aria-checked, tabIndex, roving highlight, typeahead, and Enter/Space/
|
|
459
|
-
// click activation (handleActivate rides on the primitive, whose
|
|
460
|
-
// keyboard activation calls it too). The styled div carries the Fluid
|
|
461
|
-
// Functionalism visuals and the fluid-hover registration; MenuItem
|
|
462
|
-
// itself imports no primitive.
|
|
463
|
-
return renderMenuItem({
|
|
464
|
-
radio: isRadio,
|
|
465
|
-
checkbox: isCheckbox,
|
|
466
|
-
checked: isChecked,
|
|
467
|
-
value: kind === 'radio' ? value : index,
|
|
468
|
-
disabled,
|
|
469
|
-
label: textValue ?? text,
|
|
470
|
-
// Toggling one of several stays open; picking one of one closes.
|
|
471
|
-
closeOnClick: closeOnClick ?? (kind ? kind === 'radio' : !multiple),
|
|
472
|
-
onClick: handleActivate,
|
|
473
|
-
element: rowElement(),
|
|
474
|
-
children: content,
|
|
475
|
-
})
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// The roving tab stop: the checked row, else the first one.
|
|
479
|
-
const tabStop = authored ? (checkedIndex ?? checkedIndices?.[0] ?? 0) : firstRow
|
|
480
|
-
const slotOnClick = (slot?.props as { onClick?: (e: React.MouseEvent<HTMLDivElement>) => void } | undefined)
|
|
481
|
-
?.onClick
|
|
482
|
-
return rowElement({
|
|
483
|
-
// Disabled items are never the roving tab stop.
|
|
484
|
-
tabIndex: !disabled && index === tabStop ? 0 : -1,
|
|
485
|
-
role: isCheckbox ? 'menuitemcheckbox' : isRadio ? 'menuitemradio' : 'menuitem',
|
|
486
|
-
'aria-checked': typeof isChecked === 'boolean' ? isChecked : undefined,
|
|
487
|
-
'aria-disabled': disabled || undefined,
|
|
488
|
-
onClick: (e: React.MouseEvent<HTMLDivElement>) => {
|
|
489
|
-
slotOnClick?.(e)
|
|
490
|
-
handleActivate?.(e)
|
|
491
|
-
},
|
|
492
|
-
onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => {
|
|
493
|
-
if (disabled) return
|
|
494
|
-
if (e.key === ' ' || e.key === 'Enter') {
|
|
495
|
-
e.preventDefault()
|
|
496
|
-
// A slot element is clicked once: a link navigates, its own handlers run.
|
|
497
|
-
if (slot) e.currentTarget.click()
|
|
498
|
-
else activate()
|
|
499
|
-
}
|
|
500
|
-
},
|
|
501
|
-
children: content,
|
|
502
|
-
})
|
|
503
|
-
},
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
MenuItem.displayName = 'MenuItem'
|
|
507
|
-
|
|
508
|
-
export type { DropdownShortcutProps, MenuItemProps }
|
|
509
|
-
export { DropdownShortcut, MenuItem }
|
|
510
|
-
export default MenuItem
|