@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,96 +0,0 @@
|
|
|
1
|
-
import Switch from './index'
|
|
2
|
-
import { Label } from '../input'
|
|
3
|
-
|
|
4
|
-
# Basics
|
|
5
|
-
|
|
6
|
-
## Basic
|
|
7
|
-
|
|
8
|
-
A labelled switch. Uncontrolled here — it keeps its own state; pass
|
|
9
|
-
`checked` and `onToggle` to control it.
|
|
10
|
-
|
|
11
|
-
<Switch label="Notifications" />
|
|
12
|
-
|
|
13
|
-
## Description
|
|
14
|
-
|
|
15
|
-
`description` adds a muted line under the label, and `trackSide="end"` pushes the track to the far edge, as in a settings row.
|
|
16
|
-
|
|
17
|
-
<Switch
|
|
18
|
-
className="w-80 max-w-full"
|
|
19
|
-
trackSide="end"
|
|
20
|
-
label="Auto-update"
|
|
21
|
-
description="Install updates in the background and restart when idle"
|
|
22
|
-
/>
|
|
23
|
-
|
|
24
|
-
## Bare
|
|
25
|
-
|
|
26
|
-
Without a `label` the switch is the track alone: point a `<label htmlFor>` at its `id`, or name it with `aria-label`. The thumb still drags.
|
|
27
|
-
|
|
28
|
-
<div className="flex flex-col gap-3">
|
|
29
|
-
<div className="flex items-center gap-3">
|
|
30
|
-
<Switch id="bare-wifi" defaultChecked />
|
|
31
|
-
<Label htmlFor="bare-wifi">Wi-Fi</Label>
|
|
32
|
-
</div>
|
|
33
|
-
<div className="flex items-center gap-4">
|
|
34
|
-
<Switch aria-label="Airplane mode" />
|
|
35
|
-
<Switch aria-label="Bluetooth" size="compact" defaultChecked />
|
|
36
|
-
<Switch aria-label="Hotspot" disabled />
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
## Compact
|
|
41
|
-
|
|
42
|
-
`size="compact"` shrinks the track, thumb and label one step down the
|
|
43
|
-
size ladder. `defaultChecked` starts it on.
|
|
44
|
-
|
|
45
|
-
<div className="flex flex-col">
|
|
46
|
-
<Switch size="compact" label="Auto-save" defaultChecked />
|
|
47
|
-
<Switch size="compact" label="Show hidden files" />
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
## Disabled
|
|
51
|
-
|
|
52
|
-
`disabled` dims the row and ignores pointer and keyboard input.
|
|
53
|
-
|
|
54
|
-
<Switch label="Disabled option" disabled />
|
|
55
|
-
|
|
56
|
-
# Group
|
|
57
|
-
|
|
58
|
-
`Switch.Group` frames switches as a settings list: each one becomes a row with its track at the far edge. Here beside a label column, as on a settings page; on a narrow page the label stacks above it.
|
|
59
|
-
|
|
60
|
-
<div className="@container w-full max-w-3xl">
|
|
61
|
-
<div className="grid gap-3 @xl:grid-cols-[10rem_1fr] @xl:gap-6">
|
|
62
|
-
<p id="automation" className="text-body weight-medium text-foreground [text-box:trim-both_cap_alphabetic] @xl:pt-4">
|
|
63
|
-
Automation
|
|
64
|
-
</p>
|
|
65
|
-
<Switch.Group aria-labelledby="automation">
|
|
66
|
-
<Switch
|
|
67
|
-
label="Remove Task OUT with old contracts"
|
|
68
|
-
description="When an old contract is removed automatically, its Task OUT is removed too"
|
|
69
|
-
/>
|
|
70
|
-
<Switch
|
|
71
|
-
label="Block billing until damage is inspected"
|
|
72
|
-
description="A contract can't be marked as billed while a damage inspection is required"
|
|
73
|
-
/>
|
|
74
|
-
</Switch.Group>
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
77
|
-
|
|
78
|
-
## Group states
|
|
79
|
-
|
|
80
|
-
Every switch in a group keeps its own state; a disabled row gets no highlight. Rows work without a description too.
|
|
81
|
-
|
|
82
|
-
<Switch.Group aria-label="Notifications" className="w-96 max-w-full">
|
|
83
|
-
<Switch label="Email" defaultChecked />
|
|
84
|
-
<Switch label="Push notifications" />
|
|
85
|
-
<Switch label="SMS" description="Not available in your region" disabled />
|
|
86
|
-
</Switch.Group>
|
|
87
|
-
|
|
88
|
-
## Compact group
|
|
89
|
-
|
|
90
|
-
`size` on the group pins every row to one step of the size ladder.
|
|
91
|
-
|
|
92
|
-
<Switch.Group size="compact" aria-label="Editor" className="w-80 max-w-full">
|
|
93
|
-
<Switch label="Auto-save" description="Save after every change" defaultChecked />
|
|
94
|
-
<Switch label="Format on save" />
|
|
95
|
-
<Switch label="Show hidden files" />
|
|
96
|
-
</Switch.Group>
|
|
@@ -1,504 +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/base/switch.tsx` @ b3587bdbd83fc66c2a6aae3817ffb856cb09260b
|
|
5
|
-
* MIT License © 2026 Micka Touillaud — fluidfunctionalism.com (notice: LICENSE.fluid-functionalism)
|
|
6
|
-
* Local modifications:
|
|
7
|
-
* - `"use client"` directive dropped (no RSC here).
|
|
8
|
-
* - `framer-motion` → `motion/react`; `@/lib/*` imports rewritten to relative
|
|
9
|
-
* `../../../lib/*` paths.
|
|
10
|
-
* - Uncontrolled support (local addition, Base UI style): `checked` and
|
|
11
|
-
* `onToggle` are optional; new `defaultChecked` seeds internal state and new
|
|
12
|
-
* `onCheckedChange(checked)` reports every change, via the shared
|
|
13
|
-
* `useControllableState`. With `checked` passed the component stays fully
|
|
14
|
-
* controlled and `onToggle` fires exactly as upstream.
|
|
15
|
-
* - Every in-body read of `checked` / `onToggle()` goes through the resolved
|
|
16
|
-
* state (`isChecked`) and a `toggle()` that flips it and calls `onToggle`.
|
|
17
|
-
* The Root's `onCheckedChange` is dropped: Base UI's keyboard and assistive
|
|
18
|
-
* activation re-click its hidden input, which already reaches the row's
|
|
19
|
-
* `onClick`, so keeping both toggled twice (a flip back, uncontrolled).
|
|
20
|
-
* - `SwitchProps` members carry the FF docs API-table descriptions (plus the
|
|
21
|
-
* new props), so modo's parser lists them.
|
|
22
|
-
* - TSDoc with the FF docs page's examples added above the component;
|
|
23
|
-
* `export default Switch` added.
|
|
24
|
-
* - Styling reads DS tokens (AGENTS.md styling): the hex focus-ring
|
|
25
|
-
* fallback → `ring-focus-ring` / `border-focus-ring`; literal colors →
|
|
26
|
-
* color tokens; `duration-80|120|160` and tier-length JS durations →
|
|
27
|
-
* `duration-<tier>` / `spring.*`.
|
|
28
|
-
* - The thumb is a `GooIndicator` (`lib/goo-indicator.tsx`, local) inside
|
|
29
|
-
* Base UI's Thumb: it stretches into a liquid drop as it travels. Its x is
|
|
30
|
-
* React state while dragging (the indicator snaps to it) instead of a
|
|
31
|
-
* motion value set per move.
|
|
32
|
-
* - `description` (a muted line under the label, wired as
|
|
33
|
-
* `aria-describedby`; the label then stays at full contrast and medium
|
|
34
|
-
* weight) and `trackSide` (`"end"` pushes the track to the far edge) are
|
|
35
|
-
* local additions, for settings rows.
|
|
36
|
-
* - `Switch.Group` (local addition): switches as a settings list in one
|
|
37
|
-
* outlined fieldset, after an outlined `Card.Group` (shared frame,
|
|
38
|
-
* hairlines dropped around the fluid hover highlight). A switch inside
|
|
39
|
-
* reads the group from context: track at the end, roomier padding, its
|
|
40
|
-
* position from `lib/row-index.tsx`.
|
|
41
|
-
* - Bare mode (local): `label` is optional and takes any node; without one
|
|
42
|
-
* (outside a group) the switch is the track alone, Base UI's Switch.Root,
|
|
43
|
-
* which then toggles itself (click, keyboard, a `<label htmlFor>` pointing
|
|
44
|
-
* at its `id`) through `onCheckedChange`, with the thumb drag on the track
|
|
45
|
-
* and a toggle that follows a drag swallowed. `name` / `value` /
|
|
46
|
-
* `required` reach Base UI's hidden input in both modes.
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
import { Switch as SwitchPrimitive } from '@base-ui/react/switch'
|
|
50
|
-
import type { Transition } from 'motion/react'
|
|
51
|
-
import {
|
|
52
|
-
Children,
|
|
53
|
-
createContext,
|
|
54
|
-
type ForwardRefExoticComponent,
|
|
55
|
-
forwardRef,
|
|
56
|
-
type HTMLAttributes,
|
|
57
|
-
isValidElement,
|
|
58
|
-
type ReactNode,
|
|
59
|
-
type RefAttributes,
|
|
60
|
-
useCallback,
|
|
61
|
-
useContext,
|
|
62
|
-
useId,
|
|
63
|
-
useRef,
|
|
64
|
-
useState,
|
|
65
|
-
} from 'react'
|
|
66
|
-
import { FluidHoverHighlight } from '../../../lib/fluid-hover-highlight'
|
|
67
|
-
import { GooIndicator } from '../../../lib/goo-indicator'
|
|
68
|
-
import { IndexedRows, useRowIndex } from '../../../lib/row-index'
|
|
69
|
-
import { useShape } from '../../../lib/shape-context'
|
|
70
|
-
import { type SizeVariant, useSize } from '../../../lib/size-context'
|
|
71
|
-
import { spring } from '../../../lib/springs'
|
|
72
|
-
import { useControllableState } from '../../../lib/use-controllable-state'
|
|
73
|
-
import { useFluidHover, useRegisterFluidHoverItem } from '../../../lib/use-fluid-hover'
|
|
74
|
-
import { cn } from '../../../lib/utils'
|
|
75
|
-
import { SizeProvider } from '../../../primitives/sizes'
|
|
76
|
-
|
|
77
|
-
interface SwitchProps extends HTMLAttributes<HTMLDivElement> {
|
|
78
|
-
/** Label displayed next to the switch, any node. Omit it, outside a group, for the bare track (see Bare): name it with `aria-label`, `aria-labelledby` or a `<label htmlFor>` pointing at its `id`. */
|
|
79
|
-
label?: ReactNode
|
|
80
|
-
/** Secondary text under the label: what turning the switch on does. With one, the label stays at full contrast. */
|
|
81
|
-
description?: ReactNode
|
|
82
|
-
/** The side of the label the track sits on; `"end"` pushes it to the row's far edge, as in a settings list (always, inside a `Switch.Group`). Defaults to `"start"`. */
|
|
83
|
-
trackSide?: 'start' | 'end'
|
|
84
|
-
/** Whether the switch is on (controlled). Omit it to let the switch keep its own state, seeded from `defaultChecked`. */
|
|
85
|
-
checked?: boolean
|
|
86
|
-
/** Whether the switch starts on when uncontrolled. Defaults to `false`. */
|
|
87
|
-
defaultChecked?: boolean
|
|
88
|
-
/** Called when the switch is toggled. */
|
|
89
|
-
onToggle?: () => void
|
|
90
|
-
/** Called with the new state whenever the switch is toggled, controlled or not. */
|
|
91
|
-
onCheckedChange?: (checked: boolean) => void
|
|
92
|
-
/** Disables the switch. Defaults to `false`. */
|
|
93
|
-
disabled?: boolean
|
|
94
|
-
/** Form field name: a hidden checkbox input submits `value` while on. */
|
|
95
|
-
name?: string
|
|
96
|
-
/** Value submitted with `name` while on. Defaults to `"on"`. */
|
|
97
|
-
value?: string
|
|
98
|
-
/** Marks the hidden form input required. Defaults to `false`. */
|
|
99
|
-
required?: boolean
|
|
100
|
-
/** Transition for the thumb's slide and hover/press stretch. Defaults to the `spring.moderate` motion token. */
|
|
101
|
-
thumbTransition?: Transition
|
|
102
|
-
/** Pins the switch to one step of the size ladder (see Sizes). Defaults to the surrounding SizeProvider, else `"default"`. */
|
|
103
|
-
size?: SizeVariant
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
interface SwitchGroupContextValue {
|
|
107
|
-
registerItem: (index: number, element: HTMLElement | null) => void
|
|
108
|
-
activeIndex: number | null
|
|
109
|
-
count: number
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const SwitchGroupContext = createContext<SwitchGroupContextValue | null>(null)
|
|
113
|
-
|
|
114
|
-
type SwitchComponent = ForwardRefExoticComponent<SwitchProps & RefAttributes<HTMLDivElement>> & {
|
|
115
|
-
Group: typeof SwitchGroup
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Track/thumb geometry per ladder step. The hover pill-extend and press
|
|
119
|
-
// squash scale down with the thumb so the compact switch keeps the same feel.
|
|
120
|
-
const METRICS = {
|
|
121
|
-
default: {
|
|
122
|
-
trackWidth: 34,
|
|
123
|
-
trackHeight: 20,
|
|
124
|
-
thumbSize: 16,
|
|
125
|
-
pillExtend: 2,
|
|
126
|
-
pressExtend: 4,
|
|
127
|
-
pressShrink: 4,
|
|
128
|
-
},
|
|
129
|
-
compact: {
|
|
130
|
-
trackWidth: 28,
|
|
131
|
-
trackHeight: 16,
|
|
132
|
-
thumbSize: 12,
|
|
133
|
-
pillExtend: 2,
|
|
134
|
-
pressExtend: 3,
|
|
135
|
-
pressShrink: 3,
|
|
136
|
-
},
|
|
137
|
-
} as const
|
|
138
|
-
|
|
139
|
-
const THUMB_OFFSET = 2
|
|
140
|
-
const DRAG_DEAD_ZONE = 2
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Toggle switch with animated thumb and label.
|
|
144
|
-
*
|
|
145
|
-
* The whole row — track and label — is the hit target: click anywhere to
|
|
146
|
-
* toggle, or grab the thumb and drag it across the midpoint. The thumb
|
|
147
|
-
* stretches into a pill on hover, squashes on press and melts across the
|
|
148
|
-
* track like a drop when it toggles (see Morph), springing with the motion
|
|
149
|
-
* tokens; a Base UI switch underneath carries the role, keyboard
|
|
150
|
-
* toggling (Space/Enter) and focus ring. The label brightens when the switch
|
|
151
|
-
* is on.
|
|
152
|
-
*
|
|
153
|
-
* Works controlled (`checked` + `onToggle`, exactly as upstream) or
|
|
154
|
-
* uncontrolled (`defaultChecked`, with `onCheckedChange` reporting each
|
|
155
|
-
* change). `size` pins it to one step of the size ladder; otherwise it
|
|
156
|
-
* follows the surrounding SizeProvider. `description` adds a muted line under
|
|
157
|
-
* the label and `trackSide="end"` moves the track to the row's far edge.
|
|
158
|
-
*
|
|
159
|
-
* Statics:
|
|
160
|
-
* - `Switch.Group` — switches as a settings list in one outlined frame: each
|
|
161
|
-
* `Switch` inside becomes a row with its track at the far edge, hairlines
|
|
162
|
-
* divide the rows and a fluid hover highlight melts between them, dropping
|
|
163
|
-
* the hairlines it touches (as in an outlined Card.Group); a disabled row
|
|
164
|
-
* gets no highlight. Every switch keeps its own state. `size` pins every
|
|
165
|
-
* row; name the group with `aria-label` or `aria-labelledby`.
|
|
166
|
-
*
|
|
167
|
-
* @example {@include ./examples.mdx}
|
|
168
|
-
*/
|
|
169
|
-
const Switch = forwardRef<HTMLDivElement, SwitchProps>(
|
|
170
|
-
(
|
|
171
|
-
{
|
|
172
|
-
label,
|
|
173
|
-
description,
|
|
174
|
-
trackSide = 'start',
|
|
175
|
-
checked,
|
|
176
|
-
defaultChecked = false,
|
|
177
|
-
onToggle,
|
|
178
|
-
onCheckedChange,
|
|
179
|
-
disabled = false,
|
|
180
|
-
name,
|
|
181
|
-
value,
|
|
182
|
-
required = false,
|
|
183
|
-
thumbTransition,
|
|
184
|
-
size,
|
|
185
|
-
className,
|
|
186
|
-
...props
|
|
187
|
-
},
|
|
188
|
-
ref,
|
|
189
|
-
) => {
|
|
190
|
-
const [isChecked, setChecked] = useControllableState(checked, defaultChecked, onCheckedChange)
|
|
191
|
-
const toggle = useCallback(() => {
|
|
192
|
-
setChecked(prev => !prev)
|
|
193
|
-
onToggle?.()
|
|
194
|
-
}, [setChecked, onToggle])
|
|
195
|
-
const labelId = useId()
|
|
196
|
-
const descriptionId = useId()
|
|
197
|
-
const group = useContext(SwitchGroupContext)
|
|
198
|
-
const index = useRowIndex()
|
|
199
|
-
const rowRef = useRef<HTMLDivElement | null>(null)
|
|
200
|
-
// A disabled row takes no clicks, so the group's highlight never lands on it.
|
|
201
|
-
useRegisterFluidHoverItem(disabled ? undefined : group?.registerItem, index, rowRef)
|
|
202
|
-
const end = trackSide === 'end' || !!group
|
|
203
|
-
// In a group: a hairline toward the next row, dropped where it would cut the highlight.
|
|
204
|
-
const divider = !!group && index < group.count - 1 && group.activeIndex !== index && group.activeIndex !== index + 1
|
|
205
|
-
const [hovered, setHovered] = useState(false)
|
|
206
|
-
const [pressed, setPressed] = useState(false)
|
|
207
|
-
const sizeClasses = useSize(size)
|
|
208
|
-
const m = METRICS[sizeClasses.variant]
|
|
209
|
-
const thumbTravel = m.trackWidth - m.thumbSize - THUMB_OFFSET * 2
|
|
210
|
-
|
|
211
|
-
const dragging = useRef(false)
|
|
212
|
-
const didDrag = useRef(false)
|
|
213
|
-
const pointerStart = useRef<{
|
|
214
|
-
clientX: number
|
|
215
|
-
originX: number
|
|
216
|
-
} | null>(null)
|
|
217
|
-
// Local: the dragged thumb's x, mirrored in a ref for the pointer handlers.
|
|
218
|
-
const [dragX, setDragXState] = useState<number | null>(null)
|
|
219
|
-
const dragXRef = useRef<number | null>(null)
|
|
220
|
-
const setDragX = useCallback((x: number | null) => {
|
|
221
|
-
dragXRef.current = x
|
|
222
|
-
setDragXState(x)
|
|
223
|
-
}, [])
|
|
224
|
-
|
|
225
|
-
const thumbWidth = pressed ? m.thumbSize + m.pressExtend : hovered ? m.thumbSize + m.pillExtend : m.thumbSize
|
|
226
|
-
const thumbHeight = pressed ? m.thumbSize - m.pressShrink : m.thumbSize
|
|
227
|
-
const thumbY = pressed ? THUMB_OFFSET + m.pressShrink / 2 : THUMB_OFFSET
|
|
228
|
-
const extraWidth = thumbWidth - m.thumbSize
|
|
229
|
-
const thumbX = isChecked ? THUMB_OFFSET + thumbTravel - extraWidth : THUMB_OFFSET
|
|
230
|
-
const thumb = { left: dragX ?? thumbX, top: thumbY, width: thumbWidth, height: thumbHeight }
|
|
231
|
-
|
|
232
|
-
const handlePointerDown = useCallback(
|
|
233
|
-
(e: React.PointerEvent<HTMLDivElement>) => {
|
|
234
|
-
if (disabled) return
|
|
235
|
-
if (e.pointerType === 'mouse' && e.button !== 0) return
|
|
236
|
-
setPressed(true)
|
|
237
|
-
dragging.current = false
|
|
238
|
-
didDrag.current = false
|
|
239
|
-
pointerStart.current = {
|
|
240
|
-
clientX: e.clientX,
|
|
241
|
-
// Where the pressed thumb rests.
|
|
242
|
-
originX: isChecked ? THUMB_OFFSET + thumbTravel - m.pressExtend : THUMB_OFFSET,
|
|
243
|
-
}
|
|
244
|
-
;(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId)
|
|
245
|
-
},
|
|
246
|
-
[disabled, isChecked, thumbTravel, m],
|
|
247
|
-
)
|
|
248
|
-
|
|
249
|
-
const handlePointerMove = useCallback(
|
|
250
|
-
(e: React.PointerEvent<HTMLDivElement>) => {
|
|
251
|
-
if (!pointerStart.current) return
|
|
252
|
-
const delta = e.clientX - pointerStart.current.clientX
|
|
253
|
-
|
|
254
|
-
if (!dragging.current) {
|
|
255
|
-
if (Math.abs(delta) < DRAG_DEAD_ZONE) return
|
|
256
|
-
dragging.current = true
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const dragMin = THUMB_OFFSET
|
|
260
|
-
const pressedThumbWidth = m.thumbSize + m.pressExtend
|
|
261
|
-
const dragMax = m.trackWidth - THUMB_OFFSET - pressedThumbWidth
|
|
262
|
-
const rawX = pointerStart.current.originX + delta
|
|
263
|
-
setDragX(Math.max(dragMin, Math.min(dragMax, rawX)))
|
|
264
|
-
},
|
|
265
|
-
[setDragX, m],
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
const handlePointerUp = useCallback(() => {
|
|
269
|
-
if (!pointerStart.current) return
|
|
270
|
-
setPressed(false)
|
|
271
|
-
|
|
272
|
-
if (dragging.current) {
|
|
273
|
-
didDrag.current = true
|
|
274
|
-
dragging.current = false
|
|
275
|
-
|
|
276
|
-
const currentX = dragXRef.current ?? pointerStart.current.originX
|
|
277
|
-
const dragMin = THUMB_OFFSET
|
|
278
|
-
const pressedThumbWidth = m.thumbSize + m.pressExtend
|
|
279
|
-
const dragMax = m.trackWidth - THUMB_OFFSET - pressedThumbWidth
|
|
280
|
-
const midpoint = (dragMin + dragMax) / 2
|
|
281
|
-
|
|
282
|
-
const shouldBeOn = currentX > midpoint
|
|
283
|
-
|
|
284
|
-
if (shouldBeOn !== isChecked) toggle()
|
|
285
|
-
// Let go: the thumb springs from where it was dropped to its rest.
|
|
286
|
-
setDragX(null)
|
|
287
|
-
|
|
288
|
-
requestAnimationFrame(() => {
|
|
289
|
-
didDrag.current = false
|
|
290
|
-
})
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
pointerStart.current = null
|
|
294
|
-
}, [isChecked, toggle, setDragX, m])
|
|
295
|
-
|
|
296
|
-
const handlePointerCancel = useCallback(() => {
|
|
297
|
-
if (!pointerStart.current) return
|
|
298
|
-
setPressed(false)
|
|
299
|
-
|
|
300
|
-
if (dragging.current) {
|
|
301
|
-
dragging.current = false
|
|
302
|
-
setDragX(null)
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
pointerStart.current = null
|
|
306
|
-
}, [setDragX])
|
|
307
|
-
|
|
308
|
-
const trackClass = cn(
|
|
309
|
-
'relative shrink-0 rounded-full outline-none cursor-pointer',
|
|
310
|
-
'transition-colors duration-fast',
|
|
311
|
-
'focus-visible:ring-1 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
|
|
312
|
-
isChecked ? (hovered ? 'bg-brand-hover' : 'bg-brand') : hovered ? 'bg-accent-hover' : 'bg-accent',
|
|
313
|
-
)
|
|
314
|
-
const thumbElement = (
|
|
315
|
-
<SwitchPrimitive.Thumb className="pointer-events-none absolute inset-0">
|
|
316
|
-
<GooIndicator
|
|
317
|
-
rect={thumb}
|
|
318
|
-
className="rounded-full bg-thumb"
|
|
319
|
-
shadow="shadow-thumb"
|
|
320
|
-
transition={dragX === null ? (thumbTransition ?? spring.moderate) : false}
|
|
321
|
-
/>
|
|
322
|
-
</SwitchPrimitive.Thumb>
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
// Bare: no label and no group — the track alone is the control, and Base
|
|
326
|
-
// UI's own activation (click, keyboard, a label's htmlFor) toggles it.
|
|
327
|
-
if (label === undefined && !group) {
|
|
328
|
-
return (
|
|
329
|
-
<SwitchPrimitive.Root
|
|
330
|
-
ref={node => {
|
|
331
|
-
rowRef.current = node as HTMLDivElement | null
|
|
332
|
-
if (typeof ref === 'function') ref(node as HTMLDivElement | null)
|
|
333
|
-
else if (ref) ref.current = node as HTMLDivElement | null
|
|
334
|
-
}}
|
|
335
|
-
checked={isChecked}
|
|
336
|
-
onCheckedChange={() => {
|
|
337
|
-
// The drag already toggled on release; its click must not toggle back.
|
|
338
|
-
if (didDrag.current) return
|
|
339
|
-
toggle()
|
|
340
|
-
}}
|
|
341
|
-
disabled={disabled}
|
|
342
|
-
name={name}
|
|
343
|
-
value={value}
|
|
344
|
-
required={required}
|
|
345
|
-
onPointerEnter={e => {
|
|
346
|
-
if (e.pointerType === 'mouse') setHovered(true)
|
|
347
|
-
}}
|
|
348
|
-
onPointerLeave={() => setHovered(false)}
|
|
349
|
-
onPointerDown={handlePointerDown}
|
|
350
|
-
onPointerMove={handlePointerMove}
|
|
351
|
-
onPointerUp={handlePointerUp}
|
|
352
|
-
onPointerCancel={handlePointerCancel}
|
|
353
|
-
className={cn(trackClass, 'touch-none', disabled && 'opacity-50 pointer-events-none', className)}
|
|
354
|
-
style={{
|
|
355
|
-
width: m.trackWidth,
|
|
356
|
-
height: m.trackHeight,
|
|
357
|
-
}}
|
|
358
|
-
// The root's handlers are typed for Base UI's span.
|
|
359
|
-
{...(props as HTMLAttributes<HTMLSpanElement>)}
|
|
360
|
-
>
|
|
361
|
-
{thumbElement}
|
|
362
|
-
</SwitchPrimitive.Root>
|
|
363
|
-
)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
return (
|
|
367
|
-
<div
|
|
368
|
-
ref={node => {
|
|
369
|
-
rowRef.current = node
|
|
370
|
-
if (typeof ref === 'function') ref(node)
|
|
371
|
-
else if (ref) ref.current = node
|
|
372
|
-
}}
|
|
373
|
-
className={cn(
|
|
374
|
-
'relative z-10 flex items-center cursor-pointer select-none touch-none',
|
|
375
|
-
sizeClasses.gap,
|
|
376
|
-
sizeClasses.px,
|
|
377
|
-
sizeClasses.variant === 'compact' ? 'py-1' : 'py-2',
|
|
378
|
-
group && (sizeClasses.variant === 'compact' ? 'px-3 py-2.5' : 'px-4 py-3.5'),
|
|
379
|
-
disabled && 'opacity-50 pointer-events-none',
|
|
380
|
-
className,
|
|
381
|
-
)}
|
|
382
|
-
onPointerEnter={e => {
|
|
383
|
-
if (e.pointerType === 'mouse') setHovered(true)
|
|
384
|
-
}}
|
|
385
|
-
onPointerLeave={() => setHovered(false)}
|
|
386
|
-
onPointerDown={handlePointerDown}
|
|
387
|
-
onPointerMove={handlePointerMove}
|
|
388
|
-
onPointerUp={handlePointerUp}
|
|
389
|
-
onPointerCancel={handlePointerCancel}
|
|
390
|
-
onClick={() => {
|
|
391
|
-
if (disabled || didDrag.current) return
|
|
392
|
-
toggle()
|
|
393
|
-
}}
|
|
394
|
-
{...props}
|
|
395
|
-
>
|
|
396
|
-
{/* Switch */}
|
|
397
|
-
<SwitchPrimitive.Root
|
|
398
|
-
checked={isChecked}
|
|
399
|
-
aria-labelledby={label === undefined ? undefined : labelId}
|
|
400
|
-
aria-describedby={description ? descriptionId : undefined}
|
|
401
|
-
disabled={disabled}
|
|
402
|
-
name={name}
|
|
403
|
-
value={value}
|
|
404
|
-
required={required}
|
|
405
|
-
tabIndex={0}
|
|
406
|
-
className={cn(trackClass, end && 'order-last')}
|
|
407
|
-
style={{
|
|
408
|
-
width: m.trackWidth,
|
|
409
|
-
height: m.trackHeight,
|
|
410
|
-
}}
|
|
411
|
-
// Base UI re-dispatches this click on its hidden input, which bubbles to the row and toggles it: stop the original so a press toggles once.
|
|
412
|
-
onClick={e => e.stopPropagation()}
|
|
413
|
-
>
|
|
414
|
-
{thumbElement}
|
|
415
|
-
</SwitchPrimitive.Root>
|
|
416
|
-
|
|
417
|
-
{/* Label */}
|
|
418
|
-
<span className={cn('flex min-w-0 flex-col gap-1', end && 'flex-1')}>
|
|
419
|
-
<span
|
|
420
|
-
id={labelId}
|
|
421
|
-
className={cn(
|
|
422
|
-
// text-box trim recenters the letterforms against the track; the
|
|
423
|
-
// track is taller than the label, so layout doesn't change.
|
|
424
|
-
'[text-box:trim-both_cap_alphabetic] transition-[color] duration-fast',
|
|
425
|
-
sizeClasses.text,
|
|
426
|
-
description ? 'text-foreground weight-medium' : isChecked ? 'text-foreground' : 'text-muted-foreground',
|
|
427
|
-
)}
|
|
428
|
-
>
|
|
429
|
-
{label}
|
|
430
|
-
</span>
|
|
431
|
-
{description && (
|
|
432
|
-
<span
|
|
433
|
-
id={descriptionId}
|
|
434
|
-
className={cn(
|
|
435
|
-
'leading-relaxed text-muted-foreground',
|
|
436
|
-
sizeClasses.variant === 'compact' ? 'text-caption-compact' : 'text-caption',
|
|
437
|
-
)}
|
|
438
|
-
>
|
|
439
|
-
{description}
|
|
440
|
-
</span>
|
|
441
|
-
)}
|
|
442
|
-
</span>
|
|
443
|
-
|
|
444
|
-
{divider && <span aria-hidden className="pointer-events-none absolute inset-x-0 bottom-0 h-px bg-border/60" />}
|
|
445
|
-
</div>
|
|
446
|
-
)
|
|
447
|
-
},
|
|
448
|
-
) as SwitchComponent
|
|
449
|
-
|
|
450
|
-
Switch.displayName = 'Switch'
|
|
451
|
-
|
|
452
|
-
interface SwitchGroupProps extends HTMLAttributes<HTMLFieldSetElement> {
|
|
453
|
-
/** `Switch` rows. */
|
|
454
|
-
children: ReactNode
|
|
455
|
-
/** Pins every row to one step of the size ladder (see Sizes). Defaults to the surrounding SizeProvider. */
|
|
456
|
-
size?: SizeVariant
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// `Switch.Group`: the frame, hairlines and fluid hover around switch rows.
|
|
460
|
-
const SwitchGroup = forwardRef<HTMLFieldSetElement, SwitchGroupProps>(
|
|
461
|
-
({ children, size, className, ...props }, ref) => {
|
|
462
|
-
const containerRef = useRef<HTMLFieldSetElement | null>(null)
|
|
463
|
-
const hover = useFluidHover(containerRef, { gapClick: false })
|
|
464
|
-
const shape = useShape()
|
|
465
|
-
const count = Children.toArray(children).filter(isValidElement).length
|
|
466
|
-
|
|
467
|
-
const group = (
|
|
468
|
-
<SwitchGroupContext.Provider value={{ registerItem: hover.registerItem, activeIndex: hover.activeIndex, count }}>
|
|
469
|
-
<fieldset
|
|
470
|
-
ref={node => {
|
|
471
|
-
containerRef.current = node
|
|
472
|
-
if (typeof ref === 'function') ref(node)
|
|
473
|
-
else if (ref) ref.current = node
|
|
474
|
-
}}
|
|
475
|
-
onMouseEnter={hover.handlers.onMouseEnter}
|
|
476
|
-
onMouseMove={hover.handlers.onMouseMove}
|
|
477
|
-
onMouseLeave={hover.handlers.onMouseLeave}
|
|
478
|
-
onClick={hover.handlers.onClick}
|
|
479
|
-
className={cn(
|
|
480
|
-
'relative flex min-w-0 flex-col overflow-hidden border border-border/60 select-none',
|
|
481
|
-
shape.container,
|
|
482
|
-
className,
|
|
483
|
-
)}
|
|
484
|
-
{...props}
|
|
485
|
-
>
|
|
486
|
-
<FluidHoverHighlight hover={hover} className={cn('z-0', shape.container)} />
|
|
487
|
-
<IndexedRows>{children}</IndexedRows>
|
|
488
|
-
</fieldset>
|
|
489
|
-
</SwitchGroupContext.Provider>
|
|
490
|
-
)
|
|
491
|
-
|
|
492
|
-
// A size prop pins every row in the group to one ladder step.
|
|
493
|
-
return size ? <SizeProvider size={size}>{group}</SizeProvider> : group
|
|
494
|
-
},
|
|
495
|
-
)
|
|
496
|
-
|
|
497
|
-
SwitchGroup.displayName = 'SwitchGroup'
|
|
498
|
-
|
|
499
|
-
Object.assign(Switch, { Group: SwitchGroup })
|
|
500
|
-
|
|
501
|
-
export type { SwitchGroupProps, SwitchProps }
|
|
502
|
-
export { Switch, SwitchGroup }
|
|
503
|
-
|
|
504
|
-
export default Switch
|