@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/button.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"name": "button",
|
|
3
3
|
"type": "primitive",
|
|
4
4
|
"title": "Button",
|
|
5
|
-
"summary": "The action:
|
|
6
|
-
"description": "The action:
|
|
5
|
+
"summary": "The action: six looks, three sizes, three shapes (rounded, pill, the Krizaka cut corners) — and the whole life of an action built in: a wait traced by the loader glyph, its progress, a success or a failure drawn and announced.",
|
|
6
|
+
"description": "The action: six looks, three sizes, three shapes (rounded, pill, the Krizaka cut corners) — and the whole life of an action built in: a wait traced by the loader glyph, its progress, a success or a failure drawn and announced.",
|
|
7
7
|
"status": "stable",
|
|
8
8
|
"category": "actions",
|
|
9
9
|
"platforms": "both",
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
"bestPractices": [
|
|
33
33
|
"Name the action with a verb: “Save”, “Send the invitation” — not “OK” or “Yes”.",
|
|
34
34
|
"One primary per view; the danger variant only for what destroys or cannot be undone.",
|
|
35
|
-
"`loading` while the action runs: the button is disabled
|
|
35
|
+
"`loading` while the action runs: the button is disabled, says it is busy and draws the glyph; add `progress` when you know how far it is.",
|
|
36
|
+
"End with `status` (`success` / `error`) and `announce` the result in words: sighted people see the check, everyone hears “Saved”. Clear the status after a moment.",
|
|
37
|
+
"`shape=\"cut\"`, `shimmer` and `magnetic` are the signature: keep them for the one action a page is about.",
|
|
36
38
|
"Style a link without the component with `buttonVariants({ variant, size })`."
|
|
37
39
|
],
|
|
38
40
|
"accessibility": {
|
|
@@ -49,7 +51,9 @@
|
|
|
49
51
|
"notes": [
|
|
50
52
|
"A native `<button type=\"button\">`: the role, the focus and the keyboard come from the platform.",
|
|
51
53
|
"`IconButton` requires `label`: it becomes the `aria-label` of a button that shows no text.",
|
|
52
|
-
"`loading` sets `aria-busy` and disables the button; `disabled` keeps it out of the tab order."
|
|
54
|
+
"`loading` sets `aria-busy` and disables the button; `disabled` keeps it out of the tab order.",
|
|
55
|
+
"`announce` renders a polite live region next to the button: the result of the action is heard, not only seen.",
|
|
56
|
+
"Under `prefers-reduced-motion` nothing moves (no shake, no lean, no sheen): the check, the cross and the status colour still say it."
|
|
53
57
|
]
|
|
54
58
|
},
|
|
55
59
|
"related": [
|
|
@@ -66,6 +70,13 @@
|
|
|
66
70
|
"component": "Button",
|
|
67
71
|
"description": "",
|
|
68
72
|
"props": [
|
|
73
|
+
{
|
|
74
|
+
"name": "announce",
|
|
75
|
+
"type": "string",
|
|
76
|
+
"default": null,
|
|
77
|
+
"description": "A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated.",
|
|
78
|
+
"required": false
|
|
79
|
+
},
|
|
69
80
|
{
|
|
70
81
|
"name": "asChild",
|
|
71
82
|
"type": "boolean",
|
|
@@ -73,18 +84,46 @@
|
|
|
73
84
|
"description": "Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged.",
|
|
74
85
|
"required": false
|
|
75
86
|
},
|
|
87
|
+
{
|
|
88
|
+
"name": "indicator",
|
|
89
|
+
"type": "boolean",
|
|
90
|
+
"default": "true",
|
|
91
|
+
"description": "Shows the glyph while `loading` / with a `status`. `false`: you draw your own.",
|
|
92
|
+
"required": false
|
|
93
|
+
},
|
|
76
94
|
{
|
|
77
95
|
"name": "loading",
|
|
78
96
|
"type": "boolean",
|
|
79
97
|
"default": null,
|
|
80
|
-
"description": "Disables and signals the wait (aria-busy, data-loading)
|
|
98
|
+
"description": "Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the\nbutton keeps its colour.",
|
|
99
|
+
"required": false
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "magnetic",
|
|
103
|
+
"type": "boolean",
|
|
104
|
+
"default": null,
|
|
105
|
+
"description": "The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch).",
|
|
106
|
+
"required": false
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "progress",
|
|
110
|
+
"type": "number | null",
|
|
111
|
+
"default": null,
|
|
112
|
+
"description": "Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an\nupload, an export).",
|
|
81
113
|
"required": false
|
|
82
114
|
},
|
|
83
115
|
{
|
|
84
116
|
"name": "shape",
|
|
85
|
-
"type": "\"rounded\" | \"pill\"",
|
|
117
|
+
"type": "\"rounded\" | \"pill\" | \"cut\"",
|
|
86
118
|
"default": "rounded",
|
|
87
|
-
"description": "rounded · pill.",
|
|
119
|
+
"description": "rounded · pill · cut (45° corners, the Krizaka chamfer).",
|
|
120
|
+
"required": false
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "shimmer",
|
|
124
|
+
"type": "boolean",
|
|
125
|
+
"default": null,
|
|
126
|
+
"description": "A sheen of light crosses the button on hover — for the one action a page is about.",
|
|
88
127
|
"required": false
|
|
89
128
|
},
|
|
90
129
|
{
|
|
@@ -94,6 +133,13 @@
|
|
|
94
133
|
"description": "sm · md · lg, or `icon` (a square).",
|
|
95
134
|
"required": false
|
|
96
135
|
},
|
|
136
|
+
{
|
|
137
|
+
"name": "status",
|
|
138
|
+
"type": "\"success\" | \"error\" | null",
|
|
139
|
+
"default": null,
|
|
140
|
+
"description": "How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of\nthe status colour opens around it. Clear it to return to rest.",
|
|
141
|
+
"required": false
|
|
142
|
+
},
|
|
97
143
|
{
|
|
98
144
|
"name": "variant",
|
|
99
145
|
"type": "\"danger\" | \"primary\" | \"gradient\" | \"secondary\" | \"outline\" | \"ghost\"",
|
|
@@ -105,7 +151,7 @@
|
|
|
105
151
|
},
|
|
106
152
|
{
|
|
107
153
|
"component": "IconButton",
|
|
108
|
-
"description": "An icon-only button: `label` is required, it is its accessible name.",
|
|
154
|
+
"description": "An icon-only button: `label` is required, it is its accessible name. Loading or with a status, the glyph takes the icon's place.",
|
|
109
155
|
"props": [
|
|
110
156
|
{
|
|
111
157
|
"name": "label",
|
|
@@ -114,6 +160,13 @@
|
|
|
114
160
|
"description": "The accessible name (and tooltip) of the button — required, passed translated.",
|
|
115
161
|
"required": true
|
|
116
162
|
},
|
|
163
|
+
{
|
|
164
|
+
"name": "announce",
|
|
165
|
+
"type": "string",
|
|
166
|
+
"default": null,
|
|
167
|
+
"description": "A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated.",
|
|
168
|
+
"required": false
|
|
169
|
+
},
|
|
117
170
|
{
|
|
118
171
|
"name": "asChild",
|
|
119
172
|
"type": "boolean",
|
|
@@ -121,18 +174,46 @@
|
|
|
121
174
|
"description": "Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged.",
|
|
122
175
|
"required": false
|
|
123
176
|
},
|
|
177
|
+
{
|
|
178
|
+
"name": "indicator",
|
|
179
|
+
"type": "boolean",
|
|
180
|
+
"default": "true",
|
|
181
|
+
"description": "Shows the glyph while `loading` / with a `status`. `false`: you draw your own.",
|
|
182
|
+
"required": false
|
|
183
|
+
},
|
|
124
184
|
{
|
|
125
185
|
"name": "loading",
|
|
126
186
|
"type": "boolean",
|
|
127
187
|
"default": null,
|
|
128
|
-
"description": "Disables and signals the wait (aria-busy, data-loading)
|
|
188
|
+
"description": "Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the\nbutton keeps its colour.",
|
|
189
|
+
"required": false
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "magnetic",
|
|
193
|
+
"type": "boolean",
|
|
194
|
+
"default": null,
|
|
195
|
+
"description": "The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch).",
|
|
196
|
+
"required": false
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"name": "progress",
|
|
200
|
+
"type": "number | null",
|
|
201
|
+
"default": null,
|
|
202
|
+
"description": "Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an\nupload, an export).",
|
|
129
203
|
"required": false
|
|
130
204
|
},
|
|
131
205
|
{
|
|
132
206
|
"name": "shape",
|
|
133
|
-
"type": "\"rounded\" | \"pill\"",
|
|
207
|
+
"type": "\"rounded\" | \"pill\" | \"cut\"",
|
|
134
208
|
"default": "rounded",
|
|
135
|
-
"description": "rounded · pill.",
|
|
209
|
+
"description": "rounded · pill · cut (45° corners, the Krizaka chamfer).",
|
|
210
|
+
"required": false
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"name": "shimmer",
|
|
214
|
+
"type": "boolean",
|
|
215
|
+
"default": null,
|
|
216
|
+
"description": "A sheen of light crosses the button on hover — for the one action a page is about.",
|
|
136
217
|
"required": false
|
|
137
218
|
},
|
|
138
219
|
{
|
|
@@ -142,6 +223,13 @@
|
|
|
142
223
|
"description": "sm · md · lg, or `icon` (a square).",
|
|
143
224
|
"required": false
|
|
144
225
|
},
|
|
226
|
+
{
|
|
227
|
+
"name": "status",
|
|
228
|
+
"type": "\"success\" | \"error\" | null",
|
|
229
|
+
"default": null,
|
|
230
|
+
"description": "How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of\nthe status colour opens around it. Clear it to return to rest.",
|
|
231
|
+
"required": false
|
|
232
|
+
},
|
|
145
233
|
{
|
|
146
234
|
"name": "variant",
|
|
147
235
|
"type": "\"danger\" | \"primary\" | \"gradient\" | \"secondary\" | \"outline\" | \"ghost\"",
|
|
@@ -153,6 +241,38 @@
|
|
|
153
241
|
}
|
|
154
242
|
],
|
|
155
243
|
"examples": [
|
|
244
|
+
{
|
|
245
|
+
"name": "save-flow",
|
|
246
|
+
"title": "Save, then confirm",
|
|
247
|
+
"description": "Press it: the glyph traces the wait, a check draws itself, “Changes saved” is announced, then it returns to rest.",
|
|
248
|
+
"path": "examples/button/save-flow.tsx",
|
|
249
|
+
"module": "@krizaka/ui/registry/examples/button/save-flow",
|
|
250
|
+
"code": "\"use client\";\nimport { Button } from \"@krizaka/ui/button\";\nimport { useState } from \"react\";\n\n// A save that runs, then confirms: the glyph traces the wait, a check draws itself, the result is announced.\nexport default function ButtonSaveFlow() {\n const [state, setState] = useState<\"idle\" | \"saving\" | \"saved\">(\"idle\");\n const save = () => {\n setState(\"saving\");\n setTimeout(() => setState(\"saved\"), 1400);\n setTimeout(() => setState(\"idle\"), 3400);\n };\n return (\n <Button\n variant=\"primary\"\n loading={state === \"saving\"}\n status={state === \"saved\" ? \"success\" : null}\n announce={state === \"saved\" ? \"Changes saved\" : \"\"}\n onClick={save}\n >\n {state === \"saving\" ? \"Saving…\" : state === \"saved\" ? \"Saved\" : \"Save changes\"}\n </Button>\n );\n}\n"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"name": "upload-progress",
|
|
254
|
+
"title": "An export with progress",
|
|
255
|
+
"description": "`progress`: the trace and a light fill grow across the button; it keeps its width and its colour.",
|
|
256
|
+
"path": "examples/button/upload-progress.tsx",
|
|
257
|
+
"module": "@krizaka/ui/registry/examples/button/upload-progress",
|
|
258
|
+
"code": "\"use client\";\nimport { Button } from \"@krizaka/ui/button\";\nimport { useEffect, useState } from \"react\";\n\n// An export with a known length: the trace and a light fill grow across the button; it keeps its width and colour.\n// “Run it” plays the export from the start.\nexport default function ButtonUploadProgress() {\n const [progress, setProgress] = useState(0.65);\n const [running, setRunning] = useState(false);\n useEffect(() => {\n if (!running || progress >= 1) return;\n const timer = setTimeout(() => setProgress((p) => Math.min(1, p + 0.15)), 700);\n return () => clearTimeout(timer);\n }, [running, progress]);\n const done = progress >= 1;\n return (\n <div className=\"flex items-center gap-3\">\n <Button variant=\"secondary\" loading={!done} progress={progress} status={done ? \"success\" : null}>\n {done ? \"Exported\" : `Exporting ${Math.round(progress * 100)} %`}\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => (setProgress(0.05), setRunning(true))}>\n Run it\n </Button>\n </div>\n );\n}\n"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"name": "error",
|
|
262
|
+
"title": "A failure",
|
|
263
|
+
"description": "`status=\"error\"`: a cross, one shake of the head, a ring of the danger colour — and the reason announced.",
|
|
264
|
+
"path": "examples/button/error.tsx",
|
|
265
|
+
"module": "@krizaka/ui/registry/examples/button/error",
|
|
266
|
+
"code": "import { Button } from \"@krizaka/ui/button\";\n\n// A failure, said three ways: a cross draws itself, the button shakes its head once, and the message is announced.\nexport default function ButtonError() {\n return (\n <Button variant=\"danger\" status=\"error\" announce=\"The payment was declined\">\n Payment declined — retry\n </Button>\n );\n}\n"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"name": "signature",
|
|
270
|
+
"title": "The signature action",
|
|
271
|
+
"description": "`shape=\"cut\"`, the gradient, `shimmer` and `magnetic`: the one call to action of a hero; the arrow leans forward on hover.",
|
|
272
|
+
"path": "examples/button/signature.tsx",
|
|
273
|
+
"module": "@krizaka/ui/registry/examples/button/signature",
|
|
274
|
+
"code": "import { Button } from \"@krizaka/ui/button\";\n\n// The one action a page is about: cut corners, the brand gradient, a sheen on hover, a lean toward the pointer\n// (`magnetic`, with MotionObserver mounted). The arrow of a signature icon leans forward on hover too.\nexport default function ButtonSignature() {\n return (\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button variant=\"gradient\" size=\"lg\" shape=\"cut\" shimmer magnetic>\n Start free\n <svg data-kz-icon=\"ForwardIcon\" viewBox=\"0 0 24 24\" className=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M5 12h14M13 6l6 6-6 6\" />\n </svg>\n </Button>\n <Button variant=\"outline\" size=\"lg\" shape=\"cut\">\n Talk to us\n </Button>\n </div>\n );\n}\n"
|
|
275
|
+
},
|
|
156
276
|
{
|
|
157
277
|
"name": "primary",
|
|
158
278
|
"title": "Primary",
|
|
@@ -228,10 +348,10 @@
|
|
|
228
348
|
{
|
|
229
349
|
"name": "loading",
|
|
230
350
|
"title": "Loading",
|
|
231
|
-
"description": "While the action runs: disabled, `aria-busy`, `data-loading
|
|
351
|
+
"description": "While the action runs: disabled, `aria-busy`, `data-loading`, the glyph before the label.",
|
|
232
352
|
"path": "examples/button/loading.tsx",
|
|
233
353
|
"module": "@krizaka/ui/registry/examples/button/loading",
|
|
234
|
-
"code": "import { Button } from \"@krizaka/ui/button\";\n\n//
|
|
354
|
+
"code": "import { Button } from \"@krizaka/ui/button\";\n\n// `loading`: disabled (never pressed twice), `aria-busy`, the loader glyph before the label — and its colour kept.\nexport default function ButtonLoading() {\n return (\n <Button variant=\"primary\" loading>\n Saving…\n </Button>\n );\n}\n"
|
|
235
355
|
},
|
|
236
356
|
{
|
|
237
357
|
"name": "as-child-link",
|
|
@@ -511,7 +631,7 @@
|
|
|
511
631
|
"files": [
|
|
512
632
|
{
|
|
513
633
|
"path": "button/button.tsx",
|
|
514
|
-
"content": "// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n // The brand's signature: accent → accent-2 (on-accent reads on both stops, tested in @krizaka/tokens).\n gradient: \"bg-linear-to-r from-accent to-accent-2 text-on-accent shadow-sm hover:brightness-110\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-fg-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The border and the tint carry the danger; the label stays the primary text role, legible on the tint at rest\n // and hovered over every surface (`text-fg-danger` is for text set directly on a surface).\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /**\n * The look: `primary` (the accent), `gradient` (accent → accent-2), `secondary` (a raised surface), `outline`,\n * `ghost`, `danger`.\n * @default \"secondary\"\n */\n variant?: ButtonVariants[\"variant\"];\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"md\"\n */\n size?: ButtonVariants[\"size\"];\n /**\n * rounded · pill.\n * @default \"rounded\"\n */\n shape?: ButtonVariants[\"shape\"];\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n
|
|
634
|
+
"content": "// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { LoaderGlyph } from \"../spinner/glyph\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98] \" +\n // Busy is not unavailable: a loading button keeps its colour (it is disabled only so it is not pressed twice).\n \"[&[data-loading]]:opacity-100\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n // The brand's signature: accent → accent-2 (on-accent reads on both stops, tested in @krizaka/tokens).\n gradient: \"bg-linear-to-r from-accent to-accent-2 text-on-accent shadow-sm hover:brightness-110\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-fg-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The border and the tint carry the danger; the label stays the primary text role, legible on the tint at rest\n // and hovered over every surface (`text-fg-danger` is for text set directly on a surface).\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n // `cut`: the Krizaka chamfer — 45° corners (CSS corner-shape, where supported; rounded elsewhere). The border, the\n // focus ring and the hover follow the cut, unlike a clip-path.\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\", cut: \"rounded-[10px] [corner-shape:bevel]\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /**\n * The look: `primary` (the accent), `gradient` (accent → accent-2), `secondary` (a raised surface), `outline`,\n * `ghost`, `danger`.\n * @default \"secondary\"\n */\n variant?: ButtonVariants[\"variant\"];\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"md\"\n */\n size?: ButtonVariants[\"size\"];\n /**\n * rounded · pill · cut (45° corners, the Krizaka chamfer).\n * @default \"rounded\"\n */\n shape?: ButtonVariants[\"shape\"];\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n /**\n * Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the\n * button keeps its colour.\n */\n loading?: boolean;\n /**\n * Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an\n * upload, an export).\n */\n progress?: number | null;\n /**\n * How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of\n * the status colour opens around it. Clear it to return to rest.\n */\n status?: \"success\" | \"error\" | null;\n /** A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated. */\n announce?: string;\n /**\n * Shows the glyph while `loading` / with a `status`. `false`: you draw your own.\n * @default true\n */\n indicator?: boolean;\n /** A sheen of light crosses the button on hover — for the one action a page is about. */\n shimmer?: boolean;\n /** The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch). */\n magnetic?: boolean;\n };\n\nconst STATUS_TEXT = { success: \"text-fg-success\", error: \"text-fg-danger\" } as const;\n\nexport function Button({\n asChild,\n loading,\n progress,\n status,\n announce,\n indicator = true,\n shimmer,\n magnetic,\n variant,\n size,\n shape,\n className,\n disabled,\n children,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot.Root : \"button\";\n const known = loading && typeof progress === \"number\" && Number.isFinite(progress);\n const ratio = known ? Math.min(1, Math.max(0, progress)) : 0;\n const glyph = indicator && !asChild && (loading || status) ? (status ?? \"loading\") : null;\n // On a filled variant the glyph stays in the label's colour; on the others it takes the status colour.\n const filled = variant === \"primary\" || variant === \"gradient\";\n const button = (\n <Comp\n type={asChild ? undefined : \"button\"}\n aria-busy={loading || undefined}\n data-loading={loading ? \"\" : undefined}\n data-variant={variant ?? \"secondary\"}\n data-kz-status={status ?? undefined}\n data-kz-magnetic={magnetic ? \"\" : undefined}\n disabled={asChild ? undefined : disabled || loading}\n aria-disabled={asChild && (disabled || loading) ? true : undefined}\n className={buttonVariants({\n variant,\n size,\n shape,\n className: [known && \"relative isolate overflow-hidden\", shimmer && \"kz-sheen\", className].filter(Boolean).join(\" \") || undefined,\n })}\n {...props}\n >\n {asChild ? (\n children\n ) : (\n <>\n {known && (\n <span aria-hidden className=\"absolute inset-y-0 left-0 -z-10 bg-current opacity-15 transition-[width] duration-500\" style={{ width: `${ratio * 100}%` }} />\n )}\n {glyph && (\n <span\n aria-hidden\n data-slot=\"indicator\"\n className=\"-my-1 grid grid-cols-[1fr] transition-[grid-template-columns,margin,opacity] duration-300 starting:-mr-2 starting:grid-cols-[0fr] starting:opacity-0\"\n >\n <span className=\"overflow-hidden\">\n <LoaderGlyph state={glyph} value={known ? ratio : null} className={[\"h-4 w-4\", glyph !== \"loading\" && !filled && STATUS_TEXT[glyph]].filter(Boolean).join(\" \")} />\n </span>\n </span>\n )}\n {children}\n </>\n )}\n </Comp>\n );\n if (announce === undefined || asChild) return button;\n return (\n <>\n {button}\n <span role=\"status\" className=\"sr-only\">\n {announce}\n </span>\n </>\n );\n}\n\nexport type IconButtonProps = Omit<ButtonProps, \"size\"> & {\n /** The accessible name (and tooltip) of the button — required, passed translated. */\n label: string;\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"icon\"\n */\n size?: ButtonProps[\"size\"];\n};\n\n/** An icon-only button: `label` is required, it is its accessible name. Loading or with a status, the glyph takes the icon's place. */\nexport function IconButton({ label, size = \"icon\", children, ...props }: IconButtonProps) {\n const swap = props.indicator !== false && !props.asChild && (props.loading || props.status);\n return (\n <Button aria-label={label} title={label} size={size} {...props}>\n {swap ? null : children}\n </Button>\n );\n}\n"
|
|
515
635
|
},
|
|
516
636
|
{
|
|
517
637
|
"path": "button/index.ts",
|
|
@@ -519,27 +639,36 @@
|
|
|
519
639
|
},
|
|
520
640
|
{
|
|
521
641
|
"path": "button/meta.ts",
|
|
522
|
-
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Button\",\n summary
|
|
642
|
+
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Button\",\n summary:\n \"The action: six looks, three sizes, three shapes (rounded, pill, the Krizaka cut corners) — and the whole life of an action built in: a wait traced by the loader glyph, its progress, a success or a failure drawn and announced.\",\n status: \"stable\",\n category: \"actions\",\n platforms: \"both\",\n whenToUse: [\n \"To run an action: submit a form, open a dialog, start an upload, save a draft.\",\n \"One `primary` button for the main action of a view; `secondary`, `outline` or `ghost` for the others.\",\n \"`IconButton` for a compact action shown by its icon alone (close, add, more), with a `label` for its name.\",\n ],\n whenNotToUse: [\n { when: \"To go to another page: use a link (`asChild` with your router's `<Link>` keeps the button look).\" },\n { when: \"To turn a setting on or off, with an immediate effect.\", use: \"switch\" },\n { when: \"For a destructive action that needs a second press to confirm, in place.\", use: \"confirm-button\" },\n { when: \"To choose one option among several, or filter a list.\", use: \"chip\" },\n ],\n bestPractices: [\n \"Name the action with a verb: “Save”, “Send the invitation” — not “OK” or “Yes”.\",\n \"One primary per view; the danger variant only for what destroys or cannot be undone.\",\n \"`loading` while the action runs: the button is disabled, says it is busy and draws the glyph; add `progress` when you know how far it is.\",\n \"End with `status` (`success` / `error`) and `announce` the result in words: sighted people see the check, everyone hears “Saved”. Clear the status after a moment.\",\n \"`shape=\\\"cut\\\"`, `shimmer` and `magnetic` are the signature: keep them for the one action a page is about.\",\n \"Style a link without the component with `buttonVariants({ variant, size })`.\",\n ],\n accessibility: {\n keyboard: [\n { keys: \"Enter / Space\", action: \"Runs the action.\" },\n { keys: \"Tab\", action: \"Moves the focus to the next control; the focus ring uses `--kz-ring`.\" },\n ],\n notes: [\n \"A native `<button type=\\\"button\\\">`: the role, the focus and the keyboard come from the platform.\",\n \"`IconButton` requires `label`: it becomes the `aria-label` of a button that shows no text.\",\n \"`loading` sets `aria-busy` and disables the button; `disabled` keeps it out of the tab order.\",\n \"`announce` renders a polite live region next to the button: the result of the action is heard, not only seen.\",\n \"Under `prefers-reduced-motion` nothing moves (no shake, no lean, no sheen): the check, the cross and the status colour still say it.\",\n ],\n },\n related: [\"confirm-button\", \"dialog\", \"dropdown-menu\", \"tooltip\"],\n web: {\n imports: [\"Button\", \"IconButton\"],\n examples: [\n { name: \"save-flow\", title: \"Save, then confirm\", description: \"Press it: the glyph traces the wait, a check draws itself, “Changes saved” is announced, then it returns to rest.\" },\n { name: \"upload-progress\", title: \"An export with progress\", description: \"`progress`: the trace and a light fill grow across the button; it keeps its width and its colour.\" },\n { name: \"error\", title: \"A failure\", description: \"`status=\\\"error\\\"`: a cross, one shake of the head, a ring of the danger colour — and the reason announced.\" },\n { name: \"signature\", title: \"The signature action\", description: \"`shape=\\\"cut\\\"`, the gradient, `shimmer` and `magnetic`: the one call to action of a hero; the arrow leans forward on hover.\" },\n { name: \"primary\", title: \"Primary\", description: \"The main action of a view: the accent.\" },\n { name: \"gradient\", title: \"Gradient\", description: \"The brand's signature, accent → accent-2: a hero or a closing call to action, once per page.\" },\n { name: \"secondary\", title: \"Secondary\", description: \"The default: a raised surface, for the other actions.\" },\n { name: \"outline\", title: \"Outline\", description: \"A lighter action next to a primary one.\" },\n { name: \"ghost\", title: \"Ghost\", description: \"In toolbars and dense lists: no frame until hovered.\" },\n { name: \"danger\", title: \"Danger\", description: \"A destructive action: the border and the tint carry the danger, the label stays legible in both themes.\" },\n { name: \"sizes\", title: \"Sizes\", description: \"`sm`, `md` (default) and `lg`.\" },\n { name: \"pill\", title: \"Pill\", description: \"`shape=\\\"pill\\\"`: fully rounded.\" },\n { name: \"disabled\", title: \"Disabled\", description: \"Not available yet: out of the tab order.\" },\n { name: \"loading\", title: \"Loading\", description: \"While the action runs: disabled, `aria-busy`, `data-loading`, the glyph before the label.\" },\n { name: \"as-child-link\", title: \"As a link\", description: \"`asChild` renders your `<a>` (or router link) with the button's look.\" },\n { name: \"icon\", title: \"Icon button\", description: \"`IconButton`: a square button holding an icon; `label` is its accessible name.\" },\n ],\n },\n native: {\n imports: [\"Button\", \"IconButton\"],\n differences: [\n \"The text is the `label` prop (a string), not children: it is also the accessible name.\",\n \"`onPress` instead of `onClick` (a `Pressable`); haptics, if any, belong to your `onPress`.\",\n \"`icon` places an icon before the label; there is no `asChild`.\",\n \"`loading` shows the platform's `ActivityIndicator` in place of the icon.\",\n \"`variant=\\\"gradient\\\"` draws its fill with react-native-svg (React Native has no CSS gradient).\",\n ],\n examples: [\n { name: \"primary\", title: \"Primary\", description: \"The main action of a screen.\" },\n { name: \"gradient\", title: \"Gradient\", description: \"accent → accent-2, drawn with react-native-svg: the hero action of a screen.\" },\n { name: \"secondary\", title: \"Secondary\", description: \"The default look.\" },\n { name: \"outline\", title: \"Outline\", description: \"A lighter action.\" },\n { name: \"ghost\", title: \"Ghost\", description: \"No frame: toolbars, headers.\" },\n { name: \"danger\", title: \"Danger\", description: \"A destructive action.\" },\n { name: \"sizes\", title: \"Sizes\", description: \"`sm`, `md`, `lg`, and `shape=\\\"pill\\\"`.\" },\n { name: \"icon\", title: \"With an icon\", description: \"`icon` before the label.\" },\n { name: \"disabled\", title: \"Disabled\", description: \"Not available yet.\" },\n { name: \"loading\", title: \"Loading\", description: \"Disabled and busy, a spinner in place of the icon.\" },\n { name: \"icon-only\", title: \"Icon button\", description: \"`IconButton`: `label` is required, it is the accessible name.\" },\n ],\n },\n} satisfies ComponentMeta;\n"
|
|
523
643
|
},
|
|
524
644
|
{
|
|
525
645
|
"path": "meta.ts",
|
|
526
|
-
"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"
|
|
646
|
+
"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"
|
|
527
647
|
}
|
|
528
648
|
],
|
|
529
649
|
"dependencies": [
|
|
530
650
|
"radix-ui@^1.7.0",
|
|
531
651
|
"tailwind-variants@^3.3.1"
|
|
532
652
|
],
|
|
533
|
-
"registryDependencies": [
|
|
653
|
+
"registryDependencies": [
|
|
654
|
+
"spinner"
|
|
655
|
+
],
|
|
534
656
|
"demo": {
|
|
535
|
-
"path": "examples/button/
|
|
536
|
-
"content": "
|
|
657
|
+
"path": "examples/button/save-flow.tsx",
|
|
658
|
+
"content": "\"use client\";\nimport { Button } from \"@krizaka/ui/button\";\nimport { useState } from \"react\";\n\n// A save that runs, then confirms: the glyph traces the wait, a check draws itself, the result is announced.\nexport default function ButtonSaveFlow() {\n const [state, setState] = useState<\"idle\" | \"saving\" | \"saved\">(\"idle\");\n const save = () => {\n setState(\"saving\");\n setTimeout(() => setState(\"saved\"), 1400);\n setTimeout(() => setState(\"idle\"), 3400);\n };\n return (\n <Button\n variant=\"primary\"\n loading={state === \"saving\"}\n status={state === \"saved\" ? \"success\" : null}\n announce={state === \"saved\" ? \"Changes saved\" : \"\"}\n onClick={save}\n >\n {state === \"saving\" ? \"Saving…\" : state === \"saved\" ? \"Saved\" : \"Save changes\"}\n </Button>\n );\n}\n"
|
|
537
659
|
},
|
|
538
660
|
"props": [
|
|
539
661
|
{
|
|
540
662
|
"component": "Button",
|
|
541
663
|
"description": "",
|
|
542
664
|
"props": [
|
|
665
|
+
{
|
|
666
|
+
"name": "announce",
|
|
667
|
+
"type": "string",
|
|
668
|
+
"default": null,
|
|
669
|
+
"description": "A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated.",
|
|
670
|
+
"required": false
|
|
671
|
+
},
|
|
543
672
|
{
|
|
544
673
|
"name": "asChild",
|
|
545
674
|
"type": "boolean",
|
|
@@ -547,18 +676,46 @@
|
|
|
547
676
|
"description": "Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged.",
|
|
548
677
|
"required": false
|
|
549
678
|
},
|
|
679
|
+
{
|
|
680
|
+
"name": "indicator",
|
|
681
|
+
"type": "boolean",
|
|
682
|
+
"default": "true",
|
|
683
|
+
"description": "Shows the glyph while `loading` / with a `status`. `false`: you draw your own.",
|
|
684
|
+
"required": false
|
|
685
|
+
},
|
|
550
686
|
{
|
|
551
687
|
"name": "loading",
|
|
552
688
|
"type": "boolean",
|
|
553
689
|
"default": null,
|
|
554
|
-
"description": "Disables and signals the wait (aria-busy, data-loading)
|
|
690
|
+
"description": "Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the\nbutton keeps its colour.",
|
|
691
|
+
"required": false
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
"name": "magnetic",
|
|
695
|
+
"type": "boolean",
|
|
696
|
+
"default": null,
|
|
697
|
+
"description": "The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch).",
|
|
698
|
+
"required": false
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
"name": "progress",
|
|
702
|
+
"type": "number | null",
|
|
703
|
+
"default": null,
|
|
704
|
+
"description": "Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an\nupload, an export).",
|
|
555
705
|
"required": false
|
|
556
706
|
},
|
|
557
707
|
{
|
|
558
708
|
"name": "shape",
|
|
559
|
-
"type": "\"rounded\" | \"pill\"",
|
|
709
|
+
"type": "\"rounded\" | \"pill\" | \"cut\"",
|
|
560
710
|
"default": "rounded",
|
|
561
|
-
"description": "rounded · pill.",
|
|
711
|
+
"description": "rounded · pill · cut (45° corners, the Krizaka chamfer).",
|
|
712
|
+
"required": false
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
"name": "shimmer",
|
|
716
|
+
"type": "boolean",
|
|
717
|
+
"default": null,
|
|
718
|
+
"description": "A sheen of light crosses the button on hover — for the one action a page is about.",
|
|
562
719
|
"required": false
|
|
563
720
|
},
|
|
564
721
|
{
|
|
@@ -568,6 +725,13 @@
|
|
|
568
725
|
"description": "sm · md · lg, or `icon` (a square).",
|
|
569
726
|
"required": false
|
|
570
727
|
},
|
|
728
|
+
{
|
|
729
|
+
"name": "status",
|
|
730
|
+
"type": "\"success\" | \"error\" | null",
|
|
731
|
+
"default": null,
|
|
732
|
+
"description": "How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of\nthe status colour opens around it. Clear it to return to rest.",
|
|
733
|
+
"required": false
|
|
734
|
+
},
|
|
571
735
|
{
|
|
572
736
|
"name": "variant",
|
|
573
737
|
"type": "\"danger\" | \"primary\" | \"gradient\" | \"secondary\" | \"outline\" | \"ghost\"",
|
|
@@ -579,7 +743,7 @@
|
|
|
579
743
|
},
|
|
580
744
|
{
|
|
581
745
|
"component": "IconButton",
|
|
582
|
-
"description": "An icon-only button: `label` is required, it is its accessible name.",
|
|
746
|
+
"description": "An icon-only button: `label` is required, it is its accessible name. Loading or with a status, the glyph takes the icon's place.",
|
|
583
747
|
"props": [
|
|
584
748
|
{
|
|
585
749
|
"name": "label",
|
|
@@ -588,6 +752,13 @@
|
|
|
588
752
|
"description": "The accessible name (and tooltip) of the button — required, passed translated.",
|
|
589
753
|
"required": true
|
|
590
754
|
},
|
|
755
|
+
{
|
|
756
|
+
"name": "announce",
|
|
757
|
+
"type": "string",
|
|
758
|
+
"default": null,
|
|
759
|
+
"description": "A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated.",
|
|
760
|
+
"required": false
|
|
761
|
+
},
|
|
591
762
|
{
|
|
592
763
|
"name": "asChild",
|
|
593
764
|
"type": "boolean",
|
|
@@ -595,18 +766,46 @@
|
|
|
595
766
|
"description": "Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged.",
|
|
596
767
|
"required": false
|
|
597
768
|
},
|
|
769
|
+
{
|
|
770
|
+
"name": "indicator",
|
|
771
|
+
"type": "boolean",
|
|
772
|
+
"default": "true",
|
|
773
|
+
"description": "Shows the glyph while `loading` / with a `status`. `false`: you draw your own.",
|
|
774
|
+
"required": false
|
|
775
|
+
},
|
|
598
776
|
{
|
|
599
777
|
"name": "loading",
|
|
600
778
|
"type": "boolean",
|
|
601
779
|
"default": null,
|
|
602
|
-
"description": "Disables and signals the wait (aria-busy, data-loading)
|
|
780
|
+
"description": "Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the\nbutton keeps its colour.",
|
|
781
|
+
"required": false
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
"name": "magnetic",
|
|
785
|
+
"type": "boolean",
|
|
786
|
+
"default": null,
|
|
787
|
+
"description": "The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch).",
|
|
788
|
+
"required": false
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
"name": "progress",
|
|
792
|
+
"type": "number | null",
|
|
793
|
+
"default": null,
|
|
794
|
+
"description": "Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an\nupload, an export).",
|
|
603
795
|
"required": false
|
|
604
796
|
},
|
|
605
797
|
{
|
|
606
798
|
"name": "shape",
|
|
607
|
-
"type": "\"rounded\" | \"pill\"",
|
|
799
|
+
"type": "\"rounded\" | \"pill\" | \"cut\"",
|
|
608
800
|
"default": "rounded",
|
|
609
|
-
"description": "rounded · pill.",
|
|
801
|
+
"description": "rounded · pill · cut (45° corners, the Krizaka chamfer).",
|
|
802
|
+
"required": false
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
"name": "shimmer",
|
|
806
|
+
"type": "boolean",
|
|
807
|
+
"default": null,
|
|
808
|
+
"description": "A sheen of light crosses the button on hover — for the one action a page is about.",
|
|
610
809
|
"required": false
|
|
611
810
|
},
|
|
612
811
|
{
|
|
@@ -616,6 +815,13 @@
|
|
|
616
815
|
"description": "sm · md · lg, or `icon` (a square).",
|
|
617
816
|
"required": false
|
|
618
817
|
},
|
|
818
|
+
{
|
|
819
|
+
"name": "status",
|
|
820
|
+
"type": "\"success\" | \"error\" | null",
|
|
821
|
+
"default": null,
|
|
822
|
+
"description": "How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of\nthe status colour opens around it. Clear it to return to rest.",
|
|
823
|
+
"required": false
|
|
824
|
+
},
|
|
619
825
|
{
|
|
620
826
|
"name": "variant",
|
|
621
827
|
"type": "\"danger\" | \"primary\" | \"gradient\" | \"secondary\" | \"outline\" | \"ghost\"",
|
package/registry/card.json
CHANGED
|
@@ -425,7 +425,7 @@
|
|
|
425
425
|
},
|
|
426
426
|
{
|
|
427
427
|
"path": "meta.ts",
|
|
428
|
-
"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"
|
|
428
|
+
"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"
|
|
429
429
|
}
|
|
430
430
|
],
|
|
431
431
|
"dependencies": [
|
package/registry/checkbox.json
CHANGED
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"path": "meta.ts",
|
|
136
|
-
"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"
|
|
136
|
+
"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"
|
|
137
137
|
}
|
|
138
138
|
],
|
|
139
139
|
"dependencies": [
|