@justanarthur/modo-ui 0.6.0-canary.8 → 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-4y816hwp.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-t2a3qmy9.js → components-1z6tdadk.js} +24 -40
- package/dist/shared/{components-qs4rkqsj.js → components-27nnvrwe.js} +14 -15
- package/dist/shared/{components-av5t26rc.js → components-2dxkv6zm.js} +7 -8
- package/dist/shared/{components-wqrvqq5p.js → components-2ecg8svx.js} +152 -234
- package/dist/shared/{components-3ydr2fqe.js → components-2ph6t61s.js} +34 -37
- package/dist/shared/{components-6gk118w3.js → components-39jq9va1.js} +24 -29
- package/dist/shared/components-3ky44908.js +9 -0
- package/dist/shared/{components-y1qvbawa.js → components-3mkepka5.js} +25 -28
- package/dist/shared/{components-xqszvkj4.js → components-4700p9kz.js} +22 -24
- package/dist/shared/{components-yhgq0qxx.js → components-59efxjd9.js} +12 -13
- package/dist/shared/{components-9j9abkct.js → components-5vgpnxgy.js} +27 -51
- package/dist/shared/{components-8tt3xbb5.js → components-5xc2j8jz.js} +18 -19
- package/dist/shared/{components-jymmaevv.js → components-6p8tfcd6.js} +29 -57
- package/dist/shared/{components-4nck8acq.js → components-7r3etddy.js} +54 -19
- package/dist/shared/{components-skfd7kff.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-vkwq2k96.js → components-b3c5et5b.js} +38 -49
- package/dist/shared/{components-rrbpmfx4.js → components-c6s6b43g.js} +2 -3
- package/dist/shared/{components-pw06rbxq.js → components-chacnk61.js} +19 -19
- package/dist/shared/{components-71nbt03m.js → components-cv16mryv.js} +7 -26
- package/dist/shared/{components-eqze3y30.js → components-d6xtjht3.js} +30 -35
- package/dist/shared/{components-5y5shqfd.js → components-dk0gjr5a.js} +18 -19
- package/dist/shared/{components-khspp26b.js → components-fzrq6tr3.js} +34 -37
- package/dist/shared/{components-km7fhgbk.js → components-gc5vtq2f.js} +30 -66
- package/dist/shared/components-gf5s6ap9.js +42 -0
- package/dist/shared/{components-qqcmtrbv.js → components-gz8zf3ec.js} +55 -56
- package/dist/shared/{components-mattt5jp.js → components-h2ajmhwn.js} +35 -107
- package/dist/shared/{components-awra5sff.js → components-hqeq3w9q.js} +16 -24
- package/dist/shared/{components-5tzhqbcw.js → components-hw9yk32z.js} +24 -36
- package/dist/shared/components-hyq23phv.js +310 -0
- package/dist/shared/{components-8mt5bsv6.js → components-jbbmdr74.js} +22 -41
- package/dist/shared/{components-dcc02hs2.js → components-jjw69c4c.js} +4 -7
- package/dist/shared/{components-2syq4mwc.js → components-jthe1pwb.js} +420 -139
- package/dist/shared/{components-r7q1zm7r.js → components-jwst3vtj.js} +76 -224
- package/dist/shared/{components-qdm3yh26.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-6b0zb8z3.js → components-mjthm1kf.js} +9 -13
- package/dist/shared/{components-2c64r8c9.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-dyae0y7h.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-8rb25gbe.js → components-rr7a6ja9.js} +27 -59
- package/dist/shared/{components-5012r6gr.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-w0xq6q9k.js → components-w1r67ag9.js} +149 -294
- package/dist/shared/{components-z0bqtvcp.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-5sxjeh6h.js → components-y9y0g8er.js} +28 -52
- package/dist/shared/components-ypp01w3p.js +986 -0
- package/dist/shared/{components-t50hrswb.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-124epb7f.js +0 -53
- package/dist/shared/components-1kab3j44.js +0 -337
- package/dist/shared/components-26snnbs9.js +0 -322
- 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-7zkhz3r8.js +0 -399
- package/dist/shared/components-8v644a0s.js +0 -298
- package/dist/shared/components-a4evvq8h.js +0 -271
- 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-c9yr4ed1.js +0 -44
- package/dist/shared/components-cwg1d0w6.js +0 -254
- 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-ej4r7wmj.js +0 -482
- package/dist/shared/components-f7h57m6t.js +0 -59
- package/dist/shared/components-fejdzvqc.js +0 -448
- 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-mpa2y6x8.js +0 -277
- package/dist/shared/components-mrbaxt8q.js +0 -62
- package/dist/shared/components-pt5ftm4p.js +0 -38
- package/dist/shared/components-rpw4md2b.js +0 -179
- package/dist/shared/components-rtadhd9j.js +0 -64
- package/dist/shared/components-tz4gaf1v.js +0 -23
- package/dist/shared/components-wbbckbw8.js +0 -34
- 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/shared/components-z6dfqtyt.js +0 -1545
- 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 -557
- 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,76 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Local addition (not part of Fluid Functionalism): the Craft page, a docs
|
|
3
|
-
* stage in the spirit of fluidfunctionalism.com/docs/skill's before/after
|
|
4
|
-
* pairs. Each comparison puts the naive version (`./demos.tsx`, rules broken
|
|
5
|
-
* on purpose) next to the system's own items.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { ReactNode } from 'react'
|
|
9
|
-
import Badge from '../../components/badge'
|
|
10
|
-
import { useShape } from '../../lib/shape-context'
|
|
11
|
-
import { cn } from '../../lib/utils'
|
|
12
|
-
|
|
13
|
-
interface PaneProps {
|
|
14
|
-
verdict: 'bad' | 'good'
|
|
15
|
-
note?: string
|
|
16
|
-
children: ReactNode
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function Pane({ verdict, note, children }: PaneProps) {
|
|
20
|
-
const shape = useShape()
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
// A subgrid, so both panes share the stage and caption rows and their stages line up.
|
|
24
|
-
<figure className={cn('row-span-2 m-0 grid min-w-0 grid-rows-subgrid gap-0 ring-1 ring-border', shape.container)}>
|
|
25
|
-
<div className="flex min-h-40 items-center justify-center p-4">{children}</div>
|
|
26
|
-
<figcaption className="flex items-start gap-2 border-t border-border px-4 py-3">
|
|
27
|
-
<Badge variant="dot" size="compact" color={verdict === 'bad' ? 'red' : 'green'}>
|
|
28
|
-
{verdict === 'bad' ? 'Bad' : 'Good'}
|
|
29
|
-
</Badge>
|
|
30
|
-
{note && <span className="text-caption text-muted-foreground">{note}</span>}
|
|
31
|
-
</figcaption>
|
|
32
|
-
</figure>
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface CraftProps {
|
|
37
|
-
/** The naive version: the same interface with the detail missing. */
|
|
38
|
-
bad: ReactNode
|
|
39
|
-
/** The system's version, with the detail in place. */
|
|
40
|
-
good: ReactNode
|
|
41
|
-
/** What goes wrong on the bad side, in one line. */
|
|
42
|
-
badNote?: string
|
|
43
|
-
/** What the good side does instead, in one line. */
|
|
44
|
-
goodNote?: string
|
|
45
|
-
/** Classes for the root grid. */
|
|
46
|
-
className?: string
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* The details that make an interface feel finished, each one shown without
|
|
51
|
-
* and with it.
|
|
52
|
-
*
|
|
53
|
-
* Every pair below isolates one rule of the system: the bad side is the
|
|
54
|
-
* version most component libraries ship, the good side is this design
|
|
55
|
-
* system's own item. Try both: press, hover between rows, click and then tab,
|
|
56
|
-
* open and close. The rules themselves are on the Motion, FluidHover,
|
|
57
|
-
* Morph, Elevated and SizeProvider pages; this one is where they can be felt.
|
|
58
|
-
* `Craft` is the frame: the two versions side by side, each with a one-line
|
|
59
|
-
* verdict, stacked on narrow screens.
|
|
60
|
-
*
|
|
61
|
-
* @example {@include ./examples.mdx}
|
|
62
|
-
*/
|
|
63
|
-
export default function Craft({ bad, good, badNote, goodNote, className }: CraftProps) {
|
|
64
|
-
return (
|
|
65
|
-
<div className={cn('grid w-full gap-3 sm:grid-cols-2', className)}>
|
|
66
|
-
<Pane verdict="bad" note={badNote}>
|
|
67
|
-
{bad}
|
|
68
|
-
</Pane>
|
|
69
|
-
<Pane verdict="good" note={goodNote}>
|
|
70
|
-
{good}
|
|
71
|
-
</Pane>
|
|
72
|
-
</div>
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export type { CraftProps }
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import ScrollArea from '../scroll-area'
|
|
2
|
-
import FluidHover from './index'
|
|
3
|
-
|
|
4
|
-
# Blink or glide
|
|
5
|
-
|
|
6
|
-
Plain `:hover` blinks off in every gap; this one glides, melting from row to
|
|
7
|
-
row. Run the cursor down the rows, into the padding and past the last row.
|
|
8
|
-
|
|
9
|
-
<div className="w-64 rounded-xl border border-border/60">
|
|
10
|
-
<FluidHover className="p-2" items={['Inbox', 'Drafts', 'Sent', 'Archive', 'Trash']} />
|
|
11
|
-
</div>
|
|
12
|
-
|
|
13
|
-
# 3 axes
|
|
14
|
-
|
|
15
|
-
The same highlight down a list, across a strip and to the closest card.
|
|
16
|
-
|
|
17
|
-
<div className="flex w-full max-w-md flex-col gap-8">
|
|
18
|
-
<div className="flex flex-col gap-2">
|
|
19
|
-
<span className="text-caption text-muted-foreground">axis y — lists: menus, tables, radios</span>
|
|
20
|
-
<div className="rounded-xl border border-border/60">
|
|
21
|
-
<FluidHover className="p-2" items={['Inbox', 'Drafts', 'Sent', 'Archive', 'Trash']} />
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
<div className="flex flex-col gap-2">
|
|
25
|
-
<span className="text-caption text-muted-foreground">axis x — strips: tabs, segmented controls</span>
|
|
26
|
-
<div className="w-max rounded-xl border border-border/60">
|
|
27
|
-
<FluidHover axis="x" className="p-1" items={['Library', 'Recents', 'Favorites', 'Settings']} />
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
<div className="flex flex-col gap-2">
|
|
31
|
-
<span className="text-caption text-muted-foreground">axis xy — grids: card groups</span>
|
|
32
|
-
<FluidHover columns={2} className="rounded-xl border border-border/60 p-2">
|
|
33
|
-
{[
|
|
34
|
-
{ title: 'Inbox', description: 'Everything new lands here.' },
|
|
35
|
-
{ title: 'Drafts', description: 'Unsent, saved as you type.' },
|
|
36
|
-
{ title: 'Sent', description: 'Delivered and archived.' },
|
|
37
|
-
{ title: 'Trash', description: 'Emptied after 30 days.' },
|
|
38
|
-
].map((card) => (
|
|
39
|
-
<FluidHover.Item key={card.title}>
|
|
40
|
-
<span className="text-body text-foreground">{card.title}</span>
|
|
41
|
-
<span className="text-caption text-muted-foreground">{card.description}</span>
|
|
42
|
-
</FluidHover.Item>
|
|
43
|
-
))}
|
|
44
|
-
</FluidHover>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
|
|
48
|
-
# When to split a list
|
|
49
|
-
|
|
50
|
-
The workspace rows, nested chats included, are one list; the account rows
|
|
51
|
-
below the divider are a second. Knowledge is disabled.
|
|
52
|
-
|
|
53
|
-
<div className="w-64 rounded-xl border border-border/60">
|
|
54
|
-
<FluidHover className="p-2">
|
|
55
|
-
<FluidHover.Item>Chat</FluidHover.Item>
|
|
56
|
-
<FluidHover.Item className="text-muted-foreground"><span className="w-4 shrink-0" />Today</FluidHover.Item>
|
|
57
|
-
<FluidHover.Item className="text-muted-foreground"><span className="w-4 shrink-0" />Yesterday</FluidHover.Item>
|
|
58
|
-
<FluidHover.Item>Agents</FluidHover.Item>
|
|
59
|
-
<FluidHover.Item disabled>Knowledge</FluidHover.Item>
|
|
60
|
-
<FluidHover.Item>Runs</FluidHover.Item>
|
|
61
|
-
</FluidHover>
|
|
62
|
-
<div className="h-px bg-border" />
|
|
63
|
-
<FluidHover className="p-2" items={['Profile', 'Log out']} />
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
# What it costs
|
|
67
|
-
|
|
68
|
-
60 rows, and the work per move does not grow with them.
|
|
69
|
-
|
|
70
|
-
<ScrollArea viewportClassName="scroll-fade" className="h-72 w-72 rounded-xl border border-border/60">
|
|
71
|
-
<FluidHover
|
|
72
|
-
className="p-2"
|
|
73
|
-
items={Array.from({ length: 60 }, (_, i) => 'Message ' + String(i + 1).padStart(3, '0'))}
|
|
74
|
-
/>
|
|
75
|
-
</ScrollArea>
|
|
76
|
-
|
|
77
|
-
# Reduced motion
|
|
78
|
-
|
|
79
|
-
This list follows the reduce-motion setting of the system it runs on: turn
|
|
80
|
-
it on to see the highlight fade in place instead of sliding.
|
|
81
|
-
|
|
82
|
-
<div className="w-64 rounded-xl border border-border/60">
|
|
83
|
-
<FluidHover className="p-2" items={['Inbox', 'Drafts', 'Sent', 'Archive', 'Trash']} />
|
|
84
|
-
</div>
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Ported from Fluid Functionalism — github.com/mickadesign/fluid-functionalism
|
|
3
|
-
* `app/docs/fluid-hover/page.tsx` + `app/docs/fluid-hover/demos.tsx` @ b3587bdbd83fc66c2a6aae3817ffb856cb09260b
|
|
4
|
-
* MIT License © 2026 Micka Touillaud — fluidfunctionalism.com (notice: LICENSE.fluid-functionalism)
|
|
5
|
-
* Local modifications:
|
|
6
|
-
* - Upstream ships fluid hover as a hook plus a highlight component, demoed on the
|
|
7
|
-
* docs page through local `FluidRow` / `CostRow` helpers. This item wraps that
|
|
8
|
-
* pair in one documented container (`FluidHover` + `FluidHover.Item`) so the modo
|
|
9
|
-
* examples can show all three axes without hooks. The mechanism is untouched and
|
|
10
|
-
* still lives in `lib/use-fluid-hover.ts` and
|
|
11
|
-
* `lib/fluid-hover-highlight.tsx`; both are re-exported here unchanged.
|
|
12
|
-
* - `items`, `renderItem`, `disabledIndices`, `columns` and `highlightClassName` are
|
|
13
|
-
* this container's own API; `axis` and `gapClick` are the hook's options, passed
|
|
14
|
-
* straight through.
|
|
15
|
-
* - Row classes are upstream's `rowClass` from `demos.tsx`, with per-axis variants
|
|
16
|
-
* for the strip and the grid; the highlight rides the shape system (`shape.bg`),
|
|
17
|
-
* as in upstream's `FluidHoverList`.
|
|
18
|
-
* - Prose and examples follow the FF `/docs/fluid-hover` page (its five sections,
|
|
19
|
-
* minus the two scripted-cursor demos that only exist to film the mechanism).
|
|
20
|
-
* - The prose describes the highlight as it now moves: it melts from row to
|
|
21
|
-
* row (`lib/goo-indicator.tsx`, local), with the cost of that while it moves.
|
|
22
|
-
* - Styling reads DS tokens (AGENTS.md styling): `text-[Npx]` →
|
|
23
|
-
* `text-<role>[-compact]`; the hex focus-ring fallback →
|
|
24
|
-
* `ring-focus-ring` / `border-focus-ring`.
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import {
|
|
28
|
-
Children,
|
|
29
|
-
cloneElement,
|
|
30
|
-
createContext,
|
|
31
|
-
type ForwardRefExoticComponent,
|
|
32
|
-
forwardRef,
|
|
33
|
-
type HTMLAttributes,
|
|
34
|
-
isValidElement,
|
|
35
|
-
type MutableRefObject,
|
|
36
|
-
type ReactElement,
|
|
37
|
-
type ReactNode,
|
|
38
|
-
type RefAttributes,
|
|
39
|
-
useContext,
|
|
40
|
-
useMemo,
|
|
41
|
-
useRef,
|
|
42
|
-
} from 'react'
|
|
43
|
-
import { FluidHoverHighlight } from '../../lib/fluid-hover-highlight'
|
|
44
|
-
import { useShape } from '../../lib/shape-context'
|
|
45
|
-
import { useFluidHover, useRegisterFluidHoverItem } from '../../lib/use-fluid-hover'
|
|
46
|
-
import { cn } from '../../lib/utils'
|
|
47
|
-
|
|
48
|
-
type FluidHoverAxis = 'x' | 'y' | 'xy'
|
|
49
|
-
|
|
50
|
-
interface FluidHoverContextValue {
|
|
51
|
-
registerItem: (index: number, element: HTMLElement | null) => void
|
|
52
|
-
axis: FluidHoverAxis
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const FluidHoverContext = createContext<FluidHoverContextValue | null>(null)
|
|
56
|
-
|
|
57
|
-
function isItemDisabled(element: HTMLElement) {
|
|
58
|
-
return element.hasAttribute('data-disabled')
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const itemBaseClass =
|
|
62
|
-
'relative z-10 flex shrink-0 cursor-pointer items-center text-left text-body text-foreground outline-none focus-visible:ring-1 focus-visible:ring-focus-ring'
|
|
63
|
-
|
|
64
|
-
const itemAxisClass: Record<FluidHoverAxis, string> = {
|
|
65
|
-
y: 'h-9 w-full px-3',
|
|
66
|
-
x: 'h-9 justify-center whitespace-nowrap px-3',
|
|
67
|
-
xy: 'min-h-20 w-full flex-col items-start justify-center gap-0.5 p-3',
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const containerAxisClass: Record<FluidHoverAxis, string> = {
|
|
71
|
-
y: 'flex flex-col gap-1',
|
|
72
|
-
x: 'flex flex-row gap-1',
|
|
73
|
-
xy: 'grid gap-1',
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
interface FluidHoverItemProps extends HTMLAttributes<HTMLButtonElement> {
|
|
77
|
-
/** Position in the list. Assigned automatically to direct children of `FluidHover`; pass it by hand for rows rendered inside a wrapper of your own. */
|
|
78
|
-
index?: number
|
|
79
|
-
/** Skips the row: never lit, never the target of a gap click. It stays registered, so its neighbours keep their indices. Defaults to `false`. */
|
|
80
|
-
disabled?: boolean
|
|
81
|
-
/** The row's content — a label, or an icon plus text, or (on `xy`) a title over a description. */
|
|
82
|
-
children?: ReactNode
|
|
83
|
-
/** Classes for the row, merged over the per-axis defaults. */
|
|
84
|
-
className?: string
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* One row of a fluid hover list: a real button, focusable and activatable from
|
|
89
|
-
* the keyboard, announced by its label. It registers itself with the
|
|
90
|
-
* surrounding `FluidHover` for as long as it is mounted; outside one it is
|
|
91
|
-
* just a button.
|
|
92
|
-
*/
|
|
93
|
-
const FluidHoverItem = forwardRef<HTMLButtonElement, FluidHoverItemProps>(
|
|
94
|
-
({ index, disabled = false, className, children, ...props }, ref) => {
|
|
95
|
-
const list = useContext(FluidHoverContext)
|
|
96
|
-
const shape = useShape()
|
|
97
|
-
const innerRef = useRef<HTMLButtonElement | null>(null)
|
|
98
|
-
useRegisterFluidHoverItem(list?.registerItem, index, innerRef)
|
|
99
|
-
const axis = list?.axis ?? 'y'
|
|
100
|
-
return (
|
|
101
|
-
<button
|
|
102
|
-
ref={node => {
|
|
103
|
-
innerRef.current = node
|
|
104
|
-
if (typeof ref === 'function') ref(node)
|
|
105
|
-
else if (ref) (ref as MutableRefObject<HTMLButtonElement | null>).current = node
|
|
106
|
-
}}
|
|
107
|
-
type="button"
|
|
108
|
-
data-slot="fluid-hover-item"
|
|
109
|
-
// Read back by `isItemDisabled` on every move: the hit test skips the
|
|
110
|
-
// row without the list having to re-measure.
|
|
111
|
-
data-disabled={disabled || undefined}
|
|
112
|
-
disabled={disabled}
|
|
113
|
-
{...props}
|
|
114
|
-
className={cn(
|
|
115
|
-
itemBaseClass,
|
|
116
|
-
itemAxisClass[axis],
|
|
117
|
-
shape.item,
|
|
118
|
-
disabled && 'cursor-default text-muted-foreground opacity-55',
|
|
119
|
-
className,
|
|
120
|
-
)}
|
|
121
|
-
>
|
|
122
|
-
{children}
|
|
123
|
-
</button>
|
|
124
|
-
)
|
|
125
|
-
},
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
FluidHoverItem.displayName = 'FluidHoverItem'
|
|
129
|
-
|
|
130
|
-
interface FluidHoverProps extends HTMLAttributes<HTMLDivElement> {
|
|
131
|
-
/** Which way the list runs: `'y'` for lists, `'x'` for strips, `'xy'` for grids. Defaults to `'y'`, or `'xy'` when `columns` is above 1. */
|
|
132
|
-
axis?: FluidHoverAxis
|
|
133
|
-
/** Grid columns. Above 1 the container becomes a grid and resolves the nearest item across rows and columns. Defaults to `1`, or `2` when `axis` is `'xy'`. */
|
|
134
|
-
columns?: number
|
|
135
|
-
/** Shorthand rows: one `FluidHover.Item` per string, indexed in order. Omit it and pass `FluidHover.Item` children instead. */
|
|
136
|
-
items?: string[]
|
|
137
|
-
/** Renders the content of a shorthand row. Defaults to the string itself. */
|
|
138
|
-
renderItem?: (item: string, index: number) => ReactNode
|
|
139
|
-
/** Rows to skip: never lit, never the target of a gap click. They stay registered, so their neighbours keep their indices. */
|
|
140
|
-
disabledIndices?: number[]
|
|
141
|
-
/** Whether a click that lands between rows goes to the lit one, so what is lit is what a click hits. `false` leaves empty space inert; `{ maxDistance }` routes only clicks within that many pixels of the lit row. Defaults to `true`. */
|
|
142
|
-
gapClick?: boolean | { maxDistance?: number }
|
|
143
|
-
/** Classes for the highlight itself — radius and z-index. Merged over `absolute bg-hover` and the shape system's radius. */
|
|
144
|
-
highlightClassName?: string
|
|
145
|
-
/** Classes for the list container. Padding here is part of the list: a click in it still lands on the lit row. */
|
|
146
|
-
className?: string
|
|
147
|
-
/** `FluidHover.Item` rows, when `items` is not enough. Direct Item children are indexed in order. */
|
|
148
|
-
children?: ReactNode
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
type FluidHoverComponent = ForwardRefExoticComponent<FluidHoverProps & RefAttributes<HTMLDivElement>> & {
|
|
152
|
-
Item: typeof FluidHoverItem
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Hover that never blinks and always follows your cursor to the nearest item.
|
|
157
|
-
*
|
|
158
|
-
* One rule, no dead zones: an item the pointer is inside wins, and otherwise
|
|
159
|
-
* the item whose center is nearest does — so a cursor in a gap, in the
|
|
160
|
-
* padding, or past the last row still lands on something, and a click there
|
|
161
|
-
* lands on what is lit (`gapClick`). One list is one FluidHover: it owns the
|
|
162
|
-
* container's mouse handlers, hands every row its index, and draws the single
|
|
163
|
-
* highlight that melts between the measured rectangles, stretching toward the
|
|
164
|
-
* next row and letting go (the liquid indicators in Morph).
|
|
165
|
-
*
|
|
166
|
-
* Three axes, one feel. `y` is for lists — menus, tables, radio rows — and
|
|
167
|
-
* measures the vertical center; `x` is for strips — tabs, segmented controls —
|
|
168
|
-
* and measures the horizontal one; `xy` is for card grids, where the nearest
|
|
169
|
-
* card is the shortest straight line to a center across both rows and columns.
|
|
170
|
-
* Pass `columns` and the container becomes that grid and picks `xy` on its own.
|
|
171
|
-
*
|
|
172
|
-
* Split a list at the divider. Rows that are alternatives to each other share
|
|
173
|
-
* one list — children ride with their parent — and the highlight never crosses
|
|
174
|
-
* into a different kind of thing: that is a second FluidHover. A disabled row
|
|
175
|
-
* is skipped rather than unregistered (`disabledIndices`, or `disabled` on the
|
|
176
|
-
* row), so the rows around it keep their indices and their measurements.
|
|
177
|
-
*
|
|
178
|
-
* It costs 1 transform and 1 loop per move: the pick is one pass
|
|
179
|
-
* over cached rectangles per animation frame, with no DOM reads per row, and
|
|
180
|
-
* the highlight travels on a transform. While it melts, a shrinking blob and
|
|
181
|
-
* the goo filter join it, and both are gone once it settles, so a resting
|
|
182
|
-
* highlight is filtered by nothing. Reduced motion is honoured on its own,
|
|
183
|
-
* read straight off the OS media query with no MotionConfig wrapper needed:
|
|
184
|
-
* the highlight still fades in on the nearest row, it just stops travelling
|
|
185
|
-
* between rows.
|
|
186
|
-
*
|
|
187
|
-
* Use it when everything in the list can be clicked (a menu, a list, tabs, a
|
|
188
|
-
* grid of links), when the items sit close together, and when they stay where
|
|
189
|
-
* they are while you look at them. Skip it when a wrong click would hurt, when
|
|
190
|
-
* only some of the cards can be clicked, when there is a lot of empty space
|
|
191
|
-
* around the items, or when rows change place as you scroll.
|
|
192
|
-
*
|
|
193
|
-
* Statics: FluidHover.Item — one row, rendered as a real button (focusable,
|
|
194
|
-
* activatable from the keyboard, announced by its label); the hook only lights
|
|
195
|
-
* it, it never moves focus.
|
|
196
|
-
*
|
|
197
|
-
* For a list this container cannot express, the machinery is re-exported
|
|
198
|
-
* unchanged. `useFluidHover(containerRef, { axis, isItemDisabled, gapClick })`
|
|
199
|
-
* returns `{ handlers, registerItem, activeIndex, setActiveIndex, itemRects,
|
|
200
|
-
* isMeasured, remeasure, sessionRef }`: spread `handlers` on the container,
|
|
201
|
-
* give each row `useRegisterFluidHoverItem(registerItem, index, ref)`, light a
|
|
202
|
-
* row yourself with `setActiveIndex` for keyboard focus, and call `remeasure`
|
|
203
|
-
* when the rects may be stale (a popup opening on rows that never unmounted).
|
|
204
|
-
* `FluidHoverHighlight` then draws the fill: `hover` is the hook's return
|
|
205
|
-
* value, `hidden` keeps the state but shows nothing, `from` is where a fresh
|
|
206
|
-
* entry fades in (a dropdown passes its checked row), `className` carries
|
|
207
|
-
* radius and z-index, and `transition` is the travel — `false` snaps into
|
|
208
|
-
* place after a reflow instead of sliding.
|
|
209
|
-
*
|
|
210
|
-
* @example {@include ./examples.mdx}
|
|
211
|
-
*/
|
|
212
|
-
const FluidHover = forwardRef<HTMLDivElement, FluidHoverProps>(
|
|
213
|
-
(
|
|
214
|
-
{
|
|
215
|
-
axis,
|
|
216
|
-
columns,
|
|
217
|
-
items,
|
|
218
|
-
renderItem,
|
|
219
|
-
disabledIndices,
|
|
220
|
-
gapClick = true,
|
|
221
|
-
highlightClassName,
|
|
222
|
-
className,
|
|
223
|
-
children,
|
|
224
|
-
style,
|
|
225
|
-
...props
|
|
226
|
-
},
|
|
227
|
-
ref,
|
|
228
|
-
) => {
|
|
229
|
-
const containerRef = useRef<HTMLDivElement | null>(null)
|
|
230
|
-
const shape = useShape()
|
|
231
|
-
|
|
232
|
-
const resolvedAxis: FluidHoverAxis = axis ?? ((columns ?? 1) > 1 ? 'xy' : 'y')
|
|
233
|
-
const resolvedColumns = resolvedAxis === 'xy' ? Math.max(1, columns ?? 2) : 1
|
|
234
|
-
|
|
235
|
-
const hover = useFluidHover(containerRef, {
|
|
236
|
-
axis: resolvedAxis,
|
|
237
|
-
isItemDisabled,
|
|
238
|
-
gapClick,
|
|
239
|
-
})
|
|
240
|
-
const { handlers, registerItem } = hover
|
|
241
|
-
|
|
242
|
-
const contextValue = useMemo<FluidHoverContextValue>(
|
|
243
|
-
() => ({ registerItem, axis: resolvedAxis }),
|
|
244
|
-
[registerItem, resolvedAxis],
|
|
245
|
-
)
|
|
246
|
-
|
|
247
|
-
const disabled = new Set(disabledIndices)
|
|
248
|
-
// Rows come either from `items` (the container renders them) or from
|
|
249
|
-
// Item children (the container only hands them their index). A child that
|
|
250
|
-
// is not an Item keeps its slot but never registers, and the hit test
|
|
251
|
-
// skips the hole it leaves in the rects.
|
|
252
|
-
const rows = items
|
|
253
|
-
? items.map((item, i) => (
|
|
254
|
-
<FluidHoverItem key={`${i}-${item}`} index={i} disabled={disabled.has(i)}>
|
|
255
|
-
{renderItem ? renderItem(item, i) : item}
|
|
256
|
-
</FluidHoverItem>
|
|
257
|
-
))
|
|
258
|
-
: Children.toArray(children).map((child, i) => {
|
|
259
|
-
if (!isValidElement(child) || child.type !== FluidHoverItem) return child
|
|
260
|
-
const row = child as ReactElement<FluidHoverItemProps>
|
|
261
|
-
return cloneElement(row, {
|
|
262
|
-
index: row.props.index ?? i,
|
|
263
|
-
disabled: row.props.disabled ?? disabled.has(i),
|
|
264
|
-
})
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
return (
|
|
268
|
-
<FluidHoverContext.Provider value={contextValue}>
|
|
269
|
-
<div
|
|
270
|
-
ref={node => {
|
|
271
|
-
containerRef.current = node
|
|
272
|
-
if (typeof ref === 'function') ref(node)
|
|
273
|
-
else if (ref) (ref as MutableRefObject<HTMLDivElement | null>).current = node
|
|
274
|
-
}}
|
|
275
|
-
{...props}
|
|
276
|
-
{...handlers}
|
|
277
|
-
data-slot="fluid-hover"
|
|
278
|
-
data-axis={resolvedAxis}
|
|
279
|
-
className={cn('relative', containerAxisClass[resolvedAxis], className)}
|
|
280
|
-
style={
|
|
281
|
-
resolvedAxis === 'xy'
|
|
282
|
-
? {
|
|
283
|
-
gridTemplateColumns: `repeat(${resolvedColumns}, minmax(0, 1fr))`,
|
|
284
|
-
...style,
|
|
285
|
-
}
|
|
286
|
-
: style
|
|
287
|
-
}
|
|
288
|
-
>
|
|
289
|
-
<FluidHoverHighlight hover={hover} className={cn('z-0', shape.bg, highlightClassName)} />
|
|
290
|
-
{rows}
|
|
291
|
-
</div>
|
|
292
|
-
</FluidHoverContext.Provider>
|
|
293
|
-
)
|
|
294
|
-
},
|
|
295
|
-
) as FluidHoverComponent
|
|
296
|
-
|
|
297
|
-
FluidHover.displayName = 'FluidHover'
|
|
298
|
-
|
|
299
|
-
Object.assign(FluidHover, { Item: FluidHoverItem })
|
|
300
|
-
|
|
301
|
-
export type { FluidHoverHighlightProps } from '../../lib/fluid-hover-highlight'
|
|
302
|
-
export { FluidHoverHighlight } from '../../lib/fluid-hover-highlight'
|
|
303
|
-
export type {
|
|
304
|
-
ItemRect,
|
|
305
|
-
UseFluidHoverOptions,
|
|
306
|
-
UseFluidHoverReturn,
|
|
307
|
-
} from '../../lib/use-fluid-hover'
|
|
308
|
-
// The mechanism itself, unchanged — for lists this container cannot express.
|
|
309
|
-
export {
|
|
310
|
-
useFluidHover,
|
|
311
|
-
useRegisterFluidHoverItem,
|
|
312
|
-
} from '../../lib/use-fluid-hover'
|
|
313
|
-
export type { FluidHoverAxis, FluidHoverItemProps, FluidHoverProps }
|
|
314
|
-
export { FluidHover, FluidHoverItem }
|
|
315
|
-
|
|
316
|
-
export default FluidHover
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import Checkbox from '../../components/inputs/checkbox'
|
|
2
|
-
import Radio from '../../components/inputs/radio'
|
|
3
|
-
import Switch from '../../components/inputs/switch'
|
|
4
|
-
import Tabs from '../../components/navigation/tabs'
|
|
5
|
-
import TabsSubtle from '../../components/navigation/tabs-subtle'
|
|
6
|
-
import FluidHover from '../fluid-hover'
|
|
7
|
-
import Morph from './index'
|
|
8
|
-
|
|
9
|
-
# Overlays
|
|
10
|
-
|
|
11
|
-
## Effects
|
|
12
|
-
|
|
13
|
-
The same panel, four ways in. Goo is the default: the surface melts out of the trigger and pinches off.
|
|
14
|
-
|
|
15
|
-
<div className="flex w-full flex-wrap items-start justify-center gap-x-6 gap-y-48 pb-40">
|
|
16
|
-
<Morph effect="goo" label="Goo">
|
|
17
|
-
<div className="flex flex-col gap-1">
|
|
18
|
-
<span className="text-subtitle weight-semibold text-foreground">Goo</span>
|
|
19
|
-
<span className="text-caption text-muted-foreground">A liquid neck to the trigger, then the panel lets go.</span>
|
|
20
|
-
</div>
|
|
21
|
-
</Morph>
|
|
22
|
-
<Morph effect="morph" label="Morph">
|
|
23
|
-
<div className="flex flex-col gap-1">
|
|
24
|
-
<span className="text-subtitle weight-semibold text-foreground">Morph</span>
|
|
25
|
-
<span className="text-caption text-muted-foreground">The trigger's box grows into the panel.</span>
|
|
26
|
-
</div>
|
|
27
|
-
</Morph>
|
|
28
|
-
<Morph effect="slide" label="Slide">
|
|
29
|
-
<div className="flex flex-col gap-1">
|
|
30
|
-
<span className="text-subtitle weight-semibold text-foreground">Slide</span>
|
|
31
|
-
<span className="text-caption text-muted-foreground">The finished panel travels in from the trigger.</span>
|
|
32
|
-
</div>
|
|
33
|
-
</Morph>
|
|
34
|
-
<Morph effect="fade" label="Fade">
|
|
35
|
-
<div className="flex flex-col gap-1">
|
|
36
|
-
<span className="text-subtitle weight-semibold text-foreground">Fade</span>
|
|
37
|
-
<span className="text-caption text-muted-foreground">No movement: what every effect becomes under reduced motion.</span>
|
|
38
|
-
</div>
|
|
39
|
-
</Morph>
|
|
40
|
-
</div>
|
|
41
|
-
|
|
42
|
-
## Sources
|
|
43
|
-
|
|
44
|
-
`from` picks the starting point. Press the pointer stage anywhere on the button to see the circle start under your cursor; the edges start at the side of the window.
|
|
45
|
-
|
|
46
|
-
<div className="flex w-full flex-wrap items-start justify-center gap-x-6 gap-y-48 pb-40">
|
|
47
|
-
<Morph from="trigger" label="Trigger">
|
|
48
|
-
<span className="text-caption text-muted-foreground">From the pressed trigger.</span>
|
|
49
|
-
</Morph>
|
|
50
|
-
<Morph from="pointer" label="Pointer">
|
|
51
|
-
<span className="text-caption text-muted-foreground">From the press point, as a circle.</span>
|
|
52
|
-
</Morph>
|
|
53
|
-
<Morph from="center" label="Center">
|
|
54
|
-
<span className="text-caption text-muted-foreground">Unfolds from its own center.</span>
|
|
55
|
-
</Morph>
|
|
56
|
-
<Morph from="left" label="Left edge">
|
|
57
|
-
<span className="text-caption text-muted-foreground">From the left side of the window.</span>
|
|
58
|
-
</Morph>
|
|
59
|
-
<Morph from="bottom" label="Bottom edge">
|
|
60
|
-
<span className="text-caption text-muted-foreground">From the bottom of the window.</span>
|
|
61
|
-
</Morph>
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
## Becoming the panel
|
|
65
|
-
|
|
66
|
-
With `hideSource`, the trigger disappears while the panel is open, so it reads as turning into it. With `effect="morph"` too, the panel opens in place, over its trigger: press the panel to close it.
|
|
67
|
-
|
|
68
|
-
<div className="flex w-full flex-wrap items-start justify-center gap-x-6 gap-y-48 pb-40">
|
|
69
|
-
<Morph hideSource label="Goo">
|
|
70
|
-
<span className="text-caption text-muted-foreground">The trigger melts into the panel.</span>
|
|
71
|
-
</Morph>
|
|
72
|
-
<Morph hideSource effect="morph" label="Morph">
|
|
73
|
-
<span className="text-caption text-muted-foreground">The trigger grows into the panel.</span>
|
|
74
|
-
</Morph>
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
## Two speeds
|
|
78
|
-
|
|
79
|
-
Goo always runs on `spring.goo`, so the neck has time to stretch; a plain morph takes a tier: `moderate` for small panels, `slow` by default.
|
|
80
|
-
|
|
81
|
-
<div className="flex w-full flex-wrap items-start justify-center gap-x-6 gap-y-48 pb-40">
|
|
82
|
-
<Morph effect="morph" tier="moderate" label="Moderate">
|
|
83
|
-
<span className="text-caption text-muted-foreground">spring.moderate</span>
|
|
84
|
-
</Morph>
|
|
85
|
-
<Morph effect="morph" tier="slow" label="Slow">
|
|
86
|
-
<span className="text-caption text-muted-foreground">spring.slow</span>
|
|
87
|
-
</Morph>
|
|
88
|
-
</div>
|
|
89
|
-
|
|
90
|
-
# Indicators
|
|
91
|
-
|
|
92
|
-
## Liquid indicators
|
|
93
|
-
|
|
94
|
-
Click a tab next door: the indicator stretches toward it and lets go. Click a far one: a droplet stays behind and catches up.
|
|
95
|
-
|
|
96
|
-
<div className="flex flex-col items-center gap-6">
|
|
97
|
-
<Tabs defaultValue="library">
|
|
98
|
-
<Tabs.List>
|
|
99
|
-
<Tabs.Item value="library" label="Library" />
|
|
100
|
-
<Tabs.Item value="recents" label="Recents" />
|
|
101
|
-
<Tabs.Item value="favorites" label="Favorites" />
|
|
102
|
-
<Tabs.Item value="settings" label="Settings" />
|
|
103
|
-
</Tabs.List>
|
|
104
|
-
</Tabs>
|
|
105
|
-
<TabsSubtle defaultSelectedIndex={0}>
|
|
106
|
-
{['Teamspaces', 'Recents', 'Favorites', 'Shared'].map((label, i) => (
|
|
107
|
-
<TabsSubtle.Item key={label} index={i} label={label} />
|
|
108
|
-
))}
|
|
109
|
-
</TabsSubtle>
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
## Thumbs, picks and highlights
|
|
113
|
-
|
|
114
|
-
The thumb melts across its track, the radio pick flows between rows, and the hover highlight drips from row to row.
|
|
115
|
-
|
|
116
|
-
<div className="flex flex-wrap items-start justify-center gap-6">
|
|
117
|
-
<div className="flex flex-col gap-2">
|
|
118
|
-
<Switch label="Wi-Fi" />
|
|
119
|
-
<Switch label="Bluetooth" defaultChecked />
|
|
120
|
-
</div>
|
|
121
|
-
<Radio.Group defaultSelectedIndex={0} className="w-48">
|
|
122
|
-
{['Daily', 'Weekly', 'Monthly'].map(label => (
|
|
123
|
-
<Radio key={label} label={label} />
|
|
124
|
-
))}
|
|
125
|
-
</Radio.Group>
|
|
126
|
-
<div className="w-48 rounded-xl border border-border/60">
|
|
127
|
-
<FluidHover className="p-2" items={['Inbox', 'Drafts', 'Sent', 'Archive']} />
|
|
128
|
-
</div>
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
## Merging picks
|
|
132
|
-
|
|
133
|
-
Check Bananas: it grows out of its row and melts the picks above and below into one. Uncheck it to pinch them apart.
|
|
134
|
-
|
|
135
|
-
<Checkbox.Group defaultCheckedIndices={[0, 2]}>
|
|
136
|
-
{['Apples', 'Bananas', 'Cherries', 'Dates'].map(label => (
|
|
137
|
-
<Checkbox key={label} label={label} />
|
|
138
|
-
))}
|
|
139
|
-
</Checkbox.Group>
|