@krizaka/ui 3.53.0 → 3.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/account-menu.d.ts +6 -2
- package/dist/account-menu.js +8 -1
- package/dist/account-menu.js.map +1 -1
- package/dist/account-settings.js +28 -88
- package/dist/account-settings.js.map +1 -1
- package/dist/anatomy-plate.d.ts +4 -1
- package/dist/anatomy-plate.js +4 -0
- package/dist/anatomy-plate.js.map +1 -1
- package/dist/app-header/search.d.ts +63 -0
- package/dist/app-header/search.js +70 -0
- package/dist/app-header/search.js.map +1 -0
- package/dist/app-header.d.ts +88 -4
- package/dist/app-header.js +63 -5
- package/dist/app-header.js.map +1 -1
- package/dist/app-shell.js +31 -40
- package/dist/app-shell.js.map +1 -1
- package/dist/argument-card.js +3 -3
- package/dist/bird-plate.d.ts +3 -1
- package/dist/bird-plate.js +2 -2
- package/dist/bird-plate.js.map +1 -1
- package/dist/blocks.css +202 -27
- package/dist/chapter.d.ts +20 -3
- package/dist/chapter.js +82 -31
- package/dist/chapter.js.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/chat.js.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/chip.js +5 -98
- package/dist/chip.js.map +1 -1
- package/dist/choice-grid.js +28 -88
- package/dist/choice-grid.js.map +1 -1
- package/dist/{chunk-YGIN2YIY.js → chunk-3X3OF4TI.js} +2 -2
- package/dist/chunk-3X3OF4TI.js.map +1 -0
- package/dist/chunk-5VEVYDVC.js +11 -0
- package/dist/chunk-5VEVYDVC.js.map +1 -0
- package/dist/chunk-7U5TXA5Q.js +105 -0
- package/dist/chunk-7U5TXA5Q.js.map +1 -0
- package/dist/{chunk-KBQD6HE3.js → chunk-AEP3K4YD.js} +3 -3
- package/dist/{chunk-KBQD6HE3.js.map → chunk-AEP3K4YD.js.map} +1 -1
- package/dist/chunk-BDIU5LZB.js +18 -0
- package/dist/chunk-BDIU5LZB.js.map +1 -0
- package/dist/chunk-CSRKYZ53.js +39 -0
- package/dist/chunk-CSRKYZ53.js.map +1 -0
- package/dist/chunk-HEKDKM5Y.js +128 -0
- package/dist/chunk-HEKDKM5Y.js.map +1 -0
- package/dist/chunk-KGLRZMCY.js +16 -0
- package/dist/chunk-KGLRZMCY.js.map +1 -0
- package/dist/chunk-KID32IRJ.js +18 -0
- package/dist/chunk-KID32IRJ.js.map +1 -0
- package/dist/{chunk-ZQW7LF4Y.js → chunk-OIMXKRXF.js} +2 -2
- package/dist/{chunk-YHKTYFOQ.js → chunk-QWKCNSPF.js} +271 -47
- package/dist/chunk-QWKCNSPF.js.map +1 -0
- package/dist/{chunk-4LYKBSOG.js → chunk-USPOIQV5.js} +2 -2
- package/dist/chunk-USPOIQV5.js.map +1 -0
- package/dist/{chunk-7NRSPHAF.js → chunk-VB7MWE2N.js} +2 -2
- package/dist/{chunk-7NRSPHAF.js.map → chunk-VB7MWE2N.js.map} +1 -1
- package/dist/chunk-VIPSZXO4.js +103 -0
- package/dist/chunk-VIPSZXO4.js.map +1 -0
- package/dist/chunk-YCZ7N6Q6.js +385 -0
- package/dist/chunk-YCZ7N6Q6.js.map +1 -0
- package/dist/code-block.js +81 -98
- package/dist/code-block.js.map +1 -1
- package/dist/combobox.js +2 -2
- package/dist/component-page.d.ts +4 -1
- package/dist/component-page.js +5 -0
- package/dist/component-page.js.map +1 -1
- package/dist/continue-prompt.d.ts +4 -1
- package/dist/continue-prompt.js +4 -0
- package/dist/continue-prompt.js.map +1 -1
- package/dist/data-table.d.ts +60 -4
- package/dist/data-table.js +19 -7
- package/dist/date-picker.js +2 -2
- package/dist/date-picker.js.map +1 -1
- package/dist/detail-layout.d.ts +28 -17
- package/dist/detail-layout.js +73 -16
- package/dist/detail-layout.js.map +1 -1
- package/dist/doodle.d.ts +21 -0
- package/dist/doodle.js +39 -0
- package/dist/doodle.js.map +1 -0
- package/dist/drop-overlay.d.ts +12 -4
- package/dist/drop-overlay.js +16 -6
- package/dist/drop-overlay.js.map +1 -1
- package/dist/elephant.d.ts +2 -0
- package/dist/elephant.js +4 -0
- package/dist/elephant.js.map +1 -1
- package/dist/field.js +1 -1
- package/dist/field.js.map +1 -1
- package/dist/filter-bar.js +2 -2
- package/dist/force-update-screen.d.ts +5 -1
- package/dist/force-update-screen.js +4 -0
- package/dist/force-update-screen.js.map +1 -1
- package/dist/gallery-page.d.ts +4 -1
- package/dist/gallery-page.js +4 -0
- package/dist/gallery-page.js.map +1 -1
- package/dist/genui.js +5 -5
- package/dist/image-cropper.d.ts +10 -2
- package/dist/image-cropper.js +4 -0
- package/dist/image-cropper.js.map +1 -1
- package/dist/kanban.d.ts +3 -0
- package/dist/kanban.js +4 -0
- package/dist/kanban.js.map +1 -1
- package/dist/landscape.d.ts +4 -1
- package/dist/landscape.js +4 -0
- package/dist/landscape.js.map +1 -1
- package/dist/list.js +1 -1
- package/dist/maintenance-screen.d.ts +5 -1
- package/dist/maintenance-screen.js +4 -0
- package/dist/maintenance-screen.js.map +1 -1
- package/dist/map.js +6 -0
- package/dist/map.js.map +1 -1
- package/dist/markdown.d.ts +5 -1
- package/dist/markdown.js +12 -5
- package/dist/markdown.js.map +1 -1
- package/dist/match-dialog.d.ts +4 -1
- package/dist/match-dialog.js +4 -0
- package/dist/match-dialog.js.map +1 -1
- package/dist/media-capture.d.ts +6 -1
- package/dist/media-capture.js +4 -0
- package/dist/media-capture.js.map +1 -1
- package/dist/meter.js +5 -121
- package/dist/meter.js.map +1 -1
- package/dist/native/map.js +6 -0
- package/dist/native/map.js.map +1 -1
- package/dist/native/markdown.d.ts +9 -2
- package/dist/native/markdown.js +46 -7
- package/dist/native/markdown.js.map +1 -1
- package/dist/native/media-capture.d.ts +1 -0
- package/dist/native/media-capture.js +5 -0
- package/dist/native/media-capture.js.map +1 -1
- package/dist/native/vertical-video.d.ts +8 -2
- package/dist/native/vertical-video.js +6 -0
- package/dist/native/vertical-video.js.map +1 -1
- package/dist/native.d.ts +94 -4
- package/dist/native.js +1236 -1110
- package/dist/native.js.map +1 -1
- package/dist/nav-bar/me.d.ts +32 -0
- package/dist/nav-bar/me.js +23 -0
- package/dist/nav-bar/me.js.map +1 -0
- package/dist/nav-bar.d.ts +60 -2
- package/dist/nav-bar.js +92 -48
- package/dist/nav-bar.js.map +1 -1
- package/dist/notification-preferences.d.ts +151 -0
- package/dist/notification-preferences.js +77 -0
- package/dist/notification-preferences.js.map +1 -0
- package/dist/page-header.js +1 -1
- package/dist/page-header.js.map +1 -1
- package/dist/pointer-light.js +5 -0
- package/dist/pointer-light.js.map +1 -1
- package/dist/product-page.d.ts +4 -1
- package/dist/product-page.js +4 -0
- package/dist/product-page.js.map +1 -1
- package/dist/profile-card.d.ts +119 -1
- package/dist/profile-card.js +68 -21
- package/dist/profile-card.js.map +1 -1
- package/dist/promise-card.d.ts +4 -1
- package/dist/promise-card.js +4 -0
- package/dist/promise-card.js.map +1 -1
- package/dist/quota-meter.d.ts +113 -0
- package/dist/quota-meter.js +58 -0
- package/dist/quota-meter.js.map +1 -0
- package/dist/radio-group.js +6 -8
- package/dist/radio-group.js.map +1 -1
- package/dist/rail-nav.d.ts +18 -2
- package/dist/rail-nav.js +25 -2
- package/dist/rail-nav.js.map +1 -1
- package/dist/retro-tv.d.ts +30 -0
- package/dist/retro-tv.js +124 -0
- package/dist/retro-tv.js.map +1 -0
- package/dist/router.d.ts +12 -1
- package/dist/router.js +85 -8
- package/dist/router.js.map +1 -1
- package/dist/scroll-stage.d.ts +5 -1
- package/dist/scroll-stage.js +5 -0
- package/dist/scroll-stage.js.map +1 -1
- package/dist/search-field.js +1 -1
- package/dist/showcase.d.ts +9 -2
- package/dist/showcase.js +5 -0
- package/dist/showcase.js.map +1 -1
- package/dist/signature.d.ts +19 -0
- package/dist/signature.js +39 -0
- package/dist/signature.js.map +1 -0
- package/dist/site-footer.js +1 -1
- package/dist/sites.js +1 -1
- package/dist/sites.js.map +1 -1
- package/dist/slot.d.ts +1 -1
- package/dist/stat.js +1 -1
- package/dist/stat.js.map +1 -1
- package/dist/status-page.d.ts +4 -1
- package/dist/status-page.js +5 -0
- package/dist/status-page.js.map +1 -1
- package/dist/stuck.d.ts +27 -0
- package/dist/stuck.js +26 -0
- package/dist/stuck.js.map +1 -0
- package/dist/swipe-deck.d.ts +9 -2
- package/dist/swipe-deck.js +5 -0
- package/dist/swipe-deck.js.map +1 -1
- package/dist/switch.js +4 -32
- package/dist/switch.js.map +1 -1
- package/dist/tabs.d.ts +47 -8
- package/dist/tabs.js +62 -12
- package/dist/tabs.js.map +1 -1
- package/dist/tag-input.js +2 -2
- package/dist/tag-selector.js +1 -1
- package/dist/terminal-replay.d.ts +4 -1
- package/dist/terminal-replay.js +4 -0
- package/dist/terminal-replay.js.map +1 -1
- package/dist/tree-view.js +4 -0
- package/dist/tree-view.js.map +1 -1
- package/dist/update-prompt.d.ts +5 -1
- package/dist/update-prompt.js +4 -0
- package/dist/update-prompt.js.map +1 -1
- package/dist/video-player.js +7 -376
- package/dist/video-player.js.map +1 -1
- package/dist/video-trimmer.d.ts +6 -1
- package/dist/video-trimmer.js +4 -0
- package/dist/video-trimmer.js.map +1 -1
- package/package.json +143 -31
- package/registry/account-menu.json +9 -8
- package/registry/account-settings.json +2 -2
- package/registry/achievement.json +3 -4
- package/registry/action-bar.json +3 -3
- package/registry/action-sheet.json +1 -0
- package/registry/activity-feed.json +2 -1
- package/registry/agenda.json +1 -1
- package/registry/alert.json +1 -1
- package/registry/anatomy-plate.json +13 -5
- package/registry/app-header.json +470 -23
- 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 +3 -2
- package/registry/badge.json +2 -1
- package/registry/bird-plate.json +16 -2
- package/registry/button.json +7 -6
- package/registry/captcha.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +7 -6
- package/registry/catalogue-page.json +3 -4
- package/registry/changelog-page.json +3 -5
- package/registry/chapter.json +46 -10
- package/registry/chat.json +3 -2
- package/registry/checkbox.json +4 -3
- package/registry/chip-link.json +2 -2
- package/registry/chip-row.json +2 -2
- package/registry/chip.json +3 -2
- package/registry/choice-grid.json +3 -4
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +3 -2
- package/registry/command.json +2 -2
- package/registry/comparison-table.json +1 -1
- package/registry/component-page.json +14 -5
- package/registry/confirm-button.json +4 -4
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +13 -5
- package/registry/countdown.json +4 -3
- package/registry/cover-hero.json +3 -4
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +63 -7
- package/registry/date-picker.json +5 -4
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +2 -1
- package/registry/detail-layout.json +30 -6
- package/registry/dialog.json +7 -6
- package/registry/docs-article-page.json +3 -4
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/docs-nav.json +1 -1
- package/registry/document-viewer.json +3 -5
- package/registry/doodle.json +209 -0
- package/registry/drop-overlay.json +30 -16
- package/registry/dropdown-menu.json +2 -2
- package/registry/elephant.json +15 -7
- package/registry/empty-state.json +2 -1
- package/registry/engine-flow.json +1 -1
- package/registry/error-page.json +3 -5
- package/registry/examples/app-header/family.d.ts +4 -0
- package/registry/examples/app-header/family.js +41 -0
- package/registry/examples/app-header/family.tsx +37 -0
- package/registry/examples/app-header/native/family.d.ts +4 -0
- package/registry/examples/app-header/native/family.dark.png +0 -0
- package/registry/examples/app-header/native/family.js +25 -0
- package/registry/examples/app-header/native/family.light.png +0 -0
- package/registry/examples/app-header/native/family.tsx +33 -0
- package/registry/examples/chapter/album.d.ts +4 -0
- package/registry/examples/chapter/album.js +34 -0
- package/registry/examples/chapter/album.tsx +30 -0
- package/registry/examples/chapter/in-ruled-page.d.ts +4 -0
- package/registry/examples/chapter/in-ruled-page.js +23 -0
- package/registry/examples/chapter/in-ruled-page.tsx +19 -0
- package/registry/examples/data-table/applicant-files.d.ts +4 -0
- package/registry/examples/data-table/applicant-files.js +24 -0
- package/registry/examples/data-table/applicant-files.tsx +23 -0
- package/registry/examples/data-table/checks.d.ts +4 -0
- package/registry/examples/data-table/checks.js +25 -0
- package/registry/examples/data-table/checks.tsx +24 -0
- package/registry/examples/detail-layout/profile.d.ts +4 -0
- package/registry/examples/detail-layout/profile.js +26 -0
- package/registry/examples/detail-layout/profile.tsx +21 -0
- package/registry/examples/doodle/kinds.d.ts +4 -0
- package/registry/examples/doodle/kinds.js +17 -0
- package/registry/examples/doodle/kinds.tsx +14 -0
- package/registry/examples/doodle/margin.d.ts +4 -0
- package/registry/examples/doodle/margin.js +17 -0
- package/registry/examples/doodle/margin.tsx +17 -0
- package/registry/examples/markdown/native/basic.dark.png +0 -0
- package/registry/examples/markdown/native/basic.light.png +0 -0
- package/registry/examples/markdown/native/wide-table.d.ts +4 -0
- package/registry/examples/markdown/native/wide-table.dark.png +0 -0
- package/registry/examples/markdown/native/wide-table.js +23 -0
- package/registry/examples/markdown/native/wide-table.light.png +0 -0
- package/registry/examples/markdown/native/wide-table.tsx +22 -0
- package/registry/examples/markdown/wide-table.d.ts +4 -0
- package/registry/examples/markdown/wide-table.js +28 -0
- package/registry/examples/markdown/wide-table.tsx +23 -0
- package/registry/examples/nav-bar/family-product.js +2 -4
- package/registry/examples/nav-bar/family-product.tsx +3 -5
- package/registry/examples/notification-preferences/default.d.ts +4 -0
- package/registry/examples/notification-preferences/default.js +29 -0
- package/registry/examples/notification-preferences/default.tsx +28 -0
- package/registry/examples/profile-card/banner.d.ts +4 -0
- package/registry/examples/profile-card/banner.js +28 -0
- package/registry/examples/profile-card/banner.tsx +24 -0
- package/registry/examples/profile-card/native/banner.d.ts +4 -0
- package/registry/examples/profile-card/native/banner.dark.png +0 -0
- package/registry/examples/profile-card/native/banner.js +22 -0
- package/registry/examples/profile-card/native/banner.light.png +0 -0
- package/registry/examples/profile-card/native/banner.tsx +18 -0
- package/registry/examples/quota-meter/default.d.ts +4 -0
- package/registry/examples/quota-meter/default.js +26 -0
- package/registry/examples/quota-meter/default.tsx +20 -0
- package/registry/examples/quota-meter/full.d.ts +4 -0
- package/registry/examples/quota-meter/full.js +25 -0
- package/registry/examples/quota-meter/full.tsx +18 -0
- package/registry/examples/rail-nav/shortcuts.d.ts +4 -0
- package/registry/examples/rail-nav/shortcuts.js +49 -0
- package/registry/examples/rail-nav/shortcuts.tsx +40 -0
- package/registry/examples/retro-tv/cabinet.d.ts +4 -0
- package/registry/examples/retro-tv/cabinet.js +12 -0
- package/registry/examples/retro-tv/cabinet.tsx +7 -0
- package/registry/examples/retro-tv/portable.d.ts +4 -0
- package/registry/examples/retro-tv/portable.js +12 -0
- package/registry/examples/retro-tv/portable.tsx +7 -0
- package/registry/examples/signature/both.d.ts +4 -0
- package/registry/examples/signature/both.js +11 -0
- package/registry/examples/signature/both.tsx +6 -0
- package/registry/examples/signature/variants.d.ts +4 -0
- package/registry/examples/signature/variants.js +14 -0
- package/registry/examples/signature/variants.tsx +11 -0
- package/registry/examples/stuck/card.d.ts +4 -0
- package/registry/examples/stuck/card.js +13 -0
- package/registry/examples/stuck/card.tsx +14 -0
- package/registry/examples/stuck/holds.d.ts +4 -0
- package/registry/examples/stuck/holds.js +12 -0
- package/registry/examples/stuck/holds.tsx +16 -0
- package/registry/examples/stuck/tag.d.ts +4 -0
- package/registry/examples/stuck/tag.js +12 -0
- package/registry/examples/stuck/tag.tsx +13 -0
- package/registry/examples/tabs/binder.d.ts +4 -0
- package/registry/examples/tabs/binder.js +22 -0
- package/registry/examples/tabs/binder.tsx +20 -0
- package/registry/examples/tabs/native/binder.d.ts +4 -0
- package/registry/examples/tabs/native/binder.dark.png +0 -0
- package/registry/examples/tabs/native/binder.js +26 -0
- package/registry/examples/tabs/native/binder.light.png +0 -0
- package/registry/examples/tabs/native/binder.tsx +22 -0
- package/registry/fab.json +1 -0
- package/registry/field.json +3 -2
- package/registry/file-upload.json +6 -11
- package/registry/filter-bar.json +2 -2
- package/registry/flock.json +3 -4
- package/registry/footnote.json +2 -3
- package/registry/force-update-screen.json +14 -5
- package/registry/form.json +5 -4
- package/registry/gallery-page.json +14 -5
- package/registry/genui.json +2 -2
- package/registry/glossary-term.json +1 -1
- package/registry/glossary.json +1 -1
- package/registry/glow-card.json +2 -2
- package/registry/goal-gauge.json +2 -1
- package/registry/header.json +1 -0
- package/registry/how-it-works-page.json +3 -5
- package/registry/image-cropper.json +13 -5
- package/registry/image-viewer.json +3 -4
- package/registry/index.json +306 -91
- package/registry/iso.json +1 -1
- package/registry/kanban.json +13 -5
- package/registry/kbd.json +1 -1
- package/registry/kpi-explained.json +2 -2
- package/registry/landing-page.json +3 -5
- package/registry/landscape.json +13 -5
- package/registry/language-switch.json +1 -1
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +1 -1
- package/registry/list.json +2 -1
- package/registry/loader.json +2 -1
- package/registry/longform-page.json +1 -1
- package/registry/maintenance-screen.json +14 -5
- package/registry/map.json +3 -2
- package/registry/markdown.json +86 -9
- 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 +12 -11
- package/registry/mascots.json +2 -1
- package/registry/match-dialog.json +14 -5
- package/registry/media-capture.json +14 -5
- package/registry/media-gallery.json +3 -5
- package/registry/media-grid.json +1 -1
- package/registry/media-picker.json +2 -3
- package/registry/meta-row.json +2 -1
- package/registry/meter.json +4 -3
- package/registry/nav-bar.json +100 -9
- package/registry/next-actions.json +1 -1
- package/registry/notification-preferences.json +250 -0
- package/registry/number-ticker.json +2 -1
- package/registry/onboarding.json +1 -0
- package/registry/opening-hours.json +1 -1
- package/registry/otp-input.json +1 -0
- package/registry/page-header.json +2 -2
- package/registry/page-hero.json +1 -1
- package/registry/page-index.json +1 -1
- package/registry/page.json +3 -3
- package/registry/pagination.json +2 -1
- package/registry/permission-prompt.json +2 -2
- package/registry/photo-grid.json +4 -4
- package/registry/pointer-light.json +6 -2
- package/registry/popover.json +2 -2
- package/registry/pricing-page.json +4 -6
- package/registry/product-page.json +14 -5
- package/registry/profile-card.json +232 -8
- package/registry/progress.json +4 -3
- package/registry/promise-card.json +13 -5
- package/registry/pull-to-refresh.json +1 -0
- package/registry/quota-meter.json +308 -0
- package/registry/radio-group.json +4 -3
- package/registry/rail-nav.json +48 -10
- package/registry/recipes.json +1 -1
- package/registry/retro-tv.json +478 -0
- package/registry/router.json +3 -3
- package/registry/screen.json +1 -0
- package/registry/scroll-stage.json +14 -5
- package/registry/search-field.json +3 -2
- package/registry/section-backdrop.json +1 -1
- package/registry/segmented.json +1 -0
- package/registry/separator.json +2 -2
- package/registry/service-card.json +1 -1
- package/registry/settings-layout.json +2 -1
- package/registry/showcase.json +14 -5
- package/registry/signature.json +185 -0
- package/registry/site-footer.json +3 -3
- package/registry/sites.json +2 -2
- package/registry/skeleton.json +2 -1
- package/registry/skip-link.json +1 -1
- package/registry/slider.json +5 -4
- package/registry/slot-picker.json +1 -1
- package/registry/slot.json +2 -2
- package/registry/specimen-tag.json +1 -1
- package/registry/spinner.json +4 -3
- package/registry/splash-handoff.json +1 -0
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +2 -3
- package/registry/stat.json +2 -2
- package/registry/status-page.json +13 -5
- package/registry/step-progress.json +2 -1
- package/registry/step-showcase.json +3 -5
- package/registry/stepper.json +2 -1
- package/registry/sticky-action.json +1 -1
- package/registry/stuck.json +219 -0
- package/registry/swipe-deck.json +14 -5
- package/registry/swipeable-row.json +1 -0
- package/registry/switch.json +3 -2
- package/registry/tab-bar.json +1 -0
- package/registry/tabs.json +154 -22
- package/registry/tag-input.json +1 -1
- package/registry/tag-selector.json +2 -1
- package/registry/taped-photo.json +1 -1
- package/registry/terminal-replay.json +14 -5
- package/registry/text-style.json +5 -5
- package/registry/theme.json +2 -1
- package/registry/toast.json +2 -1
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +2 -2
- package/registry/tree-view.json +6 -2
- package/registry/txt.json +1 -0
- package/registry/update-prompt.json +14 -5
- package/registry/upload-queue.json +1 -1
- package/registry/verified-badge.json +6 -6
- package/registry/vertical-video.json +8 -3
- package/registry/video-player.json +5 -6
- package/registry/video-trimmer.json +13 -5
- package/registry/virtual.json +2 -2
- package/registry/waveform.json +4 -3
- package/dist/chunk-4LYKBSOG.js.map +0 -1
- package/dist/chunk-HHFWK2HH.js +0 -163
- package/dist/chunk-HHFWK2HH.js.map +0 -1
- package/dist/chunk-R3LTSMS5.js +0 -75
- package/dist/chunk-R3LTSMS5.js.map +0 -1
- package/dist/chunk-YGIN2YIY.js.map +0 -1
- package/dist/chunk-YHKTYFOQ.js.map +0 -1
- /package/dist/{chunk-ZQW7LF4Y.js.map → chunk-OIMXKRXF.js.map} +0 -0
package/dist/chapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chapter/chapter.tsx"],"sourcesContent":["// Server-safe. The chapters of a story on the Cahier (ADR-004, blocks.css, krizaka-ui#617): a sober timeline, never a\n// stack of boxes. The rows sit on the notebook's ruled lines (`data-paper=\"lines\"`, the ruling of `Page`), the number\n// hangs in the margin beside its red rule (`data-margin`), the serif title is the link, the period is quiet.\n// - `ChapterIndex` — the chapters in reading order, one ruled line each (two at most), the latest marked « New »;\n// - `ChapterHead` — the head of a chapter's page: number in the margin, title, one quiet meta line, the standfirst;\n// - `ChapterFoot` — its foot: the previous and next chapters on the lines, then one line back to the story.\n// No border per row, no card, no button: the paper carries the rhythm. Every word arrives as a prop.\nimport type * as React from \"react\";\n\nimport { BlockLink, type LinkComponent } from \"../block-link\";\nimport { cn } from \"../cn\";\n\n/** The notebook under the rows: `lines` (the ruling of `Page`, aligned on the rows) or `false` (the page's own paper). */\ntype ChapterPaper = \"lines\" | false;\n\nexport interface ChapterEntry {\n /** Its number, hung in the margin: `01`, `§ 1`. */\n number: React.ReactNode;\n /** The title, in the serif: the link. */\n title: React.ReactNode;\n /** Where it leads. */\n href: string;\n /** When it happened, quiet on the right (under the title on a phone): `janv. – mars 2026`, or a `<time>`. */\n period?: React.ReactNode;\n /** One more line under the title (what was faced → what was built). Off unless given: the chapter's page says it. */\n detail?: React.ReactNode;\n /** The latest chapter: a small mark after the title, in the hue (`newLabel`). */\n isNew?: boolean;\n /** The page the reader is on. */\n current?: boolean;\n}\n\n/** One ruled row: number in the margin, the title as the link (its hit area the whole row), an aside on the right. */\nfunction ChapterRow({\n number,\n title,\n href,\n aside,\n mark,\n detail,\n current,\n rel,\n linkAs,\n}: {\n number?: React.ReactNode;\n title: React.ReactNode;\n href: string;\n aside?: React.ReactNode;\n mark?: React.ReactNode;\n detail?: React.ReactNode;\n current?: boolean;\n rel?: string;\n linkAs?: LinkComponent;\n}) {\n return (\n <>\n <span className=\"kz-chapter-no\">{number}</span>\n <BlockLink href={href} linkAs={linkAs} rel={rel} className=\"kz-chapter-link\" aria-current={current ? \"page\" : undefined}>\n <span className=\"kz-chapter-title\">{title}</span>\n {mark && (\n <>\n {\" \"}\n <span className=\"kz-chapter-new\">{mark}</span>\n </>\n )}\n </BlockLink>\n {aside && (\n <>\n {/* A space, not a margin: in a narrow column the period runs on after the title, and starts flush when it wraps. */}{\" \"}\n <span className=\"kz-chapter-period\">{aside}</span>\n </>\n )}\n {detail && <span className=\"kz-chapter-detail\">{detail}</span>}\n </>\n );\n}\n\nexport type ChapterIndexProps = Omit<React.OlHTMLAttributes<HTMLOListElement>, \"children\"> & {\n /** The chapters, in reading order. */\n chapters: readonly ChapterEntry[];\n /** The word of the latest chapter's mark. @default \"New\" */\n newLabel?: React.ReactNode;\n /** The accessible name of the list, when no heading names it (`aria-labelledby`). */\n label?: string;\n /** The ruling under the rows. `false` when the page is ruled already and the list starts on its module. @default \"lines\" */\n paper?: ChapterPaper;\n /** The app's router link (Next's `Link`), so internal chapters prefetch. */\n linkAs?: LinkComponent;\n};\n\n/** The chapters of a story as a sober timeline: one ruled line each, the number in the margin, the title the link. */\nexport function ChapterIndex({ chapters, newLabel = \"New\", label, paper = \"lines\", linkAs, className, ...props }: ChapterIndexProps) {\n return (\n // `role=\"list\"`: a list without bullets is still a list to VoiceOver.\n <ol role=\"list\" aria-label={label} data-paper={paper || undefined} data-margin=\"\" className={cn(\"kz-chapters\", className)} {...props}>\n {chapters.map((c, i) => (\n <li key={i} className=\"kz-chapter-row\" data-new={c.isNew ? \"\" : undefined} data-detail={c.detail ? \"\" : undefined}>\n <ChapterRow number={c.number} title={c.title} href={c.href} aside={c.period} mark={c.isNew ? newLabel : undefined} detail={c.detail} current={c.current} linkAs={linkAs} />\n </li>\n ))}\n </ol>\n );\n}\n\nexport type ChapterHeadProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The chapter's number, hung in the margin: `01`, `Chapitre 1`. */\n number: React.ReactNode;\n /** The title: the page's `h1`. */\n title: React.ReactNode;\n /** When it happened: `janv. – mars 2026`. */\n period?: React.ReactNode;\n /** How long it reads: `8 min`. */\n readingTime?: React.ReactNode;\n /** What was faced: the first half of the standfirst. */\n faced?: React.ReactNode;\n /** What was built: its second half, after the arrow. */\n built?: React.ReactNode;\n /** The words a screen reader says before each half (the arrow is drawn, not read): `[\"What I faced\", \"What we built\"]`. */\n versusLabels?: readonly [string, string];\n /** The level of the title. @default 1 */\n level?: 1 | 2;\n};\n\n/** The head of a chapter: the number in the margin, the title, the period and the reading time, the standfirst once. */\nexport function ChapterHead({ number, title, period, readingTime, faced, built, versusLabels, level = 1, className, children, ...props }: ChapterHeadProps) {\n const H = level === 1 ? \"h1\" : \"h2\";\n const meta = [period, readingTime].filter((m) => m !== undefined && m !== null && m !== \"\");\n return (\n <header data-margin=\"\" className={cn(\"kz-chapter-head\", className)} {...props}>\n <p className=\"kz-chapter-no\">{number}</p>\n <H className=\"kz-chapter-head-title\">{title}</H>\n {meta.length > 0 && (\n <p className=\"kz-chapter-meta\">\n {meta.map((m, i) => (\n <span key={i}>\n {i > 0 && <span aria-hidden> · </span>}\n {m}\n </span>\n ))}\n </p>\n )}\n {faced && built && (\n <p className=\"kz-chapter-standfirst\">\n {versusLabels && <span className=\"kz-sr-only\">{versusLabels[0]}, </span>}\n {faced}\n <span className=\"kz-chapter-arrow\" aria-hidden>\n {\" → \"}\n </span>\n {versusLabels && <span className=\"kz-sr-only\">; {versusLabels[1]}, </span>}\n {built}\n </p>\n )}\n {children}\n </header>\n );\n}\n\nexport interface ChapterLink {\n /** Its number, in the margin: `02`. */\n number?: React.ReactNode;\n /** Its title, the link. */\n title: React.ReactNode;\n /** Where it leads. */\n href: string;\n}\n\nexport type ChapterFootProps = Omit<React.HTMLAttributes<HTMLElement>, \"children\"> & {\n /** The chapter before this one (none on the first). */\n previous?: ChapterLink;\n /** The chapter after this one (none on the latest). */\n next?: ChapterLink;\n /** The line back to the story: `{ href: \"/\", label: \"Back to the story\" }`. */\n back?: { href: string; label: React.ReactNode };\n /** The quiet words beside each link. @default { previous: \"Previous\", next: \"Next\" } */\n labels?: { previous: React.ReactNode; next: React.ReactNode };\n /** The accessible name of the navigation. @default \"Chapters\" */\n label?: string;\n /** The ruling under the links. @default \"lines\" */\n paper?: ChapterPaper;\n /** The app's router link (Next's `Link`). */\n linkAs?: LinkComponent;\n};\n\n/** The foot of a chapter: the previous and the next on the ruled lines, then one line back to the story. */\nexport function ChapterFoot({\n previous,\n next,\n back,\n labels = { previous: \"Previous\", next: \"Next\" },\n label = \"Chapters\",\n paper = \"lines\",\n linkAs,\n className,\n ...props\n}: ChapterFootProps) {\n return (\n <nav aria-label={label} data-paper={paper || undefined} data-margin=\"\" className={cn(\"kz-chapters kz-chapter-foot\", className)} {...props}>\n <ul role=\"list\">\n {previous && (\n <li className=\"kz-chapter-row\" data-dir=\"previous\">\n <ChapterRow\n number={previous.number}\n title={previous.title}\n href={previous.href}\n rel=\"prev\"\n linkAs={linkAs}\n aside={\n <>\n <span aria-hidden>← </span>\n {labels.previous}\n </>\n }\n />\n </li>\n )}\n {next && (\n <li className=\"kz-chapter-row\" data-dir=\"next\">\n <ChapterRow\n number={next.number}\n title={next.title}\n href={next.href}\n rel=\"next\"\n linkAs={linkAs}\n aside={\n <>\n {labels.next}\n <span aria-hidden> →</span>\n </>\n }\n />\n </li>\n )}\n </ul>\n {back && (\n <p className=\"kz-chapter-back\">\n <BlockLink href={back.href} linkAs={linkAs} className=\"kz-chapter-back-link\">\n <span aria-hidden>↩ </span>\n {back.label}\n </BlockLink>\n </p>\n )}\n </nav>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/taped-photo/taped-photo.tsx","../src/chapter/chapter.tsx"],"sourcesContent":["// The taped photo of the Cahier (ADR-004, blocks.css): a print stuck in the notebook — slightly tilted, a thin white print\n// border, a soft paper shadow (layered, never a glow), strips of tape. Whatever it holds (an image, a video, a live scene)\n// is its picture; the tilt is a transform, so nothing shifts and the picture keeps its own box. Server-safe: no state.\nimport type * as React from \"react\";\n\nimport { cn } from \"../cn\";\n\nexport type TapedPhotoProps = React.HTMLAttributes<HTMLElement> & {\n /** The picture: an `img`, a `video`, a scene. It fills the print. */\n children: React.ReactNode;\n /** A line written under the picture, on the print. */\n caption?: React.ReactNode;\n /** The tilt in degrees (negative leans left); eased on a phone. @default -1.6 */\n tilt?: number;\n /** Where the tape holds it: two opposite `corners`, one strip at the `top`, or `none`. @default \"corners\" */\n tape?: \"corners\" | \"top\" | \"none\";\n};\n\n/** A print taped in the notebook: tilted, a white border, a paper shadow, tape at two corners or at the top. */\nexport function TapedPhoto({ children, caption, tilt = -1.6, tape = \"corners\", className, style, ...props }: TapedPhotoProps) {\n return (\n <figure\n className={cn(\"kz-taped\", className)}\n data-tape={tape === \"corners\" ? undefined : tape}\n style={{ ...style, [\"--kz-taped-tilt\" as string]: `${tilt}deg` }}\n {...props}\n >\n <div className=\"kz-taped-picture\">{children}</div>\n {caption ? <figcaption className=\"kz-taped-caption\">{caption}</figcaption> : null}\n </figure>\n );\n}\n","// Server-safe. The chapters of a story on the Cahier (ADR-004, blocks.css, krizaka-ui#617): a sober timeline, never a\n// stack of boxes. The rows sit on the notebook's ruled lines (`data-paper=\"lines\"`, the ruling of `Page`), the number\n// hangs in the margin beside its red rule (`data-margin`), the serif title is the link, the period is quiet.\n// - `ChapterIndex` — the chapters in reading order, one ruled line each (two at most), the latest marked « New »;\n// - `ChapterHead` — the head of a chapter's page: number in the margin, title, one quiet meta line, the standfirst;\n// - `ChapterFoot` — its foot: the previous and next chapters on the lines, then one line back to the story.\n// No border per row, no card, no button: the paper carries the rhythm. Every word arrives as a prop.\n// `ChapterIndex variant=\"album\"` (#621): each row is the chapter's cover as a `TapedPhoto`, the prints facing each other\n// from left to right, and beside it the same number, title, line and period — light, on the same lines.\nimport type * as React from \"react\";\n\nimport { BlockLink, type LinkComponent } from \"../block-link\";\nimport { cn } from \"../cn\";\nimport { TapedPhoto } from \"../taped-photo\";\n\n/** The notebook under the rows: `lines` (the ruling of `Page`, aligned on the rows) or `false` (the page's own paper). */\ntype ChapterPaper = \"lines\" | false;\n\nexport interface ChapterEntry {\n /** Its number, hung in the margin: `01`, `§ 1`. */\n number: React.ReactNode;\n /** The title, in the serif: the link. */\n title: React.ReactNode;\n /** Where it leads. */\n href: string;\n /** When it happened, quiet on the right (under the title on a phone): `janv. – mars 2026`, or a `<time>`. */\n period?: React.ReactNode;\n /** One more line under the title (what was faced → what was built). Off unless given: the chapter's page says it. */\n detail?: React.ReactNode;\n /** The latest chapter: a small mark after the title, in the hue (`newLabel`). */\n isNew?: boolean;\n /** The page the reader is on. */\n current?: boolean;\n /** Its cover, drawn by the `album` variant as a taped print. Decorative there (`alt=\"\"`): the title carries the link. */\n cover?: ChapterCover;\n}\n\n/** A chapter's cover: its intrinsic size gives the print its aspect-ratio, so nothing shifts while it loads. */\nexport interface ChapterCover {\n src: string;\n width: number;\n height: number;\n srcSet?: string;\n /** @default \"(max-width: 34rem) 60vw, 26rem\" */\n sizes?: string;\n}\n\n/** The covers above the fold load at once; the rest wait for the reader. */\nconst EAGER_COVERS = 2;\n/** The prints face each other: the left one leans left, the right one leans right (TapedPhoto's practice). */\nconst ALBUM_TILT = 1.4;\n\nfunction ChapterPrint({ cover, index }: { cover: ChapterCover; index: number }) {\n return (\n <TapedPhoto className=\"kz-chapter-print\" tilt={index % 2 === 0 ? -ALBUM_TILT : ALBUM_TILT} aria-hidden>\n <img\n src={cover.src}\n srcSet={cover.srcSet}\n sizes={cover.srcSet ? (cover.sizes ?? \"(max-width: 34rem) 60vw, 26rem\") : undefined}\n width={cover.width}\n height={cover.height}\n alt=\"\"\n loading={index < EAGER_COVERS ? \"eager\" : \"lazy\"}\n decoding=\"async\"\n />\n </TapedPhoto>\n );\n}\n\n/** One ruled row: number in the margin, the title as the link (its hit area the whole row), an aside on the right. */\nfunction ChapterRow({\n number,\n title,\n href,\n aside,\n mark,\n detail,\n current,\n rel,\n linkAs,\n}: {\n number?: React.ReactNode;\n title: React.ReactNode;\n href: string;\n aside?: React.ReactNode;\n mark?: React.ReactNode;\n detail?: React.ReactNode;\n current?: boolean;\n rel?: string;\n linkAs?: LinkComponent;\n}) {\n return (\n <>\n <span className=\"kz-chapter-no\">{number}</span>\n <BlockLink href={href} linkAs={linkAs} rel={rel} className=\"kz-chapter-link\" aria-current={current ? \"page\" : undefined}>\n <span className=\"kz-chapter-title\">{title}</span>\n {mark && (\n <>\n {\" \"}\n <span className=\"kz-chapter-new\">{mark}</span>\n </>\n )}\n </BlockLink>\n {aside && (\n <>\n {/* A space, not a margin: in a narrow column the period runs on after the title, and starts flush when it wraps. */}{\" \"}\n <span className=\"kz-chapter-period\">{aside}</span>\n </>\n )}\n {detail && <span className=\"kz-chapter-detail\">{detail}</span>}\n </>\n );\n}\n\nexport type ChapterIndexProps = Omit<React.OlHTMLAttributes<HTMLOListElement>, \"children\"> & {\n /** The chapters, in reading order. */\n chapters: readonly ChapterEntry[];\n /** The word of the latest chapter's mark. @default \"New\" */\n newLabel?: React.ReactNode;\n /** The accessible name of the list, when no heading names it (`aria-labelledby`). */\n label?: string;\n /** The ruling under the rows. `false` when the page is ruled already and the list starts on its module. @default \"lines\" */\n paper?: ChapterPaper;\n /** The app's router link (Next's `Link`), so internal chapters prefetch. */\n linkAs?: LinkComponent;\n /**\n * `lines` — one ruled line per chapter (the compact index); `album` — each chapter's `cover` as a taped print beside\n * its title, its `detail` (one short line) and its period, the rows alternating left and right.\n * @default \"lines\"\n */\n variant?: \"lines\" | \"album\";\n};\n\n/** The chapters of a story as a sober timeline: one ruled line each (or a taped print each), the number in the margin, the title the link. */\nexport function ChapterIndex({ chapters, newLabel = \"New\", label, paper = \"lines\", linkAs, variant = \"lines\", className, ...props }: ChapterIndexProps) {\n const album = variant === \"album\";\n return (\n // `role=\"list\"`: a list without bullets is still a list to VoiceOver.\n <ol\n role=\"list\"\n aria-label={label}\n data-paper={paper || undefined}\n data-margin=\"\"\n data-variant={album ? \"album\" : undefined}\n className={cn(\"kz-chapters\", className)}\n {...props}\n >\n {chapters.map((c, i) => (\n <li key={i} className=\"kz-chapter-row\" data-new={c.isNew ? \"\" : undefined} data-detail={c.detail ? \"\" : undefined}>\n {album && c.cover && <ChapterPrint cover={c.cover} index={i} />}\n <ChapterRow number={c.number} title={c.title} href={c.href} aside={c.period} mark={c.isNew ? newLabel : undefined} detail={c.detail} current={c.current} linkAs={linkAs} />\n </li>\n ))}\n </ol>\n );\n}\n\nexport type ChapterHeadProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The chapter's number, hung in the margin: `01`, `Chapitre 1`. */\n number: React.ReactNode;\n /** The title: the page's `h1`. */\n title: React.ReactNode;\n /** When it happened: `janv. – mars 2026`. */\n period?: React.ReactNode;\n /** How long it reads: `8 min`. */\n readingTime?: React.ReactNode;\n /** What was faced: the first half of the standfirst. */\n faced?: React.ReactNode;\n /** What was built: its second half, after the arrow. */\n built?: React.ReactNode;\n /** The words a screen reader says before each half (the arrow is drawn, not read): `[\"What I faced\", \"What we built\"]`. */\n versusLabels?: readonly [string, string];\n /** The level of the title. @default 1 */\n level?: 1 | 2;\n};\n\n/** The head of a chapter: the number in the margin, the title, the period and the reading time, the standfirst once. */\nexport function ChapterHead({ number, title, period, readingTime, faced, built, versusLabels, level = 1, className, children, ...props }: ChapterHeadProps) {\n const H = level === 1 ? \"h1\" : \"h2\";\n const meta = [period, readingTime].filter((m) => m !== undefined && m !== null && m !== \"\");\n return (\n <header data-margin=\"\" className={cn(\"kz-chapter-head\", className)} {...props}>\n <p className=\"kz-chapter-no\">{number}</p>\n <H className=\"kz-chapter-head-title\">{title}</H>\n {meta.length > 0 && (\n <p className=\"kz-chapter-meta\">\n {meta.map((m, i) => (\n <span key={i}>\n {i > 0 && <span aria-hidden> · </span>}\n {m}\n </span>\n ))}\n </p>\n )}\n {faced && built && (\n <p className=\"kz-chapter-standfirst\">\n {versusLabels && <span className=\"kz-sr-only\">{versusLabels[0]}, </span>}\n {faced}\n <span className=\"kz-chapter-arrow\" aria-hidden>\n {\" → \"}\n </span>\n {versusLabels && <span className=\"kz-sr-only\">; {versusLabels[1]}, </span>}\n {built}\n </p>\n )}\n {children}\n </header>\n );\n}\n\nexport interface ChapterLink {\n /** Its number, in the margin: `02`. */\n number?: React.ReactNode;\n /** Its title, the link. */\n title: React.ReactNode;\n /** Where it leads. */\n href: string;\n}\n\nexport type ChapterFootProps = Omit<React.HTMLAttributes<HTMLElement>, \"children\"> & {\n /** The chapter before this one (none on the first). */\n previous?: ChapterLink;\n /** The chapter after this one (none on the latest). */\n next?: ChapterLink;\n /** The line back to the story: `{ href: \"/\", label: \"Back to the story\" }`. */\n back?: { href: string; label: React.ReactNode };\n /** The quiet words beside each link. @default { previous: \"Previous\", next: \"Next\" } */\n labels?: { previous: React.ReactNode; next: React.ReactNode };\n /** The accessible name of the navigation. @default \"Chapters\" */\n label?: string;\n /** The ruling under the links. @default \"lines\" */\n paper?: ChapterPaper;\n /** The app's router link (Next's `Link`). */\n linkAs?: LinkComponent;\n};\n\n/** The foot of a chapter: the previous and the next on the ruled lines, then one line back to the story. */\nexport function ChapterFoot({\n previous,\n next,\n back,\n labels = { previous: \"Previous\", next: \"Next\" },\n label = \"Chapters\",\n paper = \"lines\",\n linkAs,\n className,\n ...props\n}: ChapterFootProps) {\n return (\n <nav aria-label={label} data-paper={paper || undefined} data-margin=\"\" className={cn(\"kz-chapters kz-chapter-foot\", className)} {...props}>\n <ul role=\"list\">\n {previous && (\n <li className=\"kz-chapter-row\" data-dir=\"previous\">\n <ChapterRow\n number={previous.number}\n title={previous.title}\n href={previous.href}\n rel=\"prev\"\n linkAs={linkAs}\n aside={\n <>\n <span aria-hidden>← </span>\n {labels.previous}\n </>\n }\n />\n </li>\n )}\n {next && (\n <li className=\"kz-chapter-row\" data-dir=\"next\">\n <ChapterRow\n number={next.number}\n title={next.title}\n href={next.href}\n rel=\"next\"\n linkAs={linkAs}\n aside={\n <>\n {labels.next}\n <span aria-hidden> →</span>\n </>\n }\n />\n </li>\n )}\n </ul>\n {back && (\n <p className=\"kz-chapter-back\">\n <BlockLink href={back.href} linkAs={linkAs} className=\"kz-chapter-back-link\">\n <span aria-hidden>↩ </span>\n {back.label}\n </BlockLink>\n </p>\n )}\n </nav>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
|
package/dist/chat.js
CHANGED
|
@@ -17,10 +17,10 @@ var chat = tv({
|
|
|
17
17
|
typing: "inline-flex items-center gap-1 self-start rounded-2xl bg-surface-2 px-3.5 py-3",
|
|
18
18
|
dot: "h-[7px] w-[7px] rounded-full bg-fg-secondary motion-safe:animate-[kz-typing_1.2s_ease-in-out_infinite]",
|
|
19
19
|
composer: "flex items-end gap-2 border-t border-border-subtle bg-surface-0 px-3 py-2",
|
|
20
|
-
input: "max-h-32 min-h-10 flex-1 resize-none rounded-2xl border border-border-
|
|
20
|
+
input: "max-h-32 min-h-10 flex-1 resize-none rounded-2xl border border-border-control bg-surface-1 px-3.5 py-2.5 text-sm text-fg placeholder:text-fg-muted focus-visible:border-accent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
21
21
|
send: "inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-on-accent hover:bg-accent-hover focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:bg-surface-3 disabled:text-fg-muted [&>svg]:h-[18px] [&>svg]:w-[18px]",
|
|
22
22
|
pillRoot: "flex w-full flex-col gap-2",
|
|
23
|
-
pill: "flex items-end gap-1.5 rounded-[1.75rem] border border-border-
|
|
23
|
+
pill: "flex items-end gap-1.5 rounded-[1.75rem] border border-border-control bg-surface-1 py-1.5 pl-2 pr-1.5 transition-colors focus-within:border-accent focus-within:ring-2 focus-within:ring-ring",
|
|
24
24
|
pillLeading: "flex min-h-9 shrink-0 items-center gap-1 self-end",
|
|
25
25
|
pillInput: "max-h-32 min-h-9 min-w-0 flex-1 resize-none border-0 bg-transparent px-1.5 py-[7px] text-sm leading-snug text-fg placeholder:text-fg-muted focus:outline-hidden focus-visible:outline-hidden",
|
|
26
26
|
pillSend: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent text-on-accent shadow-sm transition-colors hover:bg-accent-hover focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-1 disabled:cursor-not-allowed disabled:bg-surface-3 disabled:text-fg-muted disabled:shadow-none [&>svg]:h-4 [&>svg]:w-4",
|
package/dist/chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chat/chat.tsx"],"sourcesContent":["// Client (the composer's draft). A conversation's parts — the bubble with its time and receipt, the typing dots, the\n// composer, a conversation in a list — the same API as React Native. Words are props.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { Avatar } from \"../avatar\";\n\nexport const chat = tv({\n slots: {\n row: \"flex flex-col gap-0.5\",\n bubble: \"max-w-[80%] rounded-2xl px-3 py-2 text-sm leading-snug\",\n context: \"mb-0.5 block text-xs opacity-85\",\n time: \"mt-0.5 block text-right text-[11px] tabular-nums\",\n status: \"flex items-center gap-1 text-xs text-fg-secondary data-[status=failed]:text-fg-danger [&>svg]:h-3.5 [&>svg]:w-3.5\",\n typing: \"inline-flex items-center gap-1 self-start rounded-2xl bg-surface-2 px-3.5 py-3\",\n dot: \"h-[7px] w-[7px] rounded-full bg-fg-secondary motion-safe:animate-[kz-typing_1.2s_ease-in-out_infinite]\",\n composer: \"flex items-end gap-2 border-t border-border-subtle bg-surface-0 px-3 py-2\",\n input:\n \"max-h-32 min-h-10 flex-1 resize-none rounded-2xl border border-border-default bg-surface-1 px-3.5 py-2.5 text-sm text-fg placeholder:text-fg-muted \" +\n \"focus-visible:border-accent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n send:\n \"inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-on-accent hover:bg-accent-hover focus-visible:outline-hidden \" +\n \"focus-visible:ring-2 focus-visible:ring-ring disabled:bg-surface-3 disabled:text-fg-muted [&>svg]:h-[18px] [&>svg]:w-[18px]\",\n pillRoot: \"flex w-full flex-col gap-2\",\n pill:\n \"flex items-end gap-1.5 rounded-[1.75rem] border border-border-default bg-surface-1 py-1.5 pl-2 pr-1.5 transition-colors \" +\n \"focus-within:border-accent focus-within:ring-2 focus-within:ring-ring\",\n pillLeading: \"flex min-h-9 shrink-0 items-center gap-1 self-end\",\n pillInput:\n \"max-h-32 min-h-9 min-w-0 flex-1 resize-none border-0 bg-transparent px-1.5 py-[7px] text-sm leading-snug text-fg placeholder:text-fg-muted \" +\n \"focus:outline-hidden focus-visible:outline-hidden\",\n pillSend:\n \"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent text-on-accent shadow-sm transition-colors hover:bg-accent-hover \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-1 \" +\n \"disabled:cursor-not-allowed disabled:bg-surface-3 disabled:text-fg-muted disabled:shadow-none [&>svg]:h-4 [&>svg]:w-4\",\n pillStatus: \"m-0 flex min-h-5 items-center gap-1.5 px-3 text-xs text-fg-secondary [&_svg]:h-3.5 [&_svg]:w-3.5 [&_svg]:shrink-0\",\n item: \"flex w-full items-center gap-3 px-4 py-2.5 text-left hover:bg-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n count: \"inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-accent px-1.5 text-xs font-extrabold text-on-accent\",\n },\n});\n\nexport type MessageStatus = \"sending\" | \"sent\" | \"delivered\" | \"read\" | \"failed\";\n\nexport type MessageBubbleLabels = {\n /** The words of each status, shown under the last message of yours. */\n status?: Partial<Record<MessageStatus, string>>;\n /** A failed message's retry button (“Retry”). */\n retry?: string;\n};\n\nconst STATUS: Record<MessageStatus, string> = { sending: \"Sending\", sent: \"Sent\", delivered: \"Delivered\", read: \"Read\", failed: \"Not sent\" };\n\nexport type MessageBubbleProps = {\n /** The text. */\n text: string;\n /** Yours (right, in the accent) or theirs (left). */\n mine?: boolean;\n /** The time, written by the app (“14:02”). */\n time?: string;\n /** Where a message of yours stands; shown when `showStatus`. */\n status?: MessageStatus;\n /** Show the status under the bubble (the last message of yours). */\n showStatus?: boolean;\n /** A line above the text: what it answers. */\n context?: string;\n /** Sends a failed message again (a button under it). */\n onRetry?: () => void;\n /** Part of a run of the same sender: the corner towards the next one is tighter. */\n grouped?: \"first\" | \"middle\" | \"last\" | \"single\";\n /** The words, passed translated. */\n labels?: MessageBubbleLabels;\n /** Classes merged on the row. */\n className?: string;\n};\n\nconst CORNERS = {\n mine: { first: \"rounded-br-md\", middle: \"rounded-r-md\", last: \"rounded-tr-md\", single: \"\" },\n theirs: { first: \"rounded-bl-md\", middle: \"rounded-l-md\", last: \"rounded-tl-md\", single: \"\" },\n} as const;\n\n/** A message: yours in the accent on the right, theirs on the left, the time inside, the receipt under the last of yours. */\nexport function MessageBubble({ text, mine, time, status, showStatus, context, onRetry, grouped = \"single\", labels, className }: MessageBubbleProps) {\n const s = chat();\n const words = { ...STATUS, ...labels?.status };\n return (\n <div className={s.row({ className: [mine ? \"items-end\" : \"items-start\", className].filter(Boolean).join(\" \") })}>\n <p\n className={s.bubble({\n className: [mine ? \"bg-accent text-on-accent\" : \"bg-surface-2 text-fg\", CORNERS[mine ? \"mine\" : \"theirs\"][grouped], status === \"failed\" ? \"ring-2 ring-danger\" : \"\", status === \"sending\" ? \"opacity-70\" : \"\"].join(\" \"),\n })}\n >\n {context ? <span className={s.context()}>{context}</span> : null}\n {text}\n {time ? <span className={s.time()}>{time}</span> : null}\n </p>\n {showStatus && status ? (\n <p className={s.status()} data-status={status}>\n {status === \"sent\" || status === \"delivered\" || status === \"read\" ? (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden className={status === \"read\" ? \"stroke-accent\" : \"stroke-fg-secondary\"}>\n <path d={status === \"sent\" ? \"M5 12.5l4.5 4.5L19 7.5\" : \"M2 12.5l4.5 4.5L16 7.5M9 15l2 2 9.5-9.5\"} />\n </svg>\n ) : null}\n {words[status]}\n {status === \"failed\" && onRetry ? (\n <button type=\"button\" onClick={onRetry} className=\"ml-1 font-semibold text-fg underline underline-offset-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\">\n {labels?.retry ?? \"Retry\"}\n </button>\n ) : null}\n </p>\n ) : null}\n </div>\n );\n}\n\nexport type TypingIndicatorProps = {\n /** What is read and shown beside the dots (“Elena is typing”) — passed translated. */\n label: string;\n /** Show the words beside the dots. */\n showLabel?: boolean;\n /** Classes merged on the root. */\n className?: string;\n};\n\n/** Three dots that breathe while the other person types, announced politely; still under reduced motion. */\nexport function TypingIndicator({ label, showLabel, className }: TypingIndicatorProps) {\n const s = chat();\n return (\n <div role=\"status\" className={[\"flex items-center gap-2\", className].filter(Boolean).join(\" \")}>\n <style href=\"krizaka-typing\" precedence=\"default\">{\"@keyframes kz-typing{0%,60%,100%{opacity:.35;transform:none}30%{opacity:1;transform:translateY(-2px)}}\"}</style>\n <span className={s.typing()} aria-hidden>\n {[0, 1, 2].map((i) => (\n <span key={i} className={s.dot()} style={{ animationDelay: `${i * 0.18}s` }} />\n ))}\n </span>\n <span className={showLabel ? \"text-xs text-fg-secondary\" : \"sr-only\"}>{label}</span>\n </div>\n );\n}\n\nexport type MessageComposerProps = {\n /** The draft (controlled). */\n value: string;\n /** Called on every key. */\n onValueChange: (text: string) => void;\n /** Sends the draft (Enter, or the button); Shift+Enter adds a line. */\n onSend: () => void;\n /** The input's name and placeholder (“Message”). */\n placeholder: string;\n /** The send button's name (“Send”). */\n sendLabel: string;\n /** Before the input: an attach button (`bar`), or the mode/model chip and attach, inside the field (`pill`). */\n leading?: React.ReactNode;\n /** Cannot write: the reason in its place. */\n disabledReason?: string;\n /** The longest message. Default 4000. */\n maxLength?: number;\n /** `bar`: a docked bar with a square-ish field. `pill`: one rounded field holding `leading`, the text and a round send button — no inner border. Default `bar`. */\n variant?: \"bar\" | \"pill\";\n /** `pill`: the quiet line under the field (privacy, cost estimate). Its row is always reserved, so a changing line never moves the field. Read politely. */\n status?: React.ReactNode;\n /** An answer is on its way: the send is held (and `aria-busy` is set) while the field stays where it is, size included. */\n busy?: boolean;\n /** Overrides “the draft has text” — e.g. an attachment alone can be sent. A busy composer never sends. */\n canSend?: boolean;\n /** Attributes (`data-testid`, `autoFocus`, `id`…) forwarded to the textarea. */\n inputProps?: Omit<React.ComponentPropsWithoutRef<\"textarea\">, \"value\" | \"onChange\" | \"placeholder\" | \"maxLength\" | \"className\" | \"rows\">;\n /** Attributes forwarded to the send button. */\n sendProps?: Omit<React.ComponentPropsWithoutRef<\"button\">, \"type\" | \"disabled\" | \"className\" | \"aria-label\">;\n /** Classes merged on the root. */\n className?: string;\n};\n\n/** Where a message is written: a growing textarea (Enter sends, Shift+Enter a new line), an attach slot, a send button. The `pill` variant is the one-field look of the Krizaka chat card. */\nexport function MessageComposer({\n value,\n onValueChange,\n onSend,\n placeholder,\n sendLabel,\n leading,\n disabledReason,\n maxLength = 4000,\n variant = \"bar\",\n status,\n busy = false,\n canSend,\n inputProps,\n sendProps,\n className,\n}: MessageComposerProps) {\n const s = chat();\n const pill = variant === \"pill\";\n const ready = !busy && (canSend ?? value.trim().length > 0);\n const textarea = (\n <textarea\n aria-label={placeholder}\n placeholder={placeholder}\n rows={1}\n maxLength={maxLength}\n {...inputProps}\n value={value}\n onChange={(e) => onValueChange(e.target.value)}\n onKeyDown={(e) => {\n inputProps?.onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n e.preventDefault();\n if (ready) onSend();\n }\n }}\n className={pill ? s.pillInput() : s.input()}\n style={{ fieldSizing: \"content\" } as React.CSSProperties}\n />\n );\n const send = (\n <button type=\"submit\" aria-label={sendLabel} {...sendProps} disabled={!ready} className={pill ? s.pillSend() : s.send()}>\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden>\n <path d=\"M4 12l16-8-6 16-2.5-6.5L4 12z\" />\n </svg>\n </button>\n );\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n if (ready) onSend();\n };\n if (pill) {\n return (\n <form className={s.pillRoot({ className })} onSubmit={submit} aria-busy={busy || undefined}>\n {disabledReason ? (\n <p className=\"m-0 rounded-[1.75rem] border border-border-default bg-surface-1 px-4 py-2.5 text-sm text-fg-secondary\">{disabledReason}</p>\n ) : (\n <div className={s.pill()}>\n {leading ? <div className={s.pillLeading()}>{leading}</div> : null}\n {textarea}\n {send}\n </div>\n )}\n <p role=\"status\" aria-live=\"polite\" className={s.pillStatus()}>\n {status}\n </p>\n </form>\n );\n }\n return (\n <form className={s.composer({ className })} onSubmit={submit} aria-busy={busy || undefined}>\n {disabledReason ? (\n <p className=\"m-0 flex-1 py-2 text-sm text-fg-secondary\">{disabledReason}</p>\n ) : (\n <>\n {leading}\n {textarea}\n {send}\n </>\n )}\n </form>\n );\n}\n\nexport type ConversationItemProps = {\n /** The other person's name. */\n name: string;\n /** Their avatar's URL. */\n avatar?: string | null;\n /** The last message, or “typing…”. */\n preview: string;\n /** The preview is the typing signal: in the accent. */\n typing?: boolean;\n /** When (“14:02”, “Mon”). */\n time?: string;\n /** Unread messages: a count, the name in bold. */\n unread?: number;\n /** The unread count in words (“3 unread”). */\n unreadLabel?: string;\n /** Before the name: a presence dot (online). */\n online?: boolean;\n /** The presence in words (“online”). */\n onlineLabel?: string;\n /** Opens the conversation (a link). */\n href?: string;\n /** Opens the conversation (a button). */\n onSelect?: () => void;\n /** Classes merged on the row. */\n className?: string;\n};\n\n/** A conversation in the list: avatar, name, the last message or typing, the time, the unread count. */\nexport function ConversationItem({ name, avatar, preview, typing, time, unread = 0, unreadLabel, online, onlineLabel, href, onSelect, className }: ConversationItemProps) {\n const s = chat();\n const body = (\n <>\n <span className=\"relative shrink-0\">\n <Avatar src={avatar ?? null} alt=\"\" fallback={name.charAt(0)} size=\"lg\" />\n {online ? <span aria-hidden className=\"absolute bottom-0 right-0 h-3 w-3 rounded-full bg-success ring-2 ring-surface-0\" /> : null}\n </span>\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"flex items-center gap-2\">\n <span className={[\"min-w-0 flex-1 truncate text-sm text-fg\", unread > 0 ? \"font-extrabold\" : \"font-semibold\"].join(\" \")}>\n {name}\n {online && onlineLabel ? <span className=\"sr-only\">{`, ${onlineLabel}`}</span> : null}\n </span>\n {time ? <span className={[\"shrink-0 text-xs tabular-nums\", unread > 0 ? \"text-fg-accent\" : \"text-fg-secondary\"].join(\" \")}>{time}</span> : null}\n </span>\n <span className=\"flex items-center gap-2\">\n <span className={[\"min-w-0 flex-1 truncate text-xs\", typing ? \"text-fg-accent\" : unread > 0 ? \"text-fg\" : \"text-fg-secondary\"].join(\" \")}>{preview}</span>\n {unread > 0 ? (\n <span className={s.count()}>\n <span aria-hidden>{unread > 99 ? \"99+\" : unread}</span>\n <span className=\"sr-only\">{unreadLabel ?? String(unread)}</span>\n </span>\n ) : null}\n </span>\n </span>\n </>\n );\n return href ? (\n <a href={href} className={s.item({ className })}>\n {body}\n </a>\n ) : (\n <button type=\"button\" onClick={onSelect} className={s.item({ className })}>\n {body}\n </button>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/chat/chat.tsx"],"sourcesContent":["// Client (the composer's draft). A conversation's parts — the bubble with its time and receipt, the typing dots, the\n// composer, a conversation in a list — the same API as React Native. Words are props.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { Avatar } from \"../avatar\";\n\nexport const chat = tv({\n slots: {\n row: \"flex flex-col gap-0.5\",\n bubble: \"max-w-[80%] rounded-2xl px-3 py-2 text-sm leading-snug\",\n context: \"mb-0.5 block text-xs opacity-85\",\n time: \"mt-0.5 block text-right text-[11px] tabular-nums\",\n status: \"flex items-center gap-1 text-xs text-fg-secondary data-[status=failed]:text-fg-danger [&>svg]:h-3.5 [&>svg]:w-3.5\",\n typing: \"inline-flex items-center gap-1 self-start rounded-2xl bg-surface-2 px-3.5 py-3\",\n dot: \"h-[7px] w-[7px] rounded-full bg-fg-secondary motion-safe:animate-[kz-typing_1.2s_ease-in-out_infinite]\",\n composer: \"flex items-end gap-2 border-t border-border-subtle bg-surface-0 px-3 py-2\",\n input:\n \"max-h-32 min-h-10 flex-1 resize-none rounded-2xl border border-border-control bg-surface-1 px-3.5 py-2.5 text-sm text-fg placeholder:text-fg-muted \" +\n \"focus-visible:border-accent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n send:\n \"inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent text-on-accent hover:bg-accent-hover focus-visible:outline-hidden \" +\n \"focus-visible:ring-2 focus-visible:ring-ring disabled:bg-surface-3 disabled:text-fg-muted [&>svg]:h-[18px] [&>svg]:w-[18px]\",\n pillRoot: \"flex w-full flex-col gap-2\",\n pill:\n \"flex items-end gap-1.5 rounded-[1.75rem] border border-border-control bg-surface-1 py-1.5 pl-2 pr-1.5 transition-colors \" +\n \"focus-within:border-accent focus-within:ring-2 focus-within:ring-ring\",\n pillLeading: \"flex min-h-9 shrink-0 items-center gap-1 self-end\",\n pillInput:\n \"max-h-32 min-h-9 min-w-0 flex-1 resize-none border-0 bg-transparent px-1.5 py-[7px] text-sm leading-snug text-fg placeholder:text-fg-muted \" +\n \"focus:outline-hidden focus-visible:outline-hidden\",\n pillSend:\n \"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent text-on-accent shadow-sm transition-colors hover:bg-accent-hover \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-1 \" +\n \"disabled:cursor-not-allowed disabled:bg-surface-3 disabled:text-fg-muted disabled:shadow-none [&>svg]:h-4 [&>svg]:w-4\",\n pillStatus: \"m-0 flex min-h-5 items-center gap-1.5 px-3 text-xs text-fg-secondary [&_svg]:h-3.5 [&_svg]:w-3.5 [&_svg]:shrink-0\",\n item: \"flex w-full items-center gap-3 px-4 py-2.5 text-left hover:bg-surface-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n count: \"inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-accent px-1.5 text-xs font-extrabold text-on-accent\",\n },\n});\n\nexport type MessageStatus = \"sending\" | \"sent\" | \"delivered\" | \"read\" | \"failed\";\n\nexport type MessageBubbleLabels = {\n /** The words of each status, shown under the last message of yours. */\n status?: Partial<Record<MessageStatus, string>>;\n /** A failed message's retry button (“Retry”). */\n retry?: string;\n};\n\nconst STATUS: Record<MessageStatus, string> = { sending: \"Sending\", sent: \"Sent\", delivered: \"Delivered\", read: \"Read\", failed: \"Not sent\" };\n\nexport type MessageBubbleProps = {\n /** The text. */\n text: string;\n /** Yours (right, in the accent) or theirs (left). */\n mine?: boolean;\n /** The time, written by the app (“14:02”). */\n time?: string;\n /** Where a message of yours stands; shown when `showStatus`. */\n status?: MessageStatus;\n /** Show the status under the bubble (the last message of yours). */\n showStatus?: boolean;\n /** A line above the text: what it answers. */\n context?: string;\n /** Sends a failed message again (a button under it). */\n onRetry?: () => void;\n /** Part of a run of the same sender: the corner towards the next one is tighter. */\n grouped?: \"first\" | \"middle\" | \"last\" | \"single\";\n /** The words, passed translated. */\n labels?: MessageBubbleLabels;\n /** Classes merged on the row. */\n className?: string;\n};\n\nconst CORNERS = {\n mine: { first: \"rounded-br-md\", middle: \"rounded-r-md\", last: \"rounded-tr-md\", single: \"\" },\n theirs: { first: \"rounded-bl-md\", middle: \"rounded-l-md\", last: \"rounded-tl-md\", single: \"\" },\n} as const;\n\n/** A message: yours in the accent on the right, theirs on the left, the time inside, the receipt under the last of yours. */\nexport function MessageBubble({ text, mine, time, status, showStatus, context, onRetry, grouped = \"single\", labels, className }: MessageBubbleProps) {\n const s = chat();\n const words = { ...STATUS, ...labels?.status };\n return (\n <div className={s.row({ className: [mine ? \"items-end\" : \"items-start\", className].filter(Boolean).join(\" \") })}>\n <p\n className={s.bubble({\n className: [mine ? \"bg-accent text-on-accent\" : \"bg-surface-2 text-fg\", CORNERS[mine ? \"mine\" : \"theirs\"][grouped], status === \"failed\" ? \"ring-2 ring-danger\" : \"\", status === \"sending\" ? \"opacity-70\" : \"\"].join(\" \"),\n })}\n >\n {context ? <span className={s.context()}>{context}</span> : null}\n {text}\n {time ? <span className={s.time()}>{time}</span> : null}\n </p>\n {showStatus && status ? (\n <p className={s.status()} data-status={status}>\n {status === \"sent\" || status === \"delivered\" || status === \"read\" ? (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden className={status === \"read\" ? \"stroke-accent\" : \"stroke-fg-secondary\"}>\n <path d={status === \"sent\" ? \"M5 12.5l4.5 4.5L19 7.5\" : \"M2 12.5l4.5 4.5L16 7.5M9 15l2 2 9.5-9.5\"} />\n </svg>\n ) : null}\n {words[status]}\n {status === \"failed\" && onRetry ? (\n <button type=\"button\" onClick={onRetry} className=\"ml-1 font-semibold text-fg underline underline-offset-2 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\">\n {labels?.retry ?? \"Retry\"}\n </button>\n ) : null}\n </p>\n ) : null}\n </div>\n );\n}\n\nexport type TypingIndicatorProps = {\n /** What is read and shown beside the dots (“Elena is typing”) — passed translated. */\n label: string;\n /** Show the words beside the dots. */\n showLabel?: boolean;\n /** Classes merged on the root. */\n className?: string;\n};\n\n/** Three dots that breathe while the other person types, announced politely; still under reduced motion. */\nexport function TypingIndicator({ label, showLabel, className }: TypingIndicatorProps) {\n const s = chat();\n return (\n <div role=\"status\" className={[\"flex items-center gap-2\", className].filter(Boolean).join(\" \")}>\n <style href=\"krizaka-typing\" precedence=\"default\">{\"@keyframes kz-typing{0%,60%,100%{opacity:.35;transform:none}30%{opacity:1;transform:translateY(-2px)}}\"}</style>\n <span className={s.typing()} aria-hidden>\n {[0, 1, 2].map((i) => (\n <span key={i} className={s.dot()} style={{ animationDelay: `${i * 0.18}s` }} />\n ))}\n </span>\n <span className={showLabel ? \"text-xs text-fg-secondary\" : \"sr-only\"}>{label}</span>\n </div>\n );\n}\n\nexport type MessageComposerProps = {\n /** The draft (controlled). */\n value: string;\n /** Called on every key. */\n onValueChange: (text: string) => void;\n /** Sends the draft (Enter, or the button); Shift+Enter adds a line. */\n onSend: () => void;\n /** The input's name and placeholder (“Message”). */\n placeholder: string;\n /** The send button's name (“Send”). */\n sendLabel: string;\n /** Before the input: an attach button (`bar`), or the mode/model chip and attach, inside the field (`pill`). */\n leading?: React.ReactNode;\n /** Cannot write: the reason in its place. */\n disabledReason?: string;\n /** The longest message. Default 4000. */\n maxLength?: number;\n /** `bar`: a docked bar with a square-ish field. `pill`: one rounded field holding `leading`, the text and a round send button — no inner border. Default `bar`. */\n variant?: \"bar\" | \"pill\";\n /** `pill`: the quiet line under the field (privacy, cost estimate). Its row is always reserved, so a changing line never moves the field. Read politely. */\n status?: React.ReactNode;\n /** An answer is on its way: the send is held (and `aria-busy` is set) while the field stays where it is, size included. */\n busy?: boolean;\n /** Overrides “the draft has text” — e.g. an attachment alone can be sent. A busy composer never sends. */\n canSend?: boolean;\n /** Attributes (`data-testid`, `autoFocus`, `id`…) forwarded to the textarea. */\n inputProps?: Omit<React.ComponentPropsWithoutRef<\"textarea\">, \"value\" | \"onChange\" | \"placeholder\" | \"maxLength\" | \"className\" | \"rows\">;\n /** Attributes forwarded to the send button. */\n sendProps?: Omit<React.ComponentPropsWithoutRef<\"button\">, \"type\" | \"disabled\" | \"className\" | \"aria-label\">;\n /** Classes merged on the root. */\n className?: string;\n};\n\n/** Where a message is written: a growing textarea (Enter sends, Shift+Enter a new line), an attach slot, a send button. The `pill` variant is the one-field look of the Krizaka chat card. */\nexport function MessageComposer({\n value,\n onValueChange,\n onSend,\n placeholder,\n sendLabel,\n leading,\n disabledReason,\n maxLength = 4000,\n variant = \"bar\",\n status,\n busy = false,\n canSend,\n inputProps,\n sendProps,\n className,\n}: MessageComposerProps) {\n const s = chat();\n const pill = variant === \"pill\";\n const ready = !busy && (canSend ?? value.trim().length > 0);\n const textarea = (\n <textarea\n aria-label={placeholder}\n placeholder={placeholder}\n rows={1}\n maxLength={maxLength}\n {...inputProps}\n value={value}\n onChange={(e) => onValueChange(e.target.value)}\n onKeyDown={(e) => {\n inputProps?.onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n e.preventDefault();\n if (ready) onSend();\n }\n }}\n className={pill ? s.pillInput() : s.input()}\n style={{ fieldSizing: \"content\" } as React.CSSProperties}\n />\n );\n const send = (\n <button type=\"submit\" aria-label={sendLabel} {...sendProps} disabled={!ready} className={pill ? s.pillSend() : s.send()}>\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden>\n <path d=\"M4 12l16-8-6 16-2.5-6.5L4 12z\" />\n </svg>\n </button>\n );\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n if (ready) onSend();\n };\n if (pill) {\n return (\n <form className={s.pillRoot({ className })} onSubmit={submit} aria-busy={busy || undefined}>\n {disabledReason ? (\n <p className=\"m-0 rounded-[1.75rem] border border-border-default bg-surface-1 px-4 py-2.5 text-sm text-fg-secondary\">{disabledReason}</p>\n ) : (\n <div className={s.pill()}>\n {leading ? <div className={s.pillLeading()}>{leading}</div> : null}\n {textarea}\n {send}\n </div>\n )}\n <p role=\"status\" aria-live=\"polite\" className={s.pillStatus()}>\n {status}\n </p>\n </form>\n );\n }\n return (\n <form className={s.composer({ className })} onSubmit={submit} aria-busy={busy || undefined}>\n {disabledReason ? (\n <p className=\"m-0 flex-1 py-2 text-sm text-fg-secondary\">{disabledReason}</p>\n ) : (\n <>\n {leading}\n {textarea}\n {send}\n </>\n )}\n </form>\n );\n}\n\nexport type ConversationItemProps = {\n /** The other person's name. */\n name: string;\n /** Their avatar's URL. */\n avatar?: string | null;\n /** The last message, or “typing…”. */\n preview: string;\n /** The preview is the typing signal: in the accent. */\n typing?: boolean;\n /** When (“14:02”, “Mon”). */\n time?: string;\n /** Unread messages: a count, the name in bold. */\n unread?: number;\n /** The unread count in words (“3 unread”). */\n unreadLabel?: string;\n /** Before the name: a presence dot (online). */\n online?: boolean;\n /** The presence in words (“online”). */\n onlineLabel?: string;\n /** Opens the conversation (a link). */\n href?: string;\n /** Opens the conversation (a button). */\n onSelect?: () => void;\n /** Classes merged on the row. */\n className?: string;\n};\n\n/** A conversation in the list: avatar, name, the last message or typing, the time, the unread count. */\nexport function ConversationItem({ name, avatar, preview, typing, time, unread = 0, unreadLabel, online, onlineLabel, href, onSelect, className }: ConversationItemProps) {\n const s = chat();\n const body = (\n <>\n <span className=\"relative shrink-0\">\n <Avatar src={avatar ?? null} alt=\"\" fallback={name.charAt(0)} size=\"lg\" />\n {online ? <span aria-hidden className=\"absolute bottom-0 right-0 h-3 w-3 rounded-full bg-success ring-2 ring-surface-0\" /> : null}\n </span>\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"flex items-center gap-2\">\n <span className={[\"min-w-0 flex-1 truncate text-sm text-fg\", unread > 0 ? \"font-extrabold\" : \"font-semibold\"].join(\" \")}>\n {name}\n {online && onlineLabel ? <span className=\"sr-only\">{`, ${onlineLabel}`}</span> : null}\n </span>\n {time ? <span className={[\"shrink-0 text-xs tabular-nums\", unread > 0 ? \"text-fg-accent\" : \"text-fg-secondary\"].join(\" \")}>{time}</span> : null}\n </span>\n <span className=\"flex items-center gap-2\">\n <span className={[\"min-w-0 flex-1 truncate text-xs\", typing ? \"text-fg-accent\" : unread > 0 ? \"text-fg\" : \"text-fg-secondary\"].join(\" \")}>{preview}</span>\n {unread > 0 ? (\n <span className={s.count()}>\n <span aria-hidden>{unread > 99 ? \"99+\" : unread}</span>\n <span className=\"sr-only\">{unreadLabel ?? String(unread)}</span>\n </span>\n ) : null}\n </span>\n </span>\n </>\n );\n return href ? (\n <a href={href} className={s.item({ className })}>\n {body}\n </a>\n ) : (\n <button type=\"button\" onClick={onSelect} className={s.item({ className })}>\n {body}\n </button>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/checkbox.js
CHANGED
|
@@ -6,7 +6,7 @@ import { tv } from "tailwind-variants";
|
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
var checkbox = tv({
|
|
8
8
|
slots: {
|
|
9
|
-
root: "peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-border-
|
|
9
|
+
root: "peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-border-control bg-surface-1 text-on-accent transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 hover:border-accent disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:border-accent data-[state=checked]:bg-accent data-[state=indeterminate]:border-accent data-[state=indeterminate]:bg-accent aria-invalid:border-danger aria-invalid:ring-danger/30",
|
|
10
10
|
indicator: "flex items-center justify-center",
|
|
11
11
|
label: "flex cursor-pointer items-start gap-3 text-sm text-fg has-disabled:cursor-not-allowed has-disabled:opacity-70"
|
|
12
12
|
}
|
package/dist/checkbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/checkbox/checkbox.tsx"],"sourcesContent":["// Client. Radix Checkbox: role=\"checkbox\", aria-checked (true · false · mixed), Space toggles, a hidden input inside a\n// form. It sits in a `Field` like the other controls: `<Field.Label htmlFor={id}>`, `invalid`, aria-describedby.\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const checkbox = tv({\n slots: {\n root:\n \"peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-border-
|
|
1
|
+
{"version":3,"sources":["../src/checkbox/checkbox.tsx"],"sourcesContent":["// Client. Radix Checkbox: role=\"checkbox\", aria-checked (true · false · mixed), Space toggles, a hidden input inside a\n// form. It sits in a `Field` like the other controls: `<Field.Label htmlFor={id}>`, `invalid`, aria-describedby.\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const checkbox = tv({\n slots: {\n root:\n \"peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md border border-border-control bg-surface-1 text-on-accent transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"hover:border-accent disabled:cursor-not-allowed disabled:opacity-40 \" +\n \"data-[state=checked]:border-accent data-[state=checked]:bg-accent data-[state=indeterminate]:border-accent data-[state=indeterminate]:bg-accent \" +\n \"aria-invalid:border-danger aria-invalid:ring-danger/30\",\n indicator: \"flex items-center justify-center\",\n label: \"flex cursor-pointer items-start gap-3 text-sm text-fg has-disabled:cursor-not-allowed has-disabled:opacity-70\",\n },\n});\n\nfunction Check() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nfunction Dash() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M5 12h14\" />\n </svg>\n );\n}\n\nexport type CheckboxProps = Omit<React.ComponentProps<typeof CheckboxPrimitive.Root>, \"children\"> & {\n /** Marks it invalid: aria-invalid and data-invalid (pair it with a `Field.Error` in aria-describedby). */\n invalid?: boolean;\n /** The text next to the box, clickable: the box and its words in one `<label>`. Otherwise name it with\n * `Field.Label htmlFor` or `aria-label`. */\n children?: React.ReactNode;\n};\n\n/** A checkbox: `checked`/`defaultChecked` (`true` · `false` · `\"indeterminate\"`) + `onCheckedChange`. */\nexport function Checkbox({ invalid, className, children, ...props }: CheckboxProps) {\n const s = checkbox();\n const box = (\n <CheckboxPrimitive.Root\n aria-invalid={invalid || undefined}\n data-invalid={invalid ? \"\" : undefined}\n className={s.root({ className: children ? \"mt-0.5\" : className })}\n {...props}\n >\n <CheckboxPrimitive.Indicator className={s.indicator()}>\n {props.checked === \"indeterminate\" ? <Dash /> : <Check />}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n if (!children) return box;\n return (\n <label className={s.label({ className })}>\n {box}\n <span className=\"min-w-0\">{children}</span>\n </label>\n );\n}\n"],"mappings":";;;AAEA,SAAS,YAAY,yBAAyB;AAE9C,SAAS,UAAU;AAkBb,cAsCF,YAtCE;AAhBC,IAAM,WAAW,GAAG;AAAA,EACzB,OAAO;AAAA,IACL,MACE;AAAA,IAKF,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AACF,CAAC;AAED,SAAS,QAAQ;AACf,SACE,oBAAC,SAAI,SAAQ,aAAY,WAAU,eAAc,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SAAQ,eAAW,MACzJ,8BAAC,UAAK,GAAE,mBAAkB,GAC5B;AAEJ;AAEA,SAAS,OAAO;AACd,SACE,oBAAC,SAAI,SAAQ,aAAY,WAAU,eAAc,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,eAAW,MAClI,8BAAC,UAAK,GAAE,YAAW,GACrB;AAEJ;AAWO,SAAS,SAAS,EAAE,SAAS,WAAW,UAAU,GAAG,MAAM,GAAkB;AAClF,QAAM,IAAI,SAAS;AACnB,QAAM,MACJ;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,gBAAc,WAAW;AAAA,MACzB,gBAAc,UAAU,KAAK;AAAA,MAC7B,WAAW,EAAE,KAAK,EAAE,WAAW,WAAW,WAAW,UAAU,CAAC;AAAA,MAC/D,GAAG;AAAA,MAEJ,8BAAC,kBAAkB,WAAlB,EAA4B,WAAW,EAAE,UAAU,GACjD,gBAAM,YAAY,kBAAkB,oBAAC,QAAK,IAAK,oBAAC,SAAM,GACzD;AAAA;AAAA,EACF;AAEF,MAAI,CAAC,SAAU,QAAO;AACtB,SACE,qBAAC,WAAM,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,GACpC;AAAA;AAAA,IACD,oBAAC,UAAK,WAAU,WAAW,UAAS;AAAA,KACtC;AAEJ;","names":[]}
|
package/dist/chip.js
CHANGED
|
@@ -1,103 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// src/chip/chip.tsx
|
|
10
|
-
import { Toggle as TogglePrimitive, ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
|
|
11
|
-
import * as React from "react";
|
|
12
|
-
import { tv } from "tailwind-variants";
|
|
13
|
-
|
|
14
|
-
// src/chip/recipe.ts
|
|
15
|
-
var chipRecipe = defineRecipe({
|
|
16
|
-
slots: {
|
|
17
|
-
group: "flex flex-wrap items-center gap-2 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch",
|
|
18
|
-
base: "inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-sm border font-semibold transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg data-[state=on]:border-accent data-[state=on]:bg-accent-soft data-[state=on]:text-fg",
|
|
19
|
-
remove: "-mr-1.5 inline-flex h-6 w-6 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
|
|
20
|
-
},
|
|
21
|
-
variants: {
|
|
22
|
-
size: { sm: { base: "h-7 px-3 text-xs" }, md: { base: "h-9 px-3.5 text-xs" } }
|
|
23
|
-
},
|
|
24
|
-
defaultVariants: { size: "md" }
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// src/chip/chip.tsx
|
|
28
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
29
|
-
var chip = tv(chipRecipe);
|
|
30
|
-
var ChipGroupContext = React.createContext(null);
|
|
31
|
-
function RemoveIcon() {
|
|
32
|
-
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
|
|
33
|
-
}
|
|
34
|
-
function ChipBase(props) {
|
|
35
|
-
const group = React.useContext(ChipGroupContext);
|
|
36
|
-
if (props.removable) {
|
|
37
|
-
const { removable: _removable2, removeLabel, onRemove, disabled, size: size2, className: className2, children, ...rest2 } = props;
|
|
38
|
-
const s2 = chip({ size: size2 ?? group?.size });
|
|
39
|
-
return /* @__PURE__ */ jsxs("span", { "data-removable": "", className: s2.base({ className: className2 }), ...rest2, children: [
|
|
40
|
-
children,
|
|
41
|
-
/* @__PURE__ */ jsx("button", { type: "button", "aria-label": removeLabel, title: removeLabel, disabled, onClick: onRemove, className: s2.remove(), children: /* @__PURE__ */ jsx(RemoveIcon, {}) })
|
|
42
|
-
] });
|
|
43
|
-
}
|
|
44
|
-
const { removable: _removable, value, selected, defaultSelected, onSelectedChange, size, className, ...rest } = props;
|
|
45
|
-
const s = chip({ size: size ?? group?.size });
|
|
46
|
-
if (group) {
|
|
47
|
-
if (value === void 0) throw new Error("Chip: a chip inside Chip.Group needs a `value`.");
|
|
48
|
-
return /* @__PURE__ */ jsx(ToggleGroupPrimitive.Item, { value, className: s.base({ className }), ...rest });
|
|
49
|
-
}
|
|
50
|
-
return /* @__PURE__ */ jsx(
|
|
51
|
-
TogglePrimitive.Root,
|
|
52
|
-
{
|
|
53
|
-
pressed: selected,
|
|
54
|
-
defaultPressed: defaultSelected,
|
|
55
|
-
onPressedChange: onSelectedChange,
|
|
56
|
-
className: s.base({ className }),
|
|
57
|
-
...rest
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
function ChipGroup({ label, size, className, children, ...props }) {
|
|
62
|
-
const single = props.type === "single" ? props : void 0;
|
|
63
|
-
const routed = useRouteBinding(single?.routeKey, single?.routeValues, { value: single?.value, defaultValue: single?.defaultValue, onValueChange: single?.onValueChange });
|
|
64
|
-
const s = chip({ size });
|
|
65
|
-
const context = React.useMemo(() => ({ size }), [size]);
|
|
66
|
-
const common = { "aria-label": label, className: s.group({ className }) };
|
|
67
|
-
let group;
|
|
68
|
-
if (props.type === "single") {
|
|
69
|
-
const { type: _type, value: _value, defaultValue: _defaultValue, onValueChange: _onValueChange, required, routeKey: _routeKey, routeValues: _routeValues, ...rest } = props;
|
|
70
|
-
group = /* @__PURE__ */ jsx(SingleGroup, { ...rest, ...common, value: routed.value, defaultValue: routed.defaultValue, onValueChange: routed.onValueChange, required, children });
|
|
71
|
-
} else {
|
|
72
|
-
const { type: _type, required: _required, ...rest } = props;
|
|
73
|
-
group = /* @__PURE__ */ jsx(ToggleGroupPrimitive.Root, { type: "multiple", ...rest, ...common, children });
|
|
74
|
-
}
|
|
75
|
-
return /* @__PURE__ */ jsx(ChipGroupContext.Provider, { value: context, children: group });
|
|
76
|
-
}
|
|
77
|
-
function SingleGroup({
|
|
78
|
-
value,
|
|
79
|
-
defaultValue,
|
|
80
|
-
onValueChange,
|
|
81
|
-
required,
|
|
82
|
-
...props
|
|
83
|
-
}) {
|
|
84
|
-
const [inner, setInner] = React.useState(defaultValue ?? "");
|
|
85
|
-
const current = value ?? inner;
|
|
86
|
-
return /* @__PURE__ */ jsx(
|
|
87
|
-
ToggleGroupPrimitive.Root,
|
|
88
|
-
{
|
|
89
|
-
type: "single",
|
|
90
|
-
value: current,
|
|
91
|
-
onValueChange: (next) => {
|
|
92
|
-
if (required && !next) return;
|
|
93
|
-
if (value === void 0) setInner(next);
|
|
94
|
-
onValueChange?.(next);
|
|
95
|
-
},
|
|
96
|
-
...props
|
|
97
|
-
}
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
var Chip = Object.assign(ChipBase, { Group: ChipGroup });
|
|
3
|
+
Chip,
|
|
4
|
+
ChipGroup,
|
|
5
|
+
chip
|
|
6
|
+
} from "./chunk-7U5TXA5Q.js";
|
|
7
|
+
import "./chunk-D3T54RSL.js";
|
|
101
8
|
export {
|
|
102
9
|
Chip,
|
|
103
10
|
ChipGroup,
|
package/dist/chip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chip/chip.tsx","../src/chip/recipe.ts"],"sourcesContent":["// Client (a context). A chip is a pressable pill: alone it is a Radix Toggle (aria-pressed), inside `Chip.Group` an\n// item of a Radix Toggle Group (roving focus with the arrows; `single` = radio semantics, `multiple` = pressed\n// buttons). A `removable` chip is a static label with its own remove button (two buttons cannot nest).\nimport { Toggle as TogglePrimitive, ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { useRouteBinding } from \"../router\";\nimport { chipRecipe } from \"./recipe\";\n\nexport const chip = tv(chipRecipe);\n\nexport type ChipVariants = VariantProps<typeof chip>;\n\ntype GroupContext = { size: ChipVariants[\"size\"] };\nconst ChipGroupContext = React.createContext<GroupContext | null>(null);\n\nfunction RemoveIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\ntype ToggleChipProps = Omit<React.ComponentProps<\"button\">, \"value\" | \"defaultValue\"> &\n ChipVariants & {\n /**\n * sm · md (inside `Chip.Group`, the group's size by default).\n * @default \"md\"\n */\n size?: ChipVariants[\"size\"];\n /** Inside `Chip.Group`: the value this chip stands for (required there, ignored alone). */\n value?: string;\n /** Alone: pressed or not (`defaultSelected` uncontrolled), `onSelectedChange` on every press. */\n selected?: boolean;\n /** Alone: pressed at first, uncontrolled. */\n defaultSelected?: boolean;\n /** Alone: called with the new state on every press. */\n onSelectedChange?: (selected: boolean) => void;\n /** A pressable chip (the default); `true` makes it a static chip with a remove button. */\n removable?: false;\n };\n\ntype RemovableChipProps = Omit<React.ComponentProps<\"span\">, \"onSelect\"> &\n ChipVariants & {\n /** A static chip (a chosen tag, an applied filter) with a remove button. */\n removable: true;\n /** The accessible name of the remove button — passed translated, e.g. \"Remove #night\". */\n removeLabel: string;\n /** Runs when the remove button is pressed. */\n onRemove: () => void;\n /** Disables the remove button. */\n disabled?: boolean;\n };\n\nexport type ChipProps = ToggleChipProps | RemovableChipProps;\n\n/** A selectable pill (`selected` / `onSelectedChange`), an item of `Chip.Group` (`value`), or `removable`. */\nfunction ChipBase(props: ChipProps) {\n const group = React.useContext(ChipGroupContext);\n if (props.removable) {\n const { removable: _removable, removeLabel, onRemove, disabled, size, className, children, ...rest } = props;\n const s = chip({ size: size ?? group?.size });\n return (\n <span data-removable=\"\" className={s.base({ className })} {...rest}>\n {children}\n <button type=\"button\" aria-label={removeLabel} title={removeLabel} disabled={disabled} onClick={onRemove} className={s.remove()}>\n <RemoveIcon />\n </button>\n </span>\n );\n }\n const { removable: _removable, value, selected, defaultSelected, onSelectedChange, size, className, ...rest } = props;\n const s = chip({ size: size ?? group?.size });\n if (group) {\n if (value === undefined) throw new Error(\"Chip: a chip inside Chip.Group needs a `value`.\");\n return <ToggleGroupPrimitive.Item value={value} className={s.base({ className })} {...rest} />;\n }\n return (\n <TogglePrimitive.Root\n pressed={selected}\n defaultPressed={defaultSelected}\n onPressedChange={onSelectedChange}\n className={s.base({ className })}\n {...rest}\n />\n );\n}\n\ntype GroupBase = Omit<React.ComponentProps<\"div\">, \"defaultValue\" | \"dir\"> &\n ChipVariants & {\n /**\n * sm · md: the size of every chip of the group.\n * @default \"md\"\n */\n size?: ChipVariants[\"size\"];\n /** The group's accessible name — passed translated (\"Filter by format\"). */\n label?: string;\n /** The arrow keys that move: left / right (horizontal, a row) or up / down (vertical, a column). */\n orientation?: \"horizontal\" | \"vertical\";\n /** Arrow keys wrap from the last chip to the first (default `true`). */\n loop?: boolean;\n /** Disables every chip of the group. */\n disabled?: boolean;\n };\n\nexport type ChipGroupProps =\n | (GroupBase & {\n /** One choice: the chips behave as radios. */\n type: \"single\";\n /** The chosen value (controlled), `\"\"` when none. */\n value?: string;\n /** The value chosen at first, uncontrolled. */\n defaultValue?: string;\n /** Called with the new value on every choice. */\n onValueChange?: (value: string) => void;\n /** Keeps one chip selected: pressing the selected chip does not clear it (default `false`). */\n required?: boolean;\n /** Binds the choice to this search parameter of the URL (`?type=…`): the URL is the state. Without it the state is local — only for an ephemeral choice. */\n routeKey?: string;\n /** The values the parameter may hold (the chips' `value`s). */\n routeValues?: readonly string[];\n })\n | (GroupBase & {\n /** Any number of choices: the chips are pressed buttons. */\n type: \"multiple\";\n /** The chosen values (controlled). */\n value?: string[];\n /** The values chosen at first, uncontrolled. */\n defaultValue?: string[];\n /** Called with the new values on every press. */\n onValueChange?: (value: string[]) => void;\n required?: never;\n routeKey?: never;\n routeValues?: never;\n });\n\n/** Chips that choose together: `type` single · multiple, `value`/`defaultValue` + `onValueChange`. */\nexport function ChipGroup({ label, size, className, children, ...props }: ChipGroupProps) {\n const single = props.type === \"single\" ? props : undefined;\n const routed = useRouteBinding(single?.routeKey, single?.routeValues, { value: single?.value, defaultValue: single?.defaultValue, onValueChange: single?.onValueChange });\n const s = chip({ size });\n const context = React.useMemo(() => ({ size }), [size]);\n const common = { \"aria-label\": label, className: s.group({ className }) };\n let group: React.ReactNode;\n if (props.type === \"single\") {\n const { type: _type, value: _value, defaultValue: _defaultValue, onValueChange: _onValueChange, required, routeKey: _routeKey, routeValues: _routeValues, ...rest } = props;\n group = <SingleGroup {...rest} {...common} value={routed.value} defaultValue={routed.defaultValue} onValueChange={routed.onValueChange} required={required}>{children}</SingleGroup>;\n } else {\n const { type: _type, required: _required, ...rest } = props;\n group = (\n <ToggleGroupPrimitive.Root type=\"multiple\" {...rest} {...common}>\n {children}\n </ToggleGroupPrimitive.Root>\n );\n }\n return <ChipGroupContext.Provider value={context}>{group}</ChipGroupContext.Provider>;\n}\n\n/** Radix's single group, plus `required`: the value is held here so that an empty change can be refused. */\nfunction SingleGroup({\n value,\n defaultValue,\n onValueChange,\n required,\n ...props\n}: Omit<GroupBase, \"size\" | \"label\"> & {\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n required?: boolean;\n}) {\n const [inner, setInner] = React.useState(defaultValue ?? \"\");\n const current = value ?? inner;\n return (\n <ToggleGroupPrimitive.Root\n type=\"single\"\n value={current}\n onValueChange={(next) => {\n if (required && !next) return;\n if (value === undefined) setInner(next);\n onValueChange?.(next);\n }}\n {...props}\n />\n );\n}\n\n/** `Chip` (selectable, removable) and `Chip.Group` (single · multiple). */\nexport const Chip = Object.assign(ChipBase, { Group: ChipGroup });\n","// The chip's parts and sizes, written once as classes of the Krizaka tokens: the web wears them with `tv(chipRecipe)`,\n// React Native reads the same classes into styles (native/chip.tsx). `data-[state=on]:` is the chosen chip.\nimport { defineRecipe } from \"../recipes/define\";\n\nexport const chipRecipe = defineRecipe({\n slots: {\n group: \"flex flex-wrap items-center gap-2 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch\",\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-sm border font-semibold transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 \" +\n \"border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg \" +\n \"data-[state=on]:border-accent data-[state=on]:bg-accent-soft data-[state=on]:text-fg\",\n remove:\n \"-mr-1.5 inline-flex h-6 w-6 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n variants: {\n size: { sm: { base: \"h-7 px-3 text-xs\" }, md: { base: \"h-9 px-3.5 text-xs\" } },\n },\n defaultVariants: { size: \"md\" },\n});\n"],"mappings":"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","names":["_removable","size","className","rest","s"]}
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/choice-grid.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunk-WU4VLSEA.js";
|
|
9
9
|
|
|
10
10
|
// src/choice-grid/choice-grid.tsx
|
|
11
|
-
import * as
|
|
11
|
+
import * as React from "react";
|
|
12
12
|
|
|
13
13
|
// src/block-link.tsx
|
|
14
14
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -25,69 +25,9 @@ function BlockLink({
|
|
|
25
25
|
return /* @__PURE__ */ jsx(Comp, { href, rel, ...props });
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
// src/router/route-state.tsx
|
|
29
|
-
import * as React from "react";
|
|
30
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
31
|
-
var CHANGE = "kz-route-state";
|
|
32
|
-
var browserAdapter = {
|
|
33
|
-
search: () => typeof window === "undefined" ? "" : window.location.search,
|
|
34
|
-
navigate: (search, { replace }) => {
|
|
35
|
-
const url = `${window.location.pathname}${search}${window.location.hash}`;
|
|
36
|
-
window.history[replace ? "replaceState" : "pushState"](window.history.state, "", url);
|
|
37
|
-
window.dispatchEvent(new Event(CHANGE));
|
|
38
|
-
},
|
|
39
|
-
subscribe: (onChange) => {
|
|
40
|
-
window.addEventListener("popstate", onChange);
|
|
41
|
-
window.addEventListener(CHANGE, onChange);
|
|
42
|
-
return () => {
|
|
43
|
-
window.removeEventListener("popstate", onChange);
|
|
44
|
-
window.removeEventListener(CHANGE, onChange);
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
var AdapterContext = React.createContext(browserAdapter);
|
|
49
|
-
function readRouteValue(search, key, { values, default: fallback }) {
|
|
50
|
-
const raw = new URLSearchParams(search).get(key);
|
|
51
|
-
if (raw === null) return fallback;
|
|
52
|
-
return !values || values.includes(raw) ? raw : fallback;
|
|
53
|
-
}
|
|
54
|
-
function writeRouteValue(search, key, value, fallback) {
|
|
55
|
-
const params = new URLSearchParams(search);
|
|
56
|
-
if (value === fallback) params.delete(key);
|
|
57
|
-
else params.set(key, value);
|
|
58
|
-
const text = params.toString();
|
|
59
|
-
return text ? `?${text}` : "";
|
|
60
|
-
}
|
|
61
|
-
function useRouteState(key, { values, default: fallback, history = "push" }) {
|
|
62
|
-
const adapter = React.useContext(AdapterContext);
|
|
63
|
-
const search = React.useSyncExternalStore(adapter.subscribe, adapter.search, () => "");
|
|
64
|
-
const value = key === void 0 ? fallback : readRouteValue(search, key, { values, default: fallback });
|
|
65
|
-
const set = React.useCallback(
|
|
66
|
-
(next) => {
|
|
67
|
-
if (key === void 0) return;
|
|
68
|
-
adapter.navigate(writeRouteValue(adapter.search(), key, next, fallback), { replace: history === "replace" });
|
|
69
|
-
},
|
|
70
|
-
[adapter, key, fallback, history]
|
|
71
|
-
);
|
|
72
|
-
return [value, set];
|
|
73
|
-
}
|
|
74
|
-
function useRouteBinding(routeKey, routeValues, props) {
|
|
75
|
-
const initial = props.defaultValue ?? props.value ?? routeValues?.[0] ?? "";
|
|
76
|
-
const [value, set] = useRouteState(routeKey, { values: routeValues, default: initial });
|
|
77
|
-
if (routeKey === void 0) return props;
|
|
78
|
-
return {
|
|
79
|
-
...props,
|
|
80
|
-
value,
|
|
81
|
-
defaultValue: void 0,
|
|
82
|
-
onValueChange: (next) => {
|
|
83
|
-
set(next);
|
|
84
|
-
props.onValueChange?.(next);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
28
|
// src/choice-grid/choice-grid.tsx
|
|
90
|
-
import {
|
|
29
|
+
import { useRouteBinding } from "@krizaka/ui/router";
|
|
30
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
91
31
|
var CORNERS = ["tl", "tr", "bl", "br"];
|
|
92
32
|
function ChoiceGrid({
|
|
93
33
|
label,
|
|
@@ -111,9 +51,9 @@ function ChoiceGrid({
|
|
|
111
51
|
}) {
|
|
112
52
|
const { value, defaultValue, onValueChange } = useRouteBinding(routeKey, routeValues, { value: valueProp, defaultValue: defaultValueProp, onValueChange: onValueChangeProp });
|
|
113
53
|
const selectable = onValueChange !== void 0 || value !== void 0;
|
|
114
|
-
const [inner, setInner] =
|
|
54
|
+
const [inner, setInner] = React.useState(defaultValue);
|
|
115
55
|
const current = value ?? inner;
|
|
116
|
-
const refs =
|
|
56
|
+
const refs = React.useRef([]);
|
|
117
57
|
const enabled = items.map((item, i) => item.disabled ? -1 : i).filter((i) => i >= 0);
|
|
118
58
|
const chosenIndex = items.findIndex((item) => item.id === current && !item.disabled);
|
|
119
59
|
const focusIndex = chosenIndex >= 0 ? chosenIndex : enabled[0] ?? 0;
|
|
@@ -139,40 +79,40 @@ function ChoiceGrid({
|
|
|
139
79
|
const Item = selectable ? "div" : "li";
|
|
140
80
|
const vars = { "--kzs-cols": columns ?? Math.min(items.length, 4), ...style };
|
|
141
81
|
return /* @__PURE__ */ jsxs("div", { "data-kzs-scene": "", "data-animated": animated ? "" : void 0, className: cn("kzs-choice", storyVariantClass(variant), brandClass(brand), className), style: vars, ...props, children: [
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-texture", "aria-hidden": true }),
|
|
83
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-scan kzs-loop", "aria-hidden": true }),
|
|
144
84
|
(tag || caption) && /* @__PURE__ */ jsxs("p", { className: "kzs-choice-head", children: [
|
|
145
|
-
tag && /* @__PURE__ */
|
|
146
|
-
tag && caption && /* @__PURE__ */
|
|
147
|
-
caption && /* @__PURE__ */
|
|
85
|
+
tag && /* @__PURE__ */ jsx2("span", { className: "kzs-choice-tag", children: tag }),
|
|
86
|
+
tag && caption && /* @__PURE__ */ jsx2("span", { className: "kzs-choice-sep", "aria-hidden": true }),
|
|
87
|
+
caption && /* @__PURE__ */ jsx2("span", { className: "kzs-choice-caption", children: caption })
|
|
148
88
|
] }),
|
|
149
|
-
prompt && /* @__PURE__ */
|
|
150
|
-
/* @__PURE__ */
|
|
89
|
+
prompt && /* @__PURE__ */ jsx2("p", { className: "kzs-choice-prompt", children: prompt }),
|
|
90
|
+
/* @__PURE__ */ jsx2(Grid, { className: "kzs-choice-grid", role: selectable ? "radiogroup" : void 0, "aria-label": label, children: items.map((item, i) => {
|
|
151
91
|
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
152
|
-
/* @__PURE__ */
|
|
153
|
-
/* @__PURE__ */
|
|
154
|
-
CORNERS.map((at) => /* @__PURE__ */
|
|
92
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-choice-aura", "aria-hidden": true }),
|
|
93
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-choice-flash", "aria-hidden": true }),
|
|
94
|
+
CORNERS.map((at) => /* @__PURE__ */ jsx2("span", { className: "kzs-corner", "data-at": at, "aria-hidden": true }, at)),
|
|
155
95
|
(item.badge || item.eyebrow || item.icon) && /* @__PURE__ */ jsxs("span", { className: "kzs-choice-top", children: [
|
|
156
|
-
item.badge ? /* @__PURE__ */
|
|
96
|
+
item.badge ? /* @__PURE__ */ jsx2("span", { className: "kzs-choice-badge", children: item.badge }) : /* @__PURE__ */ jsx2("span", {}),
|
|
157
97
|
(item.eyebrow || item.icon) && /* @__PURE__ */ jsxs("span", { className: "kzs-choice-eyebrow", children: [
|
|
158
|
-
item.icon && /* @__PURE__ */
|
|
98
|
+
item.icon && /* @__PURE__ */ jsx2("span", { "aria-hidden": true, children: item.icon }),
|
|
159
99
|
item.eyebrow
|
|
160
100
|
] })
|
|
161
101
|
] }),
|
|
162
102
|
/* @__PURE__ */ jsxs("span", { className: "kzs-choice-frame", "aria-hidden": true, children: [
|
|
163
|
-
/* @__PURE__ */
|
|
164
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-choice-floor" }),
|
|
104
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-choice-visual", children: item.visual })
|
|
165
105
|
] }),
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
item.title && /* @__PURE__ */
|
|
168
|
-
item.extra && /* @__PURE__ */
|
|
169
|
-
item.meta && /* @__PURE__ */
|
|
170
|
-
/* @__PURE__ */
|
|
106
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-choice-name", children: item.name }),
|
|
107
|
+
item.title && /* @__PURE__ */ jsx2("span", { className: "kzs-choice-title", children: item.title }),
|
|
108
|
+
item.extra && /* @__PURE__ */ jsx2("span", { className: "kzs-choice-extra", children: item.extra }),
|
|
109
|
+
item.meta && /* @__PURE__ */ jsx2("span", { className: "kzs-choice-meta", children: item.meta }),
|
|
110
|
+
/* @__PURE__ */ jsx2("span", { className: "kzs-choice-check", "aria-hidden": true, children: /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", width: "12", height: "12", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx2("path", { d: "m5 12 5 5 9-10" }) }) })
|
|
171
111
|
] });
|
|
172
112
|
const itemStyle = { "--i": i };
|
|
173
113
|
let tile;
|
|
174
114
|
if (selectable)
|
|
175
|
-
tile = /* @__PURE__ */
|
|
115
|
+
tile = /* @__PURE__ */ jsx2(
|
|
176
116
|
"button",
|
|
177
117
|
{
|
|
178
118
|
ref: (el) => {
|
|
@@ -192,10 +132,10 @@ function ChoiceGrid({
|
|
|
192
132
|
}
|
|
193
133
|
);
|
|
194
134
|
else if (item.href)
|
|
195
|
-
tile = /* @__PURE__ */
|
|
135
|
+
tile = /* @__PURE__ */ jsx2(BlockLink, { href: item.href, linkAs, className: "kzs-choice-item", "data-link": "", style: itemStyle, children: body });
|
|
196
136
|
else
|
|
197
|
-
tile = /* @__PURE__ */
|
|
198
|
-
return /* @__PURE__ */
|
|
137
|
+
tile = /* @__PURE__ */ jsx2("div", { className: "kzs-choice-item", style: itemStyle, children: body });
|
|
138
|
+
return /* @__PURE__ */ jsx2(Item, { className: cn("kzs-choice-slot", brandClass(item.brand)), style: itemStyle, children: tile }, item.id);
|
|
199
139
|
}) })
|
|
200
140
|
] });
|
|
201
141
|
}
|