@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
package/registry/kbd.json
CHANGED
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
"path": "meta.ts",
|
|
99
|
-
"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 | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"cn\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"kbd\"\n | \"mascots\"\n | \"page-header\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"switch\"\n | \"tabs\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\";\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. */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"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 /** 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"
|
|
99
|
+
"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"
|
|
100
100
|
}
|
|
101
101
|
],
|
|
102
102
|
"dependencies": [
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "loader",
|
|
3
|
+
"type": "primitive",
|
|
4
|
+
"title": "Loader",
|
|
5
|
+
"summary": "A wait from start to end: nothing for the first instants, then the Krizaka glyph with its words, a percentage and an ETA, held long enough to read, ending on a check or a cross that is drawn and announced — and `LoadingRegion`, which hands a region over to a skeleton of its shape.",
|
|
6
|
+
"description": "A wait from start to end: nothing for the first instants, then the Krizaka glyph with its words, a percentage and an ETA, held long enough to read, ending on a check or a cross that is drawn and announced — and `LoadingRegion`, which hands a region over to a skeleton of its shape.",
|
|
7
|
+
"status": "beta",
|
|
8
|
+
"category": "feedback",
|
|
9
|
+
"platforms": "web",
|
|
10
|
+
"whenToUse": [
|
|
11
|
+
"Any wait whose length you do not control (a fetch, a refresh): the delay keeps fast answers from flashing a spinner.",
|
|
12
|
+
"A wait that ends in a result worth saying — “12 invoices loaded”, “Could not publish”.",
|
|
13
|
+
"Over a region that stays readable while it refreshes (`variant=\"overlay\"`), or over the whole screen at start-up (`page`).",
|
|
14
|
+
"`LoadingRegion` for a card, a list or a panel: a skeleton of its shape while it loads, words when it lasts."
|
|
15
|
+
],
|
|
16
|
+
"whenNotToUse": [
|
|
17
|
+
{
|
|
18
|
+
"when": "Inside the button that started the action: the button draws the same glyph.",
|
|
19
|
+
"use": "button"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"when": "For a long task with steps or a known size the user follows.",
|
|
23
|
+
"use": "progress"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"when": "A tiny wait glyph with nothing else.",
|
|
27
|
+
"use": "spinner"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"bestPractices": [
|
|
31
|
+
"Say what is loading (“Loading your invoices”), not “Loading…”; say how it ended with `successLabel` / `errorLabel`.",
|
|
32
|
+
"Keep the defaults: 250 ms of delay, 600 ms at least once shown — the two numbers that stop flicker.",
|
|
33
|
+
"Give an `eta` when you can estimate it (format durations with `@krizaka/intl`): a known wait feels shorter.",
|
|
34
|
+
"With `LoadingRegion`, draw the skeleton the shape of the content: nothing moves when it arrives."
|
|
35
|
+
],
|
|
36
|
+
"accessibility": {
|
|
37
|
+
"keyboard": [],
|
|
38
|
+
"notes": [
|
|
39
|
+
"`role=\"status\"` (polite) is present from the first render, so its words are announced when the wait shows and again when it ends.",
|
|
40
|
+
"`LoadingRegion` sets `aria-busy` on the region while it waits; the skeleton is hidden from assistive technology and the wait is announced once.",
|
|
41
|
+
"Under `prefers-reduced-motion` the glyph rests on a still frame and endings do not animate; the delay, the words and the announcements stay."
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"related": [
|
|
45
|
+
"spinner",
|
|
46
|
+
"skeleton",
|
|
47
|
+
"progress",
|
|
48
|
+
"button"
|
|
49
|
+
],
|
|
50
|
+
"web": {
|
|
51
|
+
"entry": "@krizaka/ui/loader",
|
|
52
|
+
"import": "import { Loader, LoadingRegion, useDelayedWait } from \"@krizaka/ui/loader\";",
|
|
53
|
+
"props": [
|
|
54
|
+
{
|
|
55
|
+
"component": "Loader",
|
|
56
|
+
"description": "A wait, from start to end. `role=\"status\"` (polite): its words are announced when it shows and when it ends. Under\nprefers-reduced-motion the glyph rests on a still frame; the delay and the ending stay.",
|
|
57
|
+
"props": [
|
|
58
|
+
{
|
|
59
|
+
"name": "label",
|
|
60
|
+
"type": "string",
|
|
61
|
+
"default": null,
|
|
62
|
+
"description": "What is loading, in words (“Loading your invoices”) — passed translated; shown and announced.",
|
|
63
|
+
"required": true
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "delay",
|
|
67
|
+
"type": "number",
|
|
68
|
+
"default": "250",
|
|
69
|
+
"description": "Milliseconds before anything shows: a wait shorter than this never flashes.",
|
|
70
|
+
"required": false
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "endDuration",
|
|
74
|
+
"type": "number",
|
|
75
|
+
"default": "1600",
|
|
76
|
+
"description": "Milliseconds the ending (check or cross) stays before the loader disappears; `0` never shows it, `Infinity` keeps it.",
|
|
77
|
+
"required": false
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "errorLabel",
|
|
81
|
+
"type": "string",
|
|
82
|
+
"default": null,
|
|
83
|
+
"description": "The words of a failure (“Could not load the invoices”) — passed translated.",
|
|
84
|
+
"required": false
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "eta",
|
|
88
|
+
"type": "string",
|
|
89
|
+
"default": null,
|
|
90
|
+
"description": "The time left, in words (“About 20 s left”) — passed translated (`@krizaka/intl` formats durations).",
|
|
91
|
+
"required": false
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "minDuration",
|
|
95
|
+
"type": "number",
|
|
96
|
+
"default": "600",
|
|
97
|
+
"description": "Once shown, the least milliseconds it stays: it never blinks.",
|
|
98
|
+
"required": false
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "status",
|
|
102
|
+
"type": "\"success\" | \"loading\" | \"error\"",
|
|
103
|
+
"default": "loading",
|
|
104
|
+
"description": "loading · success · error. When the wait ends, the loader shows how it ended for `endDuration` ms, then disappears.",
|
|
105
|
+
"required": false
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "successLabel",
|
|
109
|
+
"type": "string",
|
|
110
|
+
"default": null,
|
|
111
|
+
"description": "The words of a success (“Invoices loaded”) — passed translated. Default: nothing more than the check.",
|
|
112
|
+
"required": false
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "value",
|
|
116
|
+
"type": "number | null",
|
|
117
|
+
"default": null,
|
|
118
|
+
"description": "Between 0 and 1: a determinate wait — the trace grows to it and the percentage shows.",
|
|
119
|
+
"required": false
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "variant",
|
|
123
|
+
"type": "\"inline\" | \"page\" | \"overlay\" | \"block\"",
|
|
124
|
+
"default": "inline",
|
|
125
|
+
"description": "inline (beside the content) · block (a region's centre) · overlay (over a `relative` parent, frosted) · page (the\nwhole screen).",
|
|
126
|
+
"required": false
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"component": "LoadingRegion",
|
|
132
|
+
"description": "A region that hands over: its content → (after `delay`) a skeleton of the same shape → (after `slowAfter`) words over\nthe skeleton → its content again, fading in. `aria-busy` while it waits; the wait is announced once.",
|
|
133
|
+
"props": [
|
|
134
|
+
{
|
|
135
|
+
"name": "label",
|
|
136
|
+
"type": "string",
|
|
137
|
+
"default": null,
|
|
138
|
+
"description": "What is loading, in words — passed translated; announced when the wait shows.",
|
|
139
|
+
"required": true
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"name": "loading",
|
|
143
|
+
"type": "boolean",
|
|
144
|
+
"default": null,
|
|
145
|
+
"description": "Whether the content is on its way.",
|
|
146
|
+
"required": true
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "skeleton",
|
|
150
|
+
"type": "ReactNode",
|
|
151
|
+
"default": null,
|
|
152
|
+
"description": "What stands in while it loads: skeletons the shape of the content (no layout shift when it arrives).",
|
|
153
|
+
"required": true
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "delay",
|
|
157
|
+
"type": "number",
|
|
158
|
+
"default": "200",
|
|
159
|
+
"description": "Milliseconds before the skeleton shows: a fast answer goes straight to the content.",
|
|
160
|
+
"required": false
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"name": "minDuration",
|
|
164
|
+
"type": "number",
|
|
165
|
+
"default": "500",
|
|
166
|
+
"description": "Once shown, the least milliseconds the skeleton stays.",
|
|
167
|
+
"required": false
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"name": "slowAfter",
|
|
171
|
+
"type": "number",
|
|
172
|
+
"default": "4000",
|
|
173
|
+
"description": "Milliseconds of skeleton before the words of a long wait appear over it.",
|
|
174
|
+
"required": false
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"name": "slowLabel",
|
|
178
|
+
"type": "string",
|
|
179
|
+
"default": null,
|
|
180
|
+
"description": "The words when the wait grows long (“Still loading — the server is busy”) — passed translated.",
|
|
181
|
+
"required": false
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
],
|
|
186
|
+
"examples": [
|
|
187
|
+
{
|
|
188
|
+
"name": "fetch-flow",
|
|
189
|
+
"title": "No flash, then a result",
|
|
190
|
+
"description": "A fast answer shows nothing; a slow one shows the wait, then “12 invoices loaded” with a check, then nothing.",
|
|
191
|
+
"path": "examples/loader/fetch-flow.tsx",
|
|
192
|
+
"module": "@krizaka/ui/registry/examples/loader/fetch-flow",
|
|
193
|
+
"code": "\"use client\";\nimport { Button } from \"@krizaka/ui/button\";\nimport { Loader } from \"@krizaka/ui/loader\";\nimport { useState } from \"react\";\n\n// Try both: a fast answer (150 ms) shows nothing at all; a slow one shows the wait, then a check, then nothing.\nexport default function LoaderFetchFlow() {\n const [status, setStatus] = useState<\"idle\" | \"loading\" | \"success\">(\"idle\");\n const run = (ms: number) => {\n setStatus(\"loading\");\n setTimeout(() => setStatus(\"success\"), ms);\n };\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={() => run(150)}>Fast answer</Button>\n <Button size=\"sm\" onClick={() => run(2500)}>Slow answer</Button>\n </div>\n <div className=\"h-10\">\n {status !== \"idle\" && <Loader status={status} label=\"Loading your invoices\" successLabel=\"12 invoices loaded\" />}\n </div>\n </div>\n );\n}\n"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "region-handover",
|
|
197
|
+
"title": "Hand-over to a skeleton",
|
|
198
|
+
"description": "`LoadingRegion`: a skeleton of the card's shape, words when it lasts, the card fading in.",
|
|
199
|
+
"path": "examples/loader/region-handover.tsx",
|
|
200
|
+
"module": "@krizaka/ui/registry/examples/loader/region-handover",
|
|
201
|
+
"code": "\"use client\";\nimport { Button } from \"@krizaka/ui/button\";\nimport { LoadingRegion } from \"@krizaka/ui/loader\";\nimport { Skeleton } from \"@krizaka/ui/skeleton\";\nimport { useState } from \"react\";\n\n// Press “Load again”: the region hands over — a skeleton of its shape → words when it lasts → the content, fading in.\nexport default function LoaderRegionHandover() {\n const [loading, setLoading] = useState(false);\n const card = \"flex items-center gap-3 rounded-xl border border-border-default bg-surface-1 p-4\";\n return (\n <div className=\"flex w-full max-w-sm flex-col gap-3\">\n <LoadingRegion\n loading={loading}\n label=\"Loading the creator\"\n slowLabel=\"Still loading — the server is busy\"\n slowAfter={2500}\n delay={0}\n skeleton={<div className={card}><Skeleton shape=\"circle\" /><div className=\"flex flex-1 flex-col gap-2\"><Skeleton className=\"w-1/2\" /><Skeleton className=\"w-3/4\" /></div></div>}\n >\n <div className={card}>\n <span aria-hidden className=\"h-10 w-10 rounded-full bg-accent-soft\" />\n <div><p className=\"font-semibold text-fg\">Eric Moreau</p><p className=\"text-sm text-fg-secondary\">1,204 supporters</p></div>\n </div>\n </LoadingRegion>\n <Button size=\"sm\" onClick={() => setLoading((l) => !l)}>{loading ? \"Finish loading\" : \"Load again\"}</Button>\n </div>\n );\n}\n"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "upload-eta",
|
|
205
|
+
"title": "Progress and ETA",
|
|
206
|
+
"description": "`value` and `eta`: the trace grows, the percentage and the time left read in tabular figures.",
|
|
207
|
+
"path": "examples/loader/upload-eta.tsx",
|
|
208
|
+
"module": "@krizaka/ui/registry/examples/loader/upload-eta",
|
|
209
|
+
"code": "import { Loader } from \"@krizaka/ui/loader\";\n\n// A determinate wait with its time left: the trace grows, the percentage and the ETA read in tabular figures.\nexport default function LoaderUploadEta() {\n return (\n <div className=\"w-full max-w-sm rounded-xl border border-border-default bg-surface-1 p-4\">\n <Loader label=\"Uploading “Night walk.mp4”\" value={0.62} eta=\"About 40 s left\" delay={0} />\n </div>\n );\n}\n"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "overlay",
|
|
213
|
+
"title": "Over a region",
|
|
214
|
+
"description": "`variant=\"overlay\"`: the report stays readable behind frosted glass while it refreshes.",
|
|
215
|
+
"path": "examples/loader/overlay.tsx",
|
|
216
|
+
"module": "@krizaka/ui/registry/examples/loader/overlay",
|
|
217
|
+
"code": "import { Loader } from \"@krizaka/ui/loader\";\n\n// Over a region that stays readable behind frosted glass: `variant=\"overlay\"` in a `relative` parent.\nexport default function LoaderOverlay() {\n return (\n <div className=\"relative w-full max-w-sm rounded-xl border border-border-default bg-surface-1 p-5\">\n <p className=\"font-semibold text-fg\">Monthly report</p>\n <p className=\"mt-1 text-sm text-fg-secondary\">Revenue, supporters and payouts for October.</p>\n <div className=\"mt-4 h-24 rounded-lg bg-surface-2\" />\n <Loader variant=\"overlay\" label=\"Refreshing the report\" eta=\"A few seconds\" delay={0} />\n </div>\n );\n}\n"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "endings",
|
|
221
|
+
"title": "Endings",
|
|
222
|
+
"description": "`status`: a success and a failure, drawn in their colour and said in words.",
|
|
223
|
+
"path": "examples/loader/endings.tsx",
|
|
224
|
+
"module": "@krizaka/ui/registry/examples/loader/endings",
|
|
225
|
+
"code": "import { Loader } from \"@krizaka/ui/loader\";\n\n// How a wait ends: drawn (a check or a cross in the status colour) and announced in words.\nexport default function LoaderEndings() {\n return (\n <div className=\"flex flex-col gap-3\">\n <Loader status=\"success\" label=\"Publishing\" successLabel=\"Published\" endDuration={Infinity} delay={0} minDuration={0} />\n <Loader status=\"error\" label=\"Publishing\" errorLabel=\"Could not publish — check your connection\" endDuration={Infinity} delay={0} minDuration={0} />\n </div>\n );\n}\n"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"name": "minimal",
|
|
229
|
+
"title": "Minimal",
|
|
230
|
+
"description": "A label, nothing else: the defaults do the rest.",
|
|
231
|
+
"path": "examples/loader/minimal.tsx",
|
|
232
|
+
"module": "@krizaka/ui/registry/examples/loader/minimal",
|
|
233
|
+
"code": "import { Loader } from \"@krizaka/ui/loader\";\n\n// The minimal API: a label. It appears after 250 ms and stays at least 600 ms once shown.\nexport default function LoaderMinimal() {\n return <Loader label=\"Loading\" delay={0} />;\n}\n"
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
"native": null,
|
|
238
|
+
"files": [
|
|
239
|
+
{
|
|
240
|
+
"path": "loader/index.ts",
|
|
241
|
+
"content": "/** @krizaka/ui/loader — `Loader` (a wait from start to end: delay, glyph, ETA, ending), `LoadingRegion` (content ⇄ skeleton hand-over), `useDelayedWait`. Client. */\nexport { Loader, loader, type LoaderProps, type LoaderVariants, LoadingRegion, type LoadingRegionProps, useDelayedWait } from \"./loader\";\n"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"path": "loader/loader.tsx",
|
|
245
|
+
"content": "// Client (timers). The whole life of a wait, done right once: nothing for the first instants (a fast answer never\n// flashes a spinner), then the Krizaka glyph with its words and an ETA, held long enough to be read, ending on a\n// check or a cross that is drawn and announced. `LoadingRegion` hands a region over from its content to a skeleton of\n// the same shape, then to words when the wait grows long, then back to the content.\nimport * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { LoaderGlyph } from \"../spinner/glyph\";\n\nexport const loader = tv({\n slots: {\n root: \"text-fg-secondary\",\n box: \"kz-fade flex items-center gap-3\",\n glyph: \"shrink-0 text-accent\",\n text: \"flex min-w-0 flex-col\",\n label: \"font-medium text-fg\",\n detail: \"text-xs text-fg-secondary tabular-nums\",\n },\n variants: {\n variant: {\n inline: { box: \"text-sm\", glyph: \"h-5 w-5\" },\n block: { box: \"flex-col justify-center py-10 text-center text-sm\", glyph: \"h-9 w-9\", text: \"items-center\" },\n overlay: {\n root: \"absolute inset-0 z-10 flex items-center justify-center rounded-[inherit] empty:hidden\",\n box: \"flex-col rounded-xl border border-border-default bg-surface-1/90 px-6 py-5 text-center text-sm shadow-lg backdrop-blur-sm\",\n glyph: \"h-9 w-9\",\n text: \"items-center\",\n },\n page: {\n root: \"fixed inset-0 z-50 flex items-center justify-center bg-surface-0/80 backdrop-blur-sm empty:hidden\",\n box: \"flex-col text-center\",\n glyph: \"h-14 w-14\",\n text: \"items-center\",\n label: \"font-display text-lg\",\n },\n },\n ended: {\n success: { glyph: \"text-fg-success\" },\n error: { glyph: \"text-fg-danger\" },\n },\n },\n defaultVariants: { variant: \"inline\" },\n});\n\nexport type LoaderVariants = VariantProps<typeof loader>;\n\n/**\n * `true` once `active` has lasted `delay` ms; then stays `true` at least `minDuration` ms — a wait that ends early never\n * shows, one that shows never blinks.\n */\nexport function useDelayedWait(active: boolean, delay = 250, minDuration = 600): boolean {\n const [shown, setShown] = React.useState(false);\n const since = React.useRef(0);\n React.useEffect(() => {\n if (active === shown) return;\n const wait = active ? delay : Math.max(0, minDuration - (Date.now() - since.current));\n const timer = setTimeout(() => {\n since.current = Date.now();\n setShown(active);\n }, wait);\n return () => clearTimeout(timer);\n }, [active, shown, delay, minDuration]);\n return shown;\n}\n\nexport interface LoaderProps extends Omit<React.ComponentProps<\"div\">, \"children\"> {\n /** What is loading, in words (“Loading your invoices”) — passed translated; shown and announced. */\n label: string;\n /**\n * loading · success · error. When the wait ends, the loader shows how it ended for `endDuration` ms, then disappears.\n * @default \"loading\"\n */\n status?: \"loading\" | \"success\" | \"error\";\n /** The words of a success (“Invoices loaded”) — passed translated. Default: nothing more than the check. */\n successLabel?: string;\n /** The words of a failure (“Could not load the invoices”) — passed translated. */\n errorLabel?: string;\n /** Between 0 and 1: a determinate wait — the trace grows to it and the percentage shows. */\n value?: number | null;\n /** The time left, in words (“About 20 s left”) — passed translated (`@krizaka/intl` formats durations). */\n eta?: string;\n /**\n * Milliseconds before anything shows: a wait shorter than this never flashes.\n * @default 250\n */\n delay?: number;\n /**\n * Once shown, the least milliseconds it stays: it never blinks.\n * @default 600\n */\n minDuration?: number;\n /**\n * Milliseconds the ending (check or cross) stays before the loader disappears; `0` never shows it, `Infinity` keeps it.\n * @default 1600\n */\n endDuration?: number;\n /**\n * inline (beside the content) · block (a region's centre) · overlay (over a `relative` parent, frosted) · page (the\n * whole screen).\n * @default \"inline\"\n */\n variant?: LoaderVariants[\"variant\"];\n}\n\n/**\n * A wait, from start to end. `role=\"status\"` (polite): its words are announced when it shows and when it ends. Under\n * prefers-reduced-motion the glyph rests on a still frame; the delay and the ending stay.\n */\nexport function Loader({\n label,\n status = \"loading\",\n successLabel,\n errorLabel,\n value,\n eta,\n delay = 250,\n minDuration = 600,\n endDuration = 1600,\n variant,\n className,\n ...props\n}: LoaderProps) {\n const waiting = useDelayedWait(status === \"loading\", delay, minDuration);\n // Rendered already ended (a result to show), it shows its ending; otherwise only a wait that was seen ends visibly.\n const [ending, setEnding] = React.useState<\"success\" | \"error\" | null>(() => (status !== \"loading\" && endDuration > 0 ? status : null));\n const wasWaiting = React.useRef(false);\n React.useEffect(() => {\n if (!Number.isFinite(endDuration)) return;\n const hide = setTimeout(() => setEnding((e) => (wasWaiting.current ? e : null)), endDuration);\n return () => clearTimeout(hide);\n // Only the ending a loader was mounted with: later endings have their own timer below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n React.useEffect(() => {\n if (waiting) {\n wasWaiting.current = true;\n return;\n }\n if (!wasWaiting.current || status === \"loading\") return;\n wasWaiting.current = false;\n const end = status;\n const show = setTimeout(() => setEnding(endDuration > 0 ? end : null), 0);\n const hide = Number.isFinite(endDuration) ? setTimeout(() => setEnding(null), endDuration) : undefined;\n return () => {\n clearTimeout(show);\n clearTimeout(hide);\n };\n }, [waiting, status, endDuration]);\n\n const phase = waiting ? \"loading\" : ending;\n const s = loader({ variant, ended: phase === \"success\" || phase === \"error\" ? phase : undefined });\n const known = phase === \"loading\" && typeof value === \"number\" && Number.isFinite(value);\n const words = phase === \"success\" ? (successLabel ?? label) : phase === \"error\" ? (errorLabel ?? label) : label;\n const detail = phase === \"loading\" ? [known ? `${Math.round(Math.min(1, Math.max(0, value)) * 100)} %` : null, eta].filter(Boolean).join(\" · \") : \"\";\n return (\n <div role=\"status\" aria-live=\"polite\" data-phase={phase ?? \"idle\"} className={s.root({ className })} {...props}>\n {phase && (\n <div className={s.box()}>\n <LoaderGlyph state={phase} value={known ? value : null} className={s.glyph()} />\n <span className={s.text()}>\n <span className={s.label()}>{words}</span>\n {detail && <span className={s.detail()}>{detail}</span>}\n </span>\n </div>\n )}\n </div>\n );\n}\n\nexport interface LoadingRegionProps extends React.ComponentProps<\"div\"> {\n /** Whether the content is on its way. */\n loading: boolean;\n /** What stands in while it loads: skeletons the shape of the content (no layout shift when it arrives). */\n skeleton: React.ReactNode;\n /** What is loading, in words — passed translated; announced when the wait shows. */\n label: string;\n /** The words when the wait grows long (“Still loading — the server is busy”) — passed translated. */\n slowLabel?: string;\n /**\n * Milliseconds of skeleton before the words of a long wait appear over it.\n * @default 4000\n */\n slowAfter?: number;\n /**\n * Milliseconds before the skeleton shows: a fast answer goes straight to the content.\n * @default 200\n */\n delay?: number;\n /**\n * Once shown, the least milliseconds the skeleton stays.\n * @default 500\n */\n minDuration?: number;\n}\n\n/**\n * A region that hands over: its content → (after `delay`) a skeleton of the same shape → (after `slowAfter`) words over\n * the skeleton → its content again, fading in. `aria-busy` while it waits; the wait is announced once.\n */\nexport function LoadingRegion({\n loading,\n skeleton,\n label,\n slowLabel,\n slowAfter = 4000,\n delay = 200,\n minDuration = 500,\n className,\n children,\n ...props\n}: LoadingRegionProps) {\n const waiting = useDelayedWait(loading, delay, minDuration);\n const slow = useDelayedWait(waiting && loading, slowAfter, 0);\n const busy = loading || waiting;\n return (\n <div aria-busy={busy} data-phase={waiting ? (slow ? \"slow\" : \"skeleton\") : busy ? \"pending\" : \"ready\"} className={[\"relative\", className].filter(Boolean).join(\" \")} {...props}>\n <span role=\"status\" className=\"sr-only\">\n {waiting ? (slow ? (slowLabel ?? label) : label) : \"\"}\n </span>\n {waiting ? (\n <div aria-hidden className=\"kz-fade\">\n {skeleton}\n </div>\n ) : busy ? (\n // Within the delay: the skeleton holds the place, invisible — nothing flashes, nothing jumps.\n <div aria-hidden className=\"invisible\">\n {skeleton}\n </div>\n ) : (\n <div className=\"kz-fade\">{children}</div>\n )}\n {waiting && slow && <Loader label={slowLabel ?? label} variant=\"overlay\" delay={0} minDuration={0} endDuration={0} aria-live=\"off\" role=\"presentation\" />}\n </div>\n );\n}\n"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"path": "loader/meta.ts",
|
|
249
|
+
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Loader\",\n summary:\n \"A wait from start to end: nothing for the first instants, then the Krizaka glyph with its words, a percentage and an ETA, held long enough to read, ending on a check or a cross that is drawn and announced — and `LoadingRegion`, which hands a region over to a skeleton of its shape.\",\n status: \"beta\",\n category: \"feedback\",\n platforms: \"web\",\n whenToUse: [\n \"Any wait whose length you do not control (a fetch, a refresh): the delay keeps fast answers from flashing a spinner.\",\n \"A wait that ends in a result worth saying — “12 invoices loaded”, “Could not publish”.\",\n \"Over a region that stays readable while it refreshes (`variant=\\\"overlay\\\"`), or over the whole screen at start-up (`page`).\",\n \"`LoadingRegion` for a card, a list or a panel: a skeleton of its shape while it loads, words when it lasts.\",\n ],\n whenNotToUse: [\n { when: \"Inside the button that started the action: the button draws the same glyph.\", use: \"button\" },\n { when: \"For a long task with steps or a known size the user follows.\", use: \"progress\" },\n { when: \"A tiny wait glyph with nothing else.\", use: \"spinner\" },\n ],\n bestPractices: [\n \"Say what is loading (“Loading your invoices”), not “Loading…”; say how it ended with `successLabel` / `errorLabel`.\",\n \"Keep the defaults: 250 ms of delay, 600 ms at least once shown — the two numbers that stop flicker.\",\n \"Give an `eta` when you can estimate it (format durations with `@krizaka/intl`): a known wait feels shorter.\",\n \"With `LoadingRegion`, draw the skeleton the shape of the content: nothing moves when it arrives.\",\n ],\n accessibility: {\n keyboard: [],\n notes: [\n \"`role=\\\"status\\\"` (polite) is present from the first render, so its words are announced when the wait shows and again when it ends.\",\n \"`LoadingRegion` sets `aria-busy` on the region while it waits; the skeleton is hidden from assistive technology and the wait is announced once.\",\n \"Under `prefers-reduced-motion` the glyph rests on a still frame and endings do not animate; the delay, the words and the announcements stay.\",\n ],\n },\n related: [\"spinner\", \"skeleton\", \"progress\", \"button\"],\n web: {\n imports: [\"Loader\", \"LoadingRegion\", \"useDelayedWait\"],\n examples: [\n { name: \"fetch-flow\", title: \"No flash, then a result\", description: \"A fast answer shows nothing; a slow one shows the wait, then “12 invoices loaded” with a check, then nothing.\" },\n { name: \"region-handover\", title: \"Hand-over to a skeleton\", description: \"`LoadingRegion`: a skeleton of the card's shape, words when it lasts, the card fading in.\" },\n { name: \"upload-eta\", title: \"Progress and ETA\", description: \"`value` and `eta`: the trace grows, the percentage and the time left read in tabular figures.\" },\n { name: \"overlay\", title: \"Over a region\", description: \"`variant=\\\"overlay\\\"`: the report stays readable behind frosted glass while it refreshes.\" },\n { name: \"endings\", title: \"Endings\", description: \"`status`: a success and a failure, drawn in their colour and said in words.\" },\n { name: \"minimal\", title: \"Minimal\", description: \"A label, nothing else: the defaults do the rest.\" },\n ],\n },\n} satisfies ComponentMeta;\n"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"path": "meta.ts",
|
|
253
|
+
"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"
|
|
254
|
+
}
|
|
255
|
+
],
|
|
256
|
+
"dependencies": [
|
|
257
|
+
"tailwind-variants@^3.3.1"
|
|
258
|
+
],
|
|
259
|
+
"registryDependencies": [
|
|
260
|
+
"spinner"
|
|
261
|
+
],
|
|
262
|
+
"demo": {
|
|
263
|
+
"path": "examples/loader/fetch-flow.tsx",
|
|
264
|
+
"content": "\"use client\";\nimport { Button } from \"@krizaka/ui/button\";\nimport { Loader } from \"@krizaka/ui/loader\";\nimport { useState } from \"react\";\n\n// Try both: a fast answer (150 ms) shows nothing at all; a slow one shows the wait, then a check, then nothing.\nexport default function LoaderFetchFlow() {\n const [status, setStatus] = useState<\"idle\" | \"loading\" | \"success\">(\"idle\");\n const run = (ms: number) => {\n setStatus(\"loading\");\n setTimeout(() => setStatus(\"success\"), ms);\n };\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={() => run(150)}>Fast answer</Button>\n <Button size=\"sm\" onClick={() => run(2500)}>Slow answer</Button>\n </div>\n <div className=\"h-10\">\n {status !== \"idle\" && <Loader status={status} label=\"Loading your invoices\" successLabel=\"12 invoices loaded\" />}\n </div>\n </div>\n );\n}\n"
|
|
265
|
+
},
|
|
266
|
+
"props": [
|
|
267
|
+
{
|
|
268
|
+
"component": "Loader",
|
|
269
|
+
"description": "A wait, from start to end. `role=\"status\"` (polite): its words are announced when it shows and when it ends. Under\nprefers-reduced-motion the glyph rests on a still frame; the delay and the ending stay.",
|
|
270
|
+
"props": [
|
|
271
|
+
{
|
|
272
|
+
"name": "label",
|
|
273
|
+
"type": "string",
|
|
274
|
+
"default": null,
|
|
275
|
+
"description": "What is loading, in words (“Loading your invoices”) — passed translated; shown and announced.",
|
|
276
|
+
"required": true
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"name": "delay",
|
|
280
|
+
"type": "number",
|
|
281
|
+
"default": "250",
|
|
282
|
+
"description": "Milliseconds before anything shows: a wait shorter than this never flashes.",
|
|
283
|
+
"required": false
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"name": "endDuration",
|
|
287
|
+
"type": "number",
|
|
288
|
+
"default": "1600",
|
|
289
|
+
"description": "Milliseconds the ending (check or cross) stays before the loader disappears; `0` never shows it, `Infinity` keeps it.",
|
|
290
|
+
"required": false
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"name": "errorLabel",
|
|
294
|
+
"type": "string",
|
|
295
|
+
"default": null,
|
|
296
|
+
"description": "The words of a failure (“Could not load the invoices”) — passed translated.",
|
|
297
|
+
"required": false
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"name": "eta",
|
|
301
|
+
"type": "string",
|
|
302
|
+
"default": null,
|
|
303
|
+
"description": "The time left, in words (“About 20 s left”) — passed translated (`@krizaka/intl` formats durations).",
|
|
304
|
+
"required": false
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"name": "minDuration",
|
|
308
|
+
"type": "number",
|
|
309
|
+
"default": "600",
|
|
310
|
+
"description": "Once shown, the least milliseconds it stays: it never blinks.",
|
|
311
|
+
"required": false
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"name": "status",
|
|
315
|
+
"type": "\"success\" | \"loading\" | \"error\"",
|
|
316
|
+
"default": "loading",
|
|
317
|
+
"description": "loading · success · error. When the wait ends, the loader shows how it ended for `endDuration` ms, then disappears.",
|
|
318
|
+
"required": false
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"name": "successLabel",
|
|
322
|
+
"type": "string",
|
|
323
|
+
"default": null,
|
|
324
|
+
"description": "The words of a success (“Invoices loaded”) — passed translated. Default: nothing more than the check.",
|
|
325
|
+
"required": false
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"name": "value",
|
|
329
|
+
"type": "number | null",
|
|
330
|
+
"default": null,
|
|
331
|
+
"description": "Between 0 and 1: a determinate wait — the trace grows to it and the percentage shows.",
|
|
332
|
+
"required": false
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"name": "variant",
|
|
336
|
+
"type": "\"inline\" | \"page\" | \"overlay\" | \"block\"",
|
|
337
|
+
"default": "inline",
|
|
338
|
+
"description": "inline (beside the content) · block (a region's centre) · overlay (over a `relative` parent, frosted) · page (the\nwhole screen).",
|
|
339
|
+
"required": false
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"component": "LoadingRegion",
|
|
345
|
+
"description": "A region that hands over: its content → (after `delay`) a skeleton of the same shape → (after `slowAfter`) words over\nthe skeleton → its content again, fading in. `aria-busy` while it waits; the wait is announced once.",
|
|
346
|
+
"props": [
|
|
347
|
+
{
|
|
348
|
+
"name": "label",
|
|
349
|
+
"type": "string",
|
|
350
|
+
"default": null,
|
|
351
|
+
"description": "What is loading, in words — passed translated; announced when the wait shows.",
|
|
352
|
+
"required": true
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"name": "loading",
|
|
356
|
+
"type": "boolean",
|
|
357
|
+
"default": null,
|
|
358
|
+
"description": "Whether the content is on its way.",
|
|
359
|
+
"required": true
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"name": "skeleton",
|
|
363
|
+
"type": "ReactNode",
|
|
364
|
+
"default": null,
|
|
365
|
+
"description": "What stands in while it loads: skeletons the shape of the content (no layout shift when it arrives).",
|
|
366
|
+
"required": true
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"name": "delay",
|
|
370
|
+
"type": "number",
|
|
371
|
+
"default": "200",
|
|
372
|
+
"description": "Milliseconds before the skeleton shows: a fast answer goes straight to the content.",
|
|
373
|
+
"required": false
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"name": "minDuration",
|
|
377
|
+
"type": "number",
|
|
378
|
+
"default": "500",
|
|
379
|
+
"description": "Once shown, the least milliseconds the skeleton stays.",
|
|
380
|
+
"required": false
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"name": "slowAfter",
|
|
384
|
+
"type": "number",
|
|
385
|
+
"default": "4000",
|
|
386
|
+
"description": "Milliseconds of skeleton before the words of a long wait appear over it.",
|
|
387
|
+
"required": false
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"name": "slowLabel",
|
|
391
|
+
"type": "string",
|
|
392
|
+
"default": null,
|
|
393
|
+
"description": "The words when the wait grows long (“Still loading — the server is busy”) — passed translated.",
|
|
394
|
+
"required": false
|
|
395
|
+
}
|
|
396
|
+
]
|
|
397
|
+
}
|
|
398
|
+
]
|
|
399
|
+
}
|