@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,253 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Local addition (not part of Fluid Functionalism): a duration field with
|
|
3
|
-
* scrolling hour and minute columns. Props after utegsk/ui's DurationPicker
|
|
4
|
-
* (`minHours`, `maxHours`, `hourStep`, `minuteStep`, `formatValue`), its
|
|
5
|
-
* value a date-fns `Duration` instead of decimal hours.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { type Duration, formatDuration, type Locale } from 'date-fns'
|
|
9
|
-
import {
|
|
10
|
-
type ForwardRefExoticComponent,
|
|
11
|
-
forwardRef,
|
|
12
|
-
type ReactNode,
|
|
13
|
-
type RefAttributes,
|
|
14
|
-
type RefObject,
|
|
15
|
-
useMemo,
|
|
16
|
-
useRef,
|
|
17
|
-
} from 'react'
|
|
18
|
-
import { defaultLocale, fieldLabel, resolveLocale } from '../../../../lib/date-locale'
|
|
19
|
-
import type { FieldVariant } from '../../../../lib/field-classes'
|
|
20
|
-
import { dividedColumns, ScrollColumn } from '../../../../lib/scroll-column'
|
|
21
|
-
import type { SizeVariant } from '../../../../lib/size-context'
|
|
22
|
-
import { useControllableState } from '../../../../lib/use-controllable-state'
|
|
23
|
-
import { cn } from '../../../../lib/utils'
|
|
24
|
-
import { controlAttributes, invalidOf, type PickerControlProps, PickerInput, PickerShell } from '../picker-shell'
|
|
25
|
-
import { pad } from '../time-columns'
|
|
26
|
-
|
|
27
|
-
/** Every word the picker announces, for translating it. */
|
|
28
|
-
interface DurationPickerLabels {
|
|
29
|
-
/** Names the panel's duration input. Defaults to the `placeholder`, else `"Duration"`. */
|
|
30
|
-
duration?: string
|
|
31
|
-
/** Names the hour column. Defaults to the locale's name for it. */
|
|
32
|
-
hour?: string
|
|
33
|
-
/** Names the minute column. Defaults to the locale's name for it. */
|
|
34
|
-
minute?: string
|
|
35
|
-
/** Names the panel's close button. Defaults to `"Close"`. */
|
|
36
|
-
close?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
interface DurationPickerProps extends PickerControlProps {
|
|
40
|
-
/** The picked duration, a date-fns `Duration` (`{ hours, minutes }`); `null` when empty. */
|
|
41
|
-
value?: Duration | null
|
|
42
|
-
/** Initial duration, for an uncontrolled picker. Defaults to `null`. */
|
|
43
|
-
defaultValue?: Duration | null
|
|
44
|
-
/** Called with the new duration, or `null` when the field is cleared. */
|
|
45
|
-
onValueChange?: (value: Duration | null) => void
|
|
46
|
-
/** The shortest duration's hours: the hour column starts at it, and a minute picked on an empty field takes it. Defaults to `0`. */
|
|
47
|
-
minHours?: number
|
|
48
|
-
/** The longest duration's hours: the hour column runs up to it. Defaults to `99`. */
|
|
49
|
-
maxHours?: number
|
|
50
|
-
/** Steps between the hour column's options, from `minHours`. Defaults to `1`. */
|
|
51
|
-
hourStep?: number
|
|
52
|
-
/** Steps between the minute column's options. Defaults to `1`. */
|
|
53
|
-
minuteStep?: number
|
|
54
|
-
/** A react-day-picker / date-fns locale, or a BCP 47 tag (`"sk"`) read through Intl: the field spells the duration out in it ("1 Stunde 30 Minuten"; a tag reads the names in English). Defaults to `enUS`. */
|
|
55
|
-
locale?: Locale | string
|
|
56
|
-
/** The field's text for a duration, in place of the locale's words: `(value) => …`, given `{ hours, minutes }`. */
|
|
57
|
-
formatValue?: (value: Duration) => ReactNode
|
|
58
|
-
/** Every word the picker announces (`duration`, `hour`, `minute`, `close`), for translating it. Defaults to English and the locale's field names. */
|
|
59
|
-
labels?: DurationPickerLabels
|
|
60
|
-
/** Shows the duration but never opens. Defaults to `false`. */
|
|
61
|
-
readOnly?: boolean
|
|
62
|
-
/** Names the value for a native form: a hidden input carries it as an ISO 8601 duration (`"PT1H30M"`). */
|
|
63
|
-
name?: string
|
|
64
|
-
/** Shown while empty. */
|
|
65
|
-
placeholder?: string
|
|
66
|
-
/** Disables the field. Defaults to `false`. */
|
|
67
|
-
disabled?: boolean
|
|
68
|
-
/** Framed at rest, or invisible until hovered or focused. Defaults to `"bordered"`. */
|
|
69
|
-
variant?: FieldVariant
|
|
70
|
-
/** Marks the field invalid. Defaults to `false`. */
|
|
71
|
-
invalid?: boolean
|
|
72
|
-
/** Pins the field and its panel to one step of the size ladder. Defaults to the surrounding SizeProvider. */
|
|
73
|
-
size?: SizeVariant
|
|
74
|
-
/** Controlled open state. */
|
|
75
|
-
open?: boolean
|
|
76
|
-
/** Initial open state, for an uncontrolled panel. Defaults to `false`. */
|
|
77
|
-
defaultOpen?: boolean
|
|
78
|
-
/** Called when the panel opens or closes. */
|
|
79
|
-
onOpenChange?: (open: boolean) => void
|
|
80
|
-
/** Id of the field, for a `Label`'s `htmlFor`. */
|
|
81
|
-
id?: string
|
|
82
|
-
/** 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). */
|
|
83
|
-
from?: 'trigger' | 'pointer' | 'center' | 'top' | 'right' | 'bottom' | 'left' | RefObject<HTMLElement | null>
|
|
84
|
-
/** 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'`. */
|
|
85
|
-
effect?: 'goo' | 'morph' | 'slide' | 'fade'
|
|
86
|
-
/** Hide the field while open, so it reads as turning into the panel. Defaults to `false`. */
|
|
87
|
-
hideSource?: boolean
|
|
88
|
-
/** Spring tier of a plain morph, slide or fade; goo runs on its own `spring.goo`. Defaults to `'moderate'`. */
|
|
89
|
-
tier?: 'moderate' | 'slow'
|
|
90
|
-
/** Classes for the field. */
|
|
91
|
-
className?: string
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** "1:30", or a bare number of hours ("2"). */
|
|
95
|
-
const TYPED = /^\s*(\d{1,3})(?::(\d{1,2}))?\s*$/
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* A field for a length of time, in hours and minutes.
|
|
99
|
-
*
|
|
100
|
-
* The field spells the duration out in the locale ("1 hour 30 minutes"); its
|
|
101
|
-
* panel has it as `H:mm` to type over, above an hour column (`minHours` to
|
|
102
|
-
* `maxHours`, stepping by `hourStep`) and a minute column stepping by
|
|
103
|
-
* `minuteStep`. The value is a date-fns `Duration`, `{ hours, minutes }`,
|
|
104
|
-
* ready for `formatDuration` or date math.
|
|
105
|
-
*
|
|
106
|
-
* `formatValue` writes the field's text and `labels` every word it
|
|
107
|
-
* announces; `locale` also takes a BCP 47 tag. `readOnly` shows the duration
|
|
108
|
-
* and never opens. In a form, `name` submits the value as an ISO 8601
|
|
109
|
-
* duration (`"PT1H30M"`) and `required` stops an empty submit; `id`, the
|
|
110
|
-
* `aria-*` props, `onBlur`, `controlProps` and the `ref` reach the field's
|
|
111
|
-
* button.
|
|
112
|
-
*
|
|
113
|
-
* @example {@include ./examples.mdx}
|
|
114
|
-
*/
|
|
115
|
-
const DurationPicker: ForwardRefExoticComponent<DurationPickerProps & RefAttributes<HTMLButtonElement>> = forwardRef<
|
|
116
|
-
HTMLButtonElement,
|
|
117
|
-
DurationPickerProps
|
|
118
|
-
>(function DurationPicker(
|
|
119
|
-
{
|
|
120
|
-
value: valueProp,
|
|
121
|
-
defaultValue = null,
|
|
122
|
-
onValueChange,
|
|
123
|
-
minHours = 0,
|
|
124
|
-
maxHours = 99,
|
|
125
|
-
hourStep = 1,
|
|
126
|
-
minuteStep = 1,
|
|
127
|
-
locale: localeProp = defaultLocale,
|
|
128
|
-
formatValue,
|
|
129
|
-
labels,
|
|
130
|
-
readOnly = false,
|
|
131
|
-
name,
|
|
132
|
-
placeholder,
|
|
133
|
-
disabled,
|
|
134
|
-
variant,
|
|
135
|
-
invalid,
|
|
136
|
-
size,
|
|
137
|
-
open: openProp,
|
|
138
|
-
defaultOpen = false,
|
|
139
|
-
onOpenChange,
|
|
140
|
-
id,
|
|
141
|
-
from,
|
|
142
|
-
effect,
|
|
143
|
-
hideSource,
|
|
144
|
-
tier,
|
|
145
|
-
className,
|
|
146
|
-
...control
|
|
147
|
-
},
|
|
148
|
-
ref,
|
|
149
|
-
) {
|
|
150
|
-
const [value, setValue] = useControllableState(valueProp, defaultValue, onValueChange)
|
|
151
|
-
const [open, setOpen] = useControllableState(openProp, defaultOpen, onOpenChange)
|
|
152
|
-
const input = useRef<HTMLInputElement>(null)
|
|
153
|
-
const locale = resolveLocale(localeProp)
|
|
154
|
-
const hours = value?.hours ?? minHours
|
|
155
|
-
const minutes = value?.minutes ?? 0
|
|
156
|
-
|
|
157
|
-
const spelled = () =>
|
|
158
|
-
hours || minutes
|
|
159
|
-
? formatDuration({ hours, minutes }, { locale, format: ['hours', 'minutes'] })
|
|
160
|
-
: formatDuration({ minutes: 0 }, { locale, format: ['minutes'], zero: true })
|
|
161
|
-
const display = value ? (formatValue?.({ hours, minutes }) ?? spelled()) : ''
|
|
162
|
-
|
|
163
|
-
const readDuration = (text: string) => {
|
|
164
|
-
if (!text.trim()) {
|
|
165
|
-
setValue(null)
|
|
166
|
-
return true
|
|
167
|
-
}
|
|
168
|
-
const match = TYPED.exec(text)
|
|
169
|
-
const h = Number(match?.[1])
|
|
170
|
-
const m = Number(match?.[2] ?? 0)
|
|
171
|
-
if (!match || h < minHours || h > maxHours || m > 59) return false
|
|
172
|
-
setValue({ hours: h, minutes: m })
|
|
173
|
-
return true
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const hourOptions = useMemo(
|
|
177
|
-
() =>
|
|
178
|
-
Array.from({ length: Math.floor((maxHours - minHours) / Math.max(1, hourStep)) + 1 }, (_, i) => {
|
|
179
|
-
const h = minHours + i * Math.max(1, hourStep)
|
|
180
|
-
return { value: h, label: String(h) }
|
|
181
|
-
}),
|
|
182
|
-
[minHours, maxHours, hourStep],
|
|
183
|
-
)
|
|
184
|
-
const minuteOptions = useMemo(
|
|
185
|
-
() =>
|
|
186
|
-
Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => ({
|
|
187
|
-
value: i * minuteStep,
|
|
188
|
-
label: pad(i * minuteStep),
|
|
189
|
-
})),
|
|
190
|
-
[minuteStep],
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
return (
|
|
194
|
-
<PickerShell
|
|
195
|
-
open={open}
|
|
196
|
-
onOpenChange={setOpen}
|
|
197
|
-
size={size}
|
|
198
|
-
variant={variant}
|
|
199
|
-
invalid={invalidOf(invalid, control['aria-invalid'])}
|
|
200
|
-
disabled={disabled}
|
|
201
|
-
readOnly={readOnly}
|
|
202
|
-
icon="clock"
|
|
203
|
-
display={display}
|
|
204
|
-
placeholder={placeholder}
|
|
205
|
-
closeLabel={labels?.close}
|
|
206
|
-
controlRef={ref}
|
|
207
|
-
controlProps={controlAttributes(control)}
|
|
208
|
-
formValues={[{ slot: 'value', name, value: value ? `PT${hours}H${minutes}M` : '' }]}
|
|
209
|
-
required={control.required}
|
|
210
|
-
header={
|
|
211
|
-
<PickerInput
|
|
212
|
-
ref={input}
|
|
213
|
-
aria-label={labels?.duration || placeholder || 'Duration'}
|
|
214
|
-
placeholder="0:00"
|
|
215
|
-
formatted={value ? `${hours}:${pad(minutes)}` : ''}
|
|
216
|
-
onText={readDuration}
|
|
217
|
-
onEnter={() => setOpen(false)}
|
|
218
|
-
className="flex-1"
|
|
219
|
-
/>
|
|
220
|
-
}
|
|
221
|
-
initialFocus={input}
|
|
222
|
-
popupClassName="w-[max(var(--anchor-width,0px),14rem)]"
|
|
223
|
-
id={id}
|
|
224
|
-
from={from}
|
|
225
|
-
effect={effect}
|
|
226
|
-
hideSource={hideSource}
|
|
227
|
-
tier={tier}
|
|
228
|
-
className={className}
|
|
229
|
-
>
|
|
230
|
-
<div className={cn(dividedColumns, 'h-56')}>
|
|
231
|
-
<ScrollColumn
|
|
232
|
-
label={labels?.hour ?? fieldLabel(locale, 'hour')}
|
|
233
|
-
options={hourOptions}
|
|
234
|
-
value={value ? hours : null}
|
|
235
|
-
onValueChange={h => setValue({ hours: h, minutes })}
|
|
236
|
-
className="min-w-0 flex-1"
|
|
237
|
-
/>
|
|
238
|
-
<ScrollColumn
|
|
239
|
-
label={labels?.minute ?? fieldLabel(locale, 'minute')}
|
|
240
|
-
options={minuteOptions}
|
|
241
|
-
value={value ? minutes : null}
|
|
242
|
-
onValueChange={m => setValue({ hours, minutes: m })}
|
|
243
|
-
className="min-w-0 flex-1"
|
|
244
|
-
/>
|
|
245
|
-
</div>
|
|
246
|
-
</PickerShell>
|
|
247
|
-
)
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
export type { DurationPickerLabels, DurationPickerProps }
|
|
251
|
-
export { DurationPicker }
|
|
252
|
-
|
|
253
|
-
export default DurationPicker
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import MonthPicker from './index'
|
|
2
|
-
import { de } from 'react-day-picker/locale'
|
|
3
|
-
|
|
4
|
-
# Basic
|
|
5
|
-
|
|
6
|
-
<div className="w-60 max-w-full">
|
|
7
|
-
<MonthPicker defaultValue={new Date(2026, 9, 1)} />
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
# German, card expiry
|
|
11
|
-
|
|
12
|
-
`startMonth` and `endMonth` bound the years.
|
|
13
|
-
|
|
14
|
-
<div className="w-60 max-w-full">
|
|
15
|
-
<MonthPicker locale={de} placeholder="Ablaufdatum" startMonth={new Date(2026, 9, 1)} endMonth={new Date(2036, 11, 1)} />
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
# Month only
|
|
19
|
-
|
|
20
|
-
`withYear={false}` leaves the month column alone, for a month of no particular year.
|
|
21
|
-
|
|
22
|
-
<div className="w-60 max-w-full">
|
|
23
|
-
<MonthPicker withYear={false} placeholder="Billing month" defaultValue={new Date(2026, 9, 1)} />
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
# Slovak, labels and format
|
|
27
|
-
|
|
28
|
-
`locale="sk"` names the months in Slovak; `labels` names the columns and `formatDate` writes the field's text.
|
|
29
|
-
|
|
30
|
-
<div className="w-60 max-w-full">
|
|
31
|
-
<MonthPicker
|
|
32
|
-
locale="sk"
|
|
33
|
-
formatDate={date => date.toLocaleDateString('sk', { month: 'long', year: 'numeric' })}
|
|
34
|
-
labels={{ field: 'Mesiac', month: 'Mesiac', year: 'Rok', close: 'Zavrieť' }}
|
|
35
|
-
defaultValue={new Date(2026, 9, 1)}
|
|
36
|
-
/>
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
# Read only
|
|
40
|
-
|
|
41
|
-
`readOnly` shows the month and never opens.
|
|
42
|
-
|
|
43
|
-
<div className="w-60 max-w-full">
|
|
44
|
-
<MonthPicker readOnly defaultValue={new Date(2026, 9, 1)} />
|
|
45
|
-
</div>
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Local addition (not part of Fluid Functionalism): a month field with
|
|
3
|
-
* scrolling month and year columns. After utegsk/ui's MonthPicker, its value
|
|
4
|
-
* the month's first day (as react-day-picker's `month` is) instead of
|
|
5
|
-
* `{ month, year }`.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { addYears, endOfYear, format, type Locale, startOfMonth, startOfYear } from 'date-fns'
|
|
9
|
-
import {
|
|
10
|
-
type ForwardRefExoticComponent,
|
|
11
|
-
forwardRef,
|
|
12
|
-
type ReactNode,
|
|
13
|
-
type RefAttributes,
|
|
14
|
-
type RefObject,
|
|
15
|
-
useMemo,
|
|
16
|
-
useRef,
|
|
17
|
-
} from 'react'
|
|
18
|
-
import {
|
|
19
|
-
defaultLocale,
|
|
20
|
-
fieldLabel,
|
|
21
|
-
parseMonthNameText,
|
|
22
|
-
parseMonthText,
|
|
23
|
-
resolveLocale,
|
|
24
|
-
} from '../../../../lib/date-locale'
|
|
25
|
-
import type { FieldVariant } from '../../../../lib/field-classes'
|
|
26
|
-
import { dividedColumns, ScrollColumn } from '../../../../lib/scroll-column'
|
|
27
|
-
import type { SizeVariant } from '../../../../lib/size-context'
|
|
28
|
-
import { useControllableState } from '../../../../lib/use-controllable-state'
|
|
29
|
-
import { cn } from '../../../../lib/utils'
|
|
30
|
-
import { controlAttributes, invalidOf, type PickerControlProps, PickerInput, PickerShell } from '../picker-shell'
|
|
31
|
-
|
|
32
|
-
/** Every word the picker announces, for translating it. */
|
|
33
|
-
interface MonthPickerLabels {
|
|
34
|
-
/** Names the panel's month input. Defaults to the `placeholder`, else `"Month"`. */
|
|
35
|
-
field?: string
|
|
36
|
-
/** Names the month column. Defaults to the locale's name for it. */
|
|
37
|
-
month?: string
|
|
38
|
-
/** Names the year column. Defaults to the locale's name for it. */
|
|
39
|
-
year?: string
|
|
40
|
-
/** Names the panel's close button. Defaults to `"Close"`. */
|
|
41
|
-
close?: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface MonthPickerProps extends PickerControlProps {
|
|
45
|
-
/** The picked month as its first day; `null` when empty. */
|
|
46
|
-
value?: Date | null
|
|
47
|
-
/** Initial month, for an uncontrolled picker. Defaults to `null`. */
|
|
48
|
-
defaultValue?: Date | null
|
|
49
|
-
/** Called with the new month's first day, or `null` when the field is cleared. */
|
|
50
|
-
onValueChange?: (value: Date | null) => void
|
|
51
|
-
/** A react-day-picker / date-fns locale, or a BCP 47 tag (`"sk"`) read through Intl: month names and what typing reads. Defaults to `enUS`. */
|
|
52
|
-
locale?: Locale | string
|
|
53
|
-
/** Adds the year column, and the year to the field. `false` leaves a month of the current year (or of the value's). Defaults to `true`. */
|
|
54
|
-
withYear?: boolean
|
|
55
|
-
/** The field's text for a month, in place of the locale's ("October 2026"): `(date) => …`, given its first day. */
|
|
56
|
-
formatDate?: (date: Date) => ReactNode
|
|
57
|
-
/** Every word the picker announces (`field`, `month`, `year`, `close`), for translating it. Defaults to English and the locale's field names. */
|
|
58
|
-
labels?: MonthPickerLabels
|
|
59
|
-
/** Shows the month but never opens. Defaults to `false`. */
|
|
60
|
-
readOnly?: boolean
|
|
61
|
-
/** Names the value for a native form: a hidden input carries it as `"yyyy-MM"` (an `<input type="month">`'s value). */
|
|
62
|
-
name?: string
|
|
63
|
-
/** Shown while empty. */
|
|
64
|
-
placeholder?: string
|
|
65
|
-
/** The first month that can be picked. Defaults to 100 years back. */
|
|
66
|
-
startMonth?: Date
|
|
67
|
-
/** The last month that can be picked. Defaults to 50 years ahead. */
|
|
68
|
-
endMonth?: Date
|
|
69
|
-
/** Disables the field. Defaults to `false`. */
|
|
70
|
-
disabled?: boolean
|
|
71
|
-
/** Framed at rest, or invisible until hovered or focused. Defaults to `"bordered"`. */
|
|
72
|
-
variant?: FieldVariant
|
|
73
|
-
/** Marks the field invalid. Defaults to `false`. */
|
|
74
|
-
invalid?: boolean
|
|
75
|
-
/** Pins the field and its panel to one step of the size ladder. Defaults to the surrounding SizeProvider. */
|
|
76
|
-
size?: SizeVariant
|
|
77
|
-
/** Controlled open state. */
|
|
78
|
-
open?: boolean
|
|
79
|
-
/** Initial open state, for an uncontrolled panel. Defaults to `false`. */
|
|
80
|
-
defaultOpen?: boolean
|
|
81
|
-
/** Called when the panel opens or closes. */
|
|
82
|
-
onOpenChange?: (open: boolean) => void
|
|
83
|
-
/** Id of the field, for a `Label`'s `htmlFor`. */
|
|
84
|
-
id?: string
|
|
85
|
-
/** 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). */
|
|
86
|
-
from?: 'trigger' | 'pointer' | 'center' | 'top' | 'right' | 'bottom' | 'left' | RefObject<HTMLElement | null>
|
|
87
|
-
/** 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'`. */
|
|
88
|
-
effect?: 'goo' | 'morph' | 'slide' | 'fade'
|
|
89
|
-
/** Hide the field while open, so it reads as turning into the panel. Defaults to `false`. */
|
|
90
|
-
hideSource?: boolean
|
|
91
|
-
/** Spring tier of a plain morph, slide or fade; goo runs on its own `spring.goo`. Defaults to `'moderate'`. */
|
|
92
|
-
tier?: 'moderate' | 'slow'
|
|
93
|
-
/** Classes for the field. */
|
|
94
|
-
className?: string
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* A field for a month of a year: a billing period, a card's expiry.
|
|
99
|
-
*
|
|
100
|
-
* The panel has the month as text to type over ("October 2026", "10/2026"),
|
|
101
|
-
* above a month column and a year column; the picked month and year carry a
|
|
102
|
-
* dot. The value is the month's first day, the way react-day-picker names a
|
|
103
|
-
* month. `withYear={false}` leaves the month column alone, for a month of
|
|
104
|
-
* no particular year (the value keeps the current year).
|
|
105
|
-
*
|
|
106
|
-
* `formatDate` writes the field's text and `labels` every word it
|
|
107
|
-
* announces; `locale` also takes a BCP 47 tag. `readOnly` shows the month
|
|
108
|
-
* and never opens. In a form, `name` submits the value as `"yyyy-MM"` and
|
|
109
|
-
* `required` stops an empty submit; `id`, the `aria-*` props, `onBlur`,
|
|
110
|
-
* `controlProps` and the `ref` reach the field's button.
|
|
111
|
-
*
|
|
112
|
-
* @example {@include ./examples.mdx}
|
|
113
|
-
*/
|
|
114
|
-
const MonthPicker: ForwardRefExoticComponent<MonthPickerProps & RefAttributes<HTMLButtonElement>> = forwardRef<
|
|
115
|
-
HTMLButtonElement,
|
|
116
|
-
MonthPickerProps
|
|
117
|
-
>(function MonthPicker(
|
|
118
|
-
{
|
|
119
|
-
value: valueProp,
|
|
120
|
-
defaultValue = null,
|
|
121
|
-
onValueChange,
|
|
122
|
-
locale: localeProp = defaultLocale,
|
|
123
|
-
withYear = true,
|
|
124
|
-
formatDate,
|
|
125
|
-
labels,
|
|
126
|
-
readOnly = false,
|
|
127
|
-
name,
|
|
128
|
-
placeholder,
|
|
129
|
-
startMonth,
|
|
130
|
-
endMonth,
|
|
131
|
-
disabled,
|
|
132
|
-
variant,
|
|
133
|
-
invalid,
|
|
134
|
-
size,
|
|
135
|
-
open: openProp,
|
|
136
|
-
defaultOpen = false,
|
|
137
|
-
onOpenChange,
|
|
138
|
-
id,
|
|
139
|
-
from,
|
|
140
|
-
effect,
|
|
141
|
-
hideSource,
|
|
142
|
-
tier,
|
|
143
|
-
className,
|
|
144
|
-
...control
|
|
145
|
-
},
|
|
146
|
-
ref,
|
|
147
|
-
) {
|
|
148
|
-
const [value, setValue] = useControllableState(valueProp, defaultValue, onValueChange)
|
|
149
|
-
const [open, setOpen] = useControllableState(openProp, defaultOpen, onOpenChange)
|
|
150
|
-
const input = useRef<HTMLInputElement>(null)
|
|
151
|
-
const locale = resolveLocale(localeProp)
|
|
152
|
-
const today = useMemo(() => new Date(), [])
|
|
153
|
-
const start = startOfMonth(startMonth ?? startOfYear(addYears(today, -100)))
|
|
154
|
-
const end = startOfMonth(endMonth ?? endOfYear(addYears(today, 50)))
|
|
155
|
-
const year = value?.getFullYear() ?? today.getFullYear()
|
|
156
|
-
const formatted = value ? format(value, withYear ? 'LLLL y' : 'LLLL', { locale }) : ''
|
|
157
|
-
|
|
158
|
-
// Clamped into the range, so a year change can't land outside it.
|
|
159
|
-
const pick = (date: Date) => setValue(startOfMonth(date < start ? start : date > end ? end : date))
|
|
160
|
-
|
|
161
|
-
const readMonth = (text: string) => {
|
|
162
|
-
if (!text.trim()) {
|
|
163
|
-
setValue(null)
|
|
164
|
-
return true
|
|
165
|
-
}
|
|
166
|
-
const read = withYear ? parseMonthText(text, locale) : parseMonthNameText(text, locale, new Date(year, 0, 1))
|
|
167
|
-
if (!read || read < start || read > end) return false
|
|
168
|
-
setValue(startOfMonth(read))
|
|
169
|
-
return true
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const months = useMemo(
|
|
173
|
-
() =>
|
|
174
|
-
Array.from({ length: 12 }, (_, m) => ({
|
|
175
|
-
value: m,
|
|
176
|
-
label: format(new Date(2000, m, 1), 'LLLL', { locale }),
|
|
177
|
-
disabled: new Date(year, m, 1) < start || new Date(year, m, 1) > end,
|
|
178
|
-
})),
|
|
179
|
-
[locale, year, start.getTime(), end.getTime()],
|
|
180
|
-
)
|
|
181
|
-
const years = useMemo(
|
|
182
|
-
() =>
|
|
183
|
-
Array.from({ length: end.getFullYear() - start.getFullYear() + 1 }, (_, i) => ({
|
|
184
|
-
value: start.getFullYear() + i,
|
|
185
|
-
label: String(start.getFullYear() + i),
|
|
186
|
-
})),
|
|
187
|
-
[start.getFullYear(), end.getFullYear()],
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
return (
|
|
191
|
-
<PickerShell
|
|
192
|
-
open={open}
|
|
193
|
-
onOpenChange={setOpen}
|
|
194
|
-
size={size}
|
|
195
|
-
variant={variant}
|
|
196
|
-
invalid={invalidOf(invalid, control['aria-invalid'])}
|
|
197
|
-
disabled={disabled}
|
|
198
|
-
readOnly={readOnly}
|
|
199
|
-
icon="calendar"
|
|
200
|
-
display={value && formatDate ? formatDate(value) : formatted}
|
|
201
|
-
placeholder={placeholder}
|
|
202
|
-
closeLabel={labels?.close}
|
|
203
|
-
controlRef={ref}
|
|
204
|
-
controlProps={controlAttributes(control)}
|
|
205
|
-
formValues={[{ slot: 'value', name, value: value ? format(value, 'yyyy-MM') : '' }]}
|
|
206
|
-
required={control.required}
|
|
207
|
-
header={
|
|
208
|
-
<PickerInput
|
|
209
|
-
ref={input}
|
|
210
|
-
aria-label={labels?.field || placeholder || 'Month'}
|
|
211
|
-
placeholder={placeholder}
|
|
212
|
-
formatted={formatted}
|
|
213
|
-
onText={readMonth}
|
|
214
|
-
onEnter={() => setOpen(false)}
|
|
215
|
-
className="flex-1"
|
|
216
|
-
/>
|
|
217
|
-
}
|
|
218
|
-
initialFocus={input}
|
|
219
|
-
popupClassName="w-[max(var(--anchor-width,0px),14rem)]"
|
|
220
|
-
id={id}
|
|
221
|
-
from={from}
|
|
222
|
-
effect={effect}
|
|
223
|
-
hideSource={hideSource}
|
|
224
|
-
tier={tier}
|
|
225
|
-
className={className}
|
|
226
|
-
>
|
|
227
|
-
<div className={cn(dividedColumns, 'h-56')}>
|
|
228
|
-
<ScrollColumn
|
|
229
|
-
label={labels?.month ?? fieldLabel(locale, 'month')}
|
|
230
|
-
options={months}
|
|
231
|
-
value={value?.getMonth() ?? null}
|
|
232
|
-
follow={value?.getMonth() ?? today.getMonth()}
|
|
233
|
-
onValueChange={m => pick(new Date(year, m, 1))}
|
|
234
|
-
className="min-w-0 flex-1"
|
|
235
|
-
/>
|
|
236
|
-
{withYear && (
|
|
237
|
-
<ScrollColumn
|
|
238
|
-
label={labels?.year ?? fieldLabel(locale, 'year')}
|
|
239
|
-
options={years}
|
|
240
|
-
value={value?.getFullYear() ?? null}
|
|
241
|
-
follow={year}
|
|
242
|
-
onValueChange={y => pick(new Date(y, value?.getMonth() ?? today.getMonth(), 1))}
|
|
243
|
-
className="min-w-0 flex-1"
|
|
244
|
-
/>
|
|
245
|
-
)}
|
|
246
|
-
</div>
|
|
247
|
-
</PickerShell>
|
|
248
|
-
)
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
export type { MonthPickerLabels, MonthPickerProps }
|
|
252
|
-
export { MonthPicker }
|
|
253
|
-
|
|
254
|
-
export default MonthPicker
|