@krizaka/ui 3.35.0 → 3.36.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 +1 -1
- 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 +3 -3
- package/dist/app-shell.js.map +1 -1
- package/dist/argument-card.js +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/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/{chunk-3S4GHSPZ.js → chunk-63KCDMX2.js} +3 -3
- package/dist/chunk-63KCDMX2.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-JFJECOZ2.js +338 -0
- package/dist/chunk-JFJECOZ2.js.map +1 -0
- package/dist/{chunk-KIBICUZK.js → chunk-K2ZYB4HP.js} +4 -4
- 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-2PNLHZLT.js → chunk-YOTQD7JD.js} +2 -2
- package/dist/chunk-YOTQD7JD.js.map +1 -0
- 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 +4 -4
- 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/filter-bar.js +1 -1
- package/dist/footnote.d.ts +32 -0
- package/dist/footnote.js +29 -0
- package/dist/footnote.js.map +1 -0
- package/dist/genui.js +4 -4
- 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/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/meter.js +1 -1
- 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 +53 -41
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.js +8 -8
- 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/radio-group.js +1 -1
- package/dist/radio-group.js.map +1 -1
- package/dist/rail-nav.js +1 -1
- package/dist/rail-nav.js.map +1 -1
- package/dist/search-field.js +1 -1
- package/dist/service-card.js +2 -2
- package/dist/service-card.js.map +1 -1
- package/dist/site-footer.js +2 -2
- package/dist/site-footer.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/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/package.json +77 -7
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/registry/slider.json +1 -1
- package/registry/slot-picker.json +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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-REPTKUJ6.js.map +0 -1
- /package/dist/{chunk-KIBICUZK.js.map → chunk-K2ZYB4HP.js.map} +0 -0
|
@@ -8,10 +8,19 @@ import {
|
|
|
8
8
|
// src/page/page.tsx
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
function Page({ size = "default", as: Tag = "div", className, ...props }) {
|
|
12
|
-
return /* @__PURE__ */ jsx(
|
|
11
|
+
function Page({ size = "default", as: Tag = "div", paper, margin, className, ...props }) {
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
Tag,
|
|
14
|
+
{
|
|
15
|
+
"data-size": size === "default" ? void 0 : size,
|
|
16
|
+
"data-paper": paper,
|
|
17
|
+
"data-margin": margin ? "" : void 0,
|
|
18
|
+
className: cn("kz-frame", className),
|
|
19
|
+
...props
|
|
20
|
+
}
|
|
21
|
+
);
|
|
13
22
|
}
|
|
14
|
-
function SectionHeading({ id, eyebrow, title, lead, actions, level = 2, size = "md", align = "start", reveal, className, ...props }) {
|
|
23
|
+
function SectionHeading({ id, eyebrow, number, title, lead, actions, level = 2, size = "md", align = "start", reveal, className, ...props }) {
|
|
15
24
|
const H = level === 2 ? "h2" : "h3";
|
|
16
25
|
return /* @__PURE__ */ jsxs(
|
|
17
26
|
"div",
|
|
@@ -23,6 +32,7 @@ function SectionHeading({ id, eyebrow, title, lead, actions, level = 2, size = "
|
|
|
23
32
|
"data-reveal": reveal ? "" : void 0,
|
|
24
33
|
...props,
|
|
25
34
|
children: [
|
|
35
|
+
number && /* @__PURE__ */ jsx("span", { className: "kz-heading-number", children: number }),
|
|
26
36
|
eyebrow && /* @__PURE__ */ jsx("p", { className: "kz-eyebrow", children: eyebrow }),
|
|
27
37
|
/* @__PURE__ */ jsx(H, { id, className: "kz-heading-title", children: title }),
|
|
28
38
|
lead && /* @__PURE__ */ jsx("p", { className: "kz-heading-lead", children: lead }),
|
|
@@ -34,6 +44,7 @@ function SectionHeading({ id, eyebrow, title, lead, actions, level = 2, size = "
|
|
|
34
44
|
function Section({
|
|
35
45
|
id,
|
|
36
46
|
eyebrow,
|
|
47
|
+
number,
|
|
37
48
|
title,
|
|
38
49
|
lead,
|
|
39
50
|
actions,
|
|
@@ -44,18 +55,21 @@ function Section({
|
|
|
44
55
|
spacing = "md",
|
|
45
56
|
size,
|
|
46
57
|
backdrop,
|
|
58
|
+
paper,
|
|
59
|
+
margin,
|
|
47
60
|
className,
|
|
48
61
|
children,
|
|
49
62
|
...props
|
|
50
63
|
}) {
|
|
51
|
-
const body = /* @__PURE__ */ jsxs(Page, { size, children: [
|
|
52
|
-
title && /* @__PURE__ */ jsx(SectionHeading, { id, eyebrow, title, lead, actions, size: headingSize, align: headingAlign, reveal }),
|
|
64
|
+
const body = /* @__PURE__ */ jsxs(Page, { size, "data-margin": margin ? "" : void 0, children: [
|
|
65
|
+
title && /* @__PURE__ */ jsx(SectionHeading, { id, eyebrow, number, title, lead, actions, size: headingSize, align: headingAlign, reveal }),
|
|
53
66
|
children
|
|
54
67
|
] });
|
|
55
68
|
const shared = {
|
|
56
69
|
"aria-labelledby": title && id ? id : void 0,
|
|
57
70
|
"data-divider": divider ? "" : void 0,
|
|
58
71
|
"data-spacing": spacing === "md" ? void 0 : spacing,
|
|
72
|
+
"data-paper": paper,
|
|
59
73
|
...props
|
|
60
74
|
};
|
|
61
75
|
if (backdrop) {
|
|
@@ -89,4 +103,4 @@ export {
|
|
|
89
103
|
Ticks,
|
|
90
104
|
Facts
|
|
91
105
|
};
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
106
|
+
//# sourceMappingURL=chunk-YKEIOYJ5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/page/page.tsx"],"sourcesContent":["// 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"],"mappings":"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","names":["Fragment"]}
|
|
@@ -25,7 +25,7 @@ var menu = tv({
|
|
|
25
25
|
content: cn(floating, "min-w-48 max-h-(--radix-dropdown-menu-content-available-height) overflow-y-auto overflow-x-hidden overscroll-contain p-1 origin-(--radix-dropdown-menu-content-transform-origin)"),
|
|
26
26
|
item: "relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2.5 py-2 text-sm text-fg outline-hidden transition-colors data-highlighted:bg-surface-3 data-disabled:pointer-events-none data-disabled:opacity-40 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0 [&>svg]:text-fg-secondary",
|
|
27
27
|
indicator: "ml-auto flex h-4 w-4 items-center justify-center text-fg-accent",
|
|
28
|
-
label: "px-2.5 pb-1 pt-2 text-[11px] font-semibold
|
|
28
|
+
label: "px-2.5 pb-1 pt-2 text-[11px] font-semibold text-fg-secondary",
|
|
29
29
|
separator: "-mx-1 my-1 h-px bg-border-subtle"
|
|
30
30
|
},
|
|
31
31
|
variants: {
|
|
@@ -176,4 +176,4 @@ export {
|
|
|
176
176
|
readFilterParams,
|
|
177
177
|
writeFilterParams
|
|
178
178
|
};
|
|
179
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
//# sourceMappingURL=chunk-YOTQD7JD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/filter-bar/filter-bar.tsx","../src/dropdown-menu/dropdown-menu.tsx"],"sourcesContent":["// Client (menus in a portal). The bar above a list: the controls that narrow it (a SearchField, FilterMenus, a\n// DateRangePicker — any child), the filters in force as removable chips, \"Clear all\", and the count of results in a\n// polite live region. It holds no state: the app keeps the filters — in the address, ideally — and the\n// `readFilterParams` / `writeFilterParams` helpers move them between a `URLSearchParams` and an object.\nimport { DropdownMenu as MenuPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { Chip } from \"../chip\";\nimport { DropdownMenu, menu } from \"../dropdown-menu\";\nimport { ChevronGlyph } from \"../glyphs\";\n\nexport const filterBar = tv({\n slots: {\n root: \"flex w-full flex-col gap-3\",\n controls: \"flex w-full flex-wrap items-center gap-2 [&>*]:min-w-0\",\n active: \"flex flex-wrap items-center gap-2\",\n clear:\n \"rounded-md px-2 py-1 text-xs font-semibold text-fg-accent hover:bg-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n results: \"ml-auto text-xs text-fg-secondary tabular-nums\",\n trigger:\n \"inline-flex h-11 shrink-0 items-center gap-2 rounded-lg border border-border-default bg-surface-1 px-3.5 text-sm font-semibold text-fg-secondary \" +\n \"transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"data-[active]:border-accent data-[active]:bg-accent-soft data-[active]:text-fg data-[state=open]:border-border-strong\",\n count: \"inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-accent px-1.5 text-[11px] font-bold tabular-nums text-on-accent\",\n optionCount: \"ml-auto pl-4 text-xs tabular-nums text-fg-secondary\",\n },\n});\n\nexport type ActiveFilter = {\n /** A stable key (`\"status:failed\"`). */\n id: string;\n /** What the chip says, passed translated (\"Status: Failed\"). */\n label: string;\n /** Removes this filter. */\n onRemove: () => void;\n};\n\nexport type FilterBarProps = Omit<React.ComponentProps<\"div\">, \"children\" | \"results\"> & {\n /** The accessible name of the bar (\"Filter jobs\"), passed translated. */\n label: string;\n /** The controls: `SearchField`, `FilterMenu`, `DateRangePicker`, a `Chip.Group`… */\n children?: React.ReactNode;\n /** The filters in force, each a removable chip. */\n active?: readonly ActiveFilter[];\n /** Clears every filter; the \"Clear all\" button shows when there is at least one. */\n onClearAll?: () => void;\n /** The \"Clear all\" button (\"Clear filters\"), passed translated. */\n clearLabel?: string;\n /** A chip's remove button: `(label) => \"Remove \" + label`, passed translated. */\n removeLabel?: (label: string) => string;\n /** The count of results (\"42 jobs\"), announced politely when it changes. */\n results?: string;\n};\n\n/** The bar of filters above a list: controls, active filters as chips, clear all, the count of results. */\nexport function FilterBar({\n label,\n children,\n active = [],\n onClearAll,\n clearLabel = \"Clear filters\",\n removeLabel = (text) => `Remove ${text}`,\n results,\n className,\n ...props\n}: FilterBarProps) {\n const s = filterBar();\n return (\n <div role=\"group\" aria-label={label} className={s.root({ className })} {...props}>\n {children ? <div className={s.controls()}>{children}</div> : null}\n {active.length > 0 || results !== undefined ? (\n <div className={s.active()}>\n {active.map((filter) => (\n <Chip key={filter.id} size=\"sm\" removable removeLabel={removeLabel(filter.label)} onRemove={filter.onRemove}>\n {filter.label}\n </Chip>\n ))}\n {active.length > 0 && onClearAll ? (\n <button type=\"button\" className={s.clear()} onClick={onClearAll}>\n {clearLabel}\n </button>\n ) : null}\n <p className={s.results()} aria-live=\"polite\" aria-atomic>\n {results}\n </p>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport type FilterOption = {\n /** What the app stores (and puts in the address). */\n value: string;\n /** What the person reads, passed translated. */\n label: string;\n /** How many results it would give: shown on the right. */\n count?: number;\n /** Shown but not choosable. */\n disabled?: boolean;\n};\n\ntype FilterMenuBase = {\n /** The name of the filter on its button (\"Status\"), passed translated. */\n label: string;\n /** The choices. */\n options: readonly FilterOption[];\n /** Opens the menu at first (a story, a test). */\n defaultOpen?: boolean;\n /** Classes merged on the button. */\n className?: string;\n};\n\nexport type FilterMenuProps =\n | (FilterMenuBase & {\n /** Several values (checkboxes, default) or one (radios). */\n multiple?: true;\n /** The values chosen. */\n value: readonly string[];\n /** Called with the values chosen. */\n onValueChange: (value: string[]) => void;\n })\n | (FilterMenuBase & {\n /** One value: the options are radios. */\n multiple: false;\n /** The value chosen, `\"\"` for none. */\n value: string;\n /** Called with the value chosen. */\n onValueChange: (value: string) => void;\n });\n\n/** A filter's button and its menu of options — checkboxes (several values) or radios (one) — with a count of chosen ones. */\nexport function FilterMenu(props: FilterMenuProps) {\n const { label, options, defaultOpen, className } = props;\n const s = filterBar();\n const m = menu();\n const chosen = props.multiple === false ? (props.value ? [props.value] : []) : props.value;\n const single = props.multiple === false ? options.find((o) => o.value === props.value) : undefined;\n const content = (option: FilterOption) => (\n <>\n {option.label}\n {option.count !== undefined ? <span className={s.optionCount()}>{option.count}</span> : null}\n </>\n );\n return (\n <DropdownMenu.Root defaultOpen={defaultOpen} modal={false}>\n <DropdownMenu.Trigger className={s.trigger({ className })} data-active={chosen.length > 0 ? \"\" : undefined}>\n {single ? `${label}: ${single.label}` : label}\n {props.multiple !== false && chosen.length > 0 ? <span className={s.count()}>{chosen.length}</span> : null}\n <ChevronGlyph className=\"h-4 w-4\" />\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"start\" aria-label={label}>\n {props.multiple === false ? (\n <MenuPrimitive.RadioGroup value={props.value} onValueChange={props.onValueChange}>\n {options.map((option) => (\n <MenuPrimitive.RadioItem key={option.value} value={option.value} disabled={option.disabled} className={m.item()}>\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center rounded-full border border-border-strong\">\n <MenuPrimitive.ItemIndicator className=\"h-2 w-2 rounded-full bg-accent\" />\n </span>\n {content(option)}\n </MenuPrimitive.RadioItem>\n ))}\n </MenuPrimitive.RadioGroup>\n ) : (\n options.map((option) => (\n <DropdownMenu.CheckboxItem\n key={option.value}\n disabled={option.disabled}\n checked={props.value.includes(option.value)}\n onSelect={(event) => event.preventDefault()}\n onCheckedChange={(checked) =>\n props.onValueChange(checked ? [...props.value, option.value] : props.value.filter((v) => v !== option.value))\n }\n >\n {content(option)}\n </DropdownMenu.CheckboxItem>\n ))\n )}\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n );\n}\n\n/** Filters read from an address: `{ status: [\"failed\", \"running\"], q: [\"cat\"] }` for the keys asked (repeated or comma-separated values). */\nexport function readFilterParams(params: URLSearchParams, keys: readonly string[]): Record<string, string[]> {\n return Object.fromEntries(\n keys.map((key) => [key, params.getAll(key).flatMap((v) => v.split(\",\")).map((v) => v.trim()).filter(Boolean)]),\n );\n}\n\n/** Filters written into an address (a copy of `base`): empty filters removed, several values comma-separated, the page reset. */\nexport function writeFilterParams(base: URLSearchParams, filters: Record<string, string | readonly string[] | null | undefined>, resetKey = \"page\") {\n const next = new URLSearchParams(base);\n for (const [key, value] of Object.entries(filters)) {\n const list = value == null ? [] : typeof value === \"string\" ? [value] : [...value];\n if (list.filter(Boolean).length === 0) next.delete(key);\n else next.set(key, list.filter(Boolean).join(\",\"));\n }\n if (resetKey) next.delete(resetKey);\n return next;\n}\n","// Client (a portal). Radix does the roving focus, the arrows, Home/End, typeahead, Escape and the focus return.\nimport { DropdownMenu as MenuPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { floating } from \"../floating\";\n\nexport const menu = tv({\n slots: {\n content: cn(floating, \"min-w-48 max-h-(--radix-dropdown-menu-content-available-height) overflow-y-auto overflow-x-hidden overscroll-contain p-1 origin-(--radix-dropdown-menu-content-transform-origin)\"),\n item:\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2.5 py-2 text-sm text-fg outline-hidden transition-colors \" +\n \"data-highlighted:bg-surface-3 data-disabled:pointer-events-none data-disabled:opacity-40 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0 \" +\n \"[&>svg]:text-fg-secondary\",\n indicator: \"ml-auto flex h-4 w-4 items-center justify-center text-fg-accent\",\n label: \"px-2.5 pb-1 pt-2 text-[11px] font-semibold text-fg-secondary\",\n separator: \"-mx-1 my-1 h-px bg-border-subtle\",\n },\n variants: {\n // The label reads in the danger text role (≥ 4.5:1 on the menu surface, both themes); the icon and the highlight\n // carry the danger fill.\n tone: { default: {}, danger: { item: \"text-fg-danger data-highlighted:bg-danger/15 [&>svg]:text-danger\" } },\n },\n defaultVariants: { tone: \"default\" },\n});\nconst s = menu();\n\nexport type DropdownMenuContentProps = React.ComponentProps<typeof MenuPrimitive.Content> & {\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n};\n\nexport function DropdownMenuContent({ sideOffset = 6, align = \"end\", collisionPadding = 8, container, className, ...props }: DropdownMenuContentProps) {\n return (\n <MenuPrimitive.Portal container={container}>\n <MenuPrimitive.Content sideOffset={sideOffset} align={align} collisionPadding={collisionPadding} className={s.content({ className })} {...props} />\n </MenuPrimitive.Portal>\n );\n}\n\nexport type DropdownMenuItemProps = React.ComponentProps<typeof MenuPrimitive.Item> & {\n /** `danger` for a destructive action: the icon and the highlight carry the danger, the label stays legible. */\n tone?: \"default\" | \"danger\";\n};\n\n/** An action. `tone=\"danger\"` for a destructive one; `onSelect` runs it (the menu closes). */\nexport function DropdownMenuItem({ tone, className, ...props }: DropdownMenuItemProps) {\n return <MenuPrimitive.Item data-tone={tone ?? \"default\"} className={menu({ tone }).item({ className })} {...props} />;\n}\n\n/** A toggled option: `checked` + `onCheckedChange`. */\nexport function DropdownMenuCheckboxItem({ className, children, ...props }: React.ComponentProps<typeof MenuPrimitive.CheckboxItem>) {\n return (\n <MenuPrimitive.CheckboxItem className={s.item({ className })} {...props}>\n {children}\n <MenuPrimitive.ItemIndicator className={s.indicator()}>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n </MenuPrimitive.ItemIndicator>\n </MenuPrimitive.CheckboxItem>\n );\n}\n\n/** A submenu's trigger: an item that opens `DropdownMenu.SubContent`, with a chevron. */\nexport function DropdownMenuSubTrigger({ className, children, ...props }: React.ComponentProps<typeof MenuPrimitive.SubTrigger>) {\n return (\n <MenuPrimitive.SubTrigger className={s.item({ className: cn(\"data-[state=open]:bg-surface-3\", className) })} {...props}>\n {children}\n <svg className=\"ml-auto !h-4 !w-4 text-fg-secondary\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </MenuPrimitive.SubTrigger>\n );\n}\n\n/** The submenu's panel (same material as the menu). */\nexport function DropdownMenuSubContent({ sideOffset = 4, collisionPadding = 8, className, ...props }: React.ComponentProps<typeof MenuPrimitive.SubContent>) {\n return (\n <MenuPrimitive.Portal>\n <MenuPrimitive.SubContent sideOffset={sideOffset} collisionPadding={collisionPadding} className={s.content({ className: cn(\"max-h-(--radix-dropdown-menu-content-available-height)\", className) })} {...props} />\n </MenuPrimitive.Portal>\n );\n}\n\n/** One choice among several (`DropdownMenu.RadioGroup` holds the value): a language, a sort order. */\nexport function DropdownMenuRadioItem({ className, children, ...props }: React.ComponentProps<typeof MenuPrimitive.RadioItem>) {\n return (\n <MenuPrimitive.RadioItem className={s.item({ className })} {...props}>\n {children}\n <MenuPrimitive.ItemIndicator className={s.indicator()}>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n </MenuPrimitive.ItemIndicator>\n </MenuPrimitive.RadioItem>\n );\n}\n\nexport function DropdownMenuLabel({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Label>) {\n return <MenuPrimitive.Label className={s.label({ className })} {...props} />;\n}\n\nexport function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Separator>) {\n return <MenuPrimitive.Separator className={s.separator({ className })} {...props} />;\n}\n\n/** `DropdownMenu.Root/Trigger/Content/Item/CheckboxItem/Label/Separator/Group`. `open`/`defaultOpen` + `onOpenChange`. */\nexport const DropdownMenu = {\n Root: MenuPrimitive.Root,\n Trigger: MenuPrimitive.Trigger,\n Content: DropdownMenuContent,\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n Label: DropdownMenuLabel,\n Separator: DropdownMenuSeparator,\n Group: MenuPrimitive.Group,\n Sub: MenuPrimitive.Sub,\n SubTrigger: DropdownMenuSubTrigger,\n SubContent: DropdownMenuSubContent,\n RadioGroup: MenuPrimitive.RadioGroup,\n RadioItem: DropdownMenuRadioItem,\n};\n"],"mappings":"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","names":["MenuPrimitive","tv","jsx","jsxs","tv","s","MenuPrimitive"]}
|
package/dist/command.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
DialogContent
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6EAHUURY.js";
|
|
5
5
|
import "./chunk-SJS6RJIT.js";
|
|
6
6
|
import "./chunk-D3T54RSL.js";
|
|
7
7
|
import "./chunk-WEVYKZIF.js";
|
|
@@ -24,10 +24,10 @@ var command = tv({
|
|
|
24
24
|
list: "max-h-[min(60dvh,26rem)] scroll-py-2 overflow-y-auto overscroll-contain p-2 [&:not(:has([cmdk-item]))]:p-0",
|
|
25
25
|
empty: "px-3 py-8 text-center text-sm text-fg-secondary",
|
|
26
26
|
loading: "px-3 py-6 text-center text-sm text-fg-secondary",
|
|
27
|
-
group: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:
|
|
27
|
+
group: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:[&_[cmdk-group-heading]]:[&_[cmdk-group-heading]]:text-fg-secondary",
|
|
28
28
|
item: "relative flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-fg outline-hidden transition-colors before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent data-[selected=true]:bg-surface-2 data-[selected=true]:before:bg-accent data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40",
|
|
29
29
|
separator: "-mx-2 my-1 h-px bg-border-subtle",
|
|
30
|
-
shortcut: "ml-auto text-xs
|
|
30
|
+
shortcut: "ml-auto text-xs text-fg-secondary"
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
var s = command();
|
package/dist/command.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/command/command.tsx"],"sourcesContent":["// Client. A command palette on cmdk: the combobox / listbox roles, the active option (aria-activedescendant), the\n// arrows, Home / End, Enter, and the filtering (turn it off with `shouldFilter={false}` when the server searches).\n// `CommandDialog` puts it in the platform's Dialog. Words arrive as props.\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { DialogContent, type DialogContentProps } from \"../dialog/dialog\";\n\nexport const command = tv({\n slots: {\n root: \"flex h-full w-full flex-col overflow-hidden bg-surface-1 text-fg\",\n inputWrap: \"flex items-center gap-3 border-b border-border-default px-4\",\n icon: \"h-5 w-5 shrink-0 text-fg-secondary\",\n input:\n \"h-13 w-full min-w-0 flex-1 bg-transparent text-sm text-fg outline-hidden placeholder:text-fg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:text-base\",\n list: \"max-h-[min(60dvh,26rem)] scroll-py-2 overflow-y-auto overscroll-contain p-2 [&:not(:has([cmdk-item]))]:p-0\",\n empty: \"px-3 py-8 text-center text-sm text-fg-secondary\",\n loading: \"px-3 py-6 text-center text-sm text-fg-secondary\",\n group:\n \"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs \" +\n \"[&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-fg-secondary\",\n item:\n \"relative flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-fg outline-hidden transition-colors \" +\n \"before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent \" +\n \"data-[selected=true]:bg-surface-2 data-[selected=true]:before:bg-accent data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40\",\n separator: \"-mx-2 my-1 h-px bg-border-subtle\",\n shortcut: \"ml-auto text-xs tracking-widest text-fg-secondary\",\n },\n});\nconst s = command();\n\nfunction SearchIcon({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 24 24\" className={className} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n );\n}\n\nexport type CommandRootProps = React.ComponentProps<typeof CommandPrimitive> & {\n /** The accessible name of the palette — passed translated (\"Search\", \"Commands\"). */\n label: string;\n};\n\n/** The palette: `value` / `onValueChange` (the active item), `shouldFilter`, `filter`, `loop`. */\nexport function CommandRoot({ className, ...props }: CommandRootProps) {\n return <CommandPrimitive className={s.root({ className })} {...props} />;\n}\n\nexport type CommandInputProps = Omit<React.ComponentProps<typeof CommandPrimitive.Input>, \"placeholder\"> & {\n /** What to type — passed translated. The input is named by the palette's `label`. */\n placeholder: string;\n /** After the input, inside the bar: a spinner, a clear button. */\n trailing?: React.ReactNode;\n};\n\n/** The search field (`value` / `onValueChange` for the query), with a magnifier. */\nexport function CommandInput({ className, placeholder, trailing, ...props }: CommandInputProps) {\n return (\n <div className={s.inputWrap()} cmdk-input-wrapper=\"\">\n <SearchIcon className={s.icon()} />\n <CommandPrimitive.Input placeholder={placeholder} className={s.input({ className })} {...props} />\n {trailing}\n </div>\n );\n}\n\n// Set inside `Command.List`: a listbox may only hold options and groups (axe `aria-required-children`), so the empty\n// message must live beside it, not in it.\nconst InsideList = React.createContext(false);\n\nexport type CommandListProps = React.ComponentProps<typeof CommandPrimitive.List> & {\n /** The accessible name of the list of results — passed translated (\"Suggestions\", \"Results\"). */\n label: string;\n /**\n * Shown when nothing matches — passed translated. Rendered after the listbox, never inside it: an empty listbox is\n * valid, a listbox holding text is not.\n */\n emptyLabel?: React.ReactNode;\n};\n\nexport function CommandList({ className, emptyLabel, children, ...props }: CommandListProps) {\n return (\n <>\n <CommandPrimitive.List className={s.list({ className })} {...props}>\n <InsideList.Provider value>{children}</InsideList.Provider>\n </CommandPrimitive.List>\n {emptyLabel === undefined ? null : <CommandEmpty emptyLabel={emptyLabel} />}\n </>\n );\n}\n\nexport type CommandEmptyProps = Omit<React.ComponentProps<typeof CommandPrimitive.Empty>, \"children\"> & {\n /** Shown when nothing matches — passed translated. */\n emptyLabel: React.ReactNode;\n};\n\n/**\n * Shown by cmdk only when no item matches. Place it beside `Command.List` (or pass `emptyLabel` to the list), never\n * inside it: inside, it is rendered as before but warns in development — the listbox then holds text, which axe\n * refuses (`aria-required-children`).\n */\nexport function CommandEmpty({ className, emptyLabel, ...props }: CommandEmptyProps) {\n const inside = React.useContext(InsideList);\n React.useEffect(() => {\n if (inside && typeof process !== \"undefined\" && process.env.NODE_ENV !== \"production\") {\n console.warn(\"@krizaka/ui/command: <Command.Empty> inside <Command.List> breaks the listbox (axe aria-required-children). Pass `emptyLabel` to <Command.List> instead.\");\n }\n }, [inside]);\n return (\n <CommandPrimitive.Empty className={s.empty({ className })} {...props}>\n {emptyLabel}\n </CommandPrimitive.Empty>\n );\n}\n\n/** While results load (`label` is announced). */\nexport function CommandLoading({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Loading>) {\n return <CommandPrimitive.Loading className={s.loading({ className })} {...props} />;\n}\n\n/** A group of items under a `heading`. */\nexport function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return <CommandPrimitive.Group className={s.group({ className })} {...props} />;\n}\n\n/** An option: `onSelect` on Enter or click, `value` and `keywords` for the filter, `disabled`. */\nexport function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return <CommandPrimitive.Item className={s.item({ className })} {...props} />;\n}\n\n/** A line between groups. Decorative (`role=\"none\"`): cmdk's own separator is a role a listbox may not hold (axe). */\nexport function CommandSeparator({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div role=\"none\" className={s.separator({ className })} {...props} />;\n}\n\n/** A keyboard hint at the end of an item. */\nexport function CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return <span className={s.shortcut({ className })} {...props} />;\n}\n\n/** `Command.Root/Input/List/Empty/Loading/Group/Item/Separator/Shortcut`. */\nexport const Command = {\n Root: CommandRoot,\n Input: CommandInput,\n List: CommandList,\n Empty: CommandEmpty,\n Loading: CommandLoading,\n Group: CommandGroup,\n Item: CommandItem,\n Separator: CommandSeparator,\n Shortcut: CommandShortcut,\n};\n\nexport type CommandDialogProps = Omit<CommandRootProps, \"title\"> & {\n /** Open or closed (controlled), with `onOpenChange`. */\n open?: boolean;\n /** Open at first, uncontrolled. */\n defaultOpen?: boolean;\n /** Called when it opens or closes (Escape, a click outside, a shortcut of the product). */\n onOpenChange?: (open: boolean) => void;\n /** Under the palette, inside the dialog: shortcuts, a \"see all results\" link. */\n footer?: React.ReactNode;\n /** Passed to `Dialog.Content`: `size`, `container`, `className` of the dialog. */\n contentProps?: Omit<Extract<DialogContentProps, { hideClose: true }>, \"hideClose\" | \"children\" | \"placement\">;\n};\n\n/**\n * The palette in a dialog (Radix: focus trap, Escape, focus return). The dialog is named by `label`; it has no close\n * button — Escape and a click outside close it — and the input takes the focus when it opens.\n */\nexport function CommandDialog({ open, defaultOpen, onOpenChange, footer, contentProps, label, className, children, ...props }: CommandDialogProps) {\n const { className: contentClassName, ...content } = contentProps ?? {};\n return (\n <DialogPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <DialogContent\n hideClose\n size=\"lg\"\n aria-describedby={undefined}\n className={cn(\"top-[12dvh] translate-y-0 sm:top-[14dvh]\", contentClassName)}\n {...content}\n >\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n <CommandRoot label={label} className={className} {...props}>\n {children}\n </CommandRoot>\n {footer}\n </DialogContent>\n </DialogPrimitive.Root>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/command/command.tsx"],"sourcesContent":["// Client. A command palette on cmdk: the combobox / listbox roles, the active option (aria-activedescendant), the\n// arrows, Home / End, Enter, and the filtering (turn it off with `shouldFilter={false}` when the server searches).\n// `CommandDialog` puts it in the platform's Dialog. Words arrive as props.\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { DialogContent, type DialogContentProps } from \"../dialog/dialog\";\n\nexport const command = tv({\n slots: {\n root: \"flex h-full w-full flex-col overflow-hidden bg-surface-1 text-fg\",\n inputWrap: \"flex items-center gap-3 border-b border-border-default px-4\",\n icon: \"h-5 w-5 shrink-0 text-fg-secondary\",\n input:\n \"h-13 w-full min-w-0 flex-1 bg-transparent text-sm text-fg outline-hidden placeholder:text-fg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:text-base\",\n list: \"max-h-[min(60dvh,26rem)] scroll-py-2 overflow-y-auto overscroll-contain p-2 [&:not(:has([cmdk-item]))]:p-0\",\n empty: \"px-3 py-8 text-center text-sm text-fg-secondary\",\n loading: \"px-3 py-6 text-center text-sm text-fg-secondary\",\n group:\n \"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs \" +\n \"[&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:[&_[cmdk-group-heading]]:[&_[cmdk-group-heading]]:text-fg-secondary\",\n item:\n \"relative flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-fg outline-hidden transition-colors \" +\n \"before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent \" +\n \"data-[selected=true]:bg-surface-2 data-[selected=true]:before:bg-accent data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40\",\n separator: \"-mx-2 my-1 h-px bg-border-subtle\",\n shortcut: \"ml-auto text-xs text-fg-secondary\",\n },\n});\nconst s = command();\n\nfunction SearchIcon({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 24 24\" className={className} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n );\n}\n\nexport type CommandRootProps = React.ComponentProps<typeof CommandPrimitive> & {\n /** The accessible name of the palette — passed translated (\"Search\", \"Commands\"). */\n label: string;\n};\n\n/** The palette: `value` / `onValueChange` (the active item), `shouldFilter`, `filter`, `loop`. */\nexport function CommandRoot({ className, ...props }: CommandRootProps) {\n return <CommandPrimitive className={s.root({ className })} {...props} />;\n}\n\nexport type CommandInputProps = Omit<React.ComponentProps<typeof CommandPrimitive.Input>, \"placeholder\"> & {\n /** What to type — passed translated. The input is named by the palette's `label`. */\n placeholder: string;\n /** After the input, inside the bar: a spinner, a clear button. */\n trailing?: React.ReactNode;\n};\n\n/** The search field (`value` / `onValueChange` for the query), with a magnifier. */\nexport function CommandInput({ className, placeholder, trailing, ...props }: CommandInputProps) {\n return (\n <div className={s.inputWrap()} cmdk-input-wrapper=\"\">\n <SearchIcon className={s.icon()} />\n <CommandPrimitive.Input placeholder={placeholder} className={s.input({ className })} {...props} />\n {trailing}\n </div>\n );\n}\n\n// Set inside `Command.List`: a listbox may only hold options and groups (axe `aria-required-children`), so the empty\n// message must live beside it, not in it.\nconst InsideList = React.createContext(false);\n\nexport type CommandListProps = React.ComponentProps<typeof CommandPrimitive.List> & {\n /** The accessible name of the list of results — passed translated (\"Suggestions\", \"Results\"). */\n label: string;\n /**\n * Shown when nothing matches — passed translated. Rendered after the listbox, never inside it: an empty listbox is\n * valid, a listbox holding text is not.\n */\n emptyLabel?: React.ReactNode;\n};\n\nexport function CommandList({ className, emptyLabel, children, ...props }: CommandListProps) {\n return (\n <>\n <CommandPrimitive.List className={s.list({ className })} {...props}>\n <InsideList.Provider value>{children}</InsideList.Provider>\n </CommandPrimitive.List>\n {emptyLabel === undefined ? null : <CommandEmpty emptyLabel={emptyLabel} />}\n </>\n );\n}\n\nexport type CommandEmptyProps = Omit<React.ComponentProps<typeof CommandPrimitive.Empty>, \"children\"> & {\n /** Shown when nothing matches — passed translated. */\n emptyLabel: React.ReactNode;\n};\n\n/**\n * Shown by cmdk only when no item matches. Place it beside `Command.List` (or pass `emptyLabel` to the list), never\n * inside it: inside, it is rendered as before but warns in development — the listbox then holds text, which axe\n * refuses (`aria-required-children`).\n */\nexport function CommandEmpty({ className, emptyLabel, ...props }: CommandEmptyProps) {\n const inside = React.useContext(InsideList);\n React.useEffect(() => {\n if (inside && typeof process !== \"undefined\" && process.env.NODE_ENV !== \"production\") {\n console.warn(\"@krizaka/ui/command: <Command.Empty> inside <Command.List> breaks the listbox (axe aria-required-children). Pass `emptyLabel` to <Command.List> instead.\");\n }\n }, [inside]);\n return (\n <CommandPrimitive.Empty className={s.empty({ className })} {...props}>\n {emptyLabel}\n </CommandPrimitive.Empty>\n );\n}\n\n/** While results load (`label` is announced). */\nexport function CommandLoading({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Loading>) {\n return <CommandPrimitive.Loading className={s.loading({ className })} {...props} />;\n}\n\n/** A group of items under a `heading`. */\nexport function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return <CommandPrimitive.Group className={s.group({ className })} {...props} />;\n}\n\n/** An option: `onSelect` on Enter or click, `value` and `keywords` for the filter, `disabled`. */\nexport function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return <CommandPrimitive.Item className={s.item({ className })} {...props} />;\n}\n\n/** A line between groups. Decorative (`role=\"none\"`): cmdk's own separator is a role a listbox may not hold (axe). */\nexport function CommandSeparator({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div role=\"none\" className={s.separator({ className })} {...props} />;\n}\n\n/** A keyboard hint at the end of an item. */\nexport function CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return <span className={s.shortcut({ className })} {...props} />;\n}\n\n/** `Command.Root/Input/List/Empty/Loading/Group/Item/Separator/Shortcut`. */\nexport const Command = {\n Root: CommandRoot,\n Input: CommandInput,\n List: CommandList,\n Empty: CommandEmpty,\n Loading: CommandLoading,\n Group: CommandGroup,\n Item: CommandItem,\n Separator: CommandSeparator,\n Shortcut: CommandShortcut,\n};\n\nexport type CommandDialogProps = Omit<CommandRootProps, \"title\"> & {\n /** Open or closed (controlled), with `onOpenChange`. */\n open?: boolean;\n /** Open at first, uncontrolled. */\n defaultOpen?: boolean;\n /** Called when it opens or closes (Escape, a click outside, a shortcut of the product). */\n onOpenChange?: (open: boolean) => void;\n /** Under the palette, inside the dialog: shortcuts, a \"see all results\" link. */\n footer?: React.ReactNode;\n /** Passed to `Dialog.Content`: `size`, `container`, `className` of the dialog. */\n contentProps?: Omit<Extract<DialogContentProps, { hideClose: true }>, \"hideClose\" | \"children\" | \"placement\">;\n};\n\n/**\n * The palette in a dialog (Radix: focus trap, Escape, focus return). The dialog is named by `label`; it has no close\n * button — Escape and a click outside close it — and the input takes the focus when it opens.\n */\nexport function CommandDialog({ open, defaultOpen, onOpenChange, footer, contentProps, label, className, children, ...props }: CommandDialogProps) {\n const { className: contentClassName, ...content } = contentProps ?? {};\n return (\n <DialogPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <DialogContent\n hideClose\n size=\"lg\"\n aria-describedby={undefined}\n className={cn(\"top-[12dvh] translate-y-0 sm:top-[14dvh]\", contentClassName)}\n {...content}\n >\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n <CommandRoot label={label} className={className} {...props}>\n {children}\n </CommandRoot>\n {footer}\n </DialogContent>\n </DialogPrimitive.Root>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/comparison-table.js
CHANGED
|
@@ -32,7 +32,7 @@ function ComparisonTable({ label, topicLabel, columns, highlight, rows, reveal =
|
|
|
32
32
|
}
|
|
33
33
|
),
|
|
34
34
|
/* @__PURE__ */ jsxs("div", { role: "row", className: "contents", children: [
|
|
35
|
-
/* @__PURE__ */ jsx("span", { role: "columnheader", className: "row-start-1 self-end px-4 pb-4 pt-5 font-mono text-xs font-semibold
|
|
35
|
+
/* @__PURE__ */ jsx("span", { role: "columnheader", className: "row-start-1 self-end px-4 pb-4 pt-5 font-mono text-xs font-semibold text-fg-secondary", style: { gridColumn: 1 }, children: topicLabel }),
|
|
36
36
|
columns.map((c, i) => /* @__PURE__ */ jsxs(
|
|
37
37
|
"span",
|
|
38
38
|
{
|
|
@@ -72,7 +72,7 @@ function ComparisonTable({ label, topicLabel, columns, highlight, rows, reveal =
|
|
|
72
72
|
row.topic
|
|
73
73
|
] }),
|
|
74
74
|
/* @__PURE__ */ jsx("dl", { className: "mt-3 grid gap-2", children: columns.map((c, i) => /* @__PURE__ */ jsxs("div", { "data-highlight": band(i) ? "" : void 0, className: cn("rounded-xl p-3 text-sm leading-relaxed", band(i) ? "border border-accent/35 bg-accent-soft" : "bg-surface-2/60"), children: [
|
|
75
|
-
/* @__PURE__ */ jsx("dt", { className: cn("mb-1 flex items-center gap-1.5 font-mono text-[11px]
|
|
75
|
+
/* @__PURE__ */ jsx("dt", { className: cn("mb-1 flex items-center gap-1.5 font-mono text-[11px] ", band(i) ? "text-fg-accent" : "text-fg-secondary"), children: c.label }),
|
|
76
76
|
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx(Answer, { answer: row.answers[c.id] }) })
|
|
77
77
|
] }, c.id)) })
|
|
78
78
|
] }, row.id)) })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/comparison-table/comparison-table.tsx"],"sourcesContent":["// Server-safe (no state). A fair \"versus\" block: one grid where every row lines up across the columns, the column you\n// argue for drawn AS a column of the grid (a tinted band with the brand's light, its header part of the band), a small icon per question, each answer as its key phrase in bold then its detail. The other columns stay\n// neutral — never crossed out. Below `md` each question is a card: the question, then the answers stacked, the\n// highlighted one tinted. Rows arrive one after the other (`[data-reveal]`, staggered) when a MotionObserver runs.\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\n\nexport interface ComparisonColumn {\n /** A stable id: the key of the rows' `answers`. */\n id: string;\n /** The column's name (“A cloud assistant”), passed translated. */\n label: string;\n /** A small icon beside the name. */\n icon?: React.ReactNode;\n}\n\nexport interface ComparisonAnswer {\n /** The key phrase, in bold (“On your machines.”). */\n key: string;\n /** The detail after it (“A cloud model only if you connect one.”). */\n detail?: string;\n}\n\nexport interface ComparisonRow {\n /** A stable key. */\n id: string;\n /** The question (“Where do your prompts go?”). */\n topic: string;\n /** A small icon for the question. */\n icon?: React.ReactNode;\n /** One answer per column id. */\n answers: Readonly<Record<string, ComparisonAnswer>>;\n}\n\nexport interface ComparisonTableProps extends Omit<React.ComponentProps<\"div\">, \"children\"> {\n /** The table's accessible name (the section's title), passed translated. */\n label: string;\n /** The first column's header (“Question”). */\n topicLabel: string;\n /** The answer columns, in order. */\n columns: readonly ComparisonColumn[];\n /** The column drawn as the highlighted band (yours). */\n highlight: string;\n /** The questions, in order (three to six). */\n rows: readonly ComparisonRow[];\n /** Stagger the rows' entrance with `[data-reveal]` (needs MotionObserver). @default true */\n reveal?: boolean;\n}\n\nfunction Answer({ answer }: { answer?: ComparisonAnswer }) {\n if (!answer) return null;\n return (\n <>\n <strong className=\"font-semibold text-fg\">{answer.key}</strong>\n {answer.detail && <span className=\"text-fg-secondary\"> {answer.detail}</span>}\n </>\n );\n}\n\n/** The rows' stagger: 70 ms apart, through the motion system's `--kz-delay` (reduced motion: no movement at all). */\nconst stagger = (i: number): React.CSSProperties => ({ \"--kz-delay\": `${i * 70}ms` }) as React.CSSProperties;\n\n/** A comparison where your column is a highlighted band of the same grid — aligned rows, fair neutral answers, cards on a phone. */\nexport function ComparisonTable({ label, topicLabel, columns, highlight, rows, reveal = true, className, ...props }: ComparisonTableProps) {\n const at = Math.max(columns.findIndex((c) => c.id === highlight), 0);\n const grid = { gridTemplateColumns: `minmax(10rem, 0.9fr) repeat(${columns.length}, minmax(0, 1fr))` };\n const band = (i: number) => i === at;\n return (\n <div data-kz-comparison className={cn(\"w-full\", className)} {...props}>\n {/* Wide: one grid, the band is a grid item spanning every row of its column — the rows cannot drift. */}\n <div role=\"table\" aria-label={label} className=\"relative hidden md:grid\" style={grid}>\n <div\n aria-hidden\n data-band\n className=\"pointer-events-none rounded-2xl border border-accent/35 bg-accent-soft shadow-[0_0_48px_-16px_var(--kz-accent)]\"\n style={{ gridColumn: at + 2, gridRow: `1 / span ${rows.length + 1}` }}\n />\n <div role=\"row\" className=\"contents\">\n <span role=\"columnheader\" className=\"row-start-1 self-end px-4 pb-4 pt-5 font-mono text-xs font-semibold
|
|
1
|
+
{"version":3,"sources":["../src/comparison-table/comparison-table.tsx"],"sourcesContent":["// Server-safe (no state). A fair \"versus\" block: one grid where every row lines up across the columns, the column you\n// argue for drawn AS a column of the grid (a tinted band with the brand's light, its header part of the band), a small icon per question, each answer as its key phrase in bold then its detail. The other columns stay\n// neutral — never crossed out. Below `md` each question is a card: the question, then the answers stacked, the\n// highlighted one tinted. Rows arrive one after the other (`[data-reveal]`, staggered) when a MotionObserver runs.\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\n\nexport interface ComparisonColumn {\n /** A stable id: the key of the rows' `answers`. */\n id: string;\n /** The column's name (“A cloud assistant”), passed translated. */\n label: string;\n /** A small icon beside the name. */\n icon?: React.ReactNode;\n}\n\nexport interface ComparisonAnswer {\n /** The key phrase, in bold (“On your machines.”). */\n key: string;\n /** The detail after it (“A cloud model only if you connect one.”). */\n detail?: string;\n}\n\nexport interface ComparisonRow {\n /** A stable key. */\n id: string;\n /** The question (“Where do your prompts go?”). */\n topic: string;\n /** A small icon for the question. */\n icon?: React.ReactNode;\n /** One answer per column id. */\n answers: Readonly<Record<string, ComparisonAnswer>>;\n}\n\nexport interface ComparisonTableProps extends Omit<React.ComponentProps<\"div\">, \"children\"> {\n /** The table's accessible name (the section's title), passed translated. */\n label: string;\n /** The first column's header (“Question”). */\n topicLabel: string;\n /** The answer columns, in order. */\n columns: readonly ComparisonColumn[];\n /** The column drawn as the highlighted band (yours). */\n highlight: string;\n /** The questions, in order (three to six). */\n rows: readonly ComparisonRow[];\n /** Stagger the rows' entrance with `[data-reveal]` (needs MotionObserver). @default true */\n reveal?: boolean;\n}\n\nfunction Answer({ answer }: { answer?: ComparisonAnswer }) {\n if (!answer) return null;\n return (\n <>\n <strong className=\"font-semibold text-fg\">{answer.key}</strong>\n {answer.detail && <span className=\"text-fg-secondary\"> {answer.detail}</span>}\n </>\n );\n}\n\n/** The rows' stagger: 70 ms apart, through the motion system's `--kz-delay` (reduced motion: no movement at all). */\nconst stagger = (i: number): React.CSSProperties => ({ \"--kz-delay\": `${i * 70}ms` }) as React.CSSProperties;\n\n/** A comparison where your column is a highlighted band of the same grid — aligned rows, fair neutral answers, cards on a phone. */\nexport function ComparisonTable({ label, topicLabel, columns, highlight, rows, reveal = true, className, ...props }: ComparisonTableProps) {\n const at = Math.max(columns.findIndex((c) => c.id === highlight), 0);\n const grid = { gridTemplateColumns: `minmax(10rem, 0.9fr) repeat(${columns.length}, minmax(0, 1fr))` };\n const band = (i: number) => i === at;\n return (\n <div data-kz-comparison className={cn(\"w-full\", className)} {...props}>\n {/* Wide: one grid, the band is a grid item spanning every row of its column — the rows cannot drift. */}\n <div role=\"table\" aria-label={label} className=\"relative hidden md:grid\" style={grid}>\n <div\n aria-hidden\n data-band\n className=\"pointer-events-none rounded-2xl border border-accent/35 bg-accent-soft shadow-[0_0_48px_-16px_var(--kz-accent)]\"\n style={{ gridColumn: at + 2, gridRow: `1 / span ${rows.length + 1}` }}\n />\n <div role=\"row\" className=\"contents\">\n <span role=\"columnheader\" className=\"row-start-1 self-end px-4 pb-4 pt-5 font-mono text-xs font-semibold text-fg-secondary\" style={{ gridColumn: 1 }}>\n {topicLabel}\n </span>\n {columns.map((c, i) => (\n <span\n key={c.id}\n role=\"columnheader\"\n data-highlight={band(i) ? \"\" : undefined}\n className={cn(\"row-start-1 flex items-center gap-2 self-stretch px-5 pb-4 pt-5 text-sm font-semibold\", band(i) ? \"text-fg [&_svg]:text-fg-accent\" : \"text-fg-secondary\")}\n style={{ gridColumn: i + 2 }}\n >\n {c.icon}\n {c.label}\n </span>\n ))}\n </div>\n {rows.map((row, r) => (\n <div key={row.id} role=\"row\" className=\"contents\">\n <span role=\"rowheader\" data-reveal={reveal ? \"soft\" : undefined} style={{ ...stagger(r), gridColumn: 1, gridRow: r + 2 }} className=\"flex items-start gap-3 border-t border-border-subtle px-4 py-5 text-base font-semibold text-fg\">\n {row.icon && <span className=\"mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border-default bg-surface-2 text-fg-accent [&>svg]:h-4 [&>svg]:w-4\">{row.icon}</span>}\n {row.topic}\n </span>\n {columns.map((c, i) => (\n <span\n key={c.id}\n role=\"cell\"\n data-reveal={reveal ? \"soft\" : undefined}\n style={{ ...stagger(r), gridColumn: i + 2, gridRow: r + 2 }}\n className={cn(\"border-t px-5 py-5 text-sm leading-relaxed\", band(i) ? \"border-accent/20\" : \"border-border-subtle\")}\n >\n <Answer answer={row.answers[c.id]} />\n </span>\n ))}\n </div>\n ))}\n </div>\n\n {/* Phone: one card per question, the answers stacked, the highlighted one tinted. */}\n <ul aria-label={label} className=\"grid gap-4 md:hidden\">\n {rows.map((row, r) => (\n <li key={row.id} data-reveal={reveal ? \"soft\" : undefined} style={stagger(r)} className=\"rounded-2xl border border-border-subtle bg-surface-1/80 p-4\">\n <p className=\"flex items-center gap-3 text-base font-semibold text-fg\">\n {row.icon && <span className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border-default bg-surface-2 text-fg-accent [&>svg]:h-4 [&>svg]:w-4\">{row.icon}</span>}\n {row.topic}\n </p>\n <dl className=\"mt-3 grid gap-2\">\n {columns.map((c, i) => (\n <div key={c.id} data-highlight={band(i) ? \"\" : undefined} className={cn(\"rounded-xl p-3 text-sm leading-relaxed\", band(i) ? \"border border-accent/35 bg-accent-soft\" : \"bg-surface-2/60\")}>\n <dt className={cn(\"mb-1 flex items-center gap-1.5 font-mono text-[11px] \", band(i) ? \"text-fg-accent\" : \"text-fg-secondary\")}>\n {c.label}\n </dt>\n <dd>\n <Answer answer={row.answers[c.id]} />\n </dd>\n </div>\n ))}\n </dl>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/countdown.js
CHANGED
|
@@ -36,7 +36,7 @@ var countdown = tv({
|
|
|
36
36
|
slots: {
|
|
37
37
|
root: "inline-flex items-baseline gap-1.5 font-display font-black tabular-nums tracking-tight text-fg",
|
|
38
38
|
segment: "inline-flex items-baseline",
|
|
39
|
-
unit: "ml-0.5 text-[0.5em] font-bold
|
|
39
|
+
unit: "ml-0.5 text-[0.5em] font-bold text-fg-secondary",
|
|
40
40
|
label: "mr-0.5 self-center font-sans text-[0.6em] font-semibold tracking-normal text-fg-secondary"
|
|
41
41
|
},
|
|
42
42
|
variants: {
|
package/dist/countdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/countdown/core.ts","../src/countdown/countdown.tsx"],"sourcesContent":["// The countdown's clock, shared by the web (`@krizaka/ui/countdown`) and native renders: no DOM import.\nimport { useSyncExternalStore } from \"react\";\n\n// One clock for every countdown on the page: it ticks each second while someone listens.\nconst listeners = new Set<() => void>();\nlet timer: ReturnType<typeof setInterval> | null = null;\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n timer ??= setInterval(() => listeners.forEach((l) => l()), 1000);\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0 && timer) {\n clearInterval(timer);\n timer = null;\n }\n };\n}\n\nconst nowSecond = () => Math.floor(Date.now() / 1000) * 1000;\n\n/** Milliseconds left until `target` (never negative), ticking every second. `skewMs` = server clock − this clock. */\nexport function useCountdown(target: Date | string | number, skewMs = 0): number {\n const now = useSyncExternalStore(subscribe, nowSecond, nowSecond);\n return Math.max(0, new Date(target).getTime() - (now + skewMs));\n}\n\n/** Splits a duration into days, hours, minutes and seconds. */\nexport function splitDuration(ms: number): { d: number; h: number; m: number; s: number } {\n const total = Math.max(0, Math.floor(ms / 1000));\n return { d: Math.floor(total / 86400), h: Math.floor((total % 86400) / 3600), m: Math.floor((total % 3600) / 60), s: total % 60 };\n}\n\n/** The short unit labels, passed translated (e.g. `{ d: \"d\", h: \"h\", m: \"m\", s: \"s\" }`). */\nexport type CountdownUnits = { d: string; h: string; m: string; s: string };\n\n/** The three segments shown: days, hours, minutes when there are days; else hours, minutes, seconds. */\nexport function countdownParts(ms: number, units: CountdownUnits): [number, string][] {\n const { d, h, m, s } = splitDuration(ms);\n return d > 0 ? [[d, units.d], [h, units.h], [m, units.m]] : [[h, units.h], [m, units.m], [s, units.s]];\n}\n","// Client: the clock is a hook.\nimport { tv } from \"tailwind-variants\";\n\nimport { countdownParts, type CountdownUnits, useCountdown } from \"./core\";\n\nconst countdown = tv({\n slots: {\n root: \"inline-flex items-baseline gap-1.5 font-display font-black tabular-nums tracking-tight text-fg\",\n segment: \"inline-flex items-baseline\",\n unit: \"ml-0.5 text-[0.5em] font-bold
|
|
1
|
+
{"version":3,"sources":["../src/countdown/core.ts","../src/countdown/countdown.tsx"],"sourcesContent":["// The countdown's clock, shared by the web (`@krizaka/ui/countdown`) and native renders: no DOM import.\nimport { useSyncExternalStore } from \"react\";\n\n// One clock for every countdown on the page: it ticks each second while someone listens.\nconst listeners = new Set<() => void>();\nlet timer: ReturnType<typeof setInterval> | null = null;\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n timer ??= setInterval(() => listeners.forEach((l) => l()), 1000);\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0 && timer) {\n clearInterval(timer);\n timer = null;\n }\n };\n}\n\nconst nowSecond = () => Math.floor(Date.now() / 1000) * 1000;\n\n/** Milliseconds left until `target` (never negative), ticking every second. `skewMs` = server clock − this clock. */\nexport function useCountdown(target: Date | string | number, skewMs = 0): number {\n const now = useSyncExternalStore(subscribe, nowSecond, nowSecond);\n return Math.max(0, new Date(target).getTime() - (now + skewMs));\n}\n\n/** Splits a duration into days, hours, minutes and seconds. */\nexport function splitDuration(ms: number): { d: number; h: number; m: number; s: number } {\n const total = Math.max(0, Math.floor(ms / 1000));\n return { d: Math.floor(total / 86400), h: Math.floor((total % 86400) / 3600), m: Math.floor((total % 3600) / 60), s: total % 60 };\n}\n\n/** The short unit labels, passed translated (e.g. `{ d: \"d\", h: \"h\", m: \"m\", s: \"s\" }`). */\nexport type CountdownUnits = { d: string; h: string; m: string; s: string };\n\n/** The three segments shown: days, hours, minutes when there are days; else hours, minutes, seconds. */\nexport function countdownParts(ms: number, units: CountdownUnits): [number, string][] {\n const { d, h, m, s } = splitDuration(ms);\n return d > 0 ? [[d, units.d], [h, units.h], [m, units.m]] : [[h, units.h], [m, units.m], [s, units.s]];\n}\n","// Client: the clock is a hook.\nimport { tv } from \"tailwind-variants\";\n\nimport { countdownParts, type CountdownUnits, useCountdown } from \"./core\";\n\nconst countdown = tv({\n slots: {\n root: \"inline-flex items-baseline gap-1.5 font-display font-black tabular-nums tracking-tight text-fg\",\n segment: \"inline-flex items-baseline\",\n unit: \"ml-0.5 text-[0.5em] font-bold text-fg-secondary\",\n label: \"mr-0.5 self-center font-sans text-[0.6em] font-semibold tracking-normal text-fg-secondary\",\n },\n variants: {\n size: { sm: { root: \"text-sm\" }, md: { root: \"text-xl\" }, lg: { root: \"text-3xl sm:text-4xl\" } },\n urgent: { true: { root: \"text-fg-danger\" } },\n },\n defaultVariants: { size: \"md\" },\n});\n\nexport type CountdownProps = {\n /** The moment it counts down to: a Date, an ISO string or epoch milliseconds. */\n target: Date | string | number;\n /** Server clock − this clock, in milliseconds. */\n skewMs?: number;\n /** The short unit labels, passed translated. */\n units: CountdownUnits;\n /** Below this many milliseconds it turns urgent (`text-fg-danger`, the last segment pulses). Default 60 s. */\n urgentBelowMs?: number;\n /** sm · md · lg — the danger text role reads at 4.5:1 at every size, in both themes. */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Accessible name, e.g. \"Ends in\". */\n label: string;\n /** Also show `label` before the segments, in the secondary text role (default: only read by screen readers). */\n showLabel?: boolean;\n /** Classes merged last, over the primitive's. */\n className?: string;\n};\n\n/**\n * Time left until a moment, as segments (2d 04h 13m 09s — days only when there are some) in tabular figures. Under\n * `urgentBelowMs` it turns to the danger text role and its last segment pulses (no motion under prefers-reduced-motion).\n * Words come from the app: `units` are the short unit labels. `role=\"timer\"` without live announcements — the app\n * announces what matters. State: `data-urgent`, `data-ended`.\n *\n * The urgent colour is `--kz-danger-text` (≥ 4.5:1 on every surface in both themes), so `size=\"sm\"` is safe too.\n */\nexport function Countdown({ target, skewMs = 0, units, urgentBelowMs = 60_000, size = \"md\", label, showLabel = false, className }: CountdownProps) {\n const ms = useCountdown(target, skewMs);\n const urgent = ms > 0 && ms < urgentBelowMs;\n const parts = countdownParts(ms, units);\n const s = countdown({ size, urgent });\n return (\n <span\n role=\"timer\"\n aria-label={label}\n data-urgent={urgent ? \"\" : undefined}\n data-ended={ms === 0 ? \"\" : undefined}\n suppressHydrationWarning\n className={s.root({ className })}\n >\n {showLabel ? (\n <span aria-hidden className={s.label()}>\n {label}\n </span>\n ) : null}\n {parts.map(([value, unit], i) => (\n <span key={unit} className={s.segment({ className: urgent && i === parts.length - 1 ? \"motion-safe:animate-pulse\" : undefined })}>\n {String(value).padStart(2, \"0\")}\n <span className={s.unit()}>{unit}</span>\n </span>\n ))}\n </span>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/cover-hero.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
BlockLink
|
|
4
|
+
} from "./chunk-C7LTF5CC.js";
|
|
2
5
|
import {
|
|
3
6
|
ArrowGlyph
|
|
4
7
|
} from "./chunk-P7GZR5CU.js";
|
|
5
8
|
import {
|
|
6
9
|
cn
|
|
7
10
|
} from "./chunk-WU4VLSEA.js";
|
|
8
|
-
import {
|
|
9
|
-
BlockLink
|
|
10
|
-
} from "./chunk-C7LTF5CC.js";
|
|
11
11
|
|
|
12
12
|
// src/cover-hero/cover-hero.tsx
|
|
13
13
|
import * as React2 from "react";
|
|
@@ -16,8 +16,17 @@ import { tv } from "tailwind-variants";
|
|
|
16
16
|
// src/page/page.tsx
|
|
17
17
|
import * as React from "react";
|
|
18
18
|
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
-
function Page({ size = "default", as: Tag = "div", className, ...props }) {
|
|
20
|
-
return /* @__PURE__ */ jsx(
|
|
19
|
+
function Page({ size = "default", as: Tag = "div", paper, margin, className, ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsx(
|
|
21
|
+
Tag,
|
|
22
|
+
{
|
|
23
|
+
"data-size": size === "default" ? void 0 : size,
|
|
24
|
+
"data-paper": paper,
|
|
25
|
+
"data-margin": margin ? "" : void 0,
|
|
26
|
+
className: cn("kz-frame", className),
|
|
27
|
+
...props
|
|
28
|
+
}
|
|
29
|
+
);
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
// src/cover-hero/cover-hero.tsx
|
|
@@ -30,7 +39,7 @@ var coverHero = tv({
|
|
|
30
39
|
plain: "absolute inset-0 -z-10 bg-linear-to-br from-accent/25 via-surface-1 to-accent-2/20",
|
|
31
40
|
body: "flex flex-col gap-4 pb-8 pt-24 sm:pb-12",
|
|
32
41
|
back: "inline-flex w-fit items-center gap-1.5 text-sm font-semibold text-current no-underline opacity-90 hover:opacity-100",
|
|
33
|
-
eyebrow: "m-0 font-mono text-xs font-semibold
|
|
42
|
+
eyebrow: "m-0 font-mono text-xs font-semibold opacity-90",
|
|
34
43
|
title: "m-0 max-w-3xl font-display text-4xl font-black leading-[1.05] tracking-tight sm:text-5xl lg:text-6xl",
|
|
35
44
|
lead: "m-0 max-w-2xl text-base leading-relaxed opacity-95 sm:text-lg",
|
|
36
45
|
facts: "flex flex-wrap items-center gap-2",
|
package/dist/cover-hero.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cover-hero/cover-hero.tsx","../src/page/page.tsx"],"sourcesContent":["// Client (the reader's motion preference). The first screen of a shop or a place: its cover — a photo, or a muted loop that\n// stays a still under reduced motion — behind the name, a one-line promise, a few facts and the main action. The words sit\n// on a veil that reads in both themes; without a cover the brand's colours take its place.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { BlockLink, type LinkComponent } from \"../block-link\";\nimport { ArrowGlyph } from \"../glyphs\";\nimport { Page } from \"../page/page\";\n\nexport const coverHero = tv({\n slots: {\n root: \"relative isolate flex min-h-[26rem] items-end overflow-hidden bg-surface-1 text-fg data-[cover]:text-fg-on-media sm:min-h-[30rem] lg:min-h-[34rem]\",\n media: \"absolute inset-0 -z-20 h-full w-full object-cover\",\n veil: \"absolute inset-0 -z-10 bg-linear-to-t from-scrim-strong via-scrim/55 to-scrim/10\",\n plain: \"absolute inset-0 -z-10 bg-linear-to-br from-accent/25 via-surface-1 to-accent-2/20\",\n body: \"flex flex-col gap-4 pb-8 pt-24 sm:pb-12\",\n back: \"inline-flex w-fit items-center gap-1.5 text-sm font-semibold text-current no-underline opacity-90 hover:opacity-100\",\n eyebrow: \"m-0 font-mono text-xs font-semibold uppercase tracking-widest opacity-90\",\n title: \"m-0 max-w-3xl font-display text-4xl font-black leading-[1.05] tracking-tight sm:text-5xl lg:text-6xl\",\n lead: \"m-0 max-w-2xl text-base leading-relaxed opacity-95 sm:text-lg\",\n facts: \"flex flex-wrap items-center gap-2\",\n actions: \"flex flex-wrap items-center gap-3 pt-1\",\n },\n});\nconst s = coverHero();\n\nexport type CoverMedia = {\n /** The still: the photo, or the poster of the loop (shown first, and alone under reduced motion). */\n src: string;\n /** What it shows, in words; empty when it only decorates. */\n alt?: string;\n /** A muted loop over the still: WebM first, MP4 for Safari. */\n video?: { webm?: string; mp4?: string };\n};\n\nexport type CoverHeroProps = Omit<React.ComponentProps<\"header\">, \"title\"> & {\n /** The cover. Without it the hero wears the brand's colours. */\n cover?: CoverMedia;\n /** A short mono line above the name (where the shop is: `Saint-Henri · Montréal`). */\n eyebrow?: React.ReactNode;\n /** The name: the page's `h1`. */\n title: React.ReactNode;\n /** One line: what it promises. */\n lead?: React.ReactNode;\n /** Chips under the lead: open now, the neighbourhood, a rating — only what is true. */\n facts?: React.ReactNode;\n /** The main action (`ButtonLink`). */\n actions?: React.ReactNode;\n /** The way back, above the eyebrow. */\n back?: { href: string; label: string };\n /** The app's link component for the back link. */\n linkAs?: LinkComponent;\n};\n\nfunction usePlayLoop(enabled: boolean) {\n const [play, setPlay] = React.useState(false);\n React.useEffect(() => {\n if (!enabled) return;\n const q = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const sync = () => setPlay(!q.matches);\n sync();\n q.addEventListener(\"change\", sync);\n return () => q.removeEventListener(\"change\", sync);\n }, [enabled]);\n return play;\n}\n\n/** A shop's first screen: the cover, the name, the promise, the facts and the main action. */\nexport function CoverHero({ cover, eyebrow, title, lead, facts, actions, back, linkAs, className, ...props }: CoverHeroProps) {\n const play = usePlayLoop(Boolean(cover?.video));\n return (\n <header data-cover={cover ? \"\" : undefined} className={s.root({ className })} {...props}>\n {cover ? (\n <>\n <img src={cover.src} alt={cover.alt ?? \"\"} className={s.media()} fetchPriority=\"high\" decoding=\"async\" />\n {play && cover.video && (\n <video className={s.media()} poster={cover.src} autoPlay muted loop playsInline preload=\"metadata\" aria-hidden tabIndex={-1}>\n {cover.video.webm && <source src={cover.video.webm} type=\"video/webm\" />}\n {cover.video.mp4 && <source src={cover.video.mp4} type=\"video/mp4\" />}\n </video>\n )}\n <div aria-hidden className={s.veil()} />\n </>\n ) : (\n <div aria-hidden className={s.plain()} />\n )}\n <Page>\n <div className={s.body()}>\n {back && (\n <BlockLink href={back.href} linkAs={linkAs} className={s.back()}>\n <ArrowGlyph direction=\"left\" className=\"h-3.5 w-3.5\" /> {back.label}\n </BlockLink>\n )}\n {eyebrow && <p className={s.eyebrow()}>{eyebrow}</p>}\n <h1 className={s.title()}>{title}</h1>\n {lead && <p className={s.lead()}>{lead}</p>}\n {facts && <div className={s.facts()}>{facts}</div>}\n {actions && <div className={s.actions()}>{actions}</div>}\n </div>\n </Page>\n </header>\n );\n}\n","// 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 data-size={size === \"default\" ? undefined : size} className={cn(\"kz-frame\", className)} {...props} />;\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 mono line above the title (the section's subject). */\n eyebrow?: 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, 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 {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 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};\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 title,\n lead,\n actions,\n headingSize,\n headingAlign,\n reveal,\n divider,\n spacing = \"md\",\n size,\n backdrop,\n className,\n children,\n ...props\n}: SectionProps) {\n const body = (\n <Page size={size}>\n {title && <SectionHeading id={id} eyebrow={eyebrow} 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 ...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"],"mappings":"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","names":["React","Fragment","Fragment","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/cover-hero/cover-hero.tsx","../src/page/page.tsx"],"sourcesContent":["// Client (the reader's motion preference). The first screen of a shop or a place: its cover — a photo, or a muted loop that\n// stays a still under reduced motion — behind the name, a one-line promise, a few facts and the main action. The words sit\n// on a veil that reads in both themes; without a cover the brand's colours take its place.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { BlockLink, type LinkComponent } from \"../block-link\";\nimport { ArrowGlyph } from \"../glyphs\";\nimport { Page } from \"../page/page\";\n\nexport const coverHero = tv({\n slots: {\n root: \"relative isolate flex min-h-[26rem] items-end overflow-hidden bg-surface-1 text-fg data-[cover]:text-fg-on-media sm:min-h-[30rem] lg:min-h-[34rem]\",\n media: \"absolute inset-0 -z-20 h-full w-full object-cover\",\n veil: \"absolute inset-0 -z-10 bg-linear-to-t from-scrim-strong via-scrim/55 to-scrim/10\",\n plain: \"absolute inset-0 -z-10 bg-linear-to-br from-accent/25 via-surface-1 to-accent-2/20\",\n body: \"flex flex-col gap-4 pb-8 pt-24 sm:pb-12\",\n back: \"inline-flex w-fit items-center gap-1.5 text-sm font-semibold text-current no-underline opacity-90 hover:opacity-100\",\n eyebrow: \"m-0 font-mono text-xs font-semibold opacity-90\",\n title: \"m-0 max-w-3xl font-display text-4xl font-black leading-[1.05] tracking-tight sm:text-5xl lg:text-6xl\",\n lead: \"m-0 max-w-2xl text-base leading-relaxed opacity-95 sm:text-lg\",\n facts: \"flex flex-wrap items-center gap-2\",\n actions: \"flex flex-wrap items-center gap-3 pt-1\",\n },\n});\nconst s = coverHero();\n\nexport type CoverMedia = {\n /** The still: the photo, or the poster of the loop (shown first, and alone under reduced motion). */\n src: string;\n /** What it shows, in words; empty when it only decorates. */\n alt?: string;\n /** A muted loop over the still: WebM first, MP4 for Safari. */\n video?: { webm?: string; mp4?: string };\n};\n\nexport type CoverHeroProps = Omit<React.ComponentProps<\"header\">, \"title\"> & {\n /** The cover. Without it the hero wears the brand's colours. */\n cover?: CoverMedia;\n /** A short mono line above the name (where the shop is: `Saint-Henri · Montréal`). */\n eyebrow?: React.ReactNode;\n /** The name: the page's `h1`. */\n title: React.ReactNode;\n /** One line: what it promises. */\n lead?: React.ReactNode;\n /** Chips under the lead: open now, the neighbourhood, a rating — only what is true. */\n facts?: React.ReactNode;\n /** The main action (`ButtonLink`). */\n actions?: React.ReactNode;\n /** The way back, above the eyebrow. */\n back?: { href: string; label: string };\n /** The app's link component for the back link. */\n linkAs?: LinkComponent;\n};\n\nfunction usePlayLoop(enabled: boolean) {\n const [play, setPlay] = React.useState(false);\n React.useEffect(() => {\n if (!enabled) return;\n const q = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const sync = () => setPlay(!q.matches);\n sync();\n q.addEventListener(\"change\", sync);\n return () => q.removeEventListener(\"change\", sync);\n }, [enabled]);\n return play;\n}\n\n/** A shop's first screen: the cover, the name, the promise, the facts and the main action. */\nexport function CoverHero({ cover, eyebrow, title, lead, facts, actions, back, linkAs, className, ...props }: CoverHeroProps) {\n const play = usePlayLoop(Boolean(cover?.video));\n return (\n <header data-cover={cover ? \"\" : undefined} className={s.root({ className })} {...props}>\n {cover ? (\n <>\n <img src={cover.src} alt={cover.alt ?? \"\"} className={s.media()} fetchPriority=\"high\" decoding=\"async\" />\n {play && cover.video && (\n <video className={s.media()} poster={cover.src} autoPlay muted loop playsInline preload=\"metadata\" aria-hidden tabIndex={-1}>\n {cover.video.webm && <source src={cover.video.webm} type=\"video/webm\" />}\n {cover.video.mp4 && <source src={cover.video.mp4} type=\"video/mp4\" />}\n </video>\n )}\n <div aria-hidden className={s.veil()} />\n </>\n ) : (\n <div aria-hidden className={s.plain()} />\n )}\n <Page>\n <div className={s.body()}>\n {back && (\n <BlockLink href={back.href} linkAs={linkAs} className={s.back()}>\n <ArrowGlyph direction=\"left\" className=\"h-3.5 w-3.5\" /> {back.label}\n </BlockLink>\n )}\n {eyebrow && <p className={s.eyebrow()}>{eyebrow}</p>}\n <h1 className={s.title()}>{title}</h1>\n {lead && <p className={s.lead()}>{lead}</p>}\n {facts && <div className={s.facts()}>{facts}</div>}\n {actions && <div className={s.actions()}>{actions}</div>}\n </div>\n </Page>\n </header>\n );\n}\n","// 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"],"mappings":";;;;;;;;;;;;AAGA,YAAYA,YAAW;AACvB,SAAS,UAAU;;;ACFnB,YAAY,WAAW;AA+BnB,SAuKA,YAAAC,WAvKA,KA8CA,YA9CA;AAFG,SAAS,KAAK,EAAE,OAAO,WAAW,IAAI,MAAM,OAAO,OAAO,QAAQ,WAAW,GAAG,MAAM,GAAc;AACzG,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAW,SAAS,YAAY,SAAY;AAAA,MAC5C,cAAY;AAAA,MACZ,eAAa,SAAS,KAAK;AAAA,MAC3B,WAAW,GAAG,YAAY,SAAS;AAAA,MAClC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ADiCQ,qBAAAC,WACE,OAAAC,MAEE,QAAAC,aAHJ;AAhED,IAAM,YAAY,GAAG;AAAA,EAC1B,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,EACX;AACF,CAAC;AACD,IAAM,IAAI,UAAU;AA8BpB,SAAS,YAAY,SAAkB;AACrC,QAAM,CAAC,MAAM,OAAO,IAAU,gBAAS,KAAK;AAC5C,EAAM,iBAAU,MAAM;AACpB,QAAI,CAAC,QAAS;AACd,UAAM,IAAI,OAAO,WAAW,kCAAkC;AAC9D,UAAM,OAAO,MAAM,QAAQ,CAAC,EAAE,OAAO;AACrC,SAAK;AACL,MAAE,iBAAiB,UAAU,IAAI;AACjC,WAAO,MAAM,EAAE,oBAAoB,UAAU,IAAI;AAAA,EACnD,GAAG,CAAC,OAAO,CAAC;AACZ,SAAO;AACT;AAGO,SAAS,UAAU,EAAE,OAAO,SAAS,OAAO,MAAM,OAAO,SAAS,MAAM,QAAQ,WAAW,GAAG,MAAM,GAAmB;AAC5H,QAAM,OAAO,YAAY,QAAQ,OAAO,KAAK,CAAC;AAC9C,SACE,gBAAAA,MAAC,YAAO,cAAY,QAAQ,KAAK,QAAW,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAC/E;AAAA,YACC,gBAAAA,MAAAF,WAAA,EACE;AAAA,sBAAAC,KAAC,SAAI,KAAK,MAAM,KAAK,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,MAAM,GAAG,eAAc,QAAO,UAAS,SAAQ;AAAA,MACtG,QAAQ,MAAM,SACb,gBAAAC,MAAC,WAAM,WAAW,EAAE,MAAM,GAAG,QAAQ,MAAM,KAAK,UAAQ,MAAC,OAAK,MAAC,MAAI,MAAC,aAAW,MAAC,SAAQ,YAAW,eAAW,MAAC,UAAU,IACtH;AAAA,cAAM,MAAM,QAAQ,gBAAAD,KAAC,YAAO,KAAK,MAAM,MAAM,MAAM,MAAK,cAAa;AAAA,QACrE,MAAM,MAAM,OAAO,gBAAAA,KAAC,YAAO,KAAK,MAAM,MAAM,KAAK,MAAK,aAAY;AAAA,SACrE;AAAA,MAEF,gBAAAA,KAAC,SAAI,eAAW,MAAC,WAAW,EAAE,KAAK,GAAG;AAAA,OACxC,IAEA,gBAAAA,KAAC,SAAI,eAAW,MAAC,WAAW,EAAE,MAAM,GAAG;AAAA,IAEzC,gBAAAA,KAAC,QACC,0BAAAC,MAAC,SAAI,WAAW,EAAE,KAAK,GACpB;AAAA,cACC,gBAAAA,MAAC,aAAU,MAAM,KAAK,MAAM,QAAgB,WAAW,EAAE,KAAK,GAC5D;AAAA,wBAAAD,KAAC,cAAW,WAAU,QAAO,WAAU,eAAc;AAAA,QAAE;AAAA,QAAE,KAAK;AAAA,SAChE;AAAA,MAED,WAAW,gBAAAA,KAAC,OAAE,WAAW,EAAE,QAAQ,GAAI,mBAAQ;AAAA,MAChD,gBAAAA,KAAC,QAAG,WAAW,EAAE,MAAM,GAAI,iBAAM;AAAA,MAChC,QAAQ,gBAAAA,KAAC,OAAE,WAAW,EAAE,KAAK,GAAI,gBAAK;AAAA,MACtC,SAAS,gBAAAA,KAAC,SAAI,WAAW,EAAE,MAAM,GAAI,iBAAM;AAAA,MAC3C,WAAW,gBAAAA,KAAC,SAAI,WAAW,EAAE,QAAQ,GAAI,mBAAQ;AAAA,OACpD,GACF;AAAA,KACF;AAEJ;","names":["React","Fragment","Fragment","jsx","jsxs"]}
|
package/dist/dashboard-layout.js
CHANGED
|
@@ -7,7 +7,7 @@ var dashboardLayout = tv({
|
|
|
7
7
|
root: "flex w-full flex-col gap-6",
|
|
8
8
|
head: "flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between",
|
|
9
9
|
text: "flex min-w-0 flex-col gap-1",
|
|
10
|
-
eyebrow: "font-mono text-[11px] font-semibold
|
|
10
|
+
eyebrow: "font-mono text-[11px] font-semibold text-fg-accent",
|
|
11
11
|
title: "font-display text-2xl font-extrabold tracking-tight text-fg sm:text-[1.75rem]",
|
|
12
12
|
description: "max-w-2xl text-sm text-fg-secondary",
|
|
13
13
|
actions: "flex shrink-0 flex-wrap items-center gap-2",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dashboard-layout/dashboard-layout.tsx"],"sourcesContent":["// Server-safe. A dashboard, read from the products' home screens (Orochia's creator studio, Orazaka's console for\n// Eric): the screen's heading with its actions and filters, then a responsive grid of widgets — one column on a phone,\n// two from `sm`, four from `xl`; a widget spans 1, 2, 3 columns or the full row, and keeps its order everywhere.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const dashboardLayout = tv({\n slots: {\n root: \"flex w-full flex-col gap-6\",\n head: \"flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between\",\n text: \"flex min-w-0 flex-col gap-1\",\n eyebrow: \"font-mono text-[11px] font-semibold
|
|
1
|
+
{"version":3,"sources":["../src/dashboard-layout/dashboard-layout.tsx"],"sourcesContent":["// Server-safe. A dashboard, read from the products' home screens (Orochia's creator studio, Orazaka's console for\n// Eric): the screen's heading with its actions and filters, then a responsive grid of widgets — one column on a phone,\n// two from `sm`, four from `xl`; a widget spans 1, 2, 3 columns or the full row, and keeps its order everywhere.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const dashboardLayout = tv({\n slots: {\n root: \"flex w-full flex-col gap-6\",\n head: \"flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between\",\n text: \"flex min-w-0 flex-col gap-1\",\n eyebrow: \"font-mono text-[11px] font-semibold text-fg-accent\",\n title: \"font-display text-2xl font-extrabold tracking-tight text-fg sm:text-[1.75rem]\",\n description: \"max-w-2xl text-sm text-fg-secondary\",\n actions: \"flex shrink-0 flex-wrap items-center gap-2\",\n toolbar: \"flex flex-wrap items-center gap-2\",\n grid: \"grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4\",\n widget: \"flex min-w-0 flex-col gap-3 rounded-xl border border-border-default bg-surface-1 p-4 sm:p-5\",\n widgetHead: \"flex items-start justify-between gap-3\",\n widgetTitle: \"text-sm font-semibold text-fg\",\n widgetDescription: \"mt-0.5 text-xs text-fg-secondary\",\n widgetBody: \"min-w-0 flex-1\",\n },\n variants: {\n span: {\n 1: { widget: \"\" },\n 2: { widget: \"sm:col-span-2\" },\n 3: { widget: \"sm:col-span-2 xl:col-span-3\" },\n full: { widget: \"sm:col-span-2 xl:col-span-4\" },\n },\n },\n defaultVariants: { span: 1 },\n});\nconst s = dashboardLayout();\n\nexport type DashboardLayoutProps = Omit<React.ComponentProps<\"div\">, \"title\"> & {\n /** The screen's title: `Good morning, Eric`. */\n title: React.ReactNode;\n /** A mono line above it (the workspace, the date). */\n eyebrow?: React.ReactNode;\n /** One sentence under it. */\n description?: React.ReactNode;\n /** The screen's actions (a primary Button, a DropdownMenu). */\n actions?: React.ReactNode;\n /** Under the heading: the period, the filters (Segmented tabs, a DateRangePicker, a FilterBar). */\n toolbar?: React.ReactNode;\n /**\n * The heading's level: `h1` when the dashboard is the screen, `h2` inside an AppShell whose header holds the h1.\n * @default \"h1\"\n */\n headingAs?: \"h1\" | \"h2\";\n /** The widgets (`Widget`), in reading order. */\n children: React.ReactNode;\n};\n\n/** A dashboard screen: heading, actions, filters, then the grid of widgets. */\nexport function DashboardLayout({ title, eyebrow, description, actions, toolbar, headingAs: H = \"h1\", className, children, ...props }: DashboardLayoutProps) {\n return (\n <div className={s.root({ className })} {...props}>\n <div className={s.head()}>\n <div className={s.text()}>\n {eyebrow && <p className={s.eyebrow()}>{eyebrow}</p>}\n <H className={s.title()}>{title}</H>\n {description && <p className={s.description()}>{description}</p>}\n </div>\n {actions && <div className={s.actions()}>{actions}</div>}\n </div>\n {toolbar && <div className={s.toolbar()}>{toolbar}</div>}\n <div className={s.grid()}>{children}</div>\n </div>\n );\n}\n\nexport type WidgetProps = Omit<React.ComponentProps<\"section\">, \"title\"> & {\n /** The widget's title: it names the region. */\n title: React.ReactNode;\n /** One line under the title (the period, the source). */\n description?: React.ReactNode;\n /** An action on the right of the title (`See all`). */\n action?: React.ReactNode;\n /**\n * The columns it takes: 1, 2, 3 or the full row (from `sm`; one column on a phone).\n * @default 1\n */\n span?: 1 | 2 | 3 | \"full\";\n /**\n * The title's level: one under the dashboard's heading — `2` under an `h1`, `3` inside an AppShell (`headingAs=\"h2\"`).\n * @default 2\n */\n level?: 2 | 3;\n /** The content: a Stat, a chart of @krizaka/charts, a DataTable, a list. */\n children: React.ReactNode;\n};\n\n/** A widget of the dashboard: a titled region on a card. */\nexport function Widget({ title, description, action, span = 1, level = 2, className, children, id, ...props }: WidgetProps) {\n const H = level === 2 ? \"h2\" : \"h3\";\n const sv = dashboardLayout({ span });\n const auto = React.useId();\n const titleId = `${id ?? auto}-title`;\n return (\n <section className={sv.widget({ className })} aria-labelledby={titleId} id={id} {...props}>\n <div className={s.widgetHead()}>\n <div className=\"min-w-0\">\n <H id={titleId} className={s.widgetTitle()}>\n {title}\n </H>\n {description && <p className={s.widgetDescription()}>{description}</p>}\n </div>\n {action}\n </div>\n <div className={s.widgetBody()}>{children}</div>\n </section>\n );\n}\n"],"mappings":";AAGA,YAAY,WAAW;AACvB,SAAS,UAAU;AAwDX,SACc,KADd;AAtDD,IAAM,kBAAkB,GAAG;AAAA,EAChC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,mBAAmB;AAAA,IACnB,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,GAAG,EAAE,QAAQ,GAAG;AAAA,MAChB,GAAG,EAAE,QAAQ,gBAAgB;AAAA,MAC7B,GAAG,EAAE,QAAQ,8BAA8B;AAAA,MAC3C,MAAM,EAAE,QAAQ,8BAA8B;AAAA,IAChD;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,MAAM,EAAE;AAC7B,CAAC;AACD,IAAM,IAAI,gBAAgB;AAuBnB,SAAS,gBAAgB,EAAE,OAAO,SAAS,aAAa,SAAS,SAAS,WAAW,IAAI,MAAM,WAAW,UAAU,GAAG,MAAM,GAAyB;AAC3J,SACE,qBAAC,SAAI,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OACzC;AAAA,yBAAC,SAAI,WAAW,EAAE,KAAK,GACrB;AAAA,2BAAC,SAAI,WAAW,EAAE,KAAK,GACpB;AAAA,mBAAW,oBAAC,OAAE,WAAW,EAAE,QAAQ,GAAI,mBAAQ;AAAA,QAChD,oBAAC,KAAE,WAAW,EAAE,MAAM,GAAI,iBAAM;AAAA,QAC/B,eAAe,oBAAC,OAAE,WAAW,EAAE,YAAY,GAAI,uBAAY;AAAA,SAC9D;AAAA,MACC,WAAW,oBAAC,SAAI,WAAW,EAAE,QAAQ,GAAI,mBAAQ;AAAA,OACpD;AAAA,IACC,WAAW,oBAAC,SAAI,WAAW,EAAE,QAAQ,GAAI,mBAAQ;AAAA,IAClD,oBAAC,SAAI,WAAW,EAAE,KAAK,GAAI,UAAS;AAAA,KACtC;AAEJ;AAwBO,SAAS,OAAO,EAAE,OAAO,aAAa,QAAQ,OAAO,GAAG,QAAQ,GAAG,WAAW,UAAU,IAAI,GAAG,MAAM,GAAgB;AAC1H,QAAM,IAAI,UAAU,IAAI,OAAO;AAC/B,QAAM,KAAK,gBAAgB,EAAE,KAAK,CAAC;AACnC,QAAM,OAAa,YAAM;AACzB,QAAM,UAAU,GAAG,MAAM,IAAI;AAC7B,SACE,qBAAC,aAAQ,WAAW,GAAG,OAAO,EAAE,UAAU,CAAC,GAAG,mBAAiB,SAAS,IAAS,GAAG,OAClF;AAAA,yBAAC,SAAI,WAAW,EAAE,WAAW,GAC3B;AAAA,2BAAC,SAAI,WAAU,WACb;AAAA,4BAAC,KAAE,IAAI,SAAS,WAAW,EAAE,YAAY,GACtC,iBACH;AAAA,QACC,eAAe,oBAAC,OAAE,WAAW,EAAE,kBAAkB,GAAI,uBAAY;AAAA,SACpE;AAAA,MACC;AAAA,OACH;AAAA,IACA,oBAAC,SAAI,WAAW,EAAE,WAAW,GAAI,UAAS;AAAA,KAC5C;AAEJ;","names":[]}
|
package/dist/data-table.js
CHANGED
|
@@ -9,17 +9,17 @@ import {
|
|
|
9
9
|
dataTableCsv,
|
|
10
10
|
dataTableLabels,
|
|
11
11
|
useDataTable
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-K2ZYB4HP.js";
|
|
13
|
+
import "./chunk-YGIN2YIY.js";
|
|
14
14
|
import "./chunk-JXLDUDTD.js";
|
|
15
15
|
import "./chunk-3DHNN5V7.js";
|
|
16
16
|
import "./chunk-KVDB4GXV.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-YOTQD7JD.js";
|
|
18
18
|
import "./chunk-7UCPGXKN.js";
|
|
19
19
|
import "./chunk-D3T54RSL.js";
|
|
20
20
|
import "./chunk-J3NC6ER4.js";
|
|
21
21
|
import "./chunk-NSLXEDIS.js";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-7NRSPHAF.js";
|
|
23
23
|
import "./chunk-ZIXB33X7.js";
|
|
24
24
|
import "./chunk-FZBWEDQI.js";
|
|
25
25
|
import "./chunk-CPA5CF35.js";
|