@krizaka/ui 3.35.0 → 3.37.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/dist/account-menu.js +1 -1
- package/dist/account-menu.js.map +1 -1
- package/dist/activity-feed.js +2 -2
- package/dist/activity-feed.js.map +1 -1
- package/dist/anatomy-plate.d.ts +26 -0
- package/dist/anatomy-plate.js +32 -0
- package/dist/anatomy-plate.js.map +1 -0
- package/dist/app-header.js +1 -1
- package/dist/app-header.js.map +1 -1
- package/dist/app-shell.js +6 -6
- package/dist/app-shell.js.map +1 -1
- package/dist/argument-card.js +1 -1
- package/dist/badge.d.ts +1 -1
- package/dist/badge.js +1 -1
- package/dist/badge.js.map +1 -1
- package/dist/bird-plate.d.ts +38 -0
- package/dist/bird-plate.js +39 -0
- package/dist/bird-plate.js.map +1 -0
- package/dist/blocks.css +243 -46
- package/dist/card.d.ts +6 -6
- package/dist/card.js +2 -2
- package/dist/card.js.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/chip-row.js +1 -1
- package/dist/chip-row.js.map +1 -1
- package/dist/chip.js +1 -1
- package/dist/chip.js.map +1 -1
- package/dist/{chunk-QDXV544C.js → chunk-4QH6CP2Y.js} +2 -2
- package/dist/chunk-4QH6CP2Y.js.map +1 -0
- package/dist/{chunk-NJFCSVPT.js → chunk-6EAHUURY.js} +2 -2
- package/dist/chunk-6EAHUURY.js.map +1 -0
- package/dist/{chunk-REPTKUJ6.js → chunk-7NRSPHAF.js} +2 -2
- package/dist/chunk-7NRSPHAF.js.map +1 -0
- package/dist/{chunk-CKSHLSDH.js → chunk-AAP3U66V.js} +2 -2
- package/dist/{chunk-7UCPGXKN.js → chunk-C3NF7V5Y.js} +2 -2
- package/dist/{chunk-7UCPGXKN.js.map → chunk-C3NF7V5Y.js.map} +1 -1
- package/dist/chunk-JFJECOZ2.js +338 -0
- package/dist/chunk-JFJECOZ2.js.map +1 -0
- package/dist/{chunk-KIBICUZK.js → chunk-S5LP7KKW.js} +4 -4
- package/dist/{chunk-3S4GHSPZ.js → chunk-VPO27AFS.js} +5 -5
- package/dist/chunk-VPO27AFS.js.map +1 -0
- package/dist/{chunk-2PNLHZLT.js → chunk-WYQ277F2.js} +3 -3
- package/dist/chunk-WYQ277F2.js.map +1 -0
- package/dist/{chunk-7Z4KHPFC.js → chunk-YGIN2YIY.js} +2 -2
- package/dist/{chunk-7Z4KHPFC.js.map → chunk-YGIN2YIY.js.map} +1 -1
- package/dist/{chunk-LZNZLCOE.js → chunk-YKEIOYJ5.js} +20 -6
- package/dist/chunk-YKEIOYJ5.js.map +1 -0
- package/dist/{chunk-2DGLWTPS.js → chunk-YKOLME7R.js} +3 -3
- package/dist/{chunk-2DGLWTPS.js.map → chunk-YKOLME7R.js.map} +1 -1
- package/dist/code-block.js +4 -4
- package/dist/code-block.js.map +1 -1
- package/dist/combobox.js +2 -2
- package/dist/command.js +3 -3
- package/dist/command.js.map +1 -1
- package/dist/comparison-table.js +2 -2
- package/dist/comparison-table.js.map +1 -1
- package/dist/countdown.js +1 -1
- package/dist/countdown.js.map +1 -1
- package/dist/cover-hero.js +15 -6
- package/dist/cover-hero.js.map +1 -1
- package/dist/dashboard-layout.js +1 -1
- package/dist/dashboard-layout.js.map +1 -1
- package/dist/data-table.js +5 -5
- package/dist/date-picker.js +3 -3
- package/dist/date-picker.js.map +1 -1
- package/dist/description-list.js +1 -1
- package/dist/description-list.js.map +1 -1
- package/dist/detail-layout.js +1 -1
- package/dist/detail-layout.js.map +1 -1
- package/dist/dialog.js +1 -1
- package/dist/docs-nav.js +1 -1
- package/dist/docs-nav.js.map +1 -1
- package/dist/dropdown-menu.js +1 -1
- package/dist/dropdown-menu.js.map +1 -1
- package/dist/file-upload.js +3 -3
- package/dist/file-upload.js.map +1 -1
- package/dist/filter-bar.js +2 -2
- package/dist/footnote.d.ts +32 -0
- package/dist/footnote.js +29 -0
- package/dist/footnote.js.map +1 -0
- package/dist/genui.js +6 -6
- package/dist/geometry-DncHaYP8.d.ts +22 -0
- package/dist/language-switch.js +1 -1
- package/dist/list.js +1 -1
- package/dist/loader.js +2 -2
- package/dist/loader.js.map +1 -1
- package/dist/map.js +95 -83
- package/dist/map.js.map +1 -1
- package/dist/marketing-layout.js +1 -1
- package/dist/marketing-layout.js.map +1 -1
- package/dist/mascot-quote.d.ts +2 -21
- package/dist/mascot-quote.js +9 -338
- package/dist/mascot-quote.js.map +1 -1
- package/dist/match-dialog.js +1 -1
- package/dist/match-dialog.js.map +1 -1
- package/dist/media-grid.js +1 -1
- package/dist/meter.js +3 -3
- package/dist/meter.js.map +1 -1
- package/dist/motion.css +28 -41
- package/dist/native/map.js +94 -82
- package/dist/native/map.js.map +1 -1
- package/dist/native.d.ts +8 -1
- package/dist/native.js +57 -45
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.js +12 -12
- package/dist/nav-bar.js.map +1 -1
- package/dist/page-hero.js +1 -1
- package/dist/page-index.d.ts +30 -0
- package/dist/page-index.js +23 -0
- package/dist/page-index.js.map +1 -0
- package/dist/page.d.ts +19 -7
- package/dist/page.js +1 -1
- package/dist/photo-grid.js +2 -2
- package/dist/photo-grid.js.map +1 -1
- package/dist/progress.js +3 -3
- package/dist/progress.js.map +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.js.map +1 -1
- package/dist/rail-nav.js +2 -2
- package/dist/rail-nav.js.map +1 -1
- package/dist/search-field.js +1 -1
- package/dist/service-card.js +3 -3
- package/dist/service-card.js.map +1 -1
- package/dist/settings-layout.js +1 -1
- package/dist/settings-layout.js.map +1 -1
- package/dist/site-footer.js +3 -3
- package/dist/site-footer.js.map +1 -1
- package/dist/skip-link.js +1 -1
- package/dist/slot-picker.js +1 -1
- package/dist/slot-picker.js.map +1 -1
- package/dist/specimen-tag.d.ts +52 -0
- package/dist/specimen-tag.js +33 -0
- package/dist/specimen-tag.js.map +1 -0
- package/dist/stat.js +1 -1
- package/dist/stat.js.map +1 -1
- package/dist/step-progress.js +1 -1
- package/dist/step-progress.js.map +1 -1
- package/dist/sticky-action.d.ts +1 -1
- package/dist/sticky-action.js +1 -1
- package/dist/sticky-action.js.map +1 -1
- package/dist/swipe-deck.js +1 -1
- package/dist/swipe-deck.js.map +1 -1
- package/dist/tabs.js +4 -4
- package/dist/tabs.js.map +1 -1
- package/dist/tag-input.js +2 -2
- package/dist/tag-selector.js +1 -1
- package/dist/toast.js +1 -1
- package/dist/toast.js.map +1 -1
- package/package.json +74 -4
- package/registry/account-menu.json +1 -1
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/activity-feed.json +2 -2
- package/registry/alert.json +1 -1
- package/registry/anatomy-plate.json +168 -0
- package/registry/app-header.json +2 -2
- package/registry/app-shell.json +2 -2
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +1 -1
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +1 -1
- package/registry/badge.json +2 -2
- package/registry/bird-plate.json +221 -0
- package/registry/button.json +1 -1
- package/registry/captcha.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +2 -2
- package/registry/catalogue-page.json +1 -1
- package/registry/changelog-page.json +1 -1
- package/registry/chat.json +3 -3
- package/registry/checkbox.json +2 -2
- package/registry/chip-link.json +1 -1
- package/registry/chip-row.json +2 -2
- package/registry/chip.json +2 -2
- package/registry/choice-grid.json +1 -1
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +1 -1
- package/registry/command.json +2 -2
- package/registry/comparison-table.json +2 -2
- package/registry/component-page.json +1 -1
- package/registry/confirm-button.json +1 -1
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +2 -2
- package/registry/cover-hero.json +2 -2
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +2 -2
- package/registry/data-table.json +1 -1
- package/registry/date-picker.json +4 -4
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +2 -2
- package/registry/detail-layout.json +2 -2
- package/registry/dialog.json +2 -2
- package/registry/docs-article-page.json +1 -1
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/docs-nav.json +2 -2
- package/registry/document-viewer.json +1 -1
- package/registry/dropdown-menu.json +2 -2
- package/registry/empty-state.json +1 -1
- package/registry/engine-flow.json +1 -1
- package/registry/error-page.json +1 -1
- package/registry/examples/action-sheet/native/video-actions.dark.png +0 -0
- package/registry/examples/action-sheet/native/video-actions.light.png +0 -0
- package/registry/examples/activity-feed/native/notifications.dark.png +0 -0
- package/registry/examples/activity-feed/native/notifications.light.png +0 -0
- package/registry/examples/anatomy-plate/button.d.ts +4 -0
- package/registry/examples/anatomy-plate/button.js +25 -0
- package/registry/examples/anatomy-plate/button.tsx +20 -0
- package/registry/examples/avatar/native/group.dark.png +0 -0
- package/registry/examples/avatar/native/group.light.png +0 -0
- package/registry/examples/avatar/native/presence.dark.png +0 -0
- package/registry/examples/avatar/native/presence.light.png +0 -0
- package/registry/examples/avatar/native/sizes.dark.png +0 -0
- package/registry/examples/avatar/native/sizes.light.png +0 -0
- package/registry/examples/badge/native/dot.dark.png +0 -0
- package/registry/examples/badge/native/dot.light.png +0 -0
- package/registry/examples/badge/native/scrim.dark.png +0 -0
- package/registry/examples/badge/native/scrim.light.png +0 -0
- package/registry/examples/badge/native/tones.dark.png +0 -0
- package/registry/examples/badge/native/tones.light.png +0 -0
- package/registry/examples/bird-plate/flock.d.ts +4 -0
- package/registry/examples/bird-plate/flock.js +24 -0
- package/registry/examples/bird-plate/flock.tsx +18 -0
- package/registry/examples/bird-plate/single.d.ts +4 -0
- package/registry/examples/bird-plate/single.js +19 -0
- package/registry/examples/bird-plate/single.tsx +13 -0
- package/registry/examples/button/native/danger.dark.png +0 -0
- package/registry/examples/button/native/danger.light.png +0 -0
- package/registry/examples/button/native/disabled.dark.png +0 -0
- package/registry/examples/button/native/disabled.light.png +0 -0
- package/registry/examples/button/native/ghost.dark.png +0 -0
- package/registry/examples/button/native/ghost.light.png +0 -0
- package/registry/examples/button/native/gradient.dark.png +0 -0
- package/registry/examples/button/native/gradient.light.png +0 -0
- package/registry/examples/button/native/icon-only.dark.png +0 -0
- package/registry/examples/button/native/icon-only.light.png +0 -0
- package/registry/examples/button/native/icon.dark.png +0 -0
- package/registry/examples/button/native/icon.light.png +0 -0
- package/registry/examples/button/native/loading.dark.png +0 -0
- package/registry/examples/button/native/loading.light.png +0 -0
- package/registry/examples/button/native/outline.dark.png +0 -0
- package/registry/examples/button/native/outline.light.png +0 -0
- package/registry/examples/button/native/primary.dark.png +0 -0
- package/registry/examples/button/native/primary.light.png +0 -0
- package/registry/examples/button/native/secondary.dark.png +0 -0
- package/registry/examples/button/native/secondary.light.png +0 -0
- package/registry/examples/button/native/sizes.dark.png +0 -0
- package/registry/examples/button/native/sizes.light.png +0 -0
- package/registry/examples/card/native/body.dark.png +0 -0
- package/registry/examples/card/native/body.light.png +0 -0
- package/registry/examples/card/native/default.dark.png +0 -0
- package/registry/examples/card/native/default.light.png +0 -0
- package/registry/examples/card/native/elevated.dark.png +0 -0
- package/registry/examples/card/native/elevated.light.png +0 -0
- package/registry/examples/card/native/pressable.dark.png +0 -0
- package/registry/examples/card/native/pressable.light.png +0 -0
- package/registry/examples/chat/native/assistant.dark.png +0 -0
- package/registry/examples/chat/native/assistant.light.png +0 -0
- package/registry/examples/chat/native/conversation.dark.png +0 -0
- package/registry/examples/chat/native/conversation.light.png +0 -0
- package/registry/examples/chat/native/inbox.dark.png +0 -0
- package/registry/examples/chat/native/inbox.light.png +0 -0
- package/registry/examples/checkbox/native/terms.dark.png +0 -0
- package/registry/examples/checkbox/native/terms.light.png +0 -0
- package/registry/examples/chip/native/multiple.dark.png +0 -0
- package/registry/examples/chip/native/multiple.light.png +0 -0
- package/registry/examples/chip/native/removable.dark.png +0 -0
- package/registry/examples/chip/native/removable.light.png +0 -0
- package/registry/examples/chip/native/single.dark.png +0 -0
- package/registry/examples/chip/native/single.light.png +0 -0
- package/registry/examples/chip/native/toggle.dark.png +0 -0
- package/registry/examples/chip/native/toggle.light.png +0 -0
- package/registry/examples/combobox/native/multiple.dark.png +0 -0
- package/registry/examples/combobox/native/multiple.light.png +0 -0
- package/registry/examples/combobox/native/search.dark.png +0 -0
- package/registry/examples/combobox/native/search.light.png +0 -0
- package/registry/examples/countdown/native/days.dark.png +0 -0
- package/registry/examples/countdown/native/days.light.png +0 -0
- package/registry/examples/countdown/native/hours.dark.png +0 -0
- package/registry/examples/countdown/native/hours.light.png +0 -0
- package/registry/examples/countdown/native/sizes.dark.png +0 -0
- package/registry/examples/countdown/native/sizes.light.png +0 -0
- package/registry/examples/countdown/native/urgent.dark.png +0 -0
- package/registry/examples/countdown/native/urgent.light.png +0 -0
- package/registry/examples/countdown/native/with-label.dark.png +0 -0
- package/registry/examples/countdown/native/with-label.light.png +0 -0
- package/registry/examples/date-picker/native/birth-date-wheel.dark.png +0 -0
- package/registry/examples/date-picker/native/birth-date-wheel.light.png +0 -0
- package/registry/examples/date-picker/native/birth-date.dark.png +0 -0
- package/registry/examples/date-picker/native/birth-date.light.png +0 -0
- package/registry/examples/date-picker/native/calendar.dark.png +0 -0
- package/registry/examples/date-picker/native/calendar.light.png +0 -0
- package/registry/examples/date-picker/native/day-strip.dark.png +0 -0
- package/registry/examples/date-picker/native/day-strip.light.png +0 -0
- package/registry/examples/date-picker/native/month-year.dark.png +0 -0
- package/registry/examples/date-picker/native/month-year.light.png +0 -0
- package/registry/examples/date-picker/native/time-slots.dark.png +0 -0
- package/registry/examples/date-picker/native/time-slots.light.png +0 -0
- package/registry/examples/date-picker/native/time-wheel.dark.png +0 -0
- package/registry/examples/date-picker/native/time-wheel.light.png +0 -0
- package/registry/examples/description-list/native/job-details.dark.png +0 -0
- package/registry/examples/description-list/native/job-details.light.png +0 -0
- package/registry/examples/dialog/native/sheet.dark.png +0 -0
- package/registry/examples/dialog/native/sheet.light.png +0 -0
- package/registry/examples/empty-state/native/default.dark.png +0 -0
- package/registry/examples/empty-state/native/default.light.png +0 -0
- package/registry/examples/fab/native/extended.dark.png +0 -0
- package/registry/examples/fab/native/extended.light.png +0 -0
- package/registry/examples/field/native/default.dark.png +0 -0
- package/registry/examples/field/native/default.light.png +0 -0
- package/registry/examples/field/native/select.dark.png +0 -0
- package/registry/examples/field/native/select.light.png +0 -0
- package/registry/examples/footnote/notes.d.ts +4 -0
- package/registry/examples/footnote/notes.js +24 -0
- package/registry/examples/footnote/notes.tsx +19 -0
- package/registry/examples/force-update-screen/native/default.dark.png +0 -0
- package/registry/examples/force-update-screen/native/default.light.png +0 -0
- package/registry/examples/form/native/amount.dark.png +0 -0
- package/registry/examples/form/native/amount.light.png +0 -0
- package/registry/examples/form/native/audience.dark.png +0 -0
- package/registry/examples/form/native/audience.light.png +0 -0
- package/registry/examples/form/native/profile.dark.png +0 -0
- package/registry/examples/form/native/profile.light.png +0 -0
- package/registry/examples/form/native/settings.dark.png +0 -0
- package/registry/examples/form/native/settings.light.png +0 -0
- package/registry/examples/form/native/sign-up.dark.png +0 -0
- package/registry/examples/form/native/sign-up.light.png +0 -0
- package/registry/examples/form/native/upload.dark.png +0 -0
- package/registry/examples/form/native/upload.light.png +0 -0
- package/registry/examples/goal-gauge/native/default.dark.png +0 -0
- package/registry/examples/goal-gauge/native/default.light.png +0 -0
- package/registry/examples/header/native/large-title.dark.png +0 -0
- package/registry/examples/header/native/large-title.light.png +0 -0
- package/registry/examples/image-viewer/native/gallery.dark.png +0 -0
- package/registry/examples/image-viewer/native/gallery.light.png +0 -0
- package/registry/examples/list/native/default.dark.png +0 -0
- package/registry/examples/list/native/default.light.png +0 -0
- package/registry/examples/list/native/infinite.dark.png +0 -0
- package/registry/examples/list/native/infinite.light.png +0 -0
- package/registry/examples/list/native/states.dark.png +0 -0
- package/registry/examples/list/native/states.light.png +0 -0
- package/registry/examples/loader/native/block.dark.png +0 -0
- package/registry/examples/loader/native/block.light.png +0 -0
- package/registry/examples/loader/native/branded.dark.png +0 -0
- package/registry/examples/loader/native/branded.light.png +0 -0
- package/registry/examples/loader/native/job-wait.dark.png +0 -0
- package/registry/examples/loader/native/job-wait.light.png +0 -0
- package/registry/examples/maintenance-screen/native/default.dark.png +0 -0
- package/registry/examples/maintenance-screen/native/default.light.png +0 -0
- package/registry/examples/map/native/location-picker.dark.png +0 -0
- package/registry/examples/map/native/location-picker.light.png +0 -0
- package/registry/examples/map/native/places.dark.png +0 -0
- package/registry/examples/map/native/places.light.png +0 -0
- package/registry/examples/markdown/native/ai-stream.dark.png +0 -0
- package/registry/examples/markdown/native/ai-stream.light.png +0 -0
- package/registry/examples/markdown/native/basic.dark.png +0 -0
- package/registry/examples/markdown/native/basic.light.png +0 -0
- package/registry/examples/mascot-state/native/default.dark.png +0 -0
- package/registry/examples/mascot-state/native/default.light.png +0 -0
- package/registry/examples/mascots/native/crane.dark.png +0 -0
- package/registry/examples/mascots/native/crane.light.png +0 -0
- package/registry/examples/mascots/native/default.dark.png +0 -0
- package/registry/examples/mascots/native/default.light.png +0 -0
- package/registry/examples/mascots/native/lovebird.dark.png +0 -0
- package/registry/examples/mascots/native/lovebird.light.png +0 -0
- package/registry/examples/mascots/native/phoenix.dark.png +0 -0
- package/registry/examples/mascots/native/phoenix.light.png +0 -0
- package/registry/examples/match-dialog/native/its-a-match.dark.png +0 -0
- package/registry/examples/match-dialog/native/its-a-match.light.png +0 -0
- package/registry/examples/media-capture/native/photo.dark.png +0 -0
- package/registry/examples/media-capture/native/photo.light.png +0 -0
- package/registry/examples/media-picker/native/story.dark.png +0 -0
- package/registry/examples/media-picker/native/story.light.png +0 -0
- package/registry/examples/meta-row/native/video.dark.png +0 -0
- package/registry/examples/meta-row/native/video.light.png +0 -0
- package/registry/examples/meter/native/credits.dark.png +0 -0
- package/registry/examples/meter/native/credits.light.png +0 -0
- package/registry/examples/meter/native/split-ring.dark.png +0 -0
- package/registry/examples/meter/native/split-ring.light.png +0 -0
- package/registry/examples/number-ticker/native/balance.dark.png +0 -0
- package/registry/examples/number-ticker/native/balance.light.png +0 -0
- package/registry/examples/onboarding/native/first-launch.dark.png +0 -0
- package/registry/examples/onboarding/native/first-launch.light.png +0 -0
- package/registry/examples/otp-input/native/invalid.dark.png +0 -0
- package/registry/examples/otp-input/native/invalid.light.png +0 -0
- package/registry/examples/otp-input/native/verify.dark.png +0 -0
- package/registry/examples/otp-input/native/verify.light.png +0 -0
- package/registry/examples/page-index/docs.d.ts +4 -0
- package/registry/examples/page-index/docs.js +33 -0
- package/registry/examples/page-index/docs.tsx +27 -0
- package/registry/examples/pagination/native/cursor.dark.png +0 -0
- package/registry/examples/pagination/native/cursor.light.png +0 -0
- package/registry/examples/pagination/native/pages.dark.png +0 -0
- package/registry/examples/pagination/native/pages.light.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.dark.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.light.png +0 -0
- package/registry/examples/permission-prompt/native/camera.dark.png +0 -0
- package/registry/examples/permission-prompt/native/camera.light.png +0 -0
- package/registry/examples/photo-grid/native/profile-photos.dark.png +0 -0
- package/registry/examples/photo-grid/native/profile-photos.light.png +0 -0
- package/registry/examples/profile-card/native/default.dark.png +0 -0
- package/registry/examples/profile-card/native/default.light.png +0 -0
- package/registry/examples/progress/native/bar.dark.png +0 -0
- package/registry/examples/progress/native/bar.light.png +0 -0
- package/registry/examples/progress/native/indeterminate.dark.png +0 -0
- package/registry/examples/progress/native/indeterminate.light.png +0 -0
- package/registry/examples/progress/native/ring.dark.png +0 -0
- package/registry/examples/progress/native/ring.light.png +0 -0
- package/registry/examples/pull-to-refresh/native/branded.dark.png +0 -0
- package/registry/examples/pull-to-refresh/native/branded.light.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.dark.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.light.png +0 -0
- package/registry/examples/radio-group/native/buttons.dark.png +0 -0
- package/registry/examples/radio-group/native/buttons.light.png +0 -0
- package/registry/examples/radio-group/native/cards.dark.png +0 -0
- package/registry/examples/radio-group/native/cards.light.png +0 -0
- package/registry/examples/radio-group/native/list.dark.png +0 -0
- package/registry/examples/radio-group/native/list.light.png +0 -0
- package/registry/examples/radio-group/native/segmented.dark.png +0 -0
- package/registry/examples/radio-group/native/segmented.light.png +0 -0
- package/registry/examples/screen/native/app-shell.dark.png +0 -0
- package/registry/examples/screen/native/app-shell.light.png +0 -0
- package/registry/examples/screen/native/auth.dark.png +0 -0
- package/registry/examples/screen/native/auth.light.png +0 -0
- package/registry/examples/screen/native/chat.dark.png +0 -0
- package/registry/examples/screen/native/chat.light.png +0 -0
- package/registry/examples/screen/native/feed.dark.png +0 -0
- package/registry/examples/screen/native/feed.light.png +0 -0
- package/registry/examples/screen/native/map.dark.png +0 -0
- package/registry/examples/screen/native/map.light.png +0 -0
- package/registry/examples/screen/native/notifications.dark.png +0 -0
- package/registry/examples/screen/native/notifications.light.png +0 -0
- package/registry/examples/screen/native/profile.dark.png +0 -0
- package/registry/examples/screen/native/profile.light.png +0 -0
- package/registry/examples/screen/native/settings.dark.png +0 -0
- package/registry/examples/screen/native/settings.light.png +0 -0
- package/registry/examples/search-field/native/cancel.dark.png +0 -0
- package/registry/examples/search-field/native/cancel.light.png +0 -0
- package/registry/examples/search-field/native/default.dark.png +0 -0
- package/registry/examples/search-field/native/default.light.png +0 -0
- package/registry/examples/segmented/native/default.dark.png +0 -0
- package/registry/examples/segmented/native/default.light.png +0 -0
- package/registry/examples/segmented/native/small.dark.png +0 -0
- package/registry/examples/segmented/native/small.light.png +0 -0
- package/registry/examples/settings-layout/native/account.dark.png +0 -0
- package/registry/examples/settings-layout/native/account.light.png +0 -0
- package/registry/examples/showcase/native/slides.dark.png +0 -0
- package/registry/examples/showcase/native/slides.light.png +0 -0
- package/registry/examples/skeleton/native/shapes.dark.png +0 -0
- package/registry/examples/skeleton/native/shapes.light.png +0 -0
- package/registry/examples/slider/native/default.dark.png +0 -0
- package/registry/examples/slider/native/default.light.png +0 -0
- package/registry/examples/slider/native/range.dark.png +0 -0
- package/registry/examples/slider/native/range.light.png +0 -0
- package/registry/examples/slider/native/stepped.dark.png +0 -0
- package/registry/examples/slider/native/stepped.light.png +0 -0
- package/registry/examples/slider/native/vertical.dark.png +0 -0
- package/registry/examples/slider/native/vertical.light.png +0 -0
- package/registry/examples/specimen-tag/product.d.ts +4 -0
- package/registry/examples/specimen-tag/product.js +28 -0
- package/registry/examples/specimen-tag/product.tsx +25 -0
- package/registry/examples/specimen-tag/stamps.d.ts +4 -0
- package/registry/examples/specimen-tag/stamps.js +16 -0
- package/registry/examples/specimen-tag/stamps.tsx +13 -0
- package/registry/examples/specimen-tag/wire.d.ts +4 -0
- package/registry/examples/specimen-tag/wire.js +16 -0
- package/registry/examples/specimen-tag/wire.tsx +20 -0
- package/registry/examples/spinner/native/sizes.dark.png +0 -0
- package/registry/examples/spinner/native/sizes.light.png +0 -0
- package/registry/examples/splash-handoff/native/default.dark.png +0 -0
- package/registry/examples/splash-handoff/native/default.light.png +0 -0
- package/registry/examples/step-progress/native/sign-up.dark.png +0 -0
- package/registry/examples/step-progress/native/sign-up.light.png +0 -0
- package/registry/examples/stepper/native/run.dark.png +0 -0
- package/registry/examples/stepper/native/run.light.png +0 -0
- package/registry/examples/swipe-deck/native/discover.dark.png +0 -0
- package/registry/examples/swipe-deck/native/discover.light.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.dark.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.light.png +0 -0
- package/registry/examples/switch/native/default.dark.png +0 -0
- package/registry/examples/switch/native/default.light.png +0 -0
- package/registry/examples/switch/native/settings.dark.png +0 -0
- package/registry/examples/switch/native/settings.light.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.dark.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.light.png +0 -0
- package/registry/examples/tabs/native/sections.dark.png +0 -0
- package/registry/examples/tabs/native/sections.light.png +0 -0
- package/registry/examples/tabs/native/segmented.dark.png +0 -0
- package/registry/examples/tabs/native/segmented.light.png +0 -0
- package/registry/examples/tag-selector/native/interests.dark.png +0 -0
- package/registry/examples/tag-selector/native/interests.light.png +0 -0
- package/registry/examples/toast/native/notification.dark.png +0 -0
- package/registry/examples/toast/native/notification.light.png +0 -0
- package/registry/examples/toast/native/snackbar.dark.png +0 -0
- package/registry/examples/toast/native/snackbar.light.png +0 -0
- package/registry/examples/toast/native/tones.dark.png +0 -0
- package/registry/examples/toast/native/tones.light.png +0 -0
- package/registry/examples/txt/native/tones.dark.png +0 -0
- package/registry/examples/txt/native/tones.light.png +0 -0
- package/registry/examples/txt/native/variants.dark.png +0 -0
- package/registry/examples/txt/native/variants.light.png +0 -0
- package/registry/examples/update-prompt/native/default.dark.png +0 -0
- package/registry/examples/update-prompt/native/default.light.png +0 -0
- package/registry/examples/verified-badge/native/verified.dark.png +0 -0
- package/registry/examples/verified-badge/native/verified.light.png +0 -0
- package/registry/examples/vertical-video/native/rail.dark.png +0 -0
- package/registry/examples/vertical-video/native/rail.light.png +0 -0
- package/registry/examples/video-player/native/default.dark.png +0 -0
- package/registry/examples/video-player/native/default.light.png +0 -0
- package/registry/examples/waveform/native/card.dark.png +0 -0
- package/registry/examples/waveform/native/card.light.png +0 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +1 -1
- package/registry/filter-bar.json +1 -1
- package/registry/footnote.json +220 -0
- package/registry/force-update-screen.json +1 -1
- package/registry/form.json +3 -3
- package/registry/gallery-page.json +1 -1
- package/registry/genui.json +1 -1
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +1 -1
- package/registry/how-it-works-page.json +1 -1
- package/registry/image-cropper.json +1 -1
- package/registry/index.json +160 -5
- package/registry/iso.json +1 -1
- package/registry/kanban.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +1 -1
- package/registry/landscape.json +1 -1
- package/registry/language-switch.json +2 -2
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +1 -1
- package/registry/list.json +1 -1
- package/registry/loader.json +2 -2
- package/registry/longform-page.json +1 -1
- package/registry/maintenance-screen.json +1 -1
- package/registry/map.json +3 -3
- package/registry/markdown.json +1 -1
- package/registry/marketing-layout.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +1 -1
- package/registry/mascot-state.json +1 -1
- package/registry/mascots.json +1 -1
- package/registry/match-dialog.json +1 -1
- package/registry/media-capture.json +1 -1
- package/registry/media-gallery.json +1 -1
- package/registry/media-grid.json +1 -1
- package/registry/meta-row.json +1 -1
- package/registry/meter.json +2 -2
- package/registry/nav-bar.json +3 -3
- package/registry/number-ticker.json +1 -1
- package/registry/opening-hours.json +1 -1
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +1 -1
- package/registry/page-index.json +168 -0
- package/registry/page.json +89 -5
- package/registry/pagination.json +1 -1
- package/registry/photo-grid.json +2 -2
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +1 -1
- package/registry/product-page.json +1 -1
- package/registry/profile-card.json +1 -1
- package/registry/progress.json +2 -2
- package/registry/promise-card.json +1 -1
- package/registry/radio-group.json +2 -2
- package/registry/rail-nav.json +3 -3
- package/registry/recipes.json +1 -1
- package/registry/scroll-stage.json +1 -1
- package/registry/search-field.json +2 -2
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/service-card.json +2 -2
- package/registry/settings-layout.json +2 -2
- package/registry/showcase.json +1 -1
- package/registry/site-footer.json +3 -3
- package/registry/sites.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/skip-link.json +2 -2
- package/registry/slider.json +1 -1
- package/registry/slot-picker.json +2 -2
- package/registry/slot.json +1 -1
- package/registry/specimen-tag.json +269 -0
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +1 -1
- package/registry/stat.json +2 -2
- package/registry/status-page.json +1 -1
- package/registry/step-progress.json +2 -2
- package/registry/step-showcase.json +1 -1
- package/registry/stepper.json +1 -1
- package/registry/sticky-action.json +2 -2
- package/registry/swipe-deck.json +2 -2
- package/registry/switch.json +1 -1
- package/registry/tabs.json +2 -2
- package/registry/tag-input.json +1 -1
- package/registry/tag-selector.json +1 -1
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +1 -1
- package/registry/toast.json +2 -2
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/tree-view.json +1 -1
- package/registry/update-prompt.json +1 -1
- package/registry/verified-badge.json +1 -1
- package/registry/vertical-video.json +1 -1
- package/registry/video-player.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/registry/virtual.json +1 -1
- package/registry/waveform.json +1 -1
- package/dist/chunk-2PNLHZLT.js.map +0 -1
- package/dist/chunk-3S4GHSPZ.js.map +0 -1
- package/dist/chunk-LZNZLCOE.js.map +0 -1
- package/dist/chunk-NJFCSVPT.js.map +0 -1
- package/dist/chunk-QDXV544C.js.map +0 -1
- package/dist/chunk-REPTKUJ6.js.map +0 -1
- /package/dist/{chunk-CKSHLSDH.js.map → chunk-AAP3U66V.js.map} +0 -0
- /package/dist/{chunk-KIBICUZK.js.map → chunk-S5LP7KKW.js.map} +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "page-index",
|
|
3
|
+
"type": "primitive",
|
|
4
|
+
"title": "Page index",
|
|
5
|
+
"summary": "A book's index for a documentation or a catalogue: groups, entries, a dotted leader and the page number at the end of the line; the current entry marked in the margin.",
|
|
6
|
+
"description": "A book's index for a documentation or a catalogue: groups, entries, a dotted leader and the page number at the end of the line; the current entry marked in the margin.",
|
|
7
|
+
"status": "beta",
|
|
8
|
+
"deprecated": null,
|
|
9
|
+
"category": "navigation",
|
|
10
|
+
"platforms": "web",
|
|
11
|
+
"parity": {
|
|
12
|
+
"web": {
|
|
13
|
+
"state": "yes"
|
|
14
|
+
},
|
|
15
|
+
"native": {
|
|
16
|
+
"state": "n/a",
|
|
17
|
+
"reason": "A documentation sidebar; an app's navigation is its tab bar and lists.",
|
|
18
|
+
"use": "list"
|
|
19
|
+
},
|
|
20
|
+
"desktop": {
|
|
21
|
+
"state": "yes"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"whenToUse": [
|
|
25
|
+
"The sidebar of a documentation: the components of a group, numbered as the pages of a reference book.",
|
|
26
|
+
"The table of a catalogue or a long read, where a number helps the reader find a page again."
|
|
27
|
+
],
|
|
28
|
+
"whenNotToUse": [
|
|
29
|
+
{
|
|
30
|
+
"when": "The sections of the page being read.",
|
|
31
|
+
"use": "toc"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"when": "The navigation of an application.",
|
|
35
|
+
"use": "rail-nav"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"bestPractices": [
|
|
39
|
+
"Numbers are the reader's landmarks: keep them stable (a component keeps its number across versions).",
|
|
40
|
+
"Group titles are short and typed in lower case; three to eight entries per group.",
|
|
41
|
+
"Pass the router link as `linkAs` so internal entries prefetch."
|
|
42
|
+
],
|
|
43
|
+
"accessibility": {
|
|
44
|
+
"keyboard": [],
|
|
45
|
+
"notes": [
|
|
46
|
+
"A `nav` named by `label` (« Index »); each group a heading and a list of links.",
|
|
47
|
+
"The current entry carries `aria-current=\"page\"`; the margin's arrow and the dotted leader are decorative."
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"related": [
|
|
51
|
+
"docs-nav",
|
|
52
|
+
"toc",
|
|
53
|
+
"docs-layout"
|
|
54
|
+
],
|
|
55
|
+
"web": {
|
|
56
|
+
"entry": "@krizaka/ui/page-index",
|
|
57
|
+
"import": "import { PageIndex } from \"@krizaka/ui/page-index\";",
|
|
58
|
+
"props": [
|
|
59
|
+
{
|
|
60
|
+
"component": "LinkComponent",
|
|
61
|
+
"description": "The app's link component (Next's `Link`, React Router's `Link`…): receives `href`, `className` and the children.",
|
|
62
|
+
"props": []
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"component": "PageIndex",
|
|
66
|
+
"description": "A book's index: headings, entries, a dotted leader and the page number; the current entry marked in the margin.",
|
|
67
|
+
"props": [
|
|
68
|
+
{
|
|
69
|
+
"name": "groups",
|
|
70
|
+
"type": "readonly IndexGroup[]",
|
|
71
|
+
"default": null,
|
|
72
|
+
"description": "The groups, in reading order.",
|
|
73
|
+
"required": true
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "label",
|
|
77
|
+
"type": "string",
|
|
78
|
+
"default": "Index",
|
|
79
|
+
"description": "The accessible name of the navigation.",
|
|
80
|
+
"required": false
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "linkAs",
|
|
84
|
+
"type": "LinkComponent",
|
|
85
|
+
"default": null,
|
|
86
|
+
"description": "The app's router link (Next's `Link`), so internal entries prefetch.",
|
|
87
|
+
"required": false
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
"examples": [
|
|
93
|
+
{
|
|
94
|
+
"name": "docs",
|
|
95
|
+
"title": "A documentation's index",
|
|
96
|
+
"description": "Two groups, the current entry marked, the page numbers aligned.",
|
|
97
|
+
"path": "examples/page-index/docs.tsx",
|
|
98
|
+
"module": "@krizaka/ui/registry/examples/page-index/docs",
|
|
99
|
+
"code": "import { PageIndex } from \"@krizaka/ui/page-index\";\n\n// A documentation's sidebar as a book's index: the current entry marked in the margin, the page numbers aligned.\nexport default function PageIndexDocs() {\n return (\n <PageIndex\n className=\"max-w-xs pl-6\"\n groups={[\n {\n title: \"Actions\",\n entries: [\n { label: \"Button\", href: \"/components/button\", page: 42, current: true },\n { label: \"Confirm button\", href: \"/components/confirm-button\", page: 43 },\n { label: \"Continue prompt\", href: \"/components/continue-prompt\", page: 44 },\n ],\n },\n {\n title: \"Inputs & forms\",\n entries: [\n { label: \"Checkbox\", href: \"/components/checkbox\", page: 52 },\n { label: \"Date picker\", href: \"/components/date-picker\", page: 54 },\n ],\n },\n ]}\n />\n );\n}\n"
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"native": null,
|
|
104
|
+
"files": [
|
|
105
|
+
{
|
|
106
|
+
"path": "block-link.tsx",
|
|
107
|
+
"content": "// The links of the page blocks (PageHero's back link, LinkCard, ArgumentCard, ActionBar): an internal path renders\n// through the app's router link (`linkAs`, e.g. Next's `Link`), anything else is an `<a>` that opens in a new tab.\n// Shared by the block entries; never exported on its own.\nimport type * as React from \"react\";\n\n/** The app's link component (Next's `Link`, React Router's `Link`…): receives `href`, `className` and the children. */\nexport type LinkComponent = React.ElementType<{ href: string; className?: string; children?: React.ReactNode; \"aria-label\"?: string; \"aria-describedby\"?: string }>;\n\n/** An address that leaves the app: an absolute URL or a protocol (`mailto:`). */\nexport const isExternal = (href: string) => /^[a-z][a-z0-9+.-]*:/i.test(href);\n\nexport function BlockLink({\n href,\n linkAs: Link = \"a\",\n external = isExternal(href),\n rel,\n ...props\n}: Omit<React.ComponentProps<\"a\">, \"href\"> & { href: string; linkAs?: LinkComponent; external?: boolean }) {\n if (external) return <a href={href} target=\"_blank\" rel={rel ?? \"noopener noreferrer\"} {...props} />;\n const Comp = Link as React.ElementType;\n return <Comp href={href} {...props} />;\n}\n"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"path": "meta.ts",
|
|
111
|
+
"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 ui.krizaka.com (apps/site) renders as\n// ui.krizaka.com/components/<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 | \"achievement\"\n | \"anatomy-plate\"\n | \"bird-plate\"\n | \"footnote\"\n | \"page-index\"\n | \"specimen-tag\"\n | \"action-bar\"\n | \"action-sheet\"\n | \"activity-feed\"\n | \"alert\"\n | \"app-header\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"captcha\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"chat\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"chip-row\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"comparison-table\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cover-hero\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"description-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"docs-nav\"\n | \"document-viewer\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"engine-flow\"\n | \"error-page\"\n | \"fab\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"force-update-screen\"\n | \"form\"\n | \"gallery-page\"\n | \"genui\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"header\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"image-viewer\"\n | \"iso\"\n | \"kanban\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"list\"\n | \"loader\"\n | \"longform-page\"\n | \"maintenance-screen\"\n | \"map\"\n | \"markdown\"\n | \"meta-row\"\n | \"waveform\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"match-dialog\"\n | \"media-capture\"\n | \"media-grid\"\n | \"language-switch\"\n | \"media-gallery\"\n | \"media-picker\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"onboarding\"\n | \"opening-hours\"\n | \"otp-input\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"permission-prompt\"\n | \"photo-grid\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"pull-to-refresh\"\n | \"radio-group\"\n | \"rail-nav\"\n | \"recipes\"\n | \"screen\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"service-card\"\n | \"settings-layout\"\n | \"account-menu\"\n | \"showcase\"\n | \"step-showcase\"\n | \"site-footer\"\n | \"sites\"\n | \"skeleton\"\n | \"skip-link\"\n | \"slider\"\n | \"slot-picker\"\n | \"slot\"\n | \"spinner\"\n | \"sticky-action\"\n | \"splash-handoff\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"step-progress\"\n | \"stepper\"\n | \"swipe-deck\"\n | \"swipeable-row\"\n | \"switch\"\n | \"tab-bar\"\n | \"tabs\"\n | \"tag-input\"\n | \"tag-selector\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"tree-view\"\n | \"txt\"\n | \"update-prompt\"\n | \"verified-badge\"\n | \"vertical-video\"\n | \"video-player\"\n | \"video-trimmer\"\n | \"virtual\";\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/**\n * Why a component is not on a platform — a decision, never a silence (the parity matrix of ui.krizaka.com/platforms):\n * - `gap` (✗): it belongs there and is not built yet; `issue` is the issue that tracks it (`krizaka/krizaka-ui#275`);\n * - `n/a`: it is not meant for that platform (a site's page block on a phone, a swipe on a desktop); `use` names the\n * component that answers there, when one does.\n */\nexport type Absence =\n | { readonly status: \"gap\"; readonly issue: string; readonly reason: string; readonly use?: undefined }\n | { readonly status: \"n/a\"; readonly reason: string; readonly use?: ComponentName; readonly issue?: undefined };\n\n/**\n * Desktop is the Orazaka Mac app (Tauri 2: the system WebView renders the web components — ADR-002). `web`: the web\n * component runs there as it is; `desktop`: it also has a desktop form (a window's title bar, a denser layout…), said in\n * its documentation; otherwise the absence and why.\n */\nexport type DesktopSupport = \"web\" | \"desktop\" | Absence;\n\n/**\n * The three platforms of Krizaka UI — web · native (React Native, Expo) · desktop — for one component. The side a\n * component has is `platforms`; the side it lacks says why here: `native` is required for (and only for) a web-only\n * component, `web` for a native-only one; `desktop` always. `scripts/registry.test.mjs` fails on a missing decision.\n */\nexport interface Parity {\n readonly web?: Absence;\n readonly native?: Absence;\n readonly desktop: DesktopSupport;\n}\n\n/**\n * `stable`: its API only changes in a major. `beta`: it may still change in a minor. `deprecated`: no product uses it and\n * no work plans to — it still works, says what replaces it, and goes in the major named by `deprecated.removedIn`.\n */\nexport type Status = \"stable\" | \"beta\" | \"deprecated\";\n\n/** What a deprecated component says (required when `status` is `deprecated`, absent otherwise). */\nexport interface Deprecation {\n /** The version that deprecated it (`3.6.0`). */\n readonly since: string;\n /** The major that removes it (`4.0.0`). */\n readonly removedIn: string;\n /** What replaces it, when a component does. */\n readonly use?: ComponentName;\n /** Why it goes: no product uses it, no planned work needs it. */\n readonly reason: string;\n}\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/** Why a reader needs a template: the seven intents the templates are grouped by (sidebar sub-headings, catalogue filter). */\nexport type TemplatePurpose = \"convince\" | \"explain\" | \"show\" | \"act\" | \"operate\" | \"converse\" | \"recover\";\n\n/** The groups of templates, in reading order: the title, and the one line that says when to come to that group. */\nexport const templatePurposes = {\n convince: { title: \"Convince\", useWhen: \"You come here when a visitor must decide: a landing, a product, a price, a comparison, a proof.\" },\n explain: { title: \"Explain\", useWhen: \"You come here when a reader must understand: how it works, a documentation hub or article, a changelog, a FAQ, a policy.\" },\n show: { title: \"Show\", useWhen: \"You come here when the work itself is the argument: a gallery, a story, a case study, an object and its details.\" },\n act: { title: \"Act\", useWhen: \"You come here when a person must do something once: reach the team, sign in or up, set up, pay.\" },\n operate: { title: \"Operate\", useWhen: \"You come here when a person works every day: a dashboard, a console with a table, settings, an app shell.\" },\n converse: { title: \"Converse\", useWhen: \"You come here when people talk: an inbox, a chat, comments, a notifications centre.\" },\n recover: { title: \"Recover\", useWhen: \"You come here when the way is blocked: an empty list, an error, a missing page, maintenance, a product still being built.\" },\n} as const satisfies Record<TemplatePurpose, { readonly title: string; readonly useWhen: string }>;\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 */\ninterface ExampleBase {\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/** A plain example, or a template: a whole screen with its intent (`purpose`) and the user goal its layout serves (`why`). */\nexport type Example =\n | (ExampleBase & { readonly template?: false; readonly purpose?: undefined; readonly why?: undefined })\n | (ExampleBase & {\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its\n * phone version thought out), copied as a starting point — at most 160 lines, listed on ui.krizaka.com/templates.\n */\n readonly template: true;\n /** The intent that groups it: why you need this block. */\n readonly purpose: TemplatePurpose;\n /** Why this layout: the user goal it serves, in one sentence. */\n readonly why: 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 /** Required for, and only for, a `deprecated` component. */\n readonly deprecated?: Deprecation;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** The platforms it is not on, and why; and its desktop form (see `Parity`). */\n readonly parity: Parity;\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"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"path": "page-index/index.ts",
|
|
115
|
+
"content": "/** @krizaka/ui/page-index — `PageIndex`: a book's index with dotted leaders and page numbers, for a sidebar or a catalogue. Server-safe. */\nexport type { LinkComponent } from \"../block-link\";\nexport { type IndexEntry, type IndexGroup, PageIndex, type PageIndexProps } from \"./page-index\";\n"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"path": "page-index/meta.ts",
|
|
119
|
+
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Page index\",\n summary: \"A book's index for a documentation or a catalogue: groups, entries, a dotted leader and the page number at the end of the line; the current entry marked in the margin.\",\n status: \"beta\",\n category: \"navigation\",\n platforms: \"web\",\n parity: {\n native: { status: \"n/a\", reason: \"A documentation sidebar; an app's navigation is its tab bar and lists.\", use: \"list\" },\n desktop: \"web\",\n },\n whenToUse: [\n \"The sidebar of a documentation: the components of a group, numbered as the pages of a reference book.\",\n \"The table of a catalogue or a long read, where a number helps the reader find a page again.\",\n ],\n whenNotToUse: [\n { when: \"The sections of the page being read.\", use: \"toc\" },\n { when: \"The navigation of an application.\", use: \"rail-nav\" },\n ],\n bestPractices: [\n \"Numbers are the reader's landmarks: keep them stable (a component keeps its number across versions).\",\n \"Group titles are short and typed in lower case; three to eight entries per group.\",\n \"Pass the router link as `linkAs` so internal entries prefetch.\",\n ],\n accessibility: {\n keyboard: [],\n notes: [\n \"A `nav` named by `label` (« Index »); each group a heading and a list of links.\",\n \"The current entry carries `aria-current=\\\"page\\\"`; the margin's arrow and the dotted leader are decorative.\",\n ],\n },\n related: [\"docs-nav\", \"toc\", \"docs-layout\"],\n web: {\n imports: [\"PageIndex\"],\n examples: [{ name: \"docs\", title: \"A documentation's index\", description: \"Two groups, the current entry marked, the page numbers aligned.\" }],\n },\n} satisfies ComponentMeta;\n"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"path": "page-index/page-index.tsx",
|
|
123
|
+
"content": "// Server-safe. The index of the Cahier (ADR-004, blocks.css): a book's index — groups, entries, a dotted leader and the\n// page number at the end of the line — for a documentation's sidebar or a catalogue. The current entry is marked by the\n// margin's arrow; the numbers are the reader's landmarks (`No. 042` on the component's page).\nimport type * as React from \"react\";\n\nimport { BlockLink, type LinkComponent } from \"../block-link\";\nimport { cn } from \"../cn\";\n\nexport interface IndexEntry {\n /** The entry: `Button`. */\n label: React.ReactNode;\n /** Where it leads. */\n href: string;\n /** Its number at the end of the line: `42`. */\n page?: React.ReactNode;\n /** The page the reader is on. */\n current?: boolean;\n}\n\nexport interface IndexGroup {\n /** The group's heading, typed: `Actions`. */\n title: React.ReactNode;\n entries: readonly IndexEntry[];\n}\n\nexport type PageIndexProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The groups, in reading order. */\n groups: readonly IndexGroup[];\n /** The accessible name of the navigation. @default \"Index\" */\n label?: string;\n /** The app's router link (Next's `Link`), so internal entries prefetch. */\n linkAs?: LinkComponent;\n};\n\n/** A book's index: headings, entries, a dotted leader and the page number; the current entry marked in the margin. */\nexport function PageIndex({ groups, label = \"Index\", linkAs, className, ...props }: PageIndexProps) {\n return (\n <nav aria-label={label} className={cn(\"kz-index\", className)} {...props}>\n {groups.map((g, gi) => (\n <section key={gi} className=\"kz-index-group\">\n <h4 className=\"kz-index-title\">{g.title}</h4>\n <ul>\n {g.entries.map((e, i) => (\n <li key={i}>\n <BlockLink href={e.href} linkAs={linkAs} className=\"kz-index-entry\" aria-current={e.current ? \"page\" : undefined}>\n <span className=\"kz-index-label\">{e.label}</span>\n <span className=\"kz-index-leader\" aria-hidden />\n {e.page !== undefined && <span className=\"kz-index-page\">{e.page}</span>}\n </BlockLink>\n </li>\n ))}\n </ul>\n </section>\n ))}\n </nav>\n );\n}\n"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"dependencies": [],
|
|
127
|
+
"registryDependencies": [
|
|
128
|
+
"cn"
|
|
129
|
+
],
|
|
130
|
+
"demo": {
|
|
131
|
+
"path": "examples/page-index/docs.tsx",
|
|
132
|
+
"content": "import { PageIndex } from \"@krizaka/ui/page-index\";\n\n// A documentation's sidebar as a book's index: the current entry marked in the margin, the page numbers aligned.\nexport default function PageIndexDocs() {\n return (\n <PageIndex\n className=\"max-w-xs pl-6\"\n groups={[\n {\n title: \"Actions\",\n entries: [\n { label: \"Button\", href: \"/components/button\", page: 42, current: true },\n { label: \"Confirm button\", href: \"/components/confirm-button\", page: 43 },\n { label: \"Continue prompt\", href: \"/components/continue-prompt\", page: 44 },\n ],\n },\n {\n title: \"Inputs & forms\",\n entries: [\n { label: \"Checkbox\", href: \"/components/checkbox\", page: 52 },\n { label: \"Date picker\", href: \"/components/date-picker\", page: 54 },\n ],\n },\n ]}\n />\n );\n}\n"
|
|
133
|
+
},
|
|
134
|
+
"props": [
|
|
135
|
+
{
|
|
136
|
+
"component": "LinkComponent",
|
|
137
|
+
"description": "The app's link component (Next's `Link`, React Router's `Link`…): receives `href`, `className` and the children.",
|
|
138
|
+
"props": []
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"component": "PageIndex",
|
|
142
|
+
"description": "A book's index: headings, entries, a dotted leader and the page number; the current entry marked in the margin.",
|
|
143
|
+
"props": [
|
|
144
|
+
{
|
|
145
|
+
"name": "groups",
|
|
146
|
+
"type": "readonly IndexGroup[]",
|
|
147
|
+
"default": null,
|
|
148
|
+
"description": "The groups, in reading order.",
|
|
149
|
+
"required": true
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "label",
|
|
153
|
+
"type": "string",
|
|
154
|
+
"default": "Index",
|
|
155
|
+
"description": "The accessible name of the navigation.",
|
|
156
|
+
"required": false
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"name": "linkAs",
|
|
160
|
+
"type": "LinkComponent",
|
|
161
|
+
"default": null,
|
|
162
|
+
"description": "The app's router link (Next's `Link`), so internal entries prefetch.",
|
|
163
|
+
"required": false
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
}
|
package/registry/page.json
CHANGED
|
@@ -85,6 +85,20 @@
|
|
|
85
85
|
"description": "The element: `div` (default), `main`, `header`, `footer`, `section` or `article`.",
|
|
86
86
|
"required": false
|
|
87
87
|
},
|
|
88
|
+
{
|
|
89
|
+
"name": "margin",
|
|
90
|
+
"type": "boolean",
|
|
91
|
+
"default": null,
|
|
92
|
+
"description": "The red margin line on the left, where section numbers and notes hang (`§ 2`, `fig. 1`).",
|
|
93
|
+
"required": false
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "paper",
|
|
97
|
+
"type": "PagePaper",
|
|
98
|
+
"default": null,
|
|
99
|
+
"description": "The notebook's ruling under the content: `ruled` (Seyès: 32 px squares, three fine lines), `lines` (lines only, a page to read).",
|
|
100
|
+
"required": false
|
|
101
|
+
},
|
|
88
102
|
{
|
|
89
103
|
"name": "size",
|
|
90
104
|
"type": "PageSize",
|
|
@@ -147,6 +161,27 @@
|
|
|
147
161
|
"description": "The heading's lead.",
|
|
148
162
|
"required": false
|
|
149
163
|
},
|
|
164
|
+
{
|
|
165
|
+
"name": "margin",
|
|
166
|
+
"type": "boolean",
|
|
167
|
+
"default": null,
|
|
168
|
+
"description": "The red margin line on the left, where section numbers and notes hang (`§ 2`, `fig. 1`).",
|
|
169
|
+
"required": false
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"name": "number",
|
|
173
|
+
"type": "ReactNode",
|
|
174
|
+
"default": null,
|
|
175
|
+
"description": "The section's number in the margin (`§ 2`).",
|
|
176
|
+
"required": false
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "paper",
|
|
180
|
+
"type": "PagePaper",
|
|
181
|
+
"default": null,
|
|
182
|
+
"description": "The notebook's ruling under the content: `ruled` (Seyès: 32 px squares, three fine lines), `lines` (lines only, a page to read).",
|
|
183
|
+
"required": false
|
|
184
|
+
},
|
|
150
185
|
{
|
|
151
186
|
"name": "reveal",
|
|
152
187
|
"type": "boolean",
|
|
@@ -206,7 +241,7 @@
|
|
|
206
241
|
"name": "eyebrow",
|
|
207
242
|
"type": "ReactNode",
|
|
208
243
|
"default": null,
|
|
209
|
-
"description": "A short
|
|
244
|
+
"description": "A short note above the title (the section's subject), in the note face, lower case — never an uppercase overline.",
|
|
210
245
|
"required": false
|
|
211
246
|
},
|
|
212
247
|
{
|
|
@@ -223,6 +258,13 @@
|
|
|
223
258
|
"description": "The level of the title.",
|
|
224
259
|
"required": false
|
|
225
260
|
},
|
|
261
|
+
{
|
|
262
|
+
"name": "number",
|
|
263
|
+
"type": "ReactNode",
|
|
264
|
+
"default": null,
|
|
265
|
+
"description": "The section's number, hung in the margin as a notebook numbers its pages (`§ 2`).",
|
|
266
|
+
"required": false
|
|
267
|
+
},
|
|
226
268
|
{
|
|
227
269
|
"name": "reveal",
|
|
228
270
|
"type": "boolean",
|
|
@@ -292,11 +334,11 @@
|
|
|
292
334
|
"files": [
|
|
293
335
|
{
|
|
294
336
|
"path": "meta.ts",
|
|
295
|
-
"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 ui.krizaka.com (apps/site) renders as\n// ui.krizaka.com/components/<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 | \"achievement\"\n | \"action-bar\"\n | \"action-sheet\"\n | \"activity-feed\"\n | \"alert\"\n | \"app-header\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"captcha\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"chat\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"chip-row\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"comparison-table\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cover-hero\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"description-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"docs-nav\"\n | \"document-viewer\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"engine-flow\"\n | \"error-page\"\n | \"fab\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"force-update-screen\"\n | \"form\"\n | \"gallery-page\"\n | \"genui\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"header\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"image-viewer\"\n | \"iso\"\n | \"kanban\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"list\"\n | \"loader\"\n | \"longform-page\"\n | \"maintenance-screen\"\n | \"map\"\n | \"markdown\"\n | \"meta-row\"\n | \"waveform\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"match-dialog\"\n | \"media-capture\"\n | \"media-grid\"\n | \"language-switch\"\n | \"media-gallery\"\n | \"media-picker\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"onboarding\"\n | \"opening-hours\"\n | \"otp-input\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"permission-prompt\"\n | \"photo-grid\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"pull-to-refresh\"\n | \"radio-group\"\n | \"rail-nav\"\n | \"recipes\"\n | \"screen\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"service-card\"\n | \"settings-layout\"\n | \"account-menu\"\n | \"showcase\"\n | \"step-showcase\"\n | \"site-footer\"\n | \"sites\"\n | \"skeleton\"\n | \"skip-link\"\n | \"slider\"\n | \"slot-picker\"\n | \"slot\"\n | \"spinner\"\n | \"sticky-action\"\n | \"splash-handoff\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"step-progress\"\n | \"stepper\"\n | \"swipe-deck\"\n | \"swipeable-row\"\n | \"switch\"\n | \"tab-bar\"\n | \"tabs\"\n | \"tag-input\"\n | \"tag-selector\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"tree-view\"\n | \"txt\"\n | \"update-prompt\"\n | \"verified-badge\"\n | \"vertical-video\"\n | \"video-player\"\n | \"video-trimmer\"\n | \"virtual\";\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/**\n * Why a component is not on a platform — a decision, never a silence (the parity matrix of ui.krizaka.com/platforms):\n * - `gap` (✗): it belongs there and is not built yet; `issue` is the issue that tracks it (`krizaka/krizaka-ui#275`);\n * - `n/a`: it is not meant for that platform (a site's page block on a phone, a swipe on a desktop); `use` names the\n * component that answers there, when one does.\n */\nexport type Absence =\n | { readonly status: \"gap\"; readonly issue: string; readonly reason: string; readonly use?: undefined }\n | { readonly status: \"n/a\"; readonly reason: string; readonly use?: ComponentName; readonly issue?: undefined };\n\n/**\n * Desktop is the Orazaka Mac app (Tauri 2: the system WebView renders the web components — ADR-002). `web`: the web\n * component runs there as it is; `desktop`: it also has a desktop form (a window's title bar, a denser layout…), said in\n * its documentation; otherwise the absence and why.\n */\nexport type DesktopSupport = \"web\" | \"desktop\" | Absence;\n\n/**\n * The three platforms of Krizaka UI — web · native (React Native, Expo) · desktop — for one component. The side a\n * component has is `platforms`; the side it lacks says why here: `native` is required for (and only for) a web-only\n * component, `web` for a native-only one; `desktop` always. `scripts/registry.test.mjs` fails on a missing decision.\n */\nexport interface Parity {\n readonly web?: Absence;\n readonly native?: Absence;\n readonly desktop: DesktopSupport;\n}\n\n/**\n * `stable`: its API only changes in a major. `beta`: it may still change in a minor. `deprecated`: no product uses it and\n * no work plans to — it still works, says what replaces it, and goes in the major named by `deprecated.removedIn`.\n */\nexport type Status = \"stable\" | \"beta\" | \"deprecated\";\n\n/** What a deprecated component says (required when `status` is `deprecated`, absent otherwise). */\nexport interface Deprecation {\n /** The version that deprecated it (`3.6.0`). */\n readonly since: string;\n /** The major that removes it (`4.0.0`). */\n readonly removedIn: string;\n /** What replaces it, when a component does. */\n readonly use?: ComponentName;\n /** Why it goes: no product uses it, no planned work needs it. */\n readonly reason: string;\n}\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/** Why a reader needs a template: the seven intents the templates are grouped by (sidebar sub-headings, catalogue filter). */\nexport type TemplatePurpose = \"convince\" | \"explain\" | \"show\" | \"act\" | \"operate\" | \"converse\" | \"recover\";\n\n/** The groups of templates, in reading order: the title, and the one line that says when to come to that group. */\nexport const templatePurposes = {\n convince: { title: \"Convince\", useWhen: \"You come here when a visitor must decide: a landing, a product, a price, a comparison, a proof.\" },\n explain: { title: \"Explain\", useWhen: \"You come here when a reader must understand: how it works, a documentation hub or article, a changelog, a FAQ, a policy.\" },\n show: { title: \"Show\", useWhen: \"You come here when the work itself is the argument: a gallery, a story, a case study, an object and its details.\" },\n act: { title: \"Act\", useWhen: \"You come here when a person must do something once: reach the team, sign in or up, set up, pay.\" },\n operate: { title: \"Operate\", useWhen: \"You come here when a person works every day: a dashboard, a console with a table, settings, an app shell.\" },\n converse: { title: \"Converse\", useWhen: \"You come here when people talk: an inbox, a chat, comments, a notifications centre.\" },\n recover: { title: \"Recover\", useWhen: \"You come here when the way is blocked: an empty list, an error, a missing page, maintenance, a product still being built.\" },\n} as const satisfies Record<TemplatePurpose, { readonly title: string; readonly useWhen: string }>;\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 */\ninterface ExampleBase {\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/** A plain example, or a template: a whole screen with its intent (`purpose`) and the user goal its layout serves (`why`). */\nexport type Example =\n | (ExampleBase & { readonly template?: false; readonly purpose?: undefined; readonly why?: undefined })\n | (ExampleBase & {\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its\n * phone version thought out), copied as a starting point — at most 160 lines, listed on ui.krizaka.com/templates.\n */\n readonly template: true;\n /** The intent that groups it: why you need this block. */\n readonly purpose: TemplatePurpose;\n /** Why this layout: the user goal it serves, in one sentence. */\n readonly why: 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 /** Required for, and only for, a `deprecated` component. */\n readonly deprecated?: Deprecation;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** The platforms it is not on, and why; and its desktop form (see `Parity`). */\n readonly parity: Parity;\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"
|
|
337
|
+
"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 ui.krizaka.com (apps/site) renders as\n// ui.krizaka.com/components/<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 | \"achievement\"\n | \"anatomy-plate\"\n | \"bird-plate\"\n | \"footnote\"\n | \"page-index\"\n | \"specimen-tag\"\n | \"action-bar\"\n | \"action-sheet\"\n | \"activity-feed\"\n | \"alert\"\n | \"app-header\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"captcha\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"chat\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"chip-row\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"comparison-table\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cover-hero\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"description-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"docs-nav\"\n | \"document-viewer\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"engine-flow\"\n | \"error-page\"\n | \"fab\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"force-update-screen\"\n | \"form\"\n | \"gallery-page\"\n | \"genui\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"header\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"image-viewer\"\n | \"iso\"\n | \"kanban\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"list\"\n | \"loader\"\n | \"longform-page\"\n | \"maintenance-screen\"\n | \"map\"\n | \"markdown\"\n | \"meta-row\"\n | \"waveform\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"match-dialog\"\n | \"media-capture\"\n | \"media-grid\"\n | \"language-switch\"\n | \"media-gallery\"\n | \"media-picker\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"onboarding\"\n | \"opening-hours\"\n | \"otp-input\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"permission-prompt\"\n | \"photo-grid\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"pull-to-refresh\"\n | \"radio-group\"\n | \"rail-nav\"\n | \"recipes\"\n | \"screen\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"service-card\"\n | \"settings-layout\"\n | \"account-menu\"\n | \"showcase\"\n | \"step-showcase\"\n | \"site-footer\"\n | \"sites\"\n | \"skeleton\"\n | \"skip-link\"\n | \"slider\"\n | \"slot-picker\"\n | \"slot\"\n | \"spinner\"\n | \"sticky-action\"\n | \"splash-handoff\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"step-progress\"\n | \"stepper\"\n | \"swipe-deck\"\n | \"swipeable-row\"\n | \"switch\"\n | \"tab-bar\"\n | \"tabs\"\n | \"tag-input\"\n | \"tag-selector\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"tree-view\"\n | \"txt\"\n | \"update-prompt\"\n | \"verified-badge\"\n | \"vertical-video\"\n | \"video-player\"\n | \"video-trimmer\"\n | \"virtual\";\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/**\n * Why a component is not on a platform — a decision, never a silence (the parity matrix of ui.krizaka.com/platforms):\n * - `gap` (✗): it belongs there and is not built yet; `issue` is the issue that tracks it (`krizaka/krizaka-ui#275`);\n * - `n/a`: it is not meant for that platform (a site's page block on a phone, a swipe on a desktop); `use` names the\n * component that answers there, when one does.\n */\nexport type Absence =\n | { readonly status: \"gap\"; readonly issue: string; readonly reason: string; readonly use?: undefined }\n | { readonly status: \"n/a\"; readonly reason: string; readonly use?: ComponentName; readonly issue?: undefined };\n\n/**\n * Desktop is the Orazaka Mac app (Tauri 2: the system WebView renders the web components — ADR-002). `web`: the web\n * component runs there as it is; `desktop`: it also has a desktop form (a window's title bar, a denser layout…), said in\n * its documentation; otherwise the absence and why.\n */\nexport type DesktopSupport = \"web\" | \"desktop\" | Absence;\n\n/**\n * The three platforms of Krizaka UI — web · native (React Native, Expo) · desktop — for one component. The side a\n * component has is `platforms`; the side it lacks says why here: `native` is required for (and only for) a web-only\n * component, `web` for a native-only one; `desktop` always. `scripts/registry.test.mjs` fails on a missing decision.\n */\nexport interface Parity {\n readonly web?: Absence;\n readonly native?: Absence;\n readonly desktop: DesktopSupport;\n}\n\n/**\n * `stable`: its API only changes in a major. `beta`: it may still change in a minor. `deprecated`: no product uses it and\n * no work plans to — it still works, says what replaces it, and goes in the major named by `deprecated.removedIn`.\n */\nexport type Status = \"stable\" | \"beta\" | \"deprecated\";\n\n/** What a deprecated component says (required when `status` is `deprecated`, absent otherwise). */\nexport interface Deprecation {\n /** The version that deprecated it (`3.6.0`). */\n readonly since: string;\n /** The major that removes it (`4.0.0`). */\n readonly removedIn: string;\n /** What replaces it, when a component does. */\n readonly use?: ComponentName;\n /** Why it goes: no product uses it, no planned work needs it. */\n readonly reason: string;\n}\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/** Why a reader needs a template: the seven intents the templates are grouped by (sidebar sub-headings, catalogue filter). */\nexport type TemplatePurpose = \"convince\" | \"explain\" | \"show\" | \"act\" | \"operate\" | \"converse\" | \"recover\";\n\n/** The groups of templates, in reading order: the title, and the one line that says when to come to that group. */\nexport const templatePurposes = {\n convince: { title: \"Convince\", useWhen: \"You come here when a visitor must decide: a landing, a product, a price, a comparison, a proof.\" },\n explain: { title: \"Explain\", useWhen: \"You come here when a reader must understand: how it works, a documentation hub or article, a changelog, a FAQ, a policy.\" },\n show: { title: \"Show\", useWhen: \"You come here when the work itself is the argument: a gallery, a story, a case study, an object and its details.\" },\n act: { title: \"Act\", useWhen: \"You come here when a person must do something once: reach the team, sign in or up, set up, pay.\" },\n operate: { title: \"Operate\", useWhen: \"You come here when a person works every day: a dashboard, a console with a table, settings, an app shell.\" },\n converse: { title: \"Converse\", useWhen: \"You come here when people talk: an inbox, a chat, comments, a notifications centre.\" },\n recover: { title: \"Recover\", useWhen: \"You come here when the way is blocked: an empty list, an error, a missing page, maintenance, a product still being built.\" },\n} as const satisfies Record<TemplatePurpose, { readonly title: string; readonly useWhen: string }>;\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 */\ninterface ExampleBase {\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/** A plain example, or a template: a whole screen with its intent (`purpose`) and the user goal its layout serves (`why`). */\nexport type Example =\n | (ExampleBase & { readonly template?: false; readonly purpose?: undefined; readonly why?: undefined })\n | (ExampleBase & {\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its\n * phone version thought out), copied as a starting point — at most 160 lines, listed on ui.krizaka.com/templates.\n */\n readonly template: true;\n /** The intent that groups it: why you need this block. */\n readonly purpose: TemplatePurpose;\n /** Why this layout: the user goal it serves, in one sentence. */\n readonly why: 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 /** Required for, and only for, a `deprecated` component. */\n readonly deprecated?: Deprecation;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** The platforms it is not on, and why; and its desktop form (see `Parity`). */\n readonly parity: Parity;\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"
|
|
296
338
|
},
|
|
297
339
|
{
|
|
298
340
|
"path": "page/index.ts",
|
|
299
|
-
"content": "/** @krizaka/ui/page — the page frame: `Page` (width, gutters), `Section` (+ `SectionHeading`), `Facts`, `Ticks`. Server-safe. */\nexport { type Fact, Facts, type FactsProps, Page, type PageProps, type PageSize, Section, SectionHeading, type SectionHeadingProps, type SectionProps, Ticks, type TicksProps } from \"./page\";\n"
|
|
341
|
+
"content": "/** @krizaka/ui/page — the page frame: `Page` (width, gutters), `Section` (+ `SectionHeading`), `Facts`, `Ticks`. Server-safe. */\nexport { type Fact, Facts, type FactsProps, Page, type PagePaper, type PageProps, type PageSize, Section, SectionHeading, type SectionHeadingProps, type SectionProps, Ticks, type TicksProps } from \"./page\";\n"
|
|
300
342
|
},
|
|
301
343
|
{
|
|
302
344
|
"path": "page/meta.ts",
|
|
@@ -304,7 +346,7 @@
|
|
|
304
346
|
},
|
|
305
347
|
{
|
|
306
348
|
"path": "page/page.tsx",
|
|
307
|
-
"content": "// Server-safe. The frame of every page (blocks.css): one width, one pair of gutters, one vertical rhythm — so the\n// navigation, the hero and every section line up on the same edges, at any width.\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { SectionBackdrop, type SectionBackdropProps } from \"../section-backdrop/section-backdrop\";\n\nexport type PageSize = \"narrow\" | \"default\" | \"wide\" | \"full\";\n\nexport type PageProps = React.HTMLAttributes<HTMLElement> & {\n /**\n * The width of the content: `default` (72rem, `--kz-page-max`), `narrow` (48rem, a reading column), `wide`\n * (88rem, documentation with a sidebar), `full` (the gutters only).\n * @default \"default\"\n */\n size?: PageSize;\n /** The element: `div` (default), `main`, `header`, `footer`, `section` or `article`. */\n as?: \"div\" | \"main\" | \"header\" | \"footer\" | \"section\" | \"article\";\n};\n\n/** The page frame: centred, at most `--kz-page-max` wide, with the gutters of `--kz-page-gutter` (16 → 32 px). */\nexport function Page({ size = \"default\", as: Tag = \"div\", className, ...props }: PageProps) {\n return <Tag
|
|
349
|
+
"content": "// Server-safe. The frame of every page (blocks.css): one width, one pair of gutters, one vertical rhythm — so the\n// navigation, the hero and every section line up on the same edges, at any width.\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { SectionBackdrop, type SectionBackdropProps } from \"../section-backdrop/section-backdrop\";\n\nexport type PageSize = \"narrow\" | \"default\" | \"wide\" | \"full\";\n\n/** The paper under a page or a section (Cahier, ADR-004): `ruled` (Seyès squares), `lines` (lines only), or plain. */\nexport type PagePaper = \"ruled\" | \"lines\";\n\ntype PaperProps = {\n /** The notebook's ruling under the content: `ruled` (Seyès: 32 px squares, three fine lines), `lines` (lines only, a page to read). */\n paper?: PagePaper;\n /** The red margin line on the left, where section numbers and notes hang (`§ 2`, `fig. 1`). */\n margin?: boolean;\n};\n\nexport type PageProps = React.HTMLAttributes<HTMLElement> & {\n /**\n * The width of the content: `default` (72rem, `--kz-page-max`), `narrow` (48rem, a reading column), `wide`\n * (88rem, documentation with a sidebar), `full` (the gutters only).\n * @default \"default\"\n */\n size?: PageSize;\n /** The element: `div` (default), `main`, `header`, `footer`, `section` or `article`. */\n as?: \"div\" | \"main\" | \"header\" | \"footer\" | \"section\" | \"article\";\n} & PaperProps;\n\n/** The page frame: centred, at most `--kz-page-max` wide, with the gutters of `--kz-page-gutter` (16 → 32 px). */\nexport function Page({ size = \"default\", as: Tag = \"div\", paper, margin, className, ...props }: PageProps) {\n return (\n <Tag\n data-size={size === \"default\" ? undefined : size}\n data-paper={paper}\n data-margin={margin ? \"\" : undefined}\n className={cn(\"kz-frame\", className)}\n {...props}\n />\n );\n}\n\nexport type SectionHeadingProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> & {\n /** The id of the title: the section's anchor and its accessible name. */\n id?: string;\n /** A short note above the title (the section's subject), in the note face, lower case — never an uppercase overline. */\n eyebrow?: React.ReactNode;\n /** The section's number, hung in the margin as a notebook numbers its pages (`§ 2`). */\n number?: React.ReactNode;\n /** The title. */\n title: React.ReactNode;\n /** One or two sentences under the title. */\n lead?: React.ReactNode;\n /** Actions on the right of the heading (a link to everything, a filter). */\n actions?: React.ReactNode;\n /**\n * The level of the title.\n * @default 2\n */\n level?: 2 | 3;\n /**\n * `md` for a section that argues, `sm` for a section of a reading page.\n * @default \"md\"\n */\n size?: \"sm\" | \"md\";\n /**\n * `center` for a heading that stands alone above a grid.\n * @default \"start\"\n */\n align?: \"start\" | \"center\";\n /** Rises into place once, as it enters the viewport (`[data-reveal]`, MotionObserver). Never on the first screen. */\n reveal?: boolean;\n};\n\n/** The head of a section: eyebrow (mono, the accent), title, lead — and its actions on the right. */\nexport function SectionHeading({ id, eyebrow, number, title, lead, actions, level = 2, size = \"md\", align = \"start\", reveal, className, ...props }: SectionHeadingProps) {\n const H = level === 2 ? \"h2\" : \"h3\";\n return (\n <div\n className={cn(\"kz-heading\", className)}\n data-size={size === \"md\" ? undefined : size}\n data-align={align === \"start\" ? undefined : align}\n data-actions={actions ? \"\" : undefined}\n data-reveal={reveal ? \"\" : undefined}\n {...props}\n >\n {number && <span className=\"kz-heading-number\">{number}</span>}\n {eyebrow && <p className=\"kz-eyebrow\">{eyebrow}</p>}\n <H id={id} className=\"kz-heading-title\">\n {title}\n </H>\n {lead && <p className=\"kz-heading-lead\">{lead}</p>}\n {actions && <div className=\"kz-heading-actions\">{actions}</div>}\n </div>\n );\n}\n\nexport type SectionProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The id of the title (and the anchor of the section). Required with a `title`. */\n id?: string;\n /** The heading's eyebrow. */\n eyebrow?: React.ReactNode;\n /** The section's number in the margin (`§ 2`). */\n number?: React.ReactNode;\n /** The section's title: an `h2` (a `SectionHeading`), which names the section for assistive technology. */\n title?: React.ReactNode;\n /** The heading's lead. */\n lead?: React.ReactNode;\n /** The heading's actions. */\n actions?: React.ReactNode;\n /**\n * The heading's size: `md` for a page that argues, `sm` for a reading page.\n * @default \"md\"\n */\n headingSize?: \"sm\" | \"md\";\n /**\n * The heading's alignment.\n * @default \"start\"\n */\n headingAlign?: \"start\" | \"center\";\n /** The heading rises into place once (never on the first screen). */\n reveal?: boolean;\n /** A hairline above the section, inside the gutters: the transition between two sections of the same surface. */\n divider?: boolean;\n /**\n * The vertical space above and below: `sm` (a reading page), `md`, `lg` (a page's main moments).\n * @default \"md\"\n */\n spacing?: \"sm\" | \"md\" | \"lg\";\n /**\n * The width of the content.\n * @default \"default\"\n */\n size?: PageSize;\n /** The brand's colour transition behind the section (SectionBackdrop): `true`, or its props (`direction`, `grid`…). */\n backdrop?: boolean | Omit<SectionBackdropProps, \"as\" | \"children\">;\n} & PaperProps;\n\n/**\n * A section of a page: full-bleed (its backdrop reaches the edges), its content in the page frame, its heading on top.\n * Sections follow each other on one rhythm; a `divider` or a `backdrop` marks the transition.\n */\nexport function Section({\n id,\n eyebrow,\n number,\n title,\n lead,\n actions,\n headingSize,\n headingAlign,\n reveal,\n divider,\n spacing = \"md\",\n size,\n backdrop,\n paper,\n margin,\n className,\n children,\n ...props\n}: SectionProps) {\n const body = (\n <Page size={size} data-margin={margin ? \"\" : undefined}>\n {title && <SectionHeading id={id} eyebrow={eyebrow} number={number} title={title} lead={lead} actions={actions} size={headingSize} align={headingAlign} reveal={reveal} />}\n {children}\n </Page>\n );\n const shared = {\n \"aria-labelledby\": title && id ? id : undefined,\n \"data-divider\": divider ? \"\" : undefined,\n \"data-spacing\": spacing === \"md\" ? undefined : spacing,\n \"data-paper\": paper,\n ...props,\n };\n if (backdrop) {\n const backdropProps = backdrop === true ? {} : backdrop;\n return (\n <SectionBackdrop {...backdropProps} {...shared} className={cn(\"kz-section\", className)}>\n {body}\n </SectionBackdrop>\n );\n }\n return (\n <section {...shared} className={cn(\"kz-section\", className)}>\n {body}\n </section>\n );\n}\n\nexport type TicksProps = {\n /** A sentence where words between backticks are code: \"Every request carries a `requestId`.\" */\n children: string;\n};\n\n/** A sentence of a message catalogue where words between backticks read as code — no markup in the translations. */\nexport function Ticks({ children }: TicksProps) {\n const parts = children.split(\"`\");\n return (\n <>\n {parts.map((part, i) =>\n i % 2 ? (\n <code key={i} className=\"kz-ic\">\n {part}\n </code>\n ) : (\n <React.Fragment key={i}>{part}</React.Fragment>\n ),\n )}\n </>\n );\n}\n\nexport interface Fact {\n /** A few words: `npm 2.5.0`, `Maven Central`, `in progress`. */\n label: string;\n /**\n * `ok` — published, usable today; `wip` — in progress, said honestly; `neutral` — a fact.\n * @default \"neutral\"\n */\n tone?: \"ok\" | \"wip\" | \"neutral\";\n /** Where the fact is proven (a registry page): the fact becomes a link. */\n href?: string;\n}\n\nexport type FactsProps = React.HTMLAttributes<HTMLUListElement> & {\n /** The facts, in reading order. */\n items: readonly Fact[];\n};\n\n/** Compact facts on one line — a dot that says the state, a few mono words. Links open in a new tab. */\nexport function Facts({ items, className, ...props }: FactsProps) {\n return (\n <ul className={cn(\"kz-facts\", className)} {...props}>\n {items.map((fact) => {\n const body = (\n <>\n <span className=\"kz-fact-dot\" aria-hidden /> {fact.label}\n </>\n );\n const tone = fact.tone && fact.tone !== \"neutral\" ? fact.tone : undefined;\n return (\n <li key={fact.label}>\n {fact.href ? (\n <a href={fact.href} target=\"_blank\" rel=\"noopener noreferrer\" className=\"kz-fact\" data-tone={tone}>\n {body}\n </a>\n ) : (\n <span className=\"kz-fact\" data-tone={tone}>\n {body}\n </span>\n )}\n </li>\n );\n })}\n </ul>\n );\n}\n"
|
|
308
350
|
}
|
|
309
351
|
],
|
|
310
352
|
"dependencies": [],
|
|
@@ -341,6 +383,20 @@
|
|
|
341
383
|
"description": "The element: `div` (default), `main`, `header`, `footer`, `section` or `article`.",
|
|
342
384
|
"required": false
|
|
343
385
|
},
|
|
386
|
+
{
|
|
387
|
+
"name": "margin",
|
|
388
|
+
"type": "boolean",
|
|
389
|
+
"default": null,
|
|
390
|
+
"description": "The red margin line on the left, where section numbers and notes hang (`§ 2`, `fig. 1`).",
|
|
391
|
+
"required": false
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
"name": "paper",
|
|
395
|
+
"type": "PagePaper",
|
|
396
|
+
"default": null,
|
|
397
|
+
"description": "The notebook's ruling under the content: `ruled` (Seyès: 32 px squares, three fine lines), `lines` (lines only, a page to read).",
|
|
398
|
+
"required": false
|
|
399
|
+
},
|
|
344
400
|
{
|
|
345
401
|
"name": "size",
|
|
346
402
|
"type": "PageSize",
|
|
@@ -403,6 +459,27 @@
|
|
|
403
459
|
"description": "The heading's lead.",
|
|
404
460
|
"required": false
|
|
405
461
|
},
|
|
462
|
+
{
|
|
463
|
+
"name": "margin",
|
|
464
|
+
"type": "boolean",
|
|
465
|
+
"default": null,
|
|
466
|
+
"description": "The red margin line on the left, where section numbers and notes hang (`§ 2`, `fig. 1`).",
|
|
467
|
+
"required": false
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
"name": "number",
|
|
471
|
+
"type": "ReactNode",
|
|
472
|
+
"default": null,
|
|
473
|
+
"description": "The section's number in the margin (`§ 2`).",
|
|
474
|
+
"required": false
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"name": "paper",
|
|
478
|
+
"type": "PagePaper",
|
|
479
|
+
"default": null,
|
|
480
|
+
"description": "The notebook's ruling under the content: `ruled` (Seyès: 32 px squares, three fine lines), `lines` (lines only, a page to read).",
|
|
481
|
+
"required": false
|
|
482
|
+
},
|
|
406
483
|
{
|
|
407
484
|
"name": "reveal",
|
|
408
485
|
"type": "boolean",
|
|
@@ -462,7 +539,7 @@
|
|
|
462
539
|
"name": "eyebrow",
|
|
463
540
|
"type": "ReactNode",
|
|
464
541
|
"default": null,
|
|
465
|
-
"description": "A short
|
|
542
|
+
"description": "A short note above the title (the section's subject), in the note face, lower case — never an uppercase overline.",
|
|
466
543
|
"required": false
|
|
467
544
|
},
|
|
468
545
|
{
|
|
@@ -479,6 +556,13 @@
|
|
|
479
556
|
"description": "The level of the title.",
|
|
480
557
|
"required": false
|
|
481
558
|
},
|
|
559
|
+
{
|
|
560
|
+
"name": "number",
|
|
561
|
+
"type": "ReactNode",
|
|
562
|
+
"default": null,
|
|
563
|
+
"description": "The section's number, hung in the margin as a notebook numbers its pages (`§ 2`).",
|
|
564
|
+
"required": false
|
|
565
|
+
},
|
|
482
566
|
{
|
|
483
567
|
"name": "reveal",
|
|
484
568
|
"type": "boolean",
|
package/registry/pagination.json
CHANGED
|
@@ -341,7 +341,7 @@
|
|
|
341
341
|
},
|
|
342
342
|
{
|
|
343
343
|
"path": "meta.ts",
|
|
344
|
-
"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 ui.krizaka.com (apps/site) renders as\n// ui.krizaka.com/components/<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 | \"achievement\"\n | \"action-bar\"\n | \"action-sheet\"\n | \"activity-feed\"\n | \"alert\"\n | \"app-header\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"captcha\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"chat\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"chip-row\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"comparison-table\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cover-hero\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"description-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"docs-nav\"\n | \"document-viewer\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"engine-flow\"\n | \"error-page\"\n | \"fab\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"force-update-screen\"\n | \"form\"\n | \"gallery-page\"\n | \"genui\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"header\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"image-viewer\"\n | \"iso\"\n | \"kanban\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"list\"\n | \"loader\"\n | \"longform-page\"\n | \"maintenance-screen\"\n | \"map\"\n | \"markdown\"\n | \"meta-row\"\n | \"waveform\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"match-dialog\"\n | \"media-capture\"\n | \"media-grid\"\n | \"language-switch\"\n | \"media-gallery\"\n | \"media-picker\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"onboarding\"\n | \"opening-hours\"\n | \"otp-input\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"permission-prompt\"\n | \"photo-grid\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"pull-to-refresh\"\n | \"radio-group\"\n | \"rail-nav\"\n | \"recipes\"\n | \"screen\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"service-card\"\n | \"settings-layout\"\n | \"account-menu\"\n | \"showcase\"\n | \"step-showcase\"\n | \"site-footer\"\n | \"sites\"\n | \"skeleton\"\n | \"skip-link\"\n | \"slider\"\n | \"slot-picker\"\n | \"slot\"\n | \"spinner\"\n | \"sticky-action\"\n | \"splash-handoff\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"step-progress\"\n | \"stepper\"\n | \"swipe-deck\"\n | \"swipeable-row\"\n | \"switch\"\n | \"tab-bar\"\n | \"tabs\"\n | \"tag-input\"\n | \"tag-selector\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"tree-view\"\n | \"txt\"\n | \"update-prompt\"\n | \"verified-badge\"\n | \"vertical-video\"\n | \"video-player\"\n | \"video-trimmer\"\n | \"virtual\";\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/**\n * Why a component is not on a platform — a decision, never a silence (the parity matrix of ui.krizaka.com/platforms):\n * - `gap` (✗): it belongs there and is not built yet; `issue` is the issue that tracks it (`krizaka/krizaka-ui#275`);\n * - `n/a`: it is not meant for that platform (a site's page block on a phone, a swipe on a desktop); `use` names the\n * component that answers there, when one does.\n */\nexport type Absence =\n | { readonly status: \"gap\"; readonly issue: string; readonly reason: string; readonly use?: undefined }\n | { readonly status: \"n/a\"; readonly reason: string; readonly use?: ComponentName; readonly issue?: undefined };\n\n/**\n * Desktop is the Orazaka Mac app (Tauri 2: the system WebView renders the web components — ADR-002). `web`: the web\n * component runs there as it is; `desktop`: it also has a desktop form (a window's title bar, a denser layout…), said in\n * its documentation; otherwise the absence and why.\n */\nexport type DesktopSupport = \"web\" | \"desktop\" | Absence;\n\n/**\n * The three platforms of Krizaka UI — web · native (React Native, Expo) · desktop — for one component. The side a\n * component has is `platforms`; the side it lacks says why here: `native` is required for (and only for) a web-only\n * component, `web` for a native-only one; `desktop` always. `scripts/registry.test.mjs` fails on a missing decision.\n */\nexport interface Parity {\n readonly web?: Absence;\n readonly native?: Absence;\n readonly desktop: DesktopSupport;\n}\n\n/**\n * `stable`: its API only changes in a major. `beta`: it may still change in a minor. `deprecated`: no product uses it and\n * no work plans to — it still works, says what replaces it, and goes in the major named by `deprecated.removedIn`.\n */\nexport type Status = \"stable\" | \"beta\" | \"deprecated\";\n\n/** What a deprecated component says (required when `status` is `deprecated`, absent otherwise). */\nexport interface Deprecation {\n /** The version that deprecated it (`3.6.0`). */\n readonly since: string;\n /** The major that removes it (`4.0.0`). */\n readonly removedIn: string;\n /** What replaces it, when a component does. */\n readonly use?: ComponentName;\n /** Why it goes: no product uses it, no planned work needs it. */\n readonly reason: string;\n}\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/** Why a reader needs a template: the seven intents the templates are grouped by (sidebar sub-headings, catalogue filter). */\nexport type TemplatePurpose = \"convince\" | \"explain\" | \"show\" | \"act\" | \"operate\" | \"converse\" | \"recover\";\n\n/** The groups of templates, in reading order: the title, and the one line that says when to come to that group. */\nexport const templatePurposes = {\n convince: { title: \"Convince\", useWhen: \"You come here when a visitor must decide: a landing, a product, a price, a comparison, a proof.\" },\n explain: { title: \"Explain\", useWhen: \"You come here when a reader must understand: how it works, a documentation hub or article, a changelog, a FAQ, a policy.\" },\n show: { title: \"Show\", useWhen: \"You come here when the work itself is the argument: a gallery, a story, a case study, an object and its details.\" },\n act: { title: \"Act\", useWhen: \"You come here when a person must do something once: reach the team, sign in or up, set up, pay.\" },\n operate: { title: \"Operate\", useWhen: \"You come here when a person works every day: a dashboard, a console with a table, settings, an app shell.\" },\n converse: { title: \"Converse\", useWhen: \"You come here when people talk: an inbox, a chat, comments, a notifications centre.\" },\n recover: { title: \"Recover\", useWhen: \"You come here when the way is blocked: an empty list, an error, a missing page, maintenance, a product still being built.\" },\n} as const satisfies Record<TemplatePurpose, { readonly title: string; readonly useWhen: string }>;\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 */\ninterface ExampleBase {\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/** A plain example, or a template: a whole screen with its intent (`purpose`) and the user goal its layout serves (`why`). */\nexport type Example =\n | (ExampleBase & { readonly template?: false; readonly purpose?: undefined; readonly why?: undefined })\n | (ExampleBase & {\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its\n * phone version thought out), copied as a starting point — at most 160 lines, listed on ui.krizaka.com/templates.\n */\n readonly template: true;\n /** The intent that groups it: why you need this block. */\n readonly purpose: TemplatePurpose;\n /** Why this layout: the user goal it serves, in one sentence. */\n readonly why: 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 /** Required for, and only for, a `deprecated` component. */\n readonly deprecated?: Deprecation;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** The platforms it is not on, and why; and its desktop form (see `Parity`). */\n readonly parity: Parity;\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"
|
|
344
|
+
"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 ui.krizaka.com (apps/site) renders as\n// ui.krizaka.com/components/<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 | \"achievement\"\n | \"anatomy-plate\"\n | \"bird-plate\"\n | \"footnote\"\n | \"page-index\"\n | \"specimen-tag\"\n | \"action-bar\"\n | \"action-sheet\"\n | \"activity-feed\"\n | \"alert\"\n | \"app-header\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"captcha\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"chat\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"chip-row\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"comparison-table\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cover-hero\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"description-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"docs-nav\"\n | \"document-viewer\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"engine-flow\"\n | \"error-page\"\n | \"fab\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"force-update-screen\"\n | \"form\"\n | \"gallery-page\"\n | \"genui\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"header\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"image-viewer\"\n | \"iso\"\n | \"kanban\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"list\"\n | \"loader\"\n | \"longform-page\"\n | \"maintenance-screen\"\n | \"map\"\n | \"markdown\"\n | \"meta-row\"\n | \"waveform\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"match-dialog\"\n | \"media-capture\"\n | \"media-grid\"\n | \"language-switch\"\n | \"media-gallery\"\n | \"media-picker\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"onboarding\"\n | \"opening-hours\"\n | \"otp-input\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"permission-prompt\"\n | \"photo-grid\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"pull-to-refresh\"\n | \"radio-group\"\n | \"rail-nav\"\n | \"recipes\"\n | \"screen\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"service-card\"\n | \"settings-layout\"\n | \"account-menu\"\n | \"showcase\"\n | \"step-showcase\"\n | \"site-footer\"\n | \"sites\"\n | \"skeleton\"\n | \"skip-link\"\n | \"slider\"\n | \"slot-picker\"\n | \"slot\"\n | \"spinner\"\n | \"sticky-action\"\n | \"splash-handoff\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"step-progress\"\n | \"stepper\"\n | \"swipe-deck\"\n | \"swipeable-row\"\n | \"switch\"\n | \"tab-bar\"\n | \"tabs\"\n | \"tag-input\"\n | \"tag-selector\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"tree-view\"\n | \"txt\"\n | \"update-prompt\"\n | \"verified-badge\"\n | \"vertical-video\"\n | \"video-player\"\n | \"video-trimmer\"\n | \"virtual\";\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/**\n * Why a component is not on a platform — a decision, never a silence (the parity matrix of ui.krizaka.com/platforms):\n * - `gap` (✗): it belongs there and is not built yet; `issue` is the issue that tracks it (`krizaka/krizaka-ui#275`);\n * - `n/a`: it is not meant for that platform (a site's page block on a phone, a swipe on a desktop); `use` names the\n * component that answers there, when one does.\n */\nexport type Absence =\n | { readonly status: \"gap\"; readonly issue: string; readonly reason: string; readonly use?: undefined }\n | { readonly status: \"n/a\"; readonly reason: string; readonly use?: ComponentName; readonly issue?: undefined };\n\n/**\n * Desktop is the Orazaka Mac app (Tauri 2: the system WebView renders the web components — ADR-002). `web`: the web\n * component runs there as it is; `desktop`: it also has a desktop form (a window's title bar, a denser layout…), said in\n * its documentation; otherwise the absence and why.\n */\nexport type DesktopSupport = \"web\" | \"desktop\" | Absence;\n\n/**\n * The three platforms of Krizaka UI — web · native (React Native, Expo) · desktop — for one component. The side a\n * component has is `platforms`; the side it lacks says why here: `native` is required for (and only for) a web-only\n * component, `web` for a native-only one; `desktop` always. `scripts/registry.test.mjs` fails on a missing decision.\n */\nexport interface Parity {\n readonly web?: Absence;\n readonly native?: Absence;\n readonly desktop: DesktopSupport;\n}\n\n/**\n * `stable`: its API only changes in a major. `beta`: it may still change in a minor. `deprecated`: no product uses it and\n * no work plans to — it still works, says what replaces it, and goes in the major named by `deprecated.removedIn`.\n */\nexport type Status = \"stable\" | \"beta\" | \"deprecated\";\n\n/** What a deprecated component says (required when `status` is `deprecated`, absent otherwise). */\nexport interface Deprecation {\n /** The version that deprecated it (`3.6.0`). */\n readonly since: string;\n /** The major that removes it (`4.0.0`). */\n readonly removedIn: string;\n /** What replaces it, when a component does. */\n readonly use?: ComponentName;\n /** Why it goes: no product uses it, no planned work needs it. */\n readonly reason: string;\n}\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/** Why a reader needs a template: the seven intents the templates are grouped by (sidebar sub-headings, catalogue filter). */\nexport type TemplatePurpose = \"convince\" | \"explain\" | \"show\" | \"act\" | \"operate\" | \"converse\" | \"recover\";\n\n/** The groups of templates, in reading order: the title, and the one line that says when to come to that group. */\nexport const templatePurposes = {\n convince: { title: \"Convince\", useWhen: \"You come here when a visitor must decide: a landing, a product, a price, a comparison, a proof.\" },\n explain: { title: \"Explain\", useWhen: \"You come here when a reader must understand: how it works, a documentation hub or article, a changelog, a FAQ, a policy.\" },\n show: { title: \"Show\", useWhen: \"You come here when the work itself is the argument: a gallery, a story, a case study, an object and its details.\" },\n act: { title: \"Act\", useWhen: \"You come here when a person must do something once: reach the team, sign in or up, set up, pay.\" },\n operate: { title: \"Operate\", useWhen: \"You come here when a person works every day: a dashboard, a console with a table, settings, an app shell.\" },\n converse: { title: \"Converse\", useWhen: \"You come here when people talk: an inbox, a chat, comments, a notifications centre.\" },\n recover: { title: \"Recover\", useWhen: \"You come here when the way is blocked: an empty list, an error, a missing page, maintenance, a product still being built.\" },\n} as const satisfies Record<TemplatePurpose, { readonly title: string; readonly useWhen: string }>;\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 */\ninterface ExampleBase {\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/** A plain example, or a template: a whole screen with its intent (`purpose`) and the user goal its layout serves (`why`). */\nexport type Example =\n | (ExampleBase & { readonly template?: false; readonly purpose?: undefined; readonly why?: undefined })\n | (ExampleBase & {\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its\n * phone version thought out), copied as a starting point — at most 160 lines, listed on ui.krizaka.com/templates.\n */\n readonly template: true;\n /** The intent that groups it: why you need this block. */\n readonly purpose: TemplatePurpose;\n /** Why this layout: the user goal it serves, in one sentence. */\n readonly why: 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 /** Required for, and only for, a `deprecated` component. */\n readonly deprecated?: Deprecation;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** The platforms it is not on, and why; and its desktop form (see `Parity`). */\n readonly parity: Parity;\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"
|
|
345
345
|
},
|
|
346
346
|
{
|
|
347
347
|
"path": "pagination/index.ts",
|