@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,57 +0,0 @@
|
|
|
1
|
-
import TimePicker from './index'
|
|
2
|
-
import { de } from 'react-day-picker/locale'
|
|
3
|
-
|
|
4
|
-
# Basic
|
|
5
|
-
|
|
6
|
-
The locale's clock: in English, 12-hour, the hours read with AM/PM.
|
|
7
|
-
|
|
8
|
-
<div className="w-48 max-w-full">
|
|
9
|
-
<TimePicker defaultValue="15:33" />
|
|
10
|
-
</div>
|
|
11
|
-
|
|
12
|
-
# 24-hour clock
|
|
13
|
-
|
|
14
|
-
A German locale writes 24-hour times.
|
|
15
|
-
|
|
16
|
-
<div className="w-48 max-w-full">
|
|
17
|
-
<TimePicker locale={de} defaultValue="15:33" />
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
# Quarter hours
|
|
21
|
-
|
|
22
|
-
`minuteStep={15}` leaves four minutes to pick from.
|
|
23
|
-
|
|
24
|
-
<div className="w-48 max-w-full">
|
|
25
|
-
<TimePicker hourCycle="h23" minuteStep={15} placeholder="Start time" />
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
# The field follows the clock
|
|
29
|
-
|
|
30
|
-
`hourCycle` sets the field's clock as well as the columns': "20:30" on `'h23'` in English, "8:30 PM" on `'h12'` in German.
|
|
31
|
-
|
|
32
|
-
<div className="flex w-48 max-w-full flex-col gap-2">
|
|
33
|
-
<TimePicker hourCycle="h23" defaultValue="20:30" />
|
|
34
|
-
<TimePicker locale={de} hourCycle="h12" defaultValue="20:30" />
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
# Slovak, labels and format
|
|
38
|
-
|
|
39
|
-
`locale="sk"` reads Slovak off Intl; `labels` names the columns and the panel's input, and `formatTime` writes the field's text from the `"HH:mm"` value.
|
|
40
|
-
|
|
41
|
-
<div className="w-48 max-w-full">
|
|
42
|
-
<TimePicker
|
|
43
|
-
locale="sk"
|
|
44
|
-
placeholder="Čas"
|
|
45
|
-
formatTime={value => value + ' h'}
|
|
46
|
-
labels={{ time: 'Čas', hour: 'Hodina', minute: 'Minúta', close: 'Zavrieť' }}
|
|
47
|
-
defaultValue="15:30"
|
|
48
|
-
/>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
# Read only
|
|
52
|
-
|
|
53
|
-
`readOnly` shows the time and never opens.
|
|
54
|
-
|
|
55
|
-
<div className="w-48 max-w-full">
|
|
56
|
-
<TimePicker readOnly defaultValue="15:33" />
|
|
57
|
-
</div>
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Local addition (not part of Fluid Functionalism): a time-of-day field with
|
|
3
|
-
* scrolling hour and minute columns. Props after utegsk/ui's TimePicker
|
|
4
|
-
* (`hourCycle`, a string value), kept in line with the other pickers here.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { type Locale, set } from 'date-fns'
|
|
8
|
-
import {
|
|
9
|
-
type ForwardRefExoticComponent,
|
|
10
|
-
forwardRef,
|
|
11
|
-
type ReactNode,
|
|
12
|
-
type RefAttributes,
|
|
13
|
-
type RefObject,
|
|
14
|
-
useRef,
|
|
15
|
-
} from 'react'
|
|
16
|
-
import {
|
|
17
|
-
defaultLocale,
|
|
18
|
-
formatTime,
|
|
19
|
-
type HourCycle,
|
|
20
|
-
hourCycleOf,
|
|
21
|
-
parseTimeText,
|
|
22
|
-
resolveLocale,
|
|
23
|
-
} from '../../../../lib/date-locale'
|
|
24
|
-
import type { FieldVariant } from '../../../../lib/field-classes'
|
|
25
|
-
import { dividedColumns } from '../../../../lib/scroll-column'
|
|
26
|
-
import type { SizeVariant } from '../../../../lib/size-context'
|
|
27
|
-
import { useControllableState } from '../../../../lib/use-controllable-state'
|
|
28
|
-
import { cn } from '../../../../lib/utils'
|
|
29
|
-
import { controlAttributes, invalidOf, type PickerControlProps, PickerInput, PickerShell } from '../picker-shell'
|
|
30
|
-
import { pad, type Time, TimeColumns } from '../time-columns'
|
|
31
|
-
|
|
32
|
-
/** Every word the picker shows or announces, for translating it. */
|
|
33
|
-
interface TimePickerLabels {
|
|
34
|
-
/** Names the panel's time input. Defaults to the `placeholder`, else `"Time"`. */
|
|
35
|
-
time?: string
|
|
36
|
-
/** Names the hour column. Defaults to the locale's name for it. */
|
|
37
|
-
hour?: string
|
|
38
|
-
/** Names the minute column. Defaults to the locale's name for it. */
|
|
39
|
-
minute?: string
|
|
40
|
-
/** Names the panel's close button. Defaults to `"Close"`. */
|
|
41
|
-
close?: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface TimePickerProps extends PickerControlProps {
|
|
45
|
-
/** The picked time as `"HH:mm"` on a 24-hour clock (an `<input type="time">`'s value); `null` when empty. */
|
|
46
|
-
value?: string | null
|
|
47
|
-
/** Initial time, for an uncontrolled picker. Defaults to `null`. */
|
|
48
|
-
defaultValue?: string | null
|
|
49
|
-
/** Called with the new `"HH:mm"`, or `null` when the field is cleared. */
|
|
50
|
-
onValueChange?: (value: string | null) => void
|
|
51
|
-
/** The clock shown: on `'h12'` / `'h11'` the hours read with AM/PM. Defaults to the locale's. */
|
|
52
|
-
hourCycle?: HourCycle
|
|
53
|
-
/** Steps between the minute column's options. Defaults to `1`. */
|
|
54
|
-
minuteStep?: number
|
|
55
|
-
/** A react-day-picker / date-fns locale, or a BCP 47 tag (`"sk"`) read through Intl: the time's format and the AM/PM names. Defaults to `enUS`. */
|
|
56
|
-
locale?: Locale | string
|
|
57
|
-
/** The field's text for a time, in place of the locale's format: `(value) => …`, given `"HH:mm"`. */
|
|
58
|
-
formatTime?: (value: string) => ReactNode
|
|
59
|
-
/** Every word the picker announces (`time`, `hour`, `minute`, `close`), for translating it. Defaults to English and the locale's field names. */
|
|
60
|
-
labels?: TimePickerLabels
|
|
61
|
-
/** Shows the time but never opens. Defaults to `false`. */
|
|
62
|
-
readOnly?: boolean
|
|
63
|
-
/** Names the value for a native form: a hidden input carries it as `"HH:mm"`. */
|
|
64
|
-
name?: string
|
|
65
|
-
/** Shown while empty. */
|
|
66
|
-
placeholder?: string
|
|
67
|
-
/** Disables the field. Defaults to `false`. */
|
|
68
|
-
disabled?: boolean
|
|
69
|
-
/** Framed at rest, or invisible until hovered or focused. Defaults to `"bordered"`. */
|
|
70
|
-
variant?: FieldVariant
|
|
71
|
-
/** Marks the field invalid. Defaults to `false`. */
|
|
72
|
-
invalid?: boolean
|
|
73
|
-
/** Pins the field and its panel to one step of the size ladder. Defaults to the surrounding SizeProvider. */
|
|
74
|
-
size?: SizeVariant
|
|
75
|
-
/** Controlled open state. */
|
|
76
|
-
open?: boolean
|
|
77
|
-
/** Initial open state, for an uncontrolled panel. Defaults to `false`. */
|
|
78
|
-
defaultOpen?: boolean
|
|
79
|
-
/** Called when the panel opens or closes. */
|
|
80
|
-
onOpenChange?: (open: boolean) => void
|
|
81
|
-
/** Id of the field, for a `Label`'s `htmlFor`. */
|
|
82
|
-
id?: string
|
|
83
|
-
/** Where the panel grows from (see Morph): the field, the press point, its own center, a viewport edge, or a ref to any element. Defaults to `'trigger'` (the field). */
|
|
84
|
-
from?: 'trigger' | 'pointer' | 'center' | 'top' | 'right' | 'bottom' | 'left' | RefObject<HTMLElement | null>
|
|
85
|
-
/** How the panel grows (see Morph), as Combobox's list does: with the liquid goo neck, a plain morph, a slide or a fade. `'morph'` with `hideSource` opens it in place over the field. Defaults to `'goo'`. */
|
|
86
|
-
effect?: 'goo' | 'morph' | 'slide' | 'fade'
|
|
87
|
-
/** Hide the field while open, so it reads as turning into the panel. Defaults to `false`. */
|
|
88
|
-
hideSource?: boolean
|
|
89
|
-
/** Spring tier of a plain morph, slide or fade; goo runs on its own `spring.goo`. Defaults to `'moderate'`. */
|
|
90
|
-
tier?: 'moderate' | 'slow'
|
|
91
|
-
/** Classes for the field. */
|
|
92
|
-
className?: string
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const toTime = (value: string | null): Time | null => {
|
|
96
|
-
const [hours, minutes] = value?.split(':').map(Number) ?? []
|
|
97
|
-
return hours === undefined || minutes === undefined ? null : { hours, minutes }
|
|
98
|
-
}
|
|
99
|
-
const toValue = ({ hours, minutes }: Time) => `${pad(hours)}:${pad(minutes)}`
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* A time-of-day field with scrolling hour and minute columns.
|
|
103
|
-
*
|
|
104
|
-
* The panel opens with the time as text, selected and ready to type over
|
|
105
|
-
* ("15:33", "3:33 PM"), above an hour column and a minute column; on a
|
|
106
|
-
* 12-hour clock the hours read with AM/PM, and the field writes the time on
|
|
107
|
-
* the same clock. Each column keeps its pick in the middle and
|
|
108
|
-
* marks it with a dot. The value is `"HH:mm"` on a 24-hour clock whatever the
|
|
109
|
-
* locale shows, the same as a native time input's.
|
|
110
|
-
*
|
|
111
|
-
* `formatTime` writes the field's text and `labels` every word it
|
|
112
|
-
* announces; `locale` also takes a BCP 47 tag. `readOnly` shows the time
|
|
113
|
-
* and never opens. In a form, `name` submits the value as `"HH:mm"` and
|
|
114
|
-
* `required` stops an empty submit; `id`, the `aria-*` props, `onBlur`,
|
|
115
|
-
* `controlProps` and the `ref` reach the field's button.
|
|
116
|
-
*
|
|
117
|
-
* @example {@include ./examples.mdx}
|
|
118
|
-
*/
|
|
119
|
-
const TimePicker: ForwardRefExoticComponent<TimePickerProps & RefAttributes<HTMLButtonElement>> = forwardRef<
|
|
120
|
-
HTMLButtonElement,
|
|
121
|
-
TimePickerProps
|
|
122
|
-
>(function TimePicker(
|
|
123
|
-
{
|
|
124
|
-
value: valueProp,
|
|
125
|
-
defaultValue = null,
|
|
126
|
-
onValueChange,
|
|
127
|
-
hourCycle,
|
|
128
|
-
minuteStep = 1,
|
|
129
|
-
locale: localeProp = defaultLocale,
|
|
130
|
-
formatTime: formatValue,
|
|
131
|
-
labels,
|
|
132
|
-
readOnly = false,
|
|
133
|
-
name,
|
|
134
|
-
placeholder,
|
|
135
|
-
disabled,
|
|
136
|
-
variant,
|
|
137
|
-
invalid,
|
|
138
|
-
size,
|
|
139
|
-
open: openProp,
|
|
140
|
-
defaultOpen = false,
|
|
141
|
-
onOpenChange,
|
|
142
|
-
id,
|
|
143
|
-
from,
|
|
144
|
-
effect,
|
|
145
|
-
hideSource,
|
|
146
|
-
tier,
|
|
147
|
-
className,
|
|
148
|
-
...control
|
|
149
|
-
},
|
|
150
|
-
ref,
|
|
151
|
-
) {
|
|
152
|
-
const [value, setValue] = useControllableState(valueProp, defaultValue, onValueChange)
|
|
153
|
-
const [open, setOpen] = useControllableState(openProp, defaultOpen, onOpenChange)
|
|
154
|
-
const input = useRef<HTMLInputElement>(null)
|
|
155
|
-
const locale = resolveLocale(localeProp)
|
|
156
|
-
const clock = hourCycle ?? hourCycleOf(locale)
|
|
157
|
-
const time = toTime(value)
|
|
158
|
-
const formatted = time ? formatTime(set(new Date(), time), locale, hourCycle) : ''
|
|
159
|
-
|
|
160
|
-
const readTime = (text: string) => {
|
|
161
|
-
if (!text.trim()) {
|
|
162
|
-
setValue(null)
|
|
163
|
-
return true
|
|
164
|
-
}
|
|
165
|
-
const read = parseTimeText(text, locale)
|
|
166
|
-
if (!read) return false
|
|
167
|
-
setValue(toValue({ hours: read.getHours(), minutes: read.getMinutes() }))
|
|
168
|
-
return true
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return (
|
|
172
|
-
<PickerShell
|
|
173
|
-
open={open}
|
|
174
|
-
onOpenChange={setOpen}
|
|
175
|
-
size={size}
|
|
176
|
-
variant={variant}
|
|
177
|
-
invalid={invalidOf(invalid, control['aria-invalid'])}
|
|
178
|
-
disabled={disabled}
|
|
179
|
-
readOnly={readOnly}
|
|
180
|
-
icon="clock"
|
|
181
|
-
display={time && formatValue ? formatValue(toValue(time)) : formatted}
|
|
182
|
-
placeholder={placeholder}
|
|
183
|
-
closeLabel={labels?.close}
|
|
184
|
-
controlRef={ref}
|
|
185
|
-
controlProps={controlAttributes(control)}
|
|
186
|
-
formValues={[{ slot: 'value', name, value: time ? toValue(time) : '' }]}
|
|
187
|
-
required={control.required}
|
|
188
|
-
header={
|
|
189
|
-
<PickerInput
|
|
190
|
-
ref={input}
|
|
191
|
-
aria-label={labels?.time || placeholder || 'Time'}
|
|
192
|
-
placeholder={placeholder}
|
|
193
|
-
formatted={formatted}
|
|
194
|
-
onText={readTime}
|
|
195
|
-
onEnter={() => setOpen(false)}
|
|
196
|
-
className="flex-1"
|
|
197
|
-
/>
|
|
198
|
-
}
|
|
199
|
-
initialFocus={input}
|
|
200
|
-
popupClassName="w-[max(var(--anchor-width,0px),14rem)]"
|
|
201
|
-
id={id}
|
|
202
|
-
from={from}
|
|
203
|
-
effect={effect}
|
|
204
|
-
hideSource={hideSource}
|
|
205
|
-
tier={tier}
|
|
206
|
-
className={className}
|
|
207
|
-
>
|
|
208
|
-
<div className={cn(dividedColumns, 'h-56')}>
|
|
209
|
-
<TimeColumns
|
|
210
|
-
value={time}
|
|
211
|
-
onValueChange={next => setValue(toValue(next))}
|
|
212
|
-
hourCycle={clock}
|
|
213
|
-
minuteStep={minuteStep}
|
|
214
|
-
locale={locale}
|
|
215
|
-
orientation="vertical"
|
|
216
|
-
fill
|
|
217
|
-
labels={labels}
|
|
218
|
-
/>
|
|
219
|
-
</div>
|
|
220
|
-
</PickerShell>
|
|
221
|
-
)
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
export type { TimePickerLabels, TimePickerProps }
|
|
225
|
-
export { TimePicker }
|
|
226
|
-
|
|
227
|
-
export default TimePicker
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import Field from './index'
|
|
2
|
-
import Input from '../input'
|
|
3
|
-
import Textarea from '../textarea'
|
|
4
|
-
import NumberInput from '../number-input'
|
|
5
|
-
import { Mail } from 'lucide-react'
|
|
6
|
-
|
|
7
|
-
# Basics
|
|
8
|
-
|
|
9
|
-
## Field
|
|
10
|
-
|
|
11
|
-
A label above the control, help text below it. The label targets the control and the description is read with it.
|
|
12
|
-
|
|
13
|
-
<Field className="w-72 max-w-full">
|
|
14
|
-
<Field.Label>Email</Field.Label>
|
|
15
|
-
<Input icon={Mail} placeholder="you@example.com" />
|
|
16
|
-
<Field.Description>We only write about your account.</Field.Description>
|
|
17
|
-
</Field>
|
|
18
|
-
|
|
19
|
-
## Any field control
|
|
20
|
-
|
|
21
|
-
Textarea and NumberInput join the same way: the label, description and error wire to them.
|
|
22
|
-
|
|
23
|
-
<div className="flex flex-col gap-4 w-72 max-w-full">
|
|
24
|
-
<Field>
|
|
25
|
-
<Field.Label>Message</Field.Label>
|
|
26
|
-
<Textarea placeholder="Write your message" minRows={2} />
|
|
27
|
-
</Field>
|
|
28
|
-
<Field invalid>
|
|
29
|
-
<Field.Label>Seats</Field.Label>
|
|
30
|
-
<NumberInput defaultValue={0} min={0} />
|
|
31
|
-
<Field.Error>Book at least one seat.</Field.Error>
|
|
32
|
-
</Field>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
## Field.Control
|
|
36
|
-
|
|
37
|
-
A control that isn't a field control gets the field's id, `aria-describedby` and `aria-invalid` through `Field.Control`, here a native select.
|
|
38
|
-
|
|
39
|
-
<Field className="w-72 max-w-full">
|
|
40
|
-
<Field.Label>Country</Field.Label>
|
|
41
|
-
<Field.Control
|
|
42
|
-
render={
|
|
43
|
-
<select className="h-9 w-full bg-transparent px-1.5 text-body text-foreground">
|
|
44
|
-
<option>Slovakia</option>
|
|
45
|
-
<option>Czechia</option>
|
|
46
|
-
<option>Austria</option>
|
|
47
|
-
</select>
|
|
48
|
-
}
|
|
49
|
-
/>
|
|
50
|
-
<Field.Description>Where the invoice is sent.</Field.Description>
|
|
51
|
-
</Field>
|
|
52
|
-
|
|
53
|
-
## Hidden label
|
|
54
|
-
|
|
55
|
-
`visuallyHidden` keeps the label for assistive tech where the placeholder carries the meaning.
|
|
56
|
-
|
|
57
|
-
<Field className="w-72 max-w-full">
|
|
58
|
-
<Field.Label visuallyHidden>Search</Field.Label>
|
|
59
|
-
<Input variant="bordered" placeholder="Search people" />
|
|
60
|
-
</Field>
|
|
61
|
-
|
|
62
|
-
## Compact
|
|
63
|
-
|
|
64
|
-
`size` pins the field and its control to the compact step.
|
|
65
|
-
|
|
66
|
-
<Field size="compact" className="w-64 max-w-full">
|
|
67
|
-
<Field.Label>Filter</Field.Label>
|
|
68
|
-
<Input placeholder="Name contains…" />
|
|
69
|
-
<Field.Description>Matches any part of the name.</Field.Description>
|
|
70
|
-
</Field>
|
|
71
|
-
|
|
72
|
-
# States
|
|
73
|
-
|
|
74
|
-
## Error
|
|
75
|
-
|
|
76
|
-
`invalid` turns the label and the box destructive; `Field.Error` shows its message while it has one. Both come from your validation.
|
|
77
|
-
|
|
78
|
-
<Field invalid className="w-72 max-w-full">
|
|
79
|
-
<Field.Label>Email</Field.Label>
|
|
80
|
-
<Input icon={Mail} defaultValue="ada@" />
|
|
81
|
-
<Field.Error>Enter a full address, like ada@example.com.</Field.Error>
|
|
82
|
-
</Field>
|
|
83
|
-
|
|
84
|
-
## Required
|
|
85
|
-
|
|
86
|
-
`required` marks the control required and the label with an asterisk.
|
|
87
|
-
|
|
88
|
-
<Field required name="company" className="w-72 max-w-full">
|
|
89
|
-
<Field.Label>Company</Field.Label>
|
|
90
|
-
<Input placeholder="Acme Inc." />
|
|
91
|
-
</Field>
|
|
92
|
-
|
|
93
|
-
## Native validation
|
|
94
|
-
|
|
95
|
-
With `validationMode`, Base UI checks the control's own rules (`required`, `type="email"`) and the field turns destructive on a failure; an empty `Field.Error` shows the browser's message. Type something that isn't an address and leave the field.
|
|
96
|
-
|
|
97
|
-
<Field required validationMode="onBlur" className="w-72 max-w-full">
|
|
98
|
-
<Field.Label>Work email</Field.Label>
|
|
99
|
-
<Input type="email" icon={Mail} placeholder="you@company.com" />
|
|
100
|
-
<Field.Error />
|
|
101
|
-
</Field>
|
|
102
|
-
|
|
103
|
-
## Disabled and read-only
|
|
104
|
-
|
|
105
|
-
The field hands its state to the control: `disabled` dims everything, `readOnly` keeps the value selectable.
|
|
106
|
-
|
|
107
|
-
<div className="flex flex-col gap-4 w-72 max-w-full">
|
|
108
|
-
<Field disabled>
|
|
109
|
-
<Field.Label>Workspace</Field.Label>
|
|
110
|
-
<Input defaultValue="Design" />
|
|
111
|
-
<Field.Description>Only owners can rename it.</Field.Description>
|
|
112
|
-
</Field>
|
|
113
|
-
<Field readOnly>
|
|
114
|
-
<Field.Label>Invoice number</Field.Label>
|
|
115
|
-
<Input defaultValue="INV-2026-0042" />
|
|
116
|
-
</Field>
|
|
117
|
-
</div>
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Local addition (not part of Fluid Functionalism): a labelled form field on
|
|
3
|
-
* Base UI's Field, with no form library of its own. The label, description
|
|
4
|
-
* and error line up with the text inside the field box
|
|
5
|
-
* (`lib/field-variants.ts`), and the field's state reaches any control built
|
|
6
|
-
* on `useFieldBox` through `FieldStateContext` (`lib/field-classes.ts`), the
|
|
7
|
-
* way InputGroup.Field hands it to its control.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { Field as BaseField } from '@base-ui/react/field'
|
|
11
|
-
import {
|
|
12
|
-
type ForwardRefExoticComponent,
|
|
13
|
-
forwardRef,
|
|
14
|
-
type HTMLAttributes,
|
|
15
|
-
type ReactElement,
|
|
16
|
-
type ReactNode,
|
|
17
|
-
type RefAttributes,
|
|
18
|
-
useMemo,
|
|
19
|
-
} from 'react'
|
|
20
|
-
import { FIELD_TEXT_INSET, FieldStateContext, useFieldState } from '../../../lib/field-classes'
|
|
21
|
-
import { type SizeVariant, useSize } from '../../../lib/size-context'
|
|
22
|
-
import { slotId, slotRender } from '../../../lib/slot'
|
|
23
|
-
import { cn } from '../../../lib/utils'
|
|
24
|
-
import { SizeProvider } from '../../../primitives/sizes'
|
|
25
|
-
import { Label } from '../input'
|
|
26
|
-
|
|
27
|
-
/** When native validity is checked. */
|
|
28
|
-
type FieldValidationMode = 'onSubmit' | 'onBlur' | 'onChange'
|
|
29
|
-
|
|
30
|
-
interface FieldProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
31
|
-
/** The field's parts: `Field.Label`, a control, `Field.Description`, `Field.Error`. */
|
|
32
|
-
children?: ReactNode
|
|
33
|
-
/** Marks the value invalid: the label and the control turn destructive and the control sets `aria-invalid`. Set it from your validation (a form library's field state). Defaults to `false`. */
|
|
34
|
-
invalid?: boolean
|
|
35
|
-
/** Disables the control and dims the field. Defaults to `false`. */
|
|
36
|
-
disabled?: boolean
|
|
37
|
-
/** Shows the value without letting it change (Input, NumberInput and FileDropzone read it). Defaults to `false`. */
|
|
38
|
-
readOnly?: boolean
|
|
39
|
-
/** Marks the control required and the label with an asterisk. Defaults to `false`. */
|
|
40
|
-
required?: boolean
|
|
41
|
-
/** Names the value when the form is submitted; wins over the control's own `name`. */
|
|
42
|
-
name?: string
|
|
43
|
-
/** Whether the value differs from its initial one, for a form library that tracks it (sets `data-dirty`). */
|
|
44
|
-
dirty?: boolean
|
|
45
|
-
/** Whether the control has been visited, for a form library that tracks it (sets `data-touched`). */
|
|
46
|
-
touched?: boolean
|
|
47
|
-
/** When Base UI checks the control's native validity (`required`, `pattern`, `type`): on form submit, on blur, or on every change. A failure turns the field destructive and an empty `Field.Error` shows the browser's message. Defaults to `"onSubmit"`. */
|
|
48
|
-
validationMode?: FieldValidationMode
|
|
49
|
-
/** Pins the field and its control to one step of the size ladder (36px default, 28px compact). Defaults to the surrounding SizeProvider. */
|
|
50
|
-
size?: SizeVariant
|
|
51
|
-
/** Classes for the root. */
|
|
52
|
-
className?: string
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
interface FieldLabelProps {
|
|
56
|
-
/** Label text. */
|
|
57
|
-
children: ReactNode
|
|
58
|
-
/** Keep the label for assistive tech but don't render it, for a field whose placeholder or context carries the meaning. Defaults to `false`. */
|
|
59
|
-
visuallyHidden?: boolean
|
|
60
|
-
/** Classes for the label. */
|
|
61
|
-
className?: string
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function FieldLabel({ children, visuallyHidden, className }: FieldLabelProps) {
|
|
65
|
-
const field = useFieldState()
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<BaseField.Label
|
|
69
|
-
render={
|
|
70
|
-
<Label invalid={field?.invalid} className={cn(visuallyHidden && 'sr-only', className)}>
|
|
71
|
-
{children}
|
|
72
|
-
{field?.required && <span aria-hidden="true"> *</span>}
|
|
73
|
-
</Label>
|
|
74
|
-
}
|
|
75
|
-
/>
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
interface FieldDescriptionProps {
|
|
80
|
-
/** Help text under the control: a format, a limit, what the value is for. */
|
|
81
|
-
children: ReactNode
|
|
82
|
-
/** Classes for the description. */
|
|
83
|
-
className?: string
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function FieldDescription({ children, className }: FieldDescriptionProps) {
|
|
87
|
-
const size = useSize()
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<BaseField.Description
|
|
91
|
-
className={cn(
|
|
92
|
-
'text-muted-foreground weight-normal data-[disabled]:opacity-50',
|
|
93
|
-
size.variant === 'compact' ? 'text-caption-compact' : 'text-caption',
|
|
94
|
-
FIELD_TEXT_INSET[size.variant],
|
|
95
|
-
className,
|
|
96
|
-
)}
|
|
97
|
-
>
|
|
98
|
-
{children}
|
|
99
|
-
</BaseField.Description>
|
|
100
|
-
)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** Which native validity state shows the message (`"valueMissing"`, `"typeMismatch"`, …). */
|
|
104
|
-
type FieldErrorMatch = boolean | keyof ValidityState
|
|
105
|
-
|
|
106
|
-
interface FieldErrorProps {
|
|
107
|
-
/** The message. While it has one, it shows; empty, it hides. */
|
|
108
|
-
children?: ReactNode
|
|
109
|
-
/** Overrides when it shows: `true` always, `false` never, or a native validity state such as `"valueMissing"`. Defaults to showing while it has a message. */
|
|
110
|
-
match?: FieldErrorMatch
|
|
111
|
-
/** Classes for the message. */
|
|
112
|
-
className?: string
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function FieldError({ children, match, className }: FieldErrorProps) {
|
|
116
|
-
const size = useSize()
|
|
117
|
-
const hasMessage = children != null && children !== false && children !== ''
|
|
118
|
-
|
|
119
|
-
return (
|
|
120
|
-
<BaseField.Error
|
|
121
|
-
// Without a message and a match, Base UI shows the native validation message.
|
|
122
|
-
match={match ?? (hasMessage || undefined)}
|
|
123
|
-
className={cn(
|
|
124
|
-
'text-destructive weight-medium',
|
|
125
|
-
size.variant === 'compact' ? 'text-caption-compact' : 'text-caption',
|
|
126
|
-
FIELD_TEXT_INSET[size.variant],
|
|
127
|
-
'transition-opacity duration-fast data-[starting-style]:opacity-0 data-[ending-style]:opacity-0 data-[ending-style]:duration-fast-exit',
|
|
128
|
-
className,
|
|
129
|
-
)}
|
|
130
|
-
// An explicit `children: undefined` would hide Base UI's own message.
|
|
131
|
-
{...(hasMessage ? { children } : {})}
|
|
132
|
-
/>
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
interface FieldControlProps {
|
|
137
|
-
/** The element that becomes the control, e.g. a native `<select>` or a third-party input. */
|
|
138
|
-
render?: ReactElement
|
|
139
|
-
/** Compose onto the single child instead. Defaults to `false`. */
|
|
140
|
-
asChild?: boolean
|
|
141
|
-
/** The control, with `asChild`. */
|
|
142
|
-
children?: ReactNode
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function FieldControl({ render, asChild, children }: FieldControlProps) {
|
|
146
|
-
const el = slotRender(render, asChild, children)
|
|
147
|
-
return <BaseField.Control render={el} id={slotId(el)} />
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
interface ProvideFieldStateProps {
|
|
151
|
-
invalid: boolean
|
|
152
|
-
disabled: boolean
|
|
153
|
-
readOnly: boolean
|
|
154
|
-
required: boolean
|
|
155
|
-
children?: ReactNode
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function ProvideFieldState({ invalid, disabled, readOnly, required, children }: ProvideFieldStateProps) {
|
|
159
|
-
const state = useMemo(
|
|
160
|
-
() => ({ active: false, invalid, disabled, readOnly, required }),
|
|
161
|
-
[invalid, disabled, readOnly, required],
|
|
162
|
-
)
|
|
163
|
-
return <FieldStateContext.Provider value={state}>{children}</FieldStateContext.Provider>
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
type FieldComponent = ForwardRefExoticComponent<FieldProps & RefAttributes<HTMLDivElement>> & {
|
|
167
|
-
Label: typeof FieldLabel
|
|
168
|
-
Description: typeof FieldDescription
|
|
169
|
-
Error: typeof FieldError
|
|
170
|
-
Control: typeof FieldControl
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* A labelled form field: a label above the control, help text and an error
|
|
175
|
-
* message below it, all linked for assistive tech.
|
|
176
|
-
*
|
|
177
|
-
* Put an Input, Textarea, NumberInput, FileDropzone, Select or any other
|
|
178
|
-
* field control inside and it joins on its own: the label targets it, the
|
|
179
|
-
* description and error are read with it, and the field hands it its
|
|
180
|
-
* `invalid`, `disabled`, `readOnly` and `required` state, so the box turns
|
|
181
|
-
* destructive with the label. The label and messages sit inset to line up
|
|
182
|
-
* with the text in the box. The field holds no validation of its own:
|
|
183
|
-
* `invalid` and the error's message come from yours (a form library's field
|
|
184
|
-
* state, a server response), and `Field.Error` shows while it has a message.
|
|
185
|
-
* A native failure (`required`, `pattern`, `type="email"`) caught by Base UI's
|
|
186
|
-
* validation turns it destructive too, and an empty `Field.Error` then shows
|
|
187
|
-
* the browser's message.
|
|
188
|
-
* Behavior comes from Base UI's Field.
|
|
189
|
-
*
|
|
190
|
-
* `size` pins the field and its control to one step of the size ladder;
|
|
191
|
-
* without it they follow the surrounding SizeProvider, which is how to set a
|
|
192
|
-
* form's density when a control's own props keep the native `<input size>`
|
|
193
|
-
* attribute (a character width, not a height). `Field.Control` passes a
|
|
194
|
-
* native `size` through to the element untouched.
|
|
195
|
-
*
|
|
196
|
-
* InputGroup.Field is the preset for a group of text fields: a label and an
|
|
197
|
-
* error string, and the group's hover gliding from field to field. Reach for
|
|
198
|
-
* Field when a field stands alone, needs a description, or holds a control
|
|
199
|
-
* other than a text input.
|
|
200
|
-
*
|
|
201
|
-
* Statics:
|
|
202
|
-
* - `Field.Label` — the label, weight-stable and muted; destructive while
|
|
203
|
-
* the field is invalid, with an asterisk while it is required:
|
|
204
|
-
* `visuallyHidden`.
|
|
205
|
-
* - `Field.Description` — muted help text under the control.
|
|
206
|
-
* - `Field.Error` — the destructive message; it fades in while it has
|
|
207
|
-
* children: `match` (`true`, `false`, or a native validity state).
|
|
208
|
-
* - `Field.Control` — wires a control that isn't a field control (a native
|
|
209
|
-
* element, a third-party input) with the field's id, `aria-describedby`
|
|
210
|
-
* and `aria-invalid`: `render={<select/>}` or `asChild`. Field controls
|
|
211
|
-
* (Input, NumberInput, …) need no wrapper.
|
|
212
|
-
*
|
|
213
|
-
* @example {@include ./examples.mdx}
|
|
214
|
-
*/
|
|
215
|
-
const Field = forwardRef<HTMLDivElement, FieldProps>(
|
|
216
|
-
(
|
|
217
|
-
{ invalid = false, disabled = false, readOnly = false, required = false, size, className, children, ...props },
|
|
218
|
-
ref,
|
|
219
|
-
) => {
|
|
220
|
-
const field = (
|
|
221
|
-
// Base UI wires the plumbing: Field.Label's htmlFor targets the
|
|
222
|
-
// control, Description and Error ids land in its aria-describedby, and
|
|
223
|
-
// `invalid` drives aria-invalid / data-invalid.
|
|
224
|
-
<BaseField.Root
|
|
225
|
-
ref={ref}
|
|
226
|
-
invalid={invalid}
|
|
227
|
-
disabled={disabled}
|
|
228
|
-
className={cn('flex min-w-0 flex-col gap-1', className)}
|
|
229
|
-
// The render function sees Base UI's validity, so a native failure
|
|
230
|
-
// (`required`, `pattern`, a type mismatch) turns the label and the box
|
|
231
|
-
// destructive too, not only the `invalid` prop.
|
|
232
|
-
render={(rootProps, rootState) => (
|
|
233
|
-
<div {...rootProps}>
|
|
234
|
-
<ProvideFieldState
|
|
235
|
-
invalid={invalid || rootState.valid === false}
|
|
236
|
-
disabled={disabled}
|
|
237
|
-
readOnly={readOnly}
|
|
238
|
-
required={required}
|
|
239
|
-
>
|
|
240
|
-
{rootProps.children}
|
|
241
|
-
</ProvideFieldState>
|
|
242
|
-
</div>
|
|
243
|
-
)}
|
|
244
|
-
{...props}
|
|
245
|
-
>
|
|
246
|
-
{children}
|
|
247
|
-
</BaseField.Root>
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
return size ? <SizeProvider size={size}>{field}</SizeProvider> : field
|
|
251
|
-
},
|
|
252
|
-
) as FieldComponent
|
|
253
|
-
|
|
254
|
-
Field.displayName = 'Field'
|
|
255
|
-
|
|
256
|
-
Object.assign(Field, { Label: FieldLabel, Description: FieldDescription, Error: FieldError, Control: FieldControl })
|
|
257
|
-
|
|
258
|
-
export type {
|
|
259
|
-
FieldControlProps,
|
|
260
|
-
FieldDescriptionProps,
|
|
261
|
-
FieldErrorMatch,
|
|
262
|
-
FieldErrorProps,
|
|
263
|
-
FieldLabelProps,
|
|
264
|
-
FieldProps,
|
|
265
|
-
FieldValidationMode,
|
|
266
|
-
}
|
|
267
|
-
export { Field, FieldControl, FieldDescription, FieldError, FieldLabel }
|
|
268
|
-
export default Field
|