@krizaka/ui 2.2.0 → 2.4.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 +33 -8
- package/dist/audio-player.d.ts +113 -0
- package/dist/audio-player.js +207 -0
- package/dist/audio-player.js.map +1 -0
- package/dist/{button-Cgfkg_3y.d.ts → button-BMAO7dKF.d.ts} +29 -2
- package/dist/button.d.ts +32 -5
- package/dist/button.js +62 -9
- package/dist/button.js.map +1 -1
- package/dist/chip-link.d.ts +53 -0
- package/dist/chip-link.js +32 -0
- package/dist/chip-link.js.map +1 -0
- package/dist/chunk-2USC2YT6.js +17 -0
- package/dist/chunk-2USC2YT6.js.map +1 -0
- package/dist/chunk-43PTCDTL.js +31 -0
- package/dist/chunk-43PTCDTL.js.map +1 -0
- package/dist/chunk-6ISW63JI.js +11 -0
- package/dist/chunk-6ISW63JI.js.map +1 -0
- package/dist/chunk-EUPTXKH7.js +95 -0
- package/dist/chunk-EUPTXKH7.js.map +1 -0
- package/dist/chunk-HAQWKORZ.js +117 -0
- package/dist/chunk-HAQWKORZ.js.map +1 -0
- package/dist/{chunk-FHYZSO2S.js → chunk-R6SDS7JM.js} +5 -3
- package/dist/chunk-R6SDS7JM.js.map +1 -0
- package/dist/chunk-RUPNPMP3.js +103 -0
- package/dist/chunk-RUPNPMP3.js.map +1 -0
- package/dist/chunk-RUPRYJ45.js +82 -0
- package/dist/chunk-RUPRYJ45.js.map +1 -0
- package/dist/chunk-VDR2EP6K.js +49 -0
- package/dist/chunk-VDR2EP6K.js.map +1 -0
- package/dist/chunk-WEVYKZIF.js +33 -0
- package/dist/chunk-WEVYKZIF.js.map +1 -0
- package/dist/chunk-XUMJA5ZI.js +283 -0
- package/dist/chunk-XUMJA5ZI.js.map +1 -0
- package/dist/chunk-YH4LMWRU.js +92 -0
- package/dist/chunk-YH4LMWRU.js.map +1 -0
- package/dist/chunk-YX6CNVJA.js +94 -0
- package/dist/chunk-YX6CNVJA.js.map +1 -0
- package/dist/chunk-ZIXB33X7.js +95 -0
- package/dist/chunk-ZIXB33X7.js.map +1 -0
- package/dist/combobox.d.ts +188 -0
- package/dist/combobox.js +16 -0
- package/dist/combobox.js.map +1 -0
- package/dist/command.d.ts +7 -7
- package/dist/command.js +3 -2
- package/dist/command.js.map +1 -1
- package/dist/confirm-button.d.ts +1 -1
- package/dist/confirm-button.js +2 -1
- package/dist/confirm-button.js.map +1 -1
- package/dist/data-table.d.ts +246 -0
- package/dist/data-table.js +290 -0
- package/dist/data-table.js.map +1 -0
- package/dist/date-picker.d.ts +288 -0
- package/dist/date-picker.js +364 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/{dialog-GQ4Nvuyf.d.ts → dialog-D42QwYb_.d.ts} +11 -1
- package/dist/dialog.d.ts +1 -1
- package/dist/dialog.js +3 -2
- package/dist/dialog.js.map +1 -1
- package/dist/file-upload.d.ts +238 -0
- package/dist/file-upload.js +437 -0
- package/dist/file-upload.js.map +1 -0
- package/dist/filter-bar.d.ts +139 -0
- package/dist/filter-bar.js +155 -0
- package/dist/filter-bar.js.map +1 -0
- package/dist/glow-card.d.ts +20 -0
- package/dist/glow-card.js +30 -0
- package/dist/glow-card.js.map +1 -0
- package/dist/image-cropper.d.ts +115 -0
- package/dist/image-cropper.js +166 -0
- package/dist/image-cropper.js.map +1 -0
- package/dist/index.d.ts +2 -20
- package/dist/index.js +7 -64
- package/dist/index.js.map +1 -1
- package/dist/iso.d.ts +400 -0
- package/dist/iso.js +363 -0
- package/dist/iso.js.map +1 -0
- package/dist/loader.d.ts +206 -0
- package/dist/loader.js +138 -0
- package/dist/loader.js.map +1 -0
- package/dist/marquee.d.ts +33 -0
- package/dist/marquee.js +52 -0
- package/dist/marquee.js.map +1 -0
- package/dist/media-capture.d.ts +155 -0
- package/dist/media-capture.js +242 -0
- package/dist/media-capture.js.map +1 -0
- package/dist/meter.d.ts +146 -0
- package/dist/meter.js +107 -0
- package/dist/meter.js.map +1 -0
- package/dist/motion.css +394 -3
- package/dist/motion.d.ts +46 -0
- package/dist/motion.js +10 -0
- package/dist/motion.js.map +1 -0
- package/dist/native/media-capture.d.ts +49 -0
- package/dist/native/media-capture.js +113 -0
- package/dist/native/media-capture.js.map +1 -0
- package/dist/native/video-player.d.ts +50 -0
- package/dist/native/video-player.js +69 -0
- package/dist/native/video-player.js.map +1 -0
- package/dist/native.d.ts +66 -2
- package/dist/native.js +166 -68
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.d.ts +178 -0
- package/dist/nav-bar.js +157 -0
- package/dist/nav-bar.js.map +1 -0
- package/dist/number-ticker.d.ts +32 -0
- package/dist/number-ticker.js +61 -0
- package/dist/number-ticker.js.map +1 -0
- package/dist/pagination.d.ts +141 -0
- package/dist/pagination.js +165 -0
- package/dist/pagination.js.map +1 -0
- package/dist/progress.d.ts +56 -1
- package/dist/progress.js +72 -25
- package/dist/progress.js.map +1 -1
- package/dist/search-field.d.ts +100 -0
- package/dist/search-field.js +167 -0
- package/dist/search-field.js.map +1 -0
- package/dist/skeleton.d.ts +18 -3
- package/dist/skeleton.js +9 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/spinner.d.ts +21 -5
- package/dist/spinner.js +13 -12
- package/dist/spinner.js.map +1 -1
- package/dist/stepper.d.ts +112 -0
- package/dist/stepper.js +67 -0
- package/dist/stepper.js.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +14 -8
- package/dist/tabs.js.map +1 -1
- package/dist/tag-input.d.ts +44 -0
- package/dist/tag-input.js +67 -0
- package/dist/tag-input.js.map +1 -0
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +2 -1
- package/dist/theme.js.map +1 -1
- package/dist/toast.d.ts +39 -4
- package/dist/toast.js +81 -7
- package/dist/toast.js.map +1 -1
- package/dist/video-player.d.ts +204 -0
- package/dist/video-player.js +371 -0
- package/dist/video-player.js.map +1 -0
- package/dist/video-trimmer.d.ts +142 -0
- package/dist/video-trimmer.js +193 -0
- package/dist/video-trimmer.js.map +1 -0
- package/package.json +375 -7
- package/registry/alert.json +1 -1
- package/registry/audio-player.json +282 -0
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +232 -26
- package/registry/card.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +158 -0
- package/registry/chip.json +1 -1
- package/registry/combobox.json +475 -0
- package/registry/command.json +1 -1
- package/registry/confirm-button.json +91 -7
- package/registry/countdown.json +1 -1
- package/registry/data-table.json +500 -0
- package/registry/date-picker.json +978 -0
- package/registry/dialog.json +15 -7
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/examples/audio-player/podcast.js +22 -0
- package/registry/examples/audio-player/podcast.tsx +19 -0
- package/registry/examples/audio-player/voice-note.d.ts +4 -0
- package/registry/examples/audio-player/voice-note.js +12 -0
- package/registry/examples/audio-player/voice-note.tsx +12 -0
- package/registry/examples/button/error.d.ts +4 -0
- package/registry/examples/button/error.js +11 -0
- package/registry/examples/button/error.tsx +10 -0
- package/registry/examples/button/loading.tsx +1 -1
- package/registry/examples/button/save-flow.d.ts +4 -0
- package/registry/examples/button/save-flow.js +28 -0
- package/registry/examples/button/save-flow.tsx +24 -0
- package/registry/examples/button/signature.d.ts +4 -0
- package/registry/examples/button/signature.js +17 -0
- package/registry/examples/button/signature.tsx +19 -0
- package/registry/examples/button/upload-progress.d.ts +4 -0
- package/registry/examples/button/upload-progress.js +23 -0
- package/registry/examples/button/upload-progress.tsx +26 -0
- package/registry/examples/chip-link/filters.d.ts +4 -0
- package/registry/examples/chip-link/filters.js +12 -0
- package/registry/examples/chip-link/filters.tsx +17 -0
- package/registry/examples/combobox/async.d.ts +4 -0
- package/registry/examples/combobox/async.js +23 -0
- package/registry/examples/combobox/async.tsx +22 -0
- package/registry/examples/combobox/creatable.d.ts +4 -0
- package/registry/examples/combobox/creatable.js +32 -0
- package/registry/examples/combobox/creatable.tsx +28 -0
- package/registry/examples/combobox/invalid.d.ts +4 -0
- package/registry/examples/combobox/invalid.js +23 -0
- package/registry/examples/combobox/invalid.tsx +17 -0
- package/registry/examples/combobox/multiple.d.ts +4 -0
- package/registry/examples/combobox/multiple.js +29 -0
- package/registry/examples/combobox/multiple.tsx +26 -0
- package/registry/examples/data-table/cards.d.ts +4 -0
- package/registry/examples/data-table/cards.js +21 -0
- package/registry/examples/data-table/cards.tsx +20 -0
- package/registry/examples/data-table/empty.d.ts +4 -0
- package/registry/examples/data-table/empty.js +26 -0
- package/registry/examples/data-table/empty.tsx +21 -0
- package/registry/examples/data-table/error.d.ts +4 -0
- package/registry/examples/data-table/error.js +28 -0
- package/registry/examples/data-table/error.tsx +29 -0
- package/registry/examples/data-table/jobs.d.ts +4 -0
- package/registry/examples/data-table/jobs.js +37 -0
- package/registry/examples/data-table/jobs.tsx +36 -0
- package/registry/examples/data-table/loading.d.ts +4 -0
- package/registry/examples/data-table/loading.js +16 -0
- package/registry/examples/data-table/loading.tsx +12 -0
- package/registry/examples/data-table/virtualized.d.ts +4 -0
- package/registry/examples/data-table/virtualized.js +21 -0
- package/registry/examples/data-table/virtualized.tsx +20 -0
- package/registry/examples/date-picker/calendar.d.ts +4 -0
- package/registry/examples/date-picker/calendar.js +14 -0
- package/registry/examples/date-picker/calendar.tsx +16 -0
- package/registry/examples/date-picker/french.d.ts +4 -0
- package/registry/examples/date-picker/french.js +20 -0
- package/registry/examples/date-picker/french.tsx +14 -0
- package/registry/examples/date-picker/open.d.ts +4 -0
- package/registry/examples/date-picker/open.js +11 -0
- package/registry/examples/date-picker/open.tsx +8 -0
- package/registry/examples/date-picker/range.d.ts +4 -0
- package/registry/examples/date-picker/range.js +29 -0
- package/registry/examples/date-picker/range.tsx +25 -0
- package/registry/examples/date-picker/schedule.d.ts +4 -0
- package/registry/examples/date-picker/schedule.js +26 -0
- package/registry/examples/date-picker/schedule.tsx +22 -0
- package/registry/examples/dialog/left.d.ts +4 -0
- package/registry/examples/dialog/left.js +22 -0
- package/registry/examples/dialog/left.tsx +32 -0
- package/registry/examples/file-upload/images.d.ts +4 -0
- package/registry/examples/file-upload/images.js +32 -0
- package/registry/examples/file-upload/images.tsx +25 -0
- package/registry/examples/file-upload/states.d.ts +4 -0
- package/registry/examples/file-upload/states.js +28 -0
- package/registry/examples/file-upload/states.tsx +23 -0
- package/registry/examples/file-upload/tus.d.ts +4 -0
- package/registry/examples/file-upload/tus.js +23 -0
- package/registry/examples/file-upload/tus.tsx +26 -0
- package/registry/examples/file-upload/video.d.ts +4 -0
- package/registry/examples/file-upload/video.js +39 -0
- package/registry/examples/file-upload/video.tsx +36 -0
- package/registry/examples/filter-bar/address.d.ts +4 -0
- package/registry/examples/filter-bar/address.js +29 -0
- package/registry/examples/filter-bar/address.tsx +27 -0
- package/registry/examples/filter-bar/jobs.d.ts +4 -0
- package/registry/examples/filter-bar/jobs.js +37 -0
- package/registry/examples/filter-bar/jobs.tsx +37 -0
- package/registry/examples/filter-bar/menu.d.ts +4 -0
- package/registry/examples/filter-bar/menu.js +27 -0
- package/registry/examples/filter-bar/menu.tsx +23 -0
- package/registry/examples/glow-card/link-card.d.ts +4 -0
- package/registry/examples/glow-card/link-card.js +14 -0
- package/registry/examples/glow-card/link-card.tsx +13 -0
- package/registry/examples/glow-card/plans.d.ts +4 -0
- package/registry/examples/glow-card/plans.js +25 -0
- package/registry/examples/glow-card/plans.tsx +26 -0
- package/registry/examples/glow-card/spotlight.d.ts +4 -0
- package/registry/examples/glow-card/spotlight.js +14 -0
- package/registry/examples/glow-card/spotlight.tsx +15 -0
- package/registry/examples/image-cropper/avatar.d.ts +4 -0
- package/registry/examples/image-cropper/avatar.js +13 -0
- package/registry/examples/image-cropper/avatar.tsx +14 -0
- package/registry/examples/image-cropper/banner.d.ts +4 -0
- package/registry/examples/image-cropper/banner.js +11 -0
- package/registry/examples/image-cropper/banner.tsx +10 -0
- package/registry/examples/image-cropper/vertical-video.d.ts +4 -0
- package/registry/examples/image-cropper/vertical-video.js +12 -0
- package/registry/examples/image-cropper/vertical-video.tsx +16 -0
- package/registry/examples/iso/compose.d.ts +4 -0
- package/registry/examples/iso/compose.js +22 -0
- package/registry/examples/iso/compose.tsx +19 -0
- package/registry/examples/iso/orazaka-hero.d.ts +4 -0
- package/registry/examples/iso/orazaka-hero.js +26 -0
- package/registry/examples/iso/orazaka-hero.tsx +21 -0
- package/registry/examples/iso/orochia-hero.d.ts +4 -0
- package/registry/examples/iso/orochia-hero.js +29 -0
- package/registry/examples/iso/orochia-hero.tsx +23 -0
- package/registry/examples/iso/still.d.ts +4 -0
- package/registry/examples/iso/still.js +21 -0
- package/registry/examples/iso/still.tsx +15 -0
- package/registry/examples/loader/endings.d.ts +4 -0
- package/registry/examples/loader/endings.js +14 -0
- package/registry/examples/loader/endings.tsx +11 -0
- package/registry/examples/loader/fetch-flow.d.ts +4 -0
- package/registry/examples/loader/fetch-flow.js +24 -0
- package/registry/examples/loader/fetch-flow.tsx +24 -0
- package/registry/examples/loader/minimal.d.ts +4 -0
- package/registry/examples/loader/minimal.js +11 -0
- package/registry/examples/loader/minimal.tsx +6 -0
- package/registry/examples/loader/overlay.d.ts +4 -0
- package/registry/examples/loader/overlay.js +16 -0
- package/registry/examples/loader/overlay.tsx +13 -0
- package/registry/examples/loader/region-handover.d.ts +4 -0
- package/registry/examples/loader/region-handover.js +42 -0
- package/registry/examples/loader/region-handover.tsx +29 -0
- package/registry/examples/loader/upload-eta.d.ts +4 -0
- package/registry/examples/loader/upload-eta.js +11 -0
- package/registry/examples/loader/upload-eta.tsx +10 -0
- package/registry/examples/marquee/cards.d.ts +4 -0
- package/registry/examples/marquee/cards.js +23 -0
- package/registry/examples/marquee/cards.tsx +21 -0
- package/registry/examples/marquee/logos.d.ts +4 -0
- package/registry/examples/marquee/logos.js +12 -0
- package/registry/examples/marquee/logos.tsx +17 -0
- package/registry/examples/media-capture/clip.d.ts +4 -0
- package/registry/examples/media-capture/clip.js +20 -0
- package/registry/examples/media-capture/clip.tsx +18 -0
- package/registry/examples/media-capture/native/photo.d.ts +4 -0
- package/registry/examples/media-capture/native/photo.dark.png +0 -0
- package/registry/examples/media-capture/native/photo.js +27 -0
- package/registry/examples/media-capture/native/photo.light.png +0 -0
- package/registry/examples/media-capture/native/photo.tsx +20 -0
- package/registry/examples/media-capture/profile-photo.d.ts +4 -0
- package/registry/examples/media-capture/profile-photo.js +24 -0
- package/registry/examples/media-capture/profile-photo.tsx +20 -0
- package/registry/examples/meter/balance.d.ts +4 -0
- package/registry/examples/meter/balance.js +14 -0
- package/registry/examples/meter/balance.tsx +15 -0
- package/registry/examples/meter/quota.d.ts +4 -0
- package/registry/examples/meter/quota.js +15 -0
- package/registry/examples/meter/quota.tsx +12 -0
- package/registry/examples/meter/split.d.ts +4 -0
- package/registry/examples/meter/split.js +18 -0
- package/registry/examples/meter/split.tsx +18 -0
- package/registry/examples/nav-bar/app-bar.d.ts +4 -0
- package/registry/examples/nav-bar/app-bar.js +22 -0
- package/registry/examples/nav-bar/app-bar.tsx +21 -0
- package/registry/examples/nav-bar/menu-open.d.ts +4 -0
- package/registry/examples/nav-bar/menu-open.js +26 -0
- package/registry/examples/nav-bar/menu-open.tsx +26 -0
- package/registry/examples/nav-bar/site.d.ts +4 -0
- package/registry/examples/nav-bar/site.js +31 -0
- package/registry/examples/nav-bar/site.tsx +36 -0
- package/registry/examples/number-ticker/gradient.d.ts +4 -0
- package/registry/examples/number-ticker/gradient.js +11 -0
- package/registry/examples/number-ticker/gradient.tsx +10 -0
- package/registry/examples/number-ticker/live-total.d.ts +4 -0
- package/registry/examples/number-ticker/live-total.js +17 -0
- package/registry/examples/number-ticker/live-total.tsx +21 -0
- package/registry/examples/number-ticker/stats.d.ts +4 -0
- package/registry/examples/number-ticker/stats.js +19 -0
- package/registry/examples/number-ticker/stats.tsx +23 -0
- package/registry/examples/pagination/cursor.d.ts +4 -0
- package/registry/examples/pagination/cursor.js +24 -0
- package/registry/examples/pagination/cursor.tsx +20 -0
- package/registry/examples/pagination/links.d.ts +4 -0
- package/registry/examples/pagination/links.js +11 -0
- package/registry/examples/pagination/links.tsx +6 -0
- package/registry/examples/pagination/native/cursor.d.ts +4 -0
- package/registry/examples/pagination/native/cursor.dark.png +0 -0
- package/registry/examples/pagination/native/cursor.js +19 -0
- package/registry/examples/pagination/native/cursor.light.png +0 -0
- package/registry/examples/pagination/native/cursor.tsx +13 -0
- package/registry/examples/pagination/native/pages.d.ts +4 -0
- package/registry/examples/pagination/native/pages.dark.png +0 -0
- package/registry/examples/pagination/native/pages.js +21 -0
- package/registry/examples/pagination/native/pages.light.png +0 -0
- package/registry/examples/pagination/native/pages.tsx +14 -0
- package/registry/examples/pagination/results.d.ts +4 -0
- package/registry/examples/pagination/results.js +23 -0
- package/registry/examples/pagination/results.tsx +19 -0
- package/registry/examples/pagination/table-footer.d.ts +4 -0
- package/registry/examples/pagination/table-footer.js +31 -0
- package/registry/examples/pagination/table-footer.tsx +27 -0
- package/registry/examples/progress/buffer.d.ts +4 -0
- package/registry/examples/progress/buffer.js +11 -0
- package/registry/examples/progress/buffer.tsx +10 -0
- package/registry/examples/progress/statuses.d.ts +4 -0
- package/registry/examples/progress/statuses.js +14 -0
- package/registry/examples/progress/statuses.tsx +11 -0
- package/registry/examples/progress/steps.d.ts +4 -0
- package/registry/examples/progress/steps.js +14 -0
- package/registry/examples/progress/steps.tsx +13 -0
- package/registry/examples/progress/upload.d.ts +4 -0
- package/registry/examples/progress/upload.js +11 -0
- package/registry/examples/progress/upload.tsx +10 -0
- package/registry/examples/search-field/global.d.ts +4 -0
- package/registry/examples/search-field/global.js +19 -0
- package/registry/examples/search-field/global.tsx +15 -0
- package/registry/examples/search-field/native/default.d.ts +4 -0
- package/registry/examples/search-field/native/default.dark.png +0 -0
- package/registry/examples/search-field/native/default.js +13 -0
- package/registry/examples/search-field/native/default.light.png +0 -0
- package/registry/examples/search-field/native/default.tsx +7 -0
- package/registry/examples/search-field/suggestions.d.ts +4 -0
- package/registry/examples/search-field/suggestions.js +30 -0
- package/registry/examples/search-field/suggestions.tsx +27 -0
- package/registry/examples/search-field/toolbar.d.ts +4 -0
- package/registry/examples/search-field/toolbar.js +17 -0
- package/registry/examples/search-field/toolbar.tsx +21 -0
- package/registry/examples/skeleton/paragraph.d.ts +4 -0
- package/registry/examples/skeleton/paragraph.js +14 -0
- package/registry/examples/skeleton/paragraph.tsx +12 -0
- package/registry/examples/skeleton/shape-of-content.d.ts +4 -0
- package/registry/examples/skeleton/shape-of-content.js +23 -0
- package/registry/examples/skeleton/shape-of-content.tsx +26 -0
- package/registry/examples/spinner/default.js +5 -2
- package/registry/examples/spinner/default.tsx +7 -1
- package/registry/examples/spinner/sizes.js +2 -1
- package/registry/examples/spinner/sizes.tsx +2 -0
- package/registry/examples/spinner/value.d.ts +4 -0
- package/registry/examples/spinner/value.js +11 -0
- package/registry/examples/spinner/value.tsx +12 -0
- package/registry/examples/stepper/checkout.d.ts +4 -0
- package/registry/examples/stepper/checkout.js +22 -0
- package/registry/examples/stepper/checkout.tsx +17 -0
- package/registry/examples/stepper/failed.d.ts +4 -0
- package/registry/examples/stepper/failed.js +26 -0
- package/registry/examples/stepper/failed.tsx +21 -0
- package/registry/examples/stepper/job.d.ts +4 -0
- package/registry/examples/stepper/job.js +32 -0
- package/registry/examples/stepper/job.tsx +28 -0
- package/registry/examples/tag-input/recipients.d.ts +4 -0
- package/registry/examples/tag-input/recipients.js +23 -0
- package/registry/examples/tag-input/recipients.tsx +20 -0
- package/registry/examples/tag-input/video-tags.d.ts +4 -0
- package/registry/examples/tag-input/video-tags.js +26 -0
- package/registry/examples/tag-input/video-tags.tsx +22 -0
- package/registry/examples/toast/grouped.d.ts +4 -0
- package/registry/examples/toast/grouped.js +21 -0
- package/registry/examples/toast/grouped.tsx +23 -0
- package/registry/examples/toast/undo.d.ts +4 -0
- package/registry/examples/toast/undo.js +29 -0
- package/registry/examples/toast/undo.tsx +30 -0
- package/registry/examples/toast/upload-progress.d.ts +4 -0
- package/registry/examples/toast/upload-progress.js +29 -0
- package/registry/examples/toast/upload-progress.tsx +31 -0
- package/registry/examples/video-player/default.d.ts +4 -0
- package/registry/examples/video-player/default.js +12 -0
- package/registry/examples/video-player/default.tsx +8 -0
- package/registry/examples/video-player/gated.d.ts +4 -0
- package/registry/examples/video-player/gated.js +26 -0
- package/registry/examples/video-player/gated.tsx +23 -0
- package/registry/examples/video-player/native/default.d.ts +4 -0
- package/registry/examples/video-player/native/default.dark.png +0 -0
- package/registry/examples/video-player/native/default.js +18 -0
- package/registry/examples/video-player/native/default.light.png +0 -0
- package/registry/examples/video-player/native/default.tsx +12 -0
- package/registry/examples/video-player/signed-source.d.ts +4 -0
- package/registry/examples/video-player/signed-source.js +16 -0
- package/registry/examples/video-player/signed-source.tsx +15 -0
- package/registry/examples/video-player/vertical.d.ts +4 -0
- package/registry/examples/video-player/vertical.js +12 -0
- package/registry/examples/video-player/vertical.tsx +12 -0
- package/registry/examples/video-trimmer/custom.d.ts +4 -0
- package/registry/examples/video-trimmer/custom.js +24 -0
- package/registry/examples/video-trimmer/custom.tsx +26 -0
- package/registry/examples/video-trimmer/filmstrip.d.ts +4 -0
- package/registry/examples/video-trimmer/filmstrip.js +15 -0
- package/registry/examples/video-trimmer/filmstrip.tsx +13 -0
- package/registry/examples/video-trimmer/playhead.d.ts +4 -0
- package/registry/examples/video-trimmer/playhead.js +15 -0
- package/registry/examples/video-trimmer/playhead.tsx +13 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +471 -0
- package/registry/filter-bar.json +347 -0
- package/registry/glow-card.json +162 -0
- package/registry/image-cropper.json +313 -0
- package/registry/index.json +445 -20
- package/registry/iso.json +1355 -0
- package/registry/kbd.json +1 -1
- package/registry/loader.json +399 -0
- package/registry/marquee.json +225 -0
- package/registry/mascots.json +3 -3
- package/registry/media-capture.json +347 -0
- package/registry/meter.json +324 -0
- package/registry/nav-bar.json +480 -0
- package/registry/number-ticker.json +219 -0
- package/registry/page-header.json +1 -1
- package/registry/pagination.json +475 -0
- package/registry/popover.json +1 -1
- package/registry/progress.json +114 -9
- package/registry/radio-group.json +1 -1
- package/registry/search-field.json +436 -0
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/skeleton.json +69 -13
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +91 -27
- package/registry/stat.json +1 -1
- package/registry/stepper.json +174 -0
- package/registry/switch.json +1 -1
- package/registry/tabs.json +11 -7
- package/registry/tag-input.json +363 -0
- package/registry/theme.json +3 -3
- package/registry/toast.json +41 -13
- package/registry/tooltip.json +1 -1
- package/registry/video-player.json +598 -0
- package/registry/video-trimmer.json +385 -0
- package/dist/chunk-FHYZSO2S.js.map +0 -1
- package/dist/chunk-PESA2R4U.js +0 -51
- package/dist/chunk-PESA2R4U.js.map +0 -1
- package/registry/examples/spinner/muted.js +0 -11
- package/registry/examples/spinner/muted.tsx +0 -6
- /package/registry/examples/{spinner/muted.d.ts → audio-player/podcast.d.ts} +0 -0
|
@@ -0,0 +1,978 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "date-picker",
|
|
3
|
+
"type": "primitive",
|
|
4
|
+
"title": "Date picker",
|
|
5
|
+
"summary": "A date or a period chosen on a calendar — ISO values (`2026-10-11`) the form, the address and the API share, read in the locale's own words through @krizaka/intl.",
|
|
6
|
+
"description": "A date or a period chosen on a calendar — ISO values (`2026-10-11`) the form, the address and the API share, read in the locale's own words through @krizaka/intl.",
|
|
7
|
+
"status": "beta",
|
|
8
|
+
"category": "forms",
|
|
9
|
+
"platforms": "web",
|
|
10
|
+
"whenToUse": [
|
|
11
|
+
"To schedule something on a day: a publication, an auction's end, a reminder.",
|
|
12
|
+
"With `DateRangePicker` for a period: an earnings report, an audit log, a campaign — with presets.",
|
|
13
|
+
"With `Calendar` alone when the month itself is the interface (availability, a booking)."
|
|
14
|
+
],
|
|
15
|
+
"whenNotToUse": [
|
|
16
|
+
{
|
|
17
|
+
"when": "For a date of birth or a date far away: three fields (day, month, year) are faster than paging through years.",
|
|
18
|
+
"use": "field"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"when": "For a relative choice (“last 7 days”, “this month”) without a calendar: chips.",
|
|
22
|
+
"use": "chip"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"bestPractices": [
|
|
26
|
+
"Always pass the person's `locale`: month and day names, the first day of the week and the date's format follow it.",
|
|
27
|
+
"Keep the value as an ISO date in state and in the address; format it only for display.",
|
|
28
|
+
"Bound the choice with `min` / `max` and `isDateDisabled` rather than refusing after the fact.",
|
|
29
|
+
"Offer presets on a period picker: most people want “Last 30 days”, not two clicks."
|
|
30
|
+
],
|
|
31
|
+
"accessibility": {
|
|
32
|
+
"keyboard": [
|
|
33
|
+
{
|
|
34
|
+
"keys": "Arrow keys",
|
|
35
|
+
"action": "Move by a day or a week."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"keys": "Home / End",
|
|
39
|
+
"action": "First or last day of the week."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"keys": "Page Up / Page Down",
|
|
43
|
+
"action": "Previous or next month (with Shift: year)."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"keys": "Enter / Space",
|
|
47
|
+
"action": "Pick the focused day."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"keys": "Esc",
|
|
51
|
+
"action": "Close the calendar and return to the field."
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"notes": [
|
|
55
|
+
"The APG date picker: the month is a `grid` labelled by its title, one day in the tab order, each day named by its full date.",
|
|
56
|
+
"Today carries `aria-current=\"date\"`; chosen days `aria-selected`; unavailable days are disabled buttons.",
|
|
57
|
+
"The month's title is a polite live region: a change of month is heard.",
|
|
58
|
+
"The field is a button named by its `<label>`, with `aria-haspopup=\"dialog\"`; Radix returns the focus to it on close."
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"related": [
|
|
62
|
+
"field",
|
|
63
|
+
"popover",
|
|
64
|
+
"filter-bar"
|
|
65
|
+
],
|
|
66
|
+
"web": {
|
|
67
|
+
"entry": "@krizaka/ui/date-picker",
|
|
68
|
+
"import": "import { DatePicker, DateRangePicker, Calendar } from \"@krizaka/ui/date-picker\";",
|
|
69
|
+
"props": [
|
|
70
|
+
{
|
|
71
|
+
"component": "Calendar",
|
|
72
|
+
"description": "A month grid to pick a date or the ends of a range, with the full keyboard of the APG date picker.",
|
|
73
|
+
"props": [
|
|
74
|
+
{
|
|
75
|
+
"name": "locale",
|
|
76
|
+
"type": "string",
|
|
77
|
+
"default": null,
|
|
78
|
+
"description": "The BCP 47 locale of the month and day names (`\"en-US\"`, `\"fr-CA\"`): always explicit.",
|
|
79
|
+
"required": true
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "autoFocus",
|
|
83
|
+
"type": "boolean",
|
|
84
|
+
"default": null,
|
|
85
|
+
"description": "Moves the focus to the active day when it mounts (inside a popover).",
|
|
86
|
+
"required": false
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "className",
|
|
90
|
+
"type": "string",
|
|
91
|
+
"default": null,
|
|
92
|
+
"description": "Classes merged on the root.",
|
|
93
|
+
"required": false
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "defaultMonth",
|
|
97
|
+
"type": "string",
|
|
98
|
+
"default": null,
|
|
99
|
+
"description": "The month shown at first. Default: the value's, or today's.",
|
|
100
|
+
"required": false
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "isDateDisabled",
|
|
104
|
+
"type": "((date: string) => boolean)",
|
|
105
|
+
"default": null,
|
|
106
|
+
"description": "Refuses some dates (`(d) => isWeekend(d)`).",
|
|
107
|
+
"required": false
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "labels",
|
|
111
|
+
"type": "Partial<CalendarLabels>",
|
|
112
|
+
"default": null,
|
|
113
|
+
"description": "The words, passed translated; English by default.",
|
|
114
|
+
"required": false
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "max",
|
|
118
|
+
"type": "string",
|
|
119
|
+
"default": null,
|
|
120
|
+
"description": "The latest date that can be picked.",
|
|
121
|
+
"required": false
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"name": "min",
|
|
125
|
+
"type": "string",
|
|
126
|
+
"default": null,
|
|
127
|
+
"description": "The earliest date that can be picked.",
|
|
128
|
+
"required": false
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "month",
|
|
132
|
+
"type": "string",
|
|
133
|
+
"default": null,
|
|
134
|
+
"description": "The month shown, any day of it (controlled).",
|
|
135
|
+
"required": false
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"name": "onMonthChange",
|
|
139
|
+
"type": "((month: string) => void)",
|
|
140
|
+
"default": null,
|
|
141
|
+
"description": "Called when the month shown changes.",
|
|
142
|
+
"required": false
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "onSelect",
|
|
146
|
+
"type": "((date: string) => void)",
|
|
147
|
+
"default": null,
|
|
148
|
+
"description": "Called with the day picked.",
|
|
149
|
+
"required": false
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "range",
|
|
153
|
+
"type": "DateRange | null",
|
|
154
|
+
"default": null,
|
|
155
|
+
"description": "The chosen range (range mode): its ends are marked, the days between tinted.",
|
|
156
|
+
"required": false
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"name": "today",
|
|
160
|
+
"type": "string",
|
|
161
|
+
"default": null,
|
|
162
|
+
"description": "Today (marked): inject it for a stable server render or a test. Default: the device's date.",
|
|
163
|
+
"required": false
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "value",
|
|
167
|
+
"type": "string | null",
|
|
168
|
+
"default": null,
|
|
169
|
+
"description": "The chosen date (one-date mode).",
|
|
170
|
+
"required": false
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "weekStartsOn",
|
|
174
|
+
"type": "number",
|
|
175
|
+
"default": null,
|
|
176
|
+
"description": "The first day of the week, 0 = Sunday. Default: the locale's.",
|
|
177
|
+
"required": false
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"component": "DatePicker",
|
|
183
|
+
"description": "A date field: a button showing the date in the locale's format, a calendar in a popover, an ISO value.",
|
|
184
|
+
"props": [
|
|
185
|
+
{
|
|
186
|
+
"name": "label",
|
|
187
|
+
"type": "string",
|
|
188
|
+
"default": null,
|
|
189
|
+
"description": "The visible label, passed translated (also the button's accessible name, with the value).",
|
|
190
|
+
"required": true
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"name": "locale",
|
|
194
|
+
"type": "string",
|
|
195
|
+
"default": null,
|
|
196
|
+
"description": "The BCP 47 locale of the month and day names (`\"en-US\"`, `\"fr-CA\"`): always explicit.",
|
|
197
|
+
"required": true
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "className",
|
|
201
|
+
"type": "string",
|
|
202
|
+
"default": null,
|
|
203
|
+
"description": "Classes merged on the root.",
|
|
204
|
+
"required": false
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"name": "clearable",
|
|
208
|
+
"type": "boolean",
|
|
209
|
+
"default": null,
|
|
210
|
+
"description": "Adds a button that empties the value.",
|
|
211
|
+
"required": false
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"name": "defaultOpen",
|
|
215
|
+
"type": "boolean",
|
|
216
|
+
"default": "false",
|
|
217
|
+
"description": "Opens the calendar at first (a story, a test).",
|
|
218
|
+
"required": false
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"name": "defaultValue",
|
|
222
|
+
"type": "string | null",
|
|
223
|
+
"default": "null",
|
|
224
|
+
"description": "The chosen date at first, uncontrolled.",
|
|
225
|
+
"required": false
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"name": "disabled",
|
|
229
|
+
"type": "boolean",
|
|
230
|
+
"default": null,
|
|
231
|
+
"description": "Not available.",
|
|
232
|
+
"required": false
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"name": "error",
|
|
236
|
+
"type": "string",
|
|
237
|
+
"default": null,
|
|
238
|
+
"description": "An error under the field: marks it invalid and is read with it.",
|
|
239
|
+
"required": false
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"name": "format",
|
|
243
|
+
"type": "\"short\" | \"medium\" | \"long\"",
|
|
244
|
+
"default": null,
|
|
245
|
+
"description": "`short` · `medium` (default) · `long`: how the button writes the date.",
|
|
246
|
+
"required": false
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"name": "hint",
|
|
250
|
+
"type": "string",
|
|
251
|
+
"default": null,
|
|
252
|
+
"description": "A help text under the field.",
|
|
253
|
+
"required": false
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"name": "isDateDisabled",
|
|
257
|
+
"type": "((date: string) => boolean)",
|
|
258
|
+
"default": null,
|
|
259
|
+
"description": "Refuses some dates (`(d) => isWeekend(d)`).",
|
|
260
|
+
"required": false
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"name": "labels",
|
|
264
|
+
"type": "Partial<DatePickerLabels>",
|
|
265
|
+
"default": null,
|
|
266
|
+
"description": "The words, passed translated; English by default.",
|
|
267
|
+
"required": false
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"name": "max",
|
|
271
|
+
"type": "string",
|
|
272
|
+
"default": null,
|
|
273
|
+
"description": "The latest date that can be picked.",
|
|
274
|
+
"required": false
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"name": "min",
|
|
278
|
+
"type": "string",
|
|
279
|
+
"default": null,
|
|
280
|
+
"description": "The earliest date that can be picked.",
|
|
281
|
+
"required": false
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
"name": "name",
|
|
285
|
+
"type": "string",
|
|
286
|
+
"default": null,
|
|
287
|
+
"description": "The name of a hidden input holding the ISO value, for a plain `<form>` post.",
|
|
288
|
+
"required": false
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"name": "onValueChange",
|
|
292
|
+
"type": "((value: string | null) => void)",
|
|
293
|
+
"default": null,
|
|
294
|
+
"description": "Called with the date picked, or `null` when cleared.",
|
|
295
|
+
"required": false
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"name": "placeholder",
|
|
299
|
+
"type": "string",
|
|
300
|
+
"default": null,
|
|
301
|
+
"description": "Shown while nothing is chosen (\"Pick a date\"), passed translated.",
|
|
302
|
+
"required": false
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"name": "today",
|
|
306
|
+
"type": "string",
|
|
307
|
+
"default": null,
|
|
308
|
+
"description": "Today (marked): inject it for a stable server render or a test. Default: the device's date.",
|
|
309
|
+
"required": false
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"name": "value",
|
|
313
|
+
"type": "string | null",
|
|
314
|
+
"default": null,
|
|
315
|
+
"description": "The chosen date, ISO (controlled); `null` for none.",
|
|
316
|
+
"required": false
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"name": "weekStartsOn",
|
|
320
|
+
"type": "number",
|
|
321
|
+
"default": null,
|
|
322
|
+
"description": "The first day of the week, 0 = Sunday. Default: the locale's.",
|
|
323
|
+
"required": false
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"component": "DateRangePicker",
|
|
329
|
+
"description": "A period field: two clicks on one calendar (the days between tinted as you hover), optional presets.",
|
|
330
|
+
"props": [
|
|
331
|
+
{
|
|
332
|
+
"name": "label",
|
|
333
|
+
"type": "string",
|
|
334
|
+
"default": null,
|
|
335
|
+
"description": "The visible label, passed translated (also the button's accessible name, with the value).",
|
|
336
|
+
"required": true
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"name": "locale",
|
|
340
|
+
"type": "string",
|
|
341
|
+
"default": null,
|
|
342
|
+
"description": "The BCP 47 locale of the month and day names (`\"en-US\"`, `\"fr-CA\"`): always explicit.",
|
|
343
|
+
"required": true
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
"name": "className",
|
|
347
|
+
"type": "string",
|
|
348
|
+
"default": null,
|
|
349
|
+
"description": "Classes merged on the root.",
|
|
350
|
+
"required": false
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"name": "clearable",
|
|
354
|
+
"type": "boolean",
|
|
355
|
+
"default": null,
|
|
356
|
+
"description": "Adds a button that empties the value.",
|
|
357
|
+
"required": false
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"name": "defaultOpen",
|
|
361
|
+
"type": "boolean",
|
|
362
|
+
"default": "false",
|
|
363
|
+
"description": "Opens the calendar at first (a story, a test).",
|
|
364
|
+
"required": false
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"name": "defaultValue",
|
|
368
|
+
"type": "{ start: string; end: string; } | null",
|
|
369
|
+
"default": "null",
|
|
370
|
+
"description": "The range at first, uncontrolled.",
|
|
371
|
+
"required": false
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
"name": "disabled",
|
|
375
|
+
"type": "boolean",
|
|
376
|
+
"default": null,
|
|
377
|
+
"description": "Not available.",
|
|
378
|
+
"required": false
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"name": "error",
|
|
382
|
+
"type": "string",
|
|
383
|
+
"default": null,
|
|
384
|
+
"description": "An error under the field: marks it invalid and is read with it.",
|
|
385
|
+
"required": false
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"name": "format",
|
|
389
|
+
"type": "\"short\" | \"medium\" | \"long\"",
|
|
390
|
+
"default": null,
|
|
391
|
+
"description": "`short` · `medium` (default) · `long`: how the button writes the date.",
|
|
392
|
+
"required": false
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"name": "hint",
|
|
396
|
+
"type": "string",
|
|
397
|
+
"default": null,
|
|
398
|
+
"description": "A help text under the field.",
|
|
399
|
+
"required": false
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"name": "isDateDisabled",
|
|
403
|
+
"type": "((date: string) => boolean)",
|
|
404
|
+
"default": null,
|
|
405
|
+
"description": "Refuses some dates (`(d) => isWeekend(d)`).",
|
|
406
|
+
"required": false
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"name": "labels",
|
|
410
|
+
"type": "Partial<DatePickerLabels>",
|
|
411
|
+
"default": null,
|
|
412
|
+
"description": "The words, passed translated; English by default.",
|
|
413
|
+
"required": false
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"name": "max",
|
|
417
|
+
"type": "string",
|
|
418
|
+
"default": null,
|
|
419
|
+
"description": "The latest date that can be picked.",
|
|
420
|
+
"required": false
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"name": "min",
|
|
424
|
+
"type": "string",
|
|
425
|
+
"default": null,
|
|
426
|
+
"description": "The earliest date that can be picked.",
|
|
427
|
+
"required": false
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
"name": "name",
|
|
431
|
+
"type": "string",
|
|
432
|
+
"default": null,
|
|
433
|
+
"description": "The name of a hidden input holding the ISO value, for a plain `<form>` post.",
|
|
434
|
+
"required": false
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
"name": "onValueChange",
|
|
438
|
+
"type": "((value: { start: string; end: string; } | null) => void)",
|
|
439
|
+
"default": null,
|
|
440
|
+
"description": "Called once both ends are chosen (or with `null` when cleared).",
|
|
441
|
+
"required": false
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"name": "placeholder",
|
|
445
|
+
"type": "string",
|
|
446
|
+
"default": null,
|
|
447
|
+
"description": "Shown while nothing is chosen (\"Pick a date\"), passed translated.",
|
|
448
|
+
"required": false
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
"name": "presets",
|
|
452
|
+
"type": "readonly DateRangePreset[]",
|
|
453
|
+
"default": null,
|
|
454
|
+
"description": "Ranges one click away (\"Last 7 days\", \"This month\"), beside the calendar.",
|
|
455
|
+
"required": false
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"name": "today",
|
|
459
|
+
"type": "string",
|
|
460
|
+
"default": null,
|
|
461
|
+
"description": "Today (marked): inject it for a stable server render or a test. Default: the device's date.",
|
|
462
|
+
"required": false
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"name": "value",
|
|
466
|
+
"type": "{ start: string; end: string; } | null",
|
|
467
|
+
"default": null,
|
|
468
|
+
"description": "The chosen range (controlled); `null` for none. `end` is never `null` in a committed value.",
|
|
469
|
+
"required": false
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"name": "weekStartsOn",
|
|
473
|
+
"type": "number",
|
|
474
|
+
"default": null,
|
|
475
|
+
"description": "The first day of the week, 0 = Sunday. Default: the locale's.",
|
|
476
|
+
"required": false
|
|
477
|
+
}
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
],
|
|
481
|
+
"examples": [
|
|
482
|
+
{
|
|
483
|
+
"name": "schedule",
|
|
484
|
+
"title": "Schedule",
|
|
485
|
+
"description": "A publication date, from today on, written the way the locale writes it.",
|
|
486
|
+
"path": "examples/date-picker/schedule.tsx",
|
|
487
|
+
"module": "@krizaka/ui/registry/examples/date-picker/schedule",
|
|
488
|
+
"code": "\"use client\";\n\nimport { DatePicker } from \"@krizaka/ui/date-picker\";\nimport * as React from \"react\";\n\n// `today` is fixed here for the documentation; leave it out in an app.\nexport default function DatePickerSchedule() {\n const [date, setDate] = React.useState<string | null>(\"2026-10-14\");\n return (\n <DatePicker\n label=\"Publish on\"\n locale=\"en-US\"\n value={date}\n onValueChange={setDate}\n min=\"2026-10-11\"\n today=\"2026-10-11\"\n clearable\n placeholder=\"Publish now\"\n hint=\"Your followers are told when it goes live.\"\n />\n );\n}\n"
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
"name": "open",
|
|
492
|
+
"title": "Calendar open",
|
|
493
|
+
"description": "The popover open on the month: today marked, the chosen day filled.",
|
|
494
|
+
"path": "examples/date-picker/open.tsx",
|
|
495
|
+
"module": "@krizaka/ui/registry/examples/date-picker/open",
|
|
496
|
+
"code": "\"use client\";\n\nimport { DatePicker } from \"@krizaka/ui/date-picker\";\n\n// The calendar open: today marked, the chosen day filled, the past unavailable.\nexport default function DatePickerOpen({ defaultOpen }: { defaultOpen?: boolean }) {\n return <DatePicker label=\"Auction ends\" locale=\"en-US\" defaultValue=\"2026-10-18\" min=\"2026-10-11\" today=\"2026-10-11\" defaultOpen={defaultOpen} />;\n}\n"
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
"name": "range",
|
|
500
|
+
"title": "Period with presets",
|
|
501
|
+
"description": "`DateRangePicker` for an earnings report: presets beside the calendar.",
|
|
502
|
+
"path": "examples/date-picker/range.tsx",
|
|
503
|
+
"module": "@krizaka/ui/registry/examples/date-picker/range",
|
|
504
|
+
"code": "\"use client\";\n\nimport { DateRangePicker } from \"@krizaka/ui/date-picker\";\nimport * as React from \"react\";\n\n// An earnings report: presets for the usual periods, two clicks for any other.\nexport default function DatePickerRange({ defaultOpen }: { defaultOpen?: boolean }) {\n const [period, setPeriod] = React.useState<{ start: string; end: string } | null>({ start: \"2026-10-01\", end: \"2026-10-11\" });\n return (\n <DateRangePicker\n label=\"Period\"\n locale=\"en-US\"\n value={period}\n onValueChange={setPeriod}\n max=\"2026-10-11\"\n today=\"2026-10-11\"\n defaultOpen={defaultOpen}\n presets={[\n { label: \"Last 7 days\", start: \"2026-10-05\", end: \"2026-10-11\" },\n { label: \"This month\", start: \"2026-10-01\", end: \"2026-10-11\" },\n { label: \"Last month\", start: \"2026-09-01\", end: \"2026-09-30\" },\n ]}\n />\n );\n}\n"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"name": "french",
|
|
508
|
+
"title": "In French",
|
|
509
|
+
"description": "`locale=\"fr-CA\"`: the names, the order and the first day of the week follow.",
|
|
510
|
+
"path": "examples/date-picker/french.tsx",
|
|
511
|
+
"module": "@krizaka/ui/registry/examples/date-picker/french",
|
|
512
|
+
"code": "import { DatePicker } from \"@krizaka/ui/date-picker\";\n\n// fr-CA: “11 oct. 2026”, the months and days in French, the week as Canada counts it.\nexport default function DatePickerFrench() {\n return (\n <DatePicker\n label=\"Date du rendez-vous\"\n locale=\"fr-CA\"\n defaultValue=\"2026-10-11\"\n today=\"2026-10-11\"\n labels={{ previousMonth: \"Mois précédent\", nextMonth: \"Mois suivant\", clear: \"Effacer la date\" }}\n />\n );\n}\n"
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
"name": "calendar",
|
|
516
|
+
"title": "Calendar alone",
|
|
517
|
+
"description": "`Calendar` inline: the month is the interface, weekends unavailable.",
|
|
518
|
+
"path": "examples/date-picker/calendar.tsx",
|
|
519
|
+
"module": "@krizaka/ui/registry/examples/date-picker/calendar",
|
|
520
|
+
"code": "\"use client\";\n\nimport { Calendar } from \"@krizaka/ui/date-picker\";\nimport * as React from \"react\";\n\nconst weekend = (iso: string) => [0, 6].includes(new Date(`${iso}T12:00:00`).getDay());\n\n// The month is the interface: pick a day for a call, weekends unavailable.\nexport default function DatePickerCalendar() {\n const [day, setDay] = React.useState(\"2026-10-15\");\n return (\n <div className=\"inline-block rounded-xl border border-border-default bg-surface-1 p-3\">\n <Calendar locale=\"en-GB\" value={day} onSelect={setDay} isDateDisabled={weekend} min=\"2026-10-12\" today=\"2026-10-11\" />\n </div>\n );\n}\n"
|
|
521
|
+
}
|
|
522
|
+
]
|
|
523
|
+
},
|
|
524
|
+
"native": null,
|
|
525
|
+
"files": [
|
|
526
|
+
{
|
|
527
|
+
"path": "date-picker/calendar.tsx",
|
|
528
|
+
"content": "// Client. A month as an ARIA grid (the APG date picker): one day in the tab order, the arrows walk the days, Home /\n// End the week, Page Up / Page Down the months (Shift: the years), Enter or Space picks. Dates are ISO calendar dates\n// (`\"2026-10-11\"`): no time zone, nothing to convert, safe in an address. Month and day names come from\n// `@krizaka/intl` for the `locale` given — never the runtime's default.\nimport { formatDate, getDateTimeFormat } from \"@krizaka/intl\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { ChevronGlyph } from \"../glyphs\";\n\n/** A calendar date, `YYYY-MM-DD`. */\nexport type IsoDate = string;\n/** A range of calendar dates; `end` is `null` while the second date is not chosen. */\nexport type DateRange = { start: IsoDate; end: IsoDate | null };\n\nexport const calendar = tv({\n slots: {\n root: \"w-[17.5rem] select-none text-sm text-fg\",\n header: \"mb-2 flex items-center justify-between gap-2\",\n title: \"text-sm font-semibold capitalize\",\n nav:\n \"inline-flex h-8 w-8 items-center justify-center rounded-md text-fg-secondary hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40\",\n grid: \"w-full border-collapse\",\n weekday: \"h-8 w-10 text-center text-[11px] font-semibold uppercase text-fg-secondary\",\n cell: \"p-0 text-center\",\n day:\n \"relative h-10 w-10 rounded-lg text-sm tabular-nums text-fg transition-colors hover:bg-surface-3 \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"data-[outside]:text-fg-secondary data-[today]:font-bold data-[today]:not-data-[selected]:text-fg-accent \" +\n \"data-[in-range]:rounded-none data-[in-range]:bg-accent-soft \" +\n \"data-[selected]:bg-accent data-[selected]:text-on-accent data-[selected]:hover:bg-accent \" +\n \"disabled:cursor-not-allowed disabled:text-fg-muted disabled:line-through disabled:opacity-50 disabled:hover:bg-transparent\",\n },\n});\n\nexport const pad = (n: number) => String(n).padStart(2, \"0\");\nconst parts = (iso: IsoDate) => iso.split(\"-\").map(Number) as [number, number, number];\n/** A local `Date` at midnight for an ISO date (for formatting). */\nexport const toLocalDate = (iso: IsoDate) => {\n const [y, m, d] = parts(iso);\n return new Date(y, m - 1, d);\n};\n/** The ISO date of a local `Date`. */\nexport const toIsoDate = (date: Date): IsoDate => `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\nexport const addDays = (iso: IsoDate, days: number) => {\n const date = toLocalDate(iso);\n date.setDate(date.getDate() + days);\n return toIsoDate(date);\n};\nexport const addMonths = (iso: IsoDate, months: number) => {\n const [y, m, d] = parts(iso);\n const first = new Date(y, m - 1 + months, 1);\n const last = new Date(first.getFullYear(), first.getMonth() + 1, 0).getDate();\n return toIsoDate(new Date(first.getFullYear(), first.getMonth(), Math.min(d, last)));\n};\nconst monthOf = (iso: IsoDate) => `${iso.slice(0, 7)}-01`;\nconst clampIso = (iso: IsoDate, min?: IsoDate, max?: IsoDate) => (min && iso < min ? min : max && iso > max ? max : iso);\n\n/** The first day of the week for a locale (0 = Sunday … 6 = Saturday), from `Intl.Locale` week info; Monday otherwise. */\nexport function weekStartOf(locale: string): number {\n try {\n const info = new Intl.Locale(locale) as Intl.Locale & { getWeekInfo?: () => { firstDay: number }; weekInfo?: { firstDay: number } };\n const firstDay = info.getWeekInfo?.().firstDay ?? info.weekInfo?.firstDay;\n return firstDay ? firstDay % 7 : 1;\n } catch {\n return 1;\n }\n}\n\nexport type CalendarLabels = {\n /** The previous-month button (\"Previous month\"). */\n previousMonth: string;\n /** The next-month button (\"Next month\"). */\n nextMonth: string;\n};\n\nexport const calendarLabels: CalendarLabels = { previousMonth: \"Previous month\", nextMonth: \"Next month\" };\n\nexport type CalendarProps = {\n /** The BCP 47 locale of the month and day names (`\"en-US\"`, `\"fr-CA\"`): always explicit. */\n locale: string;\n /** The chosen date (one-date mode). */\n value?: IsoDate | null;\n /** The chosen range (range mode): its ends are marked, the days between tinted. */\n range?: DateRange | null;\n /** Called with the day picked. */\n onSelect?: (date: IsoDate) => void;\n /** The month shown, any day of it (controlled). */\n month?: IsoDate;\n /** The month shown at first. Default: the value's, or today's. */\n defaultMonth?: IsoDate;\n /** Called when the month shown changes. */\n onMonthChange?: (month: IsoDate) => void;\n /** The earliest date that can be picked. */\n min?: IsoDate;\n /** The latest date that can be picked. */\n max?: IsoDate;\n /** Refuses some dates (`(d) => isWeekend(d)`). */\n isDateDisabled?: (date: IsoDate) => boolean;\n /** The first day of the week, 0 = Sunday. Default: the locale's. */\n weekStartsOn?: number;\n /** Today (marked): inject it for a stable server render or a test. Default: the device's date. */\n today?: IsoDate;\n /** Moves the focus to the active day when it mounts (inside a popover). */\n autoFocus?: boolean;\n /** The words, passed translated; English by default. */\n labels?: Partial<CalendarLabels>;\n /** Classes merged on the root. */\n className?: string;\n};\n\n/** A month grid to pick a date or the ends of a range, with the full keyboard of the APG date picker. */\nexport function Calendar({\n locale,\n value,\n range,\n onSelect,\n month: monthProp,\n defaultMonth,\n onMonthChange,\n min,\n max,\n isDateDisabled,\n weekStartsOn,\n today: todayProp,\n autoFocus,\n labels: given,\n className,\n}: CalendarProps) {\n const labels = { ...calendarLabels, ...given };\n const s = calendar();\n const today = todayProp ?? toIsoDate(new Date());\n const anchor = value ?? range?.start ?? clampIso(today, min, max);\n const [innerMonth, setInnerMonth] = React.useState(monthOf(defaultMonth ?? anchor));\n const month = monthProp ? monthOf(monthProp) : innerMonth;\n const [focused, setFocused] = React.useState<IsoDate>(anchor.slice(0, 7) === month.slice(0, 7) ? anchor : month);\n const [hover, setHover] = React.useState<IsoDate | null>(null);\n const grid = React.useRef<HTMLTableElement>(null);\n const moved = React.useRef(Boolean(autoFocus));\n const titleId = React.useId();\n\n const setMonth = (next: IsoDate) => {\n const m = monthOf(next);\n if (!monthProp) setInnerMonth(m);\n onMonthChange?.(m);\n };\n // The focused day follows the month shown when it is changed from outside (the buttons, a controlled `month`).\n const active = focused.slice(0, 7) === month.slice(0, 7) ? focused : month;\n\n React.useEffect(() => {\n if (!moved.current) return;\n moved.current = false;\n grid.current?.querySelector<HTMLButtonElement>(`[data-date=\"${active}\"]`)?.focus();\n }, [active]);\n\n const disabled = (iso: IsoDate) => Boolean((min && iso < min) || (max && iso > max) || isDateDisabled?.(iso));\n const start = weekStartsOn ?? weekStartOf(locale);\n const first = toLocalDate(month);\n const lead = (first.getDay() - start + 7) % 7;\n const gridStart = addDays(month, -lead);\n const days = Array.from({ length: 42 }, (_, i) => addDays(gridStart, i));\n const weeks = Array.from({ length: 6 }, (_, w) => days.slice(w * 7, w * 7 + 7)).filter((week, w) => w < 5 || week[0]!.slice(0, 7) === month.slice(0, 7));\n const weekdayShort = getDateTimeFormat(locale, { weekday: \"short\" });\n const weekdayLong = getDateTimeFormat(locale, { weekday: \"long\" });\n const title = getDateTimeFormat(locale, { month: \"long\", year: \"numeric\" }).format(first);\n\n const rangeEnd = range ? (range.end ?? hover) : null;\n const [lo, hi] = range && rangeEnd ? (range.start <= rangeEnd ? [range.start, rangeEnd] : [rangeEnd, range.start]) : [null, null];\n\n const focusDay = (iso: IsoDate) => {\n moved.current = true;\n setFocused(iso);\n if (iso.slice(0, 7) !== month.slice(0, 7)) setMonth(iso);\n };\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n const weekday = (toLocalDate(active).getDay() - start + 7) % 7;\n const moves: Record<string, () => IsoDate> = {\n ArrowLeft: () => addDays(active, -1),\n ArrowRight: () => addDays(active, 1),\n ArrowUp: () => addDays(active, -7),\n ArrowDown: () => addDays(active, 7),\n Home: () => addDays(active, -weekday),\n End: () => addDays(active, 6 - weekday),\n PageUp: () => addMonths(active, event.shiftKey ? -12 : -1),\n PageDown: () => addMonths(active, event.shiftKey ? 12 : 1),\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n focusDay(move());\n };\n\n const prevDisabled = Boolean(min && addDays(month, -1) < min);\n const nextDisabled = Boolean(max && addMonths(month, 1) > max);\n\n return (\n <div className={s.root({ className })}>\n <div className={s.header()}>\n <button type=\"button\" className={s.nav()} aria-label={labels.previousMonth} disabled={prevDisabled} onClick={() => setMonth(addMonths(month, -1))}>\n <ChevronGlyph direction=\"left\" />\n </button>\n <h2 id={titleId} className={s.title()} aria-live=\"polite\">\n {title}\n </h2>\n <button type=\"button\" className={s.nav()} aria-label={labels.nextMonth} disabled={nextDisabled} onClick={() => setMonth(addMonths(month, 1))}>\n <ChevronGlyph direction=\"right\" />\n </button>\n </div>\n <table ref={grid} role=\"grid\" aria-labelledby={titleId} className={s.grid()} onKeyDown={onKeyDown}>\n <thead>\n <tr>\n {days.slice(0, 7).map((iso) => (\n <th key={iso} scope=\"col\" abbr={weekdayLong.format(toLocalDate(iso))} className={s.weekday()}>\n {weekdayShort.format(toLocalDate(iso)).replace(/\\.$/, \"\")}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeks.map((week) => (\n <tr key={week[0]}>\n {week.map((iso) => {\n const selected = iso === value || (range && (iso === range.start || iso === range.end));\n const inRange = Boolean(lo && hi && iso > lo && iso < hi);\n return (\n <td key={iso} role=\"gridcell\" aria-selected={selected || inRange || undefined} className={s.cell()}>\n <button\n type=\"button\"\n data-date={iso}\n tabIndex={iso === active ? 0 : -1}\n aria-label={formatDate(toLocalDate(iso), { locale, style: \"long\" })}\n aria-current={iso === today ? \"date\" : undefined}\n data-today={iso === today ? \"\" : undefined}\n data-outside={iso.slice(0, 7) !== month.slice(0, 7) ? \"\" : undefined}\n data-selected={selected ? \"\" : undefined}\n data-in-range={inRange ? \"\" : undefined}\n disabled={disabled(iso)}\n className={s.day()}\n onClick={() => {\n setFocused(iso);\n onSelect?.(iso);\n }}\n onMouseEnter={range && !range.end ? () => setHover(iso) : undefined}\n onFocus={range && !range.end ? () => setHover(iso) : undefined}\n >\n {Number(iso.slice(8))}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
"path": "date-picker/date-picker.tsx",
|
|
532
|
+
"content": "// Client (a portal). A field-like button that opens the `Calendar` in a Popover (Radix: Escape closes, the focus\n// returns to the button). The value is an ISO date (`\"2026-10-11\"`) — the same string in a form, an address and an\n// API; the button reads it in the `locale`'s own format through `@krizaka/intl`.\nimport { formatDate, getDateTimeFormat } from \"@krizaka/intl\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { CalendarGlyph, CloseGlyph } from \"../glyphs\";\nimport { useControllable } from \"../media\";\nimport { Popover } from \"../popover\";\nimport { Calendar, type CalendarLabels, type CalendarProps, type DateRange, type IsoDate, toLocalDate } from \"./calendar\";\n\nexport const datePicker = tv({\n slots: {\n root: \"flex w-full flex-col gap-1.5\",\n label: \"text-xs font-semibold text-fg-secondary\",\n row: \"relative flex w-full\",\n trigger:\n \"flex h-11 w-full items-center gap-2.5 rounded-lg border border-border-default bg-surface-2 px-3 text-left text-sm text-fg \" +\n \"transition-[border-color,box-shadow] focus-visible:border-accent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"data-[placeholder]:text-fg-muted aria-invalid:border-danger disabled:cursor-not-allowed disabled:opacity-50 data-[clearable]:pr-10\",\n icon: \"h-4 w-4 shrink-0 text-fg-secondary\",\n clear:\n \"absolute right-1.5 top-1/2 inline-flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-md text-fg-secondary hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n content: \"w-auto p-3\",\n layout: \"flex flex-col gap-3 sm:flex-row\",\n presets: \"flex flex-wrap gap-1.5 sm:w-36 sm:flex-col sm:flex-nowrap sm:border-r sm:border-border-default sm:pr-3\",\n preset:\n \"rounded-md px-2.5 py-1.5 text-left text-xs font-semibold text-fg-secondary hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-pressed:bg-accent-soft aria-pressed:text-fg\",\n hint: \"text-xs text-fg-secondary\",\n error: \"flex items-center gap-1.5 text-xs font-medium text-fg-danger before:h-1.5 before:w-1.5 before:shrink-0 before:rounded-full before:bg-danger\",\n },\n});\n\nexport type DatePickerLabels = CalendarLabels & {\n /** The clear button (\"Clear date\"). */\n clear: string;\n};\n\nexport const datePickerLabels: DatePickerLabels = { previousMonth: \"Previous month\", nextMonth: \"Next month\", clear: \"Clear date\" };\n\ntype Shared = Pick<CalendarProps, \"locale\" | \"min\" | \"max\" | \"isDateDisabled\" | \"weekStartsOn\" | \"today\"> & {\n /** The visible label, passed translated (also the button's accessible name, with the value). */\n label: string;\n /** Shown while nothing is chosen (\"Pick a date\"), passed translated. */\n placeholder?: string;\n /** `short` · `medium` (default) · `long`: how the button writes the date. */\n format?: \"short\" | \"medium\" | \"long\";\n /** Adds a button that empties the value. */\n clearable?: boolean;\n /** A help text under the field. */\n hint?: string;\n /** An error under the field: marks it invalid and is read with it. */\n error?: string;\n /** Not available. */\n disabled?: boolean;\n /** The name of a hidden input holding the ISO value, for a plain `<form>` post. */\n name?: string;\n /** Opens the calendar at first (a story, a test). */\n defaultOpen?: boolean;\n /** The words, passed translated; English by default. */\n labels?: Partial<DatePickerLabels>;\n /** Classes merged on the root. */\n className?: string;\n};\n\nexport type DatePickerProps = Shared & {\n /** The chosen date, ISO (controlled); `null` for none. */\n value?: IsoDate | null;\n /** The chosen date at first, uncontrolled. */\n defaultValue?: IsoDate | null;\n /** Called with the date picked, or `null` when cleared. */\n onValueChange?: (value: IsoDate | null) => void;\n};\n\nfunction Field({\n shared,\n text,\n hasValue,\n onClear,\n hidden,\n open,\n setOpen,\n children,\n}: {\n shared: Shared;\n text: string | null;\n hasValue: boolean;\n onClear: () => void;\n hidden: string;\n open: boolean;\n setOpen: (open: boolean) => void;\n children: React.ReactNode;\n}) {\n const { label, placeholder, clearable, hint, error, disabled, name, className } = shared;\n const labels = { ...datePickerLabels, ...shared.labels };\n const s = datePicker();\n const id = React.useId();\n const describedBy = [hint ? `${id}-hint` : null, error ? `${id}-error` : null].filter(Boolean).join(\" \") || undefined;\n return (\n <div className={s.root({ className })}>\n <label htmlFor={`${id}-trigger`} className={s.label()}>\n {label}\n </label>\n <Popover.Root open={open} onOpenChange={setOpen}>\n <div className={s.row()}>\n <Popover.Trigger asChild>\n <button\n id={`${id}-trigger`}\n type=\"button\"\n aria-haspopup=\"dialog\"\n aria-describedby={describedBy}\n aria-invalid={error ? true : undefined}\n disabled={disabled}\n data-placeholder={hasValue ? undefined : \"\"}\n data-clearable={clearable && hasValue ? \"\" : undefined}\n className={s.trigger()}\n >\n <CalendarGlyph className={s.icon()} />\n <span className=\"truncate\">{text ?? placeholder ?? \"\"}</span>\n </button>\n </Popover.Trigger>\n {clearable && hasValue && !disabled ? (\n <button type=\"button\" aria-label={labels.clear} className={s.clear()} onClick={onClear}>\n <CloseGlyph className=\"h-4 w-4\" />\n </button>\n ) : null}\n </div>\n <Popover.Content align=\"start\" aria-label={label} className={s.content()}>\n {children}\n </Popover.Content>\n </Popover.Root>\n {name ? <input type=\"hidden\" name={name} value={hidden} /> : null}\n {hint ? (\n <p id={`${id}-hint`} className={s.hint()}>\n {hint}\n </p>\n ) : null}\n {error ? (\n <p id={`${id}-error`} className={s.error()}>\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n\n/** A date field: a button showing the date in the locale's format, a calendar in a popover, an ISO value. */\nexport function DatePicker({ value: valueProp, defaultValue = null, onValueChange, defaultOpen = false, ...shared }: DatePickerProps) {\n const [value, setValue] = useControllable<IsoDate | null>(valueProp, defaultValue, onValueChange);\n const [open, setOpen] = React.useState(defaultOpen);\n const { locale, format = \"medium\" } = shared;\n return (\n <Field\n shared={shared}\n text={value ? formatDate(toLocalDate(value), { locale, style: format }) : null}\n hasValue={Boolean(value)}\n onClear={() => setValue(null)}\n hidden={value ?? \"\"}\n open={open}\n setOpen={setOpen}\n >\n <Calendar\n {...shared}\n autoFocus\n value={value}\n onSelect={(date) => {\n setValue(date);\n setOpen(false);\n }}\n />\n </Field>\n );\n}\n\nexport type DateRangePreset = {\n /** Its name, passed translated (\"Last 7 days\"). */\n label: string;\n /** The first day, ISO. */\n start: IsoDate;\n /** The last day, ISO. */\n end: IsoDate;\n};\n\nexport type DateRangePickerProps = Shared & {\n /** The chosen range (controlled); `null` for none. `end` is never `null` in a committed value. */\n value?: { start: IsoDate; end: IsoDate } | null;\n /** The range at first, uncontrolled. */\n defaultValue?: { start: IsoDate; end: IsoDate } | null;\n /** Called once both ends are chosen (or with `null` when cleared). */\n onValueChange?: (value: { start: IsoDate; end: IsoDate } | null) => void;\n /** Ranges one click away (\"Last 7 days\", \"This month\"), beside the calendar. */\n presets?: readonly DateRangePreset[];\n};\n\n/** Formats a range as the locale writes one (\"Oct 1 – 11, 2026\"), through Intl's `formatRange` where available. */\nfunction formatRange(locale: string, start: IsoDate, end: IsoDate, style: \"short\" | \"medium\" | \"long\") {\n const formatter = getDateTimeFormat(locale, { dateStyle: style }) as Intl.DateTimeFormat & { formatRange?: (a: Date, b: Date) => string };\n return formatter.formatRange\n ? formatter.formatRange(toLocalDate(start), toLocalDate(end))\n : `${formatter.format(toLocalDate(start))} – ${formatter.format(toLocalDate(end))}`;\n}\n\n/** A period field: two clicks on one calendar (the days between tinted as you hover), optional presets. */\nexport function DateRangePicker({ value: valueProp, defaultValue = null, onValueChange, presets, defaultOpen = false, ...shared }: DateRangePickerProps) {\n const [value, setValue] = useControllable(valueProp, defaultValue, onValueChange);\n const [draft, setDraft] = React.useState<DateRange | null>(null);\n const [open, setOpenState] = React.useState(defaultOpen);\n const { locale, format = \"medium\" } = shared;\n const s = datePicker();\n const setOpen = (next: boolean) => {\n setOpenState(next);\n setDraft(null);\n };\n const shown: DateRange | null = draft ?? value;\n const pick = (date: IsoDate) => {\n if (!draft) setDraft({ start: date, end: null });\n else {\n const [start, end] = date < draft.start ? [date, draft.start] : [draft.start, date];\n setValue({ start, end });\n setOpen(false);\n }\n };\n return (\n <Field\n shared={shared}\n text={value ? formatRange(locale, value.start, value.end, format) : null}\n hasValue={Boolean(value)}\n onClear={() => setValue(null)}\n hidden={value ? `${value.start}/${value.end}` : \"\"}\n open={open}\n setOpen={setOpen}\n >\n <div className={s.layout()}>\n {presets?.length ? (\n <div className={s.presets()}>\n {presets.map((preset) => (\n <button\n key={preset.label}\n type=\"button\"\n aria-pressed={value?.start === preset.start && value?.end === preset.end}\n className={s.preset()}\n onClick={() => {\n setValue({ start: preset.start, end: preset.end });\n setOpen(false);\n }}\n >\n {preset.label}\n </button>\n ))}\n </div>\n ) : null}\n <Calendar {...shared} autoFocus range={shown} onSelect={pick} />\n </div>\n </Field>\n );\n}\n"
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
"path": "date-picker/index.ts",
|
|
536
|
+
"content": "/** @krizaka/ui/date-picker — `DatePicker`, `DateRangePicker`, `Calendar` (ISO dates, the locale's names through @krizaka/intl), the date helpers and slots. Client (\"use client\"). */\nexport {\n addDays,\n addMonths,\n Calendar,\n calendar,\n type CalendarLabels,\n calendarLabels,\n type CalendarProps,\n type DateRange,\n type IsoDate,\n toIsoDate,\n toLocalDate,\n weekStartOf,\n} from \"./calendar\";\nexport {\n DatePicker,\n datePicker,\n type DatePickerLabels,\n datePickerLabels,\n type DatePickerProps,\n DateRangePicker,\n type DateRangePickerProps,\n type DateRangePreset,\n} from \"./date-picker\";\n"
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
"path": "date-picker/meta.ts",
|
|
540
|
+
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Date picker\",\n summary: \"A date or a period chosen on a calendar — ISO values (`2026-10-11`) the form, the address and the API share, read in the locale's own words through @krizaka/intl.\",\n status: \"beta\",\n category: \"forms\",\n platforms: \"web\",\n whenToUse: [\n \"To schedule something on a day: a publication, an auction's end, a reminder.\",\n \"With `DateRangePicker` for a period: an earnings report, an audit log, a campaign — with presets.\",\n \"With `Calendar` alone when the month itself is the interface (availability, a booking).\",\n ],\n whenNotToUse: [\n { when: \"For a date of birth or a date far away: three fields (day, month, year) are faster than paging through years.\", use: \"field\" },\n { when: \"For a relative choice (“last 7 days”, “this month”) without a calendar: chips.\", use: \"chip\" },\n ],\n bestPractices: [\n \"Always pass the person's `locale`: month and day names, the first day of the week and the date's format follow it.\",\n \"Keep the value as an ISO date in state and in the address; format it only for display.\",\n \"Bound the choice with `min` / `max` and `isDateDisabled` rather than refusing after the fact.\",\n \"Offer presets on a period picker: most people want “Last 30 days”, not two clicks.\",\n ],\n accessibility: {\n keyboard: [\n { keys: \"Arrow keys\", action: \"Move by a day or a week.\" },\n { keys: \"Home / End\", action: \"First or last day of the week.\" },\n { keys: \"Page Up / Page Down\", action: \"Previous or next month (with Shift: year).\" },\n { keys: \"Enter / Space\", action: \"Pick the focused day.\" },\n { keys: \"Esc\", action: \"Close the calendar and return to the field.\" },\n ],\n notes: [\n \"The APG date picker: the month is a `grid` labelled by its title, one day in the tab order, each day named by its full date.\",\n \"Today carries `aria-current=\\\"date\\\"`; chosen days `aria-selected`; unavailable days are disabled buttons.\",\n \"The month's title is a polite live region: a change of month is heard.\",\n \"The field is a button named by its `<label>`, with `aria-haspopup=\\\"dialog\\\"`; Radix returns the focus to it on close.\",\n ],\n },\n related: [\"field\", \"popover\", \"filter-bar\"],\n web: {\n imports: [\"DatePicker\", \"DateRangePicker\", \"Calendar\"],\n examples: [\n { name: \"schedule\", title: \"Schedule\", description: \"A publication date, from today on, written the way the locale writes it.\" },\n { name: \"open\", title: \"Calendar open\", description: \"The popover open on the month: today marked, the chosen day filled.\" },\n { name: \"range\", title: \"Period with presets\", description: \"`DateRangePicker` for an earnings report: presets beside the calendar.\" },\n { name: \"french\", title: \"In French\", description: \"`locale=\\\"fr-CA\\\"`: the names, the order and the first day of the week follow.\" },\n { name: \"calendar\", title: \"Calendar alone\", description: \"`Calendar` inline: the month is the interface, weekends unavailable.\" },\n ],\n },\n} satisfies ComponentMeta;\n"
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
"path": "glyphs.tsx",
|
|
544
|
+
"content": "// The small line glyphs the data and media primitives draw (play, volume, search, chevrons…): decorative, 24-unit\n// box, `currentColor`, sized by the caller's class. Shared by the entries that need them; never exported on its own —\n// a product draws its own icons with @krizaka/icons.\nimport type * as React from \"react\";\n\ntype GlyphProps = { className?: string };\n\nfunction Glyph({ className = \"h-4 w-4\", fill, children }: GlyphProps & { fill?: boolean; children: React.ReactNode }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n className={className}\n fill={fill ? \"currentColor\" : \"none\"}\n stroke={fill ? \"none\" : \"currentColor\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable=\"false\"\n >\n {children}\n </svg>\n );\n}\n\nexport const PlayGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <path d=\"M8 5.5v13a1 1 0 0 0 1.5.86l10.4-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5Z\" />\n </Glyph>\n);\nexport const PauseGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </Glyph>\n);\nexport const VolumeGlyph = ({ muted, ...p }: GlyphProps & { muted?: boolean }) => (\n <Glyph {...p}>\n <path d=\"M11 5 6 9H3v6h3l5 4V5Z\" />\n {muted ? <path d=\"m22 9-6 6m0-6 6 6\" /> : <path d=\"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13\" />}\n </Glyph>\n);\nexport const FullscreenGlyph = ({ exit, ...p }: GlyphProps & { exit?: boolean }) => (\n <Glyph {...p}>\n {exit ? <path d=\"M9 4v5H4m11-5v5h5M9 20v-5H4m11 5v-5h5\" /> : <path d=\"M4 9V4h5m6 0h5v5M4 15v5h5m11-5v5h-5\" />}\n </Glyph>\n);\nexport const CaptionsGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M10 10.5a2 2 0 1 0 0 3M17 10.5a2 2 0 1 0 0 3\" />\n </Glyph>\n);\nexport const PipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"12\" width=\"6\" height=\"4\" rx=\"1\" />\n </Glyph>\n);\nexport const SearchGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </Glyph>\n);\nexport const CloseGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Glyph>\n);\nexport const ChevronGlyph = ({ direction = \"down\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" | \"up\" | \"down\" }) => (\n <Glyph {...p}>\n <path d={{ left: \"m15 6-6 6 6 6\", right: \"m9 6 6 6-6 6\", up: \"m6 15 6-6 6 6\", down: \"m6 9 6 6 6-6\" }[direction]} />\n </Glyph>\n);\nexport const CheckGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Glyph>\n);\nexport const PlusGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 5v14M5 12h14\" />\n </Glyph>\n);\nexport const CalendarGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 10h18M8 3v4M16 3v4\" />\n </Glyph>\n);\nexport const UploadGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 16V4m0 0L7 9m5-5 5 5\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Glyph>\n);\nexport const FileGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5Z\" />\n <path d=\"M14 3v5h5\" />\n </Glyph>\n);\nexport const CameraGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 8h3l2-3h6l2 3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z\" />\n <circle cx=\"12\" cy=\"13.5\" r=\"3.5\" />\n </Glyph>\n);\nexport const FlipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 0 1 14-5.3M20 12a8 8 0 0 1-14 5.3\" />\n <path d=\"M18 3v4h-4M6 21v-4h4\" />\n </Glyph>\n);\nexport const RetryGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 1 0 2.3-5.7L4 8.5\" />\n <path d=\"M4 4v4.5h4.5\" />\n </Glyph>\n);\nexport const SortGlyph = ({ direction, ...p }: GlyphProps & { direction?: \"ascending\" | \"descending\" }) => (\n <Glyph {...p}>\n {direction === \"ascending\" ? <path d=\"m7 14 5-5 5 5\" /> : direction === \"descending\" ? <path d=\"m7 10 5 5 5-5\" /> : <path d=\"m8 9 4-4 4 4M8 15l4 4 4-4\" />}\n </Glyph>\n);\n"
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
"path": "media.ts",
|
|
548
|
+
"content": "// Shared by the data and media primitives (client): the clock format, the reduced-motion preference, the\n// in-view observer, a debounced callback. Never an entry of its own.\nimport * as React from \"react\";\n\n/** Seconds as a clock: `75` → `1:15`, `3725` → `1:02:05`. Negative or unknown values read `0:00`. */\nexport function formatClock(seconds: number): string {\n const s = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const rest = String(s % 60).padStart(2, \"0\");\n return h > 0 ? `${h}:${String(m).padStart(2, \"0\")}:${rest}` : `${m}:${rest}`;\n}\n\n/** Clamps `value` between `min` and `max`. */\nexport const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));\n\nconst REDUCE = \"(prefers-reduced-motion: reduce)\";\nconst subscribeReduce = (notify: () => void) => {\n if (typeof window === \"undefined\" || !window.matchMedia) return () => undefined;\n const query = window.matchMedia(REDUCE);\n query.addEventListener?.(\"change\", notify);\n return () => query.removeEventListener?.(\"change\", notify);\n};\n\n/** `true` when the person asked for less motion (`prefers-reduced-motion: reduce`); follows a change of the setting. */\nexport function usePrefersReducedMotion(): boolean {\n return React.useSyncExternalStore(\n subscribeReduce,\n () => (typeof window !== \"undefined\" && window.matchMedia ? window.matchMedia(REDUCE).matches : false),\n () => false,\n );\n}\n\n/** The latest value of a callback, for an effect or an event that must not re-subscribe when it changes. */\nexport function useLatest<T>(value: T) {\n const ref = React.useRef(value);\n React.useLayoutEffect(() => {\n ref.current = value;\n });\n return ref;\n}\n\n/** Calls `onChange(visible)` when at least `threshold` of the element enters or leaves the viewport. */\nexport function useInView(ref: React.RefObject<Element | null>, onChange: (visible: boolean) => void, enabled = true, threshold = 0.25) {\n const latest = useLatest(onChange);\n React.useEffect(() => {\n const element = ref.current;\n if (!enabled || !element || typeof IntersectionObserver === \"undefined\") return;\n const observer = new IntersectionObserver(([entry]) => entry && latest.current(entry.isIntersecting), { threshold });\n observer.observe(element);\n return () => observer.disconnect();\n }, [ref, enabled, threshold, latest]);\n}\n\n/** A stable function that runs `callback` once `delay` ms have passed without a new call; `cancel()` drops the pending one. */\nexport function useDebouncedCallback<A extends unknown[]>(callback: (...args: A) => void, delay: number) {\n const latest = useLatest(callback);\n const [debounced] = React.useState(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let wait = delay;\n const run = (...args: A) => {\n clearTimeout(timer);\n if (wait <= 0) latest.current(...args);\n else timer = setTimeout(() => latest.current(...args), wait);\n };\n return Object.assign(run, {\n cancel: () => clearTimeout(timer),\n setDelay: (next: number) => {\n wait = next;\n },\n });\n });\n React.useEffect(() => debounced.setDelay(delay), [debounced, delay]);\n React.useEffect(() => () => debounced.cancel(), [debounced]);\n return debounced;\n}\n\n/** A value controlled by a prop when it is given, held inside otherwise; `set` calls `onChange` either way. */\nexport function useControllable<T>(value: T | undefined, defaultValue: T, onChange?: (next: T) => void) {\n const [inner, setInner] = React.useState(defaultValue);\n const controlled = value !== undefined;\n const current = controlled ? value : inner;\n const set = React.useCallback(\n (next: T) => {\n if (!controlled) setInner(next);\n onChange?.(next);\n },\n [controlled, onChange],\n );\n return [current, set] as const;\n}\n\n/** Starts a media element without an unhandled rejection (autoplay refused, the source replaced meanwhile). */\nexport function playSafely(media: HTMLMediaElement | null | undefined) {\n try {\n const started = media?.play() as Promise<void> | undefined;\n started?.catch?.(() => undefined);\n } catch {\n // Not playable here (no media support): the controls stay as they are.\n }\n}\n"
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
"path": "meta.ts",
|
|
552
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"data-table\"\n | \"date-picker\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"loader\"\n | \"marquee\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page-header\"\n | \"pagination\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/** The group of the catalogue. `media`: video, sound, camera, files, cropping. */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
553
|
+
}
|
|
554
|
+
],
|
|
555
|
+
"dependencies": [
|
|
556
|
+
"@krizaka/intl@^0.1.0",
|
|
557
|
+
"tailwind-variants@^3.3.1"
|
|
558
|
+
],
|
|
559
|
+
"registryDependencies": [
|
|
560
|
+
"popover"
|
|
561
|
+
],
|
|
562
|
+
"demo": {
|
|
563
|
+
"path": "examples/date-picker/schedule.tsx",
|
|
564
|
+
"content": "\"use client\";\n\nimport { DatePicker } from \"@krizaka/ui/date-picker\";\nimport * as React from \"react\";\n\n// `today` is fixed here for the documentation; leave it out in an app.\nexport default function DatePickerSchedule() {\n const [date, setDate] = React.useState<string | null>(\"2026-10-14\");\n return (\n <DatePicker\n label=\"Publish on\"\n locale=\"en-US\"\n value={date}\n onValueChange={setDate}\n min=\"2026-10-11\"\n today=\"2026-10-11\"\n clearable\n placeholder=\"Publish now\"\n hint=\"Your followers are told when it goes live.\"\n />\n );\n}\n"
|
|
565
|
+
},
|
|
566
|
+
"props": [
|
|
567
|
+
{
|
|
568
|
+
"component": "Calendar",
|
|
569
|
+
"description": "A month grid to pick a date or the ends of a range, with the full keyboard of the APG date picker.",
|
|
570
|
+
"props": [
|
|
571
|
+
{
|
|
572
|
+
"name": "locale",
|
|
573
|
+
"type": "string",
|
|
574
|
+
"default": null,
|
|
575
|
+
"description": "The BCP 47 locale of the month and day names (`\"en-US\"`, `\"fr-CA\"`): always explicit.",
|
|
576
|
+
"required": true
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"name": "autoFocus",
|
|
580
|
+
"type": "boolean",
|
|
581
|
+
"default": null,
|
|
582
|
+
"description": "Moves the focus to the active day when it mounts (inside a popover).",
|
|
583
|
+
"required": false
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"name": "className",
|
|
587
|
+
"type": "string",
|
|
588
|
+
"default": null,
|
|
589
|
+
"description": "Classes merged on the root.",
|
|
590
|
+
"required": false
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
"name": "defaultMonth",
|
|
594
|
+
"type": "string",
|
|
595
|
+
"default": null,
|
|
596
|
+
"description": "The month shown at first. Default: the value's, or today's.",
|
|
597
|
+
"required": false
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"name": "isDateDisabled",
|
|
601
|
+
"type": "((date: string) => boolean)",
|
|
602
|
+
"default": null,
|
|
603
|
+
"description": "Refuses some dates (`(d) => isWeekend(d)`).",
|
|
604
|
+
"required": false
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
"name": "labels",
|
|
608
|
+
"type": "Partial<CalendarLabels>",
|
|
609
|
+
"default": null,
|
|
610
|
+
"description": "The words, passed translated; English by default.",
|
|
611
|
+
"required": false
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
"name": "max",
|
|
615
|
+
"type": "string",
|
|
616
|
+
"default": null,
|
|
617
|
+
"description": "The latest date that can be picked.",
|
|
618
|
+
"required": false
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
"name": "min",
|
|
622
|
+
"type": "string",
|
|
623
|
+
"default": null,
|
|
624
|
+
"description": "The earliest date that can be picked.",
|
|
625
|
+
"required": false
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
"name": "month",
|
|
629
|
+
"type": "string",
|
|
630
|
+
"default": null,
|
|
631
|
+
"description": "The month shown, any day of it (controlled).",
|
|
632
|
+
"required": false
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
"name": "onMonthChange",
|
|
636
|
+
"type": "((month: string) => void)",
|
|
637
|
+
"default": null,
|
|
638
|
+
"description": "Called when the month shown changes.",
|
|
639
|
+
"required": false
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
"name": "onSelect",
|
|
643
|
+
"type": "((date: string) => void)",
|
|
644
|
+
"default": null,
|
|
645
|
+
"description": "Called with the day picked.",
|
|
646
|
+
"required": false
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
"name": "range",
|
|
650
|
+
"type": "DateRange | null",
|
|
651
|
+
"default": null,
|
|
652
|
+
"description": "The chosen range (range mode): its ends are marked, the days between tinted.",
|
|
653
|
+
"required": false
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
"name": "today",
|
|
657
|
+
"type": "string",
|
|
658
|
+
"default": null,
|
|
659
|
+
"description": "Today (marked): inject it for a stable server render or a test. Default: the device's date.",
|
|
660
|
+
"required": false
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"name": "value",
|
|
664
|
+
"type": "string | null",
|
|
665
|
+
"default": null,
|
|
666
|
+
"description": "The chosen date (one-date mode).",
|
|
667
|
+
"required": false
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
"name": "weekStartsOn",
|
|
671
|
+
"type": "number",
|
|
672
|
+
"default": null,
|
|
673
|
+
"description": "The first day of the week, 0 = Sunday. Default: the locale's.",
|
|
674
|
+
"required": false
|
|
675
|
+
}
|
|
676
|
+
]
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
"component": "DatePicker",
|
|
680
|
+
"description": "A date field: a button showing the date in the locale's format, a calendar in a popover, an ISO value.",
|
|
681
|
+
"props": [
|
|
682
|
+
{
|
|
683
|
+
"name": "label",
|
|
684
|
+
"type": "string",
|
|
685
|
+
"default": null,
|
|
686
|
+
"description": "The visible label, passed translated (also the button's accessible name, with the value).",
|
|
687
|
+
"required": true
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"name": "locale",
|
|
691
|
+
"type": "string",
|
|
692
|
+
"default": null,
|
|
693
|
+
"description": "The BCP 47 locale of the month and day names (`\"en-US\"`, `\"fr-CA\"`): always explicit.",
|
|
694
|
+
"required": true
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"name": "className",
|
|
698
|
+
"type": "string",
|
|
699
|
+
"default": null,
|
|
700
|
+
"description": "Classes merged on the root.",
|
|
701
|
+
"required": false
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"name": "clearable",
|
|
705
|
+
"type": "boolean",
|
|
706
|
+
"default": null,
|
|
707
|
+
"description": "Adds a button that empties the value.",
|
|
708
|
+
"required": false
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
"name": "defaultOpen",
|
|
712
|
+
"type": "boolean",
|
|
713
|
+
"default": "false",
|
|
714
|
+
"description": "Opens the calendar at first (a story, a test).",
|
|
715
|
+
"required": false
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
"name": "defaultValue",
|
|
719
|
+
"type": "string | null",
|
|
720
|
+
"default": "null",
|
|
721
|
+
"description": "The chosen date at first, uncontrolled.",
|
|
722
|
+
"required": false
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"name": "disabled",
|
|
726
|
+
"type": "boolean",
|
|
727
|
+
"default": null,
|
|
728
|
+
"description": "Not available.",
|
|
729
|
+
"required": false
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
"name": "error",
|
|
733
|
+
"type": "string",
|
|
734
|
+
"default": null,
|
|
735
|
+
"description": "An error under the field: marks it invalid and is read with it.",
|
|
736
|
+
"required": false
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
"name": "format",
|
|
740
|
+
"type": "\"short\" | \"medium\" | \"long\"",
|
|
741
|
+
"default": null,
|
|
742
|
+
"description": "`short` · `medium` (default) · `long`: how the button writes the date.",
|
|
743
|
+
"required": false
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
"name": "hint",
|
|
747
|
+
"type": "string",
|
|
748
|
+
"default": null,
|
|
749
|
+
"description": "A help text under the field.",
|
|
750
|
+
"required": false
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
"name": "isDateDisabled",
|
|
754
|
+
"type": "((date: string) => boolean)",
|
|
755
|
+
"default": null,
|
|
756
|
+
"description": "Refuses some dates (`(d) => isWeekend(d)`).",
|
|
757
|
+
"required": false
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
"name": "labels",
|
|
761
|
+
"type": "Partial<DatePickerLabels>",
|
|
762
|
+
"default": null,
|
|
763
|
+
"description": "The words, passed translated; English by default.",
|
|
764
|
+
"required": false
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"name": "max",
|
|
768
|
+
"type": "string",
|
|
769
|
+
"default": null,
|
|
770
|
+
"description": "The latest date that can be picked.",
|
|
771
|
+
"required": false
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
"name": "min",
|
|
775
|
+
"type": "string",
|
|
776
|
+
"default": null,
|
|
777
|
+
"description": "The earliest date that can be picked.",
|
|
778
|
+
"required": false
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
"name": "name",
|
|
782
|
+
"type": "string",
|
|
783
|
+
"default": null,
|
|
784
|
+
"description": "The name of a hidden input holding the ISO value, for a plain `<form>` post.",
|
|
785
|
+
"required": false
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
"name": "onValueChange",
|
|
789
|
+
"type": "((value: string | null) => void)",
|
|
790
|
+
"default": null,
|
|
791
|
+
"description": "Called with the date picked, or `null` when cleared.",
|
|
792
|
+
"required": false
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
"name": "placeholder",
|
|
796
|
+
"type": "string",
|
|
797
|
+
"default": null,
|
|
798
|
+
"description": "Shown while nothing is chosen (\"Pick a date\"), passed translated.",
|
|
799
|
+
"required": false
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
"name": "today",
|
|
803
|
+
"type": "string",
|
|
804
|
+
"default": null,
|
|
805
|
+
"description": "Today (marked): inject it for a stable server render or a test. Default: the device's date.",
|
|
806
|
+
"required": false
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
"name": "value",
|
|
810
|
+
"type": "string | null",
|
|
811
|
+
"default": null,
|
|
812
|
+
"description": "The chosen date, ISO (controlled); `null` for none.",
|
|
813
|
+
"required": false
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
"name": "weekStartsOn",
|
|
817
|
+
"type": "number",
|
|
818
|
+
"default": null,
|
|
819
|
+
"description": "The first day of the week, 0 = Sunday. Default: the locale's.",
|
|
820
|
+
"required": false
|
|
821
|
+
}
|
|
822
|
+
]
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
"component": "DateRangePicker",
|
|
826
|
+
"description": "A period field: two clicks on one calendar (the days between tinted as you hover), optional presets.",
|
|
827
|
+
"props": [
|
|
828
|
+
{
|
|
829
|
+
"name": "label",
|
|
830
|
+
"type": "string",
|
|
831
|
+
"default": null,
|
|
832
|
+
"description": "The visible label, passed translated (also the button's accessible name, with the value).",
|
|
833
|
+
"required": true
|
|
834
|
+
},
|
|
835
|
+
{
|
|
836
|
+
"name": "locale",
|
|
837
|
+
"type": "string",
|
|
838
|
+
"default": null,
|
|
839
|
+
"description": "The BCP 47 locale of the month and day names (`\"en-US\"`, `\"fr-CA\"`): always explicit.",
|
|
840
|
+
"required": true
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
"name": "className",
|
|
844
|
+
"type": "string",
|
|
845
|
+
"default": null,
|
|
846
|
+
"description": "Classes merged on the root.",
|
|
847
|
+
"required": false
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
"name": "clearable",
|
|
851
|
+
"type": "boolean",
|
|
852
|
+
"default": null,
|
|
853
|
+
"description": "Adds a button that empties the value.",
|
|
854
|
+
"required": false
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
"name": "defaultOpen",
|
|
858
|
+
"type": "boolean",
|
|
859
|
+
"default": "false",
|
|
860
|
+
"description": "Opens the calendar at first (a story, a test).",
|
|
861
|
+
"required": false
|
|
862
|
+
},
|
|
863
|
+
{
|
|
864
|
+
"name": "defaultValue",
|
|
865
|
+
"type": "{ start: string; end: string; } | null",
|
|
866
|
+
"default": "null",
|
|
867
|
+
"description": "The range at first, uncontrolled.",
|
|
868
|
+
"required": false
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
"name": "disabled",
|
|
872
|
+
"type": "boolean",
|
|
873
|
+
"default": null,
|
|
874
|
+
"description": "Not available.",
|
|
875
|
+
"required": false
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
"name": "error",
|
|
879
|
+
"type": "string",
|
|
880
|
+
"default": null,
|
|
881
|
+
"description": "An error under the field: marks it invalid and is read with it.",
|
|
882
|
+
"required": false
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
"name": "format",
|
|
886
|
+
"type": "\"short\" | \"medium\" | \"long\"",
|
|
887
|
+
"default": null,
|
|
888
|
+
"description": "`short` · `medium` (default) · `long`: how the button writes the date.",
|
|
889
|
+
"required": false
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
"name": "hint",
|
|
893
|
+
"type": "string",
|
|
894
|
+
"default": null,
|
|
895
|
+
"description": "A help text under the field.",
|
|
896
|
+
"required": false
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
"name": "isDateDisabled",
|
|
900
|
+
"type": "((date: string) => boolean)",
|
|
901
|
+
"default": null,
|
|
902
|
+
"description": "Refuses some dates (`(d) => isWeekend(d)`).",
|
|
903
|
+
"required": false
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
"name": "labels",
|
|
907
|
+
"type": "Partial<DatePickerLabels>",
|
|
908
|
+
"default": null,
|
|
909
|
+
"description": "The words, passed translated; English by default.",
|
|
910
|
+
"required": false
|
|
911
|
+
},
|
|
912
|
+
{
|
|
913
|
+
"name": "max",
|
|
914
|
+
"type": "string",
|
|
915
|
+
"default": null,
|
|
916
|
+
"description": "The latest date that can be picked.",
|
|
917
|
+
"required": false
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
"name": "min",
|
|
921
|
+
"type": "string",
|
|
922
|
+
"default": null,
|
|
923
|
+
"description": "The earliest date that can be picked.",
|
|
924
|
+
"required": false
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
"name": "name",
|
|
928
|
+
"type": "string",
|
|
929
|
+
"default": null,
|
|
930
|
+
"description": "The name of a hidden input holding the ISO value, for a plain `<form>` post.",
|
|
931
|
+
"required": false
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
"name": "onValueChange",
|
|
935
|
+
"type": "((value: { start: string; end: string; } | null) => void)",
|
|
936
|
+
"default": null,
|
|
937
|
+
"description": "Called once both ends are chosen (or with `null` when cleared).",
|
|
938
|
+
"required": false
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
"name": "placeholder",
|
|
942
|
+
"type": "string",
|
|
943
|
+
"default": null,
|
|
944
|
+
"description": "Shown while nothing is chosen (\"Pick a date\"), passed translated.",
|
|
945
|
+
"required": false
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
"name": "presets",
|
|
949
|
+
"type": "readonly DateRangePreset[]",
|
|
950
|
+
"default": null,
|
|
951
|
+
"description": "Ranges one click away (\"Last 7 days\", \"This month\"), beside the calendar.",
|
|
952
|
+
"required": false
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
"name": "today",
|
|
956
|
+
"type": "string",
|
|
957
|
+
"default": null,
|
|
958
|
+
"description": "Today (marked): inject it for a stable server render or a test. Default: the device's date.",
|
|
959
|
+
"required": false
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
"name": "value",
|
|
963
|
+
"type": "{ start: string; end: string; } | null",
|
|
964
|
+
"default": null,
|
|
965
|
+
"description": "The chosen range (controlled); `null` for none. `end` is never `null` in a committed value.",
|
|
966
|
+
"required": false
|
|
967
|
+
},
|
|
968
|
+
{
|
|
969
|
+
"name": "weekStartsOn",
|
|
970
|
+
"type": "number",
|
|
971
|
+
"default": null,
|
|
972
|
+
"description": "The first day of the week, 0 = Sunday. Default: the locale's.",
|
|
973
|
+
"required": false
|
|
974
|
+
}
|
|
975
|
+
]
|
|
976
|
+
}
|
|
977
|
+
]
|
|
978
|
+
}
|