@krizaka/ui 3.21.0 → 3.23.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 +5 -0
- package/dist/achievement.js +1 -1
- package/dist/action-bar.js +4 -4
- package/dist/app-header.d.ts +79 -0
- package/dist/app-header.js +32 -0
- package/dist/app-header.js.map +1 -0
- package/dist/app-shell.d.ts +20 -2
- package/dist/app-shell.js +35 -20
- package/dist/app-shell.js.map +1 -1
- package/dist/argument-card.d.ts +4 -1
- package/dist/argument-card.js +8 -5
- package/dist/argument-card.js.map +1 -1
- package/dist/audio-player.d.ts +3 -2
- package/dist/audio-player.js +14 -10
- package/dist/audio-player.js.map +1 -1
- package/dist/blocks.css +28 -0
- package/dist/button.js +2 -1
- package/dist/captcha.d.ts +81 -0
- package/dist/captcha.js +162 -0
- package/dist/captcha.js.map +1 -0
- package/dist/card-grid.d.ts +10 -1
- package/dist/card-grid.js +3 -2
- package/dist/card-grid.js.map +1 -1
- package/dist/card.js +3 -3
- package/dist/changelog-page.d.ts +57 -3
- package/dist/changelog-page.js +117 -1
- package/dist/changelog-page.js.map +1 -1
- package/dist/choice-grid.js +1 -1
- package/dist/{chunk-5MH64NIL.js → chunk-2L67YTNV.js} +2 -2
- package/dist/{chunk-3IN6TOPM.js → chunk-6ZYRUOTA.js} +6 -3
- package/dist/chunk-6ZYRUOTA.js.map +1 -0
- package/dist/chunk-APNIVNIX.js +54 -0
- package/dist/chunk-APNIVNIX.js.map +1 -0
- package/dist/{chunk-FKBHWS4N.js → chunk-CEJDH6SA.js} +2 -2
- package/dist/{chunk-OWC2LZD2.js → chunk-CHOJUCVE.js} +6 -3
- package/dist/chunk-CHOJUCVE.js.map +1 -0
- package/dist/{chunk-3BC4XQ6C.js → chunk-DZU6RMYD.js} +6 -3
- package/dist/chunk-DZU6RMYD.js.map +1 -0
- package/dist/chunk-F7FVPPBB.js +1080 -0
- package/dist/chunk-F7FVPPBB.js.map +1 -0
- package/dist/{chunk-5Z7FWCV2.js → chunk-HBZPJ3EP.js} +2 -2
- package/dist/{chunk-C2BRIFJG.js → chunk-HJFRHYCI.js} +2 -2
- package/dist/{chunk-ZNMFG62E.js → chunk-KH3JOEPY.js} +3 -2
- package/dist/chunk-KH3JOEPY.js.map +1 -0
- package/dist/{chunk-BTMFZ66D.js → chunk-KM6VAKIE.js} +2 -2
- package/dist/{chunk-DGQMDJXK.js → chunk-LZNZLCOE.js} +2 -2
- package/dist/chunk-MQPC3P4T.js +126 -0
- package/dist/chunk-MQPC3P4T.js.map +1 -0
- package/dist/{chunk-2FRWNSRO.js → chunk-NSLXEDIS.js} +3 -2
- package/dist/chunk-NSLXEDIS.js.map +1 -0
- package/dist/{chunk-3GODX3D6.js → chunk-QDXV544C.js} +2 -2
- package/dist/chunk-QDXV544C.js.map +1 -0
- package/dist/{chunk-4LOMIQVX.js → chunk-W675RFOA.js} +3 -2
- package/dist/chunk-W675RFOA.js.map +1 -0
- package/dist/{chunk-G3ETON2A.js → chunk-WU4VLSEA.js} +3 -2
- package/dist/chunk-WU4VLSEA.js.map +1 -0
- package/dist/{chunk-IZ7MV6HM.js → chunk-XVFQZ3ZG.js} +3 -2
- package/dist/chunk-XVFQZ3ZG.js.map +1 -0
- package/dist/{chunk-LIPK4UCS.js → chunk-YCIBJ6OQ.js} +140 -209
- package/dist/chunk-YCIBJ6OQ.js.map +1 -0
- package/dist/cn.js +1 -1
- package/dist/code-block.js +2 -2
- package/dist/code-block.js.map +1 -1
- package/dist/command.js +3 -3
- package/dist/comparison-table.d.ts +44 -0
- package/dist/comparison-table.js +84 -0
- package/dist/comparison-table.js.map +1 -0
- package/dist/confirm-button.js +2 -2
- package/dist/continue-prompt.js +3 -3
- package/dist/continue-prompt.js.map +1 -1
- package/dist/cta-panel.js +1 -1
- package/dist/data-table.js +19 -1066
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.js +4 -4
- package/dist/decision-list.js +1 -1
- package/dist/dialog.js +3 -2
- package/dist/dialog.js.map +1 -1
- package/dist/docs-nav.d.ts +36 -0
- package/dist/docs-nav.js +44 -0
- package/dist/docs-nav.js.map +1 -0
- package/dist/dropdown-menu.js +1 -1
- package/dist/error-page.js +1 -1
- package/dist/field.js +1 -1
- package/dist/filter-bar.js +2 -2
- package/dist/force-update-screen.js +2 -1
- package/dist/force-update-screen.js.map +1 -1
- package/dist/gallery-page.js +1 -1
- package/dist/genui.d.ts +221 -0
- package/dist/genui.js +533 -0
- package/dist/genui.js.map +1 -0
- package/dist/glow-card.js +1 -1
- package/dist/goal-gauge.js +1 -1
- package/dist/how-it-works-page.js +1 -1
- package/dist/image-cropper.js +3 -3
- package/dist/index.d.ts +17 -24
- package/dist/index.js +4 -4
- package/dist/landscape.js +1 -1
- package/dist/link-card.d.ts +9 -2
- package/dist/link-card.js +5 -44
- package/dist/link-card.js.map +1 -1
- package/dist/longform-page.js +1 -1
- package/dist/maintenance-screen.js +2 -1
- package/dist/maintenance-screen.js.map +1 -1
- package/dist/map.js +3 -3
- package/dist/map.js.map +1 -1
- package/dist/markdown.js +2 -1
- package/dist/markdown.js.map +1 -1
- package/dist/marketing-layout.js +1 -1
- package/dist/marketing-layout.js.map +1 -1
- package/dist/marquee.js +1 -1
- package/dist/mascot-quote.js +1 -1
- package/dist/match-dialog.js +2 -1
- package/dist/match-dialog.js.map +1 -1
- package/dist/media-grid.d.ts +26 -4
- package/dist/media-grid.js +122 -163
- package/dist/media-grid.js.map +1 -1
- package/dist/meta-row.d.ts +54 -0
- package/dist/meta-row.js +35 -0
- package/dist/meta-row.js.map +1 -0
- package/dist/native/map.js +3 -3
- package/dist/native/map.js.map +1 -1
- package/dist/native.d.ts +42 -16
- package/dist/native.js +591 -537
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.js +3 -3
- package/dist/page-hero.js +5 -5
- package/dist/page.js +2 -2
- package/dist/popover.js +1 -1
- package/dist/pricing-page.js +1 -1
- package/dist/product-page.js +1 -1
- package/dist/profile-card.js +1 -1
- package/dist/promise-card.js +1 -1
- package/dist/radio-group.js +2 -2
- package/dist/rail-nav.d.ts +149 -0
- package/dist/rail-nav.js +177 -0
- package/dist/rail-nav.js.map +1 -0
- package/dist/scroll-stage.js +1 -1
- package/dist/settings-layout.d.ts +75 -62
- package/dist/settings-layout.js +39 -6
- package/dist/settings-layout.js.map +1 -1
- package/dist/showcase.js +1 -1
- package/dist/site-footer.d.ts +48 -67
- package/dist/site-footer.js +36 -12
- package/dist/site-footer.js.map +1 -1
- package/dist/skip-link.js +1 -1
- package/dist/slider.js +2 -2
- package/dist/stage-banner.js +1 -1
- package/dist/step-showcase.d.ts +62 -0
- package/dist/step-showcase.js +227 -0
- package/dist/step-showcase.js.map +1 -0
- package/dist/tabs.js +1 -1
- package/dist/tabs.js.map +1 -1
- package/dist/terminal-replay.js +1 -1
- package/dist/theme.js +2 -1
- package/dist/theme.js.map +1 -1
- package/dist/toast.js +1 -1
- package/dist/toc.js +1 -1
- package/dist/tooltip.js +1 -1
- package/dist/update-prompt.js +2 -1
- package/dist/update-prompt.js.map +1 -1
- package/dist/vertical-video.js +2 -2
- package/dist/video-player.js +3 -3
- package/dist/waveform.d.ts +93 -0
- package/dist/waveform.js +95 -0
- package/dist/waveform.js.map +1 -0
- package/package.json +138 -10
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/activity-feed.json +1 -1
- package/registry/alert.json +1 -1
- package/registry/app-header.json +202 -0
- package/registry/app-shell.json +33 -9
- package/registry/argument-card.json +37 -5
- package/registry/audio-player.json +5 -3
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +3 -2
- package/registry/captcha.json +300 -0
- package/registry/card-grid.json +27 -3
- package/registry/card.json +1 -1
- package/registry/catalogue-page.json +1 -1
- package/registry/changelog-page.json +11 -7
- package/registry/chat.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/choice-grid.json +1 -1
- package/registry/cn.json +1 -1
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +1 -1
- package/registry/command.json +1 -1
- package/registry/comparison-table.json +207 -0
- package/registry/component-page.json +1 -1
- package/registry/confirm-button.json +1 -1
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +1 -1
- package/registry/date-picker.json +1 -1
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +1 -1
- package/registry/detail-layout.json +1 -1
- package/registry/dialog.json +1 -1
- package/registry/docs-article-page.json +1 -1
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/docs-nav.json +177 -0
- package/registry/document-viewer.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +1 -1
- package/registry/examples/activity-feed/native/notifications.light.png +0 -0
- package/registry/examples/app-header/basic.d.ts +4 -0
- package/registry/examples/app-header/basic.js +23 -0
- package/registry/examples/app-header/basic.tsx +17 -0
- package/registry/examples/app-shell/desktop.d.ts +4 -0
- package/registry/examples/app-shell/desktop.js +41 -0
- package/registry/examples/app-shell/desktop.tsx +37 -0
- package/registry/examples/argument-card/hover-light.d.ts +4 -0
- package/registry/examples/argument-card/hover-light.js +17 -0
- package/registry/examples/argument-card/hover-light.tsx +19 -0
- package/registry/examples/argument-card/hover-quiet.d.ts +4 -0
- package/registry/examples/argument-card/hover-quiet.js +17 -0
- package/registry/examples/argument-card/hover-quiet.tsx +19 -0
- package/registry/examples/avatar/native/group.light.png +0 -0
- package/registry/examples/avatar/native/presence.light.png +0 -0
- package/registry/examples/avatar/native/sizes.light.png +0 -0
- package/registry/examples/badge/native/tones.light.png +0 -0
- package/registry/examples/button/native/ghost.light.png +0 -0
- package/registry/examples/captcha/disclosure.d.ts +4 -0
- package/registry/examples/captcha/disclosure.js +14 -0
- package/registry/examples/captcha/disclosure.tsx +11 -0
- package/registry/examples/captcha/form.d.ts +4 -0
- package/registry/examples/captcha/form.js +18 -0
- package/registry/examples/captcha/form.tsx +17 -0
- package/registry/examples/card/native/body.light.png +0 -0
- package/registry/examples/card/native/default.light.png +0 -0
- package/registry/examples/card/native/elevated.light.png +0 -0
- package/registry/examples/card/native/pressable.light.png +0 -0
- package/registry/examples/card-grid/hover-quiet.d.ts +4 -0
- package/registry/examples/card-grid/hover-quiet.js +18 -0
- package/registry/examples/card-grid/hover-quiet.tsx +20 -0
- package/registry/examples/changelog-page/releases.js +1 -1
- package/registry/examples/changelog-page/releases.tsx +1 -1
- package/registry/examples/chat/native/conversation.light.png +0 -0
- package/registry/examples/chat/native/inbox.light.png +0 -0
- package/registry/examples/chip/native/multiple.light.png +0 -0
- package/registry/examples/chip/native/removable.light.png +0 -0
- package/registry/examples/chip/native/single.light.png +0 -0
- package/registry/examples/chip/native/toggle.light.png +0 -0
- package/registry/examples/combobox/native/multiple.light.png +0 -0
- package/registry/examples/combobox/native/search.light.png +0 -0
- package/registry/examples/comparison-table/versus.d.ts +4 -0
- package/registry/examples/comparison-table/versus.js +28 -0
- package/registry/examples/comparison-table/versus.tsx +20 -0
- package/registry/examples/countdown/native/days.light.png +0 -0
- package/registry/examples/countdown/native/hours.light.png +0 -0
- package/registry/examples/countdown/native/sizes.light.png +0 -0
- package/registry/examples/countdown/native/urgent.light.png +0 -0
- package/registry/examples/countdown/native/with-label.light.png +0 -0
- package/registry/examples/date-picker/native/birth-date-wheel.light.png +0 -0
- package/registry/examples/date-picker/native/birth-date.light.png +0 -0
- package/registry/examples/date-picker/native/calendar.dark.png +0 -0
- package/registry/examples/date-picker/native/calendar.light.png +0 -0
- package/registry/examples/date-picker/native/day-strip.dark.png +0 -0
- package/registry/examples/date-picker/native/day-strip.light.png +0 -0
- package/registry/examples/date-picker/native/time-slots.dark.png +0 -0
- package/registry/examples/date-picker/native/time-slots.light.png +0 -0
- package/registry/examples/date-picker/native/time-wheel.light.png +0 -0
- package/registry/examples/description-list/native/job-details.light.png +0 -0
- package/registry/examples/dialog/native/sheet.dark.png +0 -0
- package/registry/examples/dialog/native/sheet.light.png +0 -0
- package/registry/examples/docs-nav/groups.d.ts +4 -0
- package/registry/examples/docs-nav/groups.js +21 -0
- package/registry/examples/docs-nav/groups.tsx +15 -0
- package/registry/examples/empty-state/native/default.light.png +0 -0
- package/registry/examples/field/native/default.light.png +0 -0
- package/registry/examples/field/native/select.light.png +0 -0
- package/registry/examples/force-update-screen/native/default.light.png +0 -0
- package/registry/examples/form/native/amount.light.png +0 -0
- package/registry/examples/form/native/audience.light.png +0 -0
- package/registry/examples/form/native/profile.light.png +0 -0
- package/registry/examples/form/native/settings.light.png +0 -0
- package/registry/examples/form/native/sign-up.light.png +0 -0
- package/registry/examples/form/native/upload.dark.png +0 -0
- package/registry/examples/form/native/upload.light.png +0 -0
- package/registry/examples/genui/streaming.d.ts +4 -0
- package/registry/examples/genui/streaming.js +18 -0
- package/registry/examples/genui/streaming.tsx +14 -0
- package/registry/examples/genui/table.d.ts +4 -0
- package/registry/examples/genui/table.js +19 -0
- package/registry/examples/genui/table.tsx +14 -0
- package/registry/examples/goal-gauge/native/default.light.png +0 -0
- package/registry/examples/header/native/large-title.light.png +0 -0
- package/registry/examples/link-card/hover-light.d.ts +4 -0
- package/registry/examples/link-card/hover-light.js +18 -0
- package/registry/examples/link-card/hover-light.tsx +20 -0
- package/registry/examples/link-card/hover-quiet.d.ts +4 -0
- package/registry/examples/link-card/hover-quiet.js +18 -0
- package/registry/examples/link-card/hover-quiet.tsx +20 -0
- package/registry/examples/loader/native/job-wait.light.png +0 -0
- package/registry/examples/maintenance-screen/native/default.light.png +0 -0
- package/registry/examples/map/native/places.light.png +0 -0
- package/registry/examples/markdown/native/basic.light.png +0 -0
- package/registry/examples/mascot-state/native/default.light.png +0 -0
- package/registry/examples/media-picker/native/story.light.png +0 -0
- package/registry/examples/meta-row/native/video.d.ts +4 -0
- package/registry/examples/meta-row/native/video.dark.png +0 -0
- package/registry/examples/meta-row/native/video.js +11 -0
- package/registry/examples/meta-row/native/video.light.png +0 -0
- package/registry/examples/meta-row/native/video.tsx +5 -0
- package/registry/examples/meta-row/status.d.ts +4 -0
- package/registry/examples/meta-row/status.js +12 -0
- package/registry/examples/meta-row/status.tsx +7 -0
- package/registry/examples/meta-row/video.d.ts +4 -0
- package/registry/examples/meta-row/video.js +12 -0
- package/registry/examples/meta-row/video.tsx +7 -0
- package/registry/examples/meter/native/credits.light.png +0 -0
- package/registry/examples/meter/native/split-ring.light.png +0 -0
- package/registry/examples/number-ticker/native/balance.light.png +0 -0
- package/registry/examples/onboarding/native/first-launch.light.png +0 -0
- package/registry/examples/otp-input/native/verify.light.png +0 -0
- package/registry/examples/pagination/native/cursor.light.png +0 -0
- package/registry/examples/pagination/native/pages.light.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.light.png +0 -0
- package/registry/examples/permission-prompt/native/camera.light.png +0 -0
- package/registry/examples/profile-card/native/default.light.png +0 -0
- package/registry/examples/radio-group/native/buttons.light.png +0 -0
- package/registry/examples/radio-group/native/cards.light.png +0 -0
- package/registry/examples/radio-group/native/list.light.png +0 -0
- package/registry/examples/radio-group/native/segmented.light.png +0 -0
- package/registry/examples/rail-nav/expandable.d.ts +4 -0
- package/registry/examples/rail-nav/expandable.js +34 -0
- package/registry/examples/rail-nav/expandable.tsx +28 -0
- package/registry/examples/rail-nav/studio.d.ts +4 -0
- package/registry/examples/rail-nav/studio.js +43 -0
- package/registry/examples/rail-nav/studio.tsx +38 -0
- package/registry/examples/screen/native/app-shell.light.png +0 -0
- package/registry/examples/screen/native/auth.light.png +0 -0
- package/registry/examples/screen/native/map.light.png +0 -0
- package/registry/examples/screen/native/notifications.light.png +0 -0
- package/registry/examples/screen/native/profile.light.png +0 -0
- package/registry/examples/segmented/native/default.light.png +0 -0
- package/registry/examples/segmented/native/small.light.png +0 -0
- package/registry/examples/settings-layout/flat.d.ts +4 -0
- package/registry/examples/settings-layout/flat.js +26 -0
- package/registry/examples/settings-layout/flat.tsx +30 -0
- package/registry/examples/showcase/native/slides.light.png +0 -0
- package/registry/examples/site-footer/app.d.ts +4 -0
- package/registry/examples/site-footer/app.js +25 -0
- package/registry/examples/site-footer/app.tsx +22 -0
- package/registry/examples/site-footer/docs.d.ts +4 -0
- package/registry/examples/site-footer/docs.js +31 -0
- package/registry/examples/site-footer/docs.tsx +24 -0
- package/registry/examples/slider/native/default.light.png +0 -0
- package/registry/examples/slider/native/stepped.light.png +0 -0
- package/registry/examples/step-progress/native/sign-up.light.png +0 -0
- package/registry/examples/step-showcase/desktop.d.ts +4 -0
- package/registry/examples/step-showcase/desktop.js +24 -0
- package/registry/examples/step-showcase/desktop.tsx +19 -0
- package/registry/examples/step-showcase/phone.d.ts +4 -0
- package/registry/examples/step-showcase/phone.js +24 -0
- package/registry/examples/step-showcase/phone.tsx +19 -0
- package/registry/examples/stepper/native/run.light.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.light.png +0 -0
- package/registry/examples/switch/native/settings.light.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.light.png +0 -0
- package/registry/examples/tabs/native/sections.light.png +0 -0
- package/registry/examples/tabs/native/segmented.light.png +0 -0
- package/registry/examples/tag-selector/native/interests.light.png +0 -0
- package/registry/examples/toast/native/tones.light.png +0 -0
- package/registry/examples/txt/native/tones.dark.png +0 -0
- package/registry/examples/txt/native/tones.light.png +0 -0
- package/registry/examples/update-prompt/native/default.light.png +0 -0
- package/registry/examples/waveform/card.d.ts +4 -0
- package/registry/examples/waveform/card.js +18 -0
- package/registry/examples/waveform/card.tsx +16 -0
- package/registry/examples/waveform/native/card.d.ts +4 -0
- package/registry/examples/waveform/native/card.dark.png +0 -0
- package/registry/examples/waveform/native/card.js +19 -0
- package/registry/examples/waveform/native/card.light.png +0 -0
- package/registry/examples/waveform/native/card.tsx +19 -0
- package/registry/examples/waveform/sizes.d.ts +4 -0
- package/registry/examples/waveform/sizes.js +16 -0
- package/registry/examples/waveform/sizes.tsx +14 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +1 -1
- package/registry/filter-bar.json +1 -1
- package/registry/force-update-screen.json +1 -1
- package/registry/form.json +1 -1
- package/registry/gallery-page.json +1 -1
- package/registry/genui.json +409 -0
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +1 -1
- package/registry/how-it-works-page.json +1 -1
- package/registry/image-cropper.json +1 -1
- package/registry/index.json +323 -14
- package/registry/iso.json +1 -1
- package/registry/kanban.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +1 -1
- package/registry/landscape.json +1 -1
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +38 -6
- package/registry/list.json +1 -1
- package/registry/loader.json +1 -1
- package/registry/longform-page.json +1 -1
- package/registry/maintenance-screen.json +1 -1
- package/registry/map.json +2 -2
- package/registry/markdown.json +1 -1
- package/registry/marketing-layout.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +1 -1
- package/registry/mascot-state.json +1 -1
- package/registry/mascots.json +1 -1
- package/registry/match-dialog.json +1 -1
- package/registry/media-capture.json +1 -1
- package/registry/media-grid.json +92 -6
- package/registry/meta-row.json +215 -0
- package/registry/meter.json +1 -1
- package/registry/nav-bar.json +13 -13
- package/registry/number-ticker.json +1 -1
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +1 -1
- package/registry/page.json +1 -1
- package/registry/pagination.json +1 -1
- package/registry/photo-grid.json +1 -1
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +1 -1
- package/registry/product-page.json +1 -1
- package/registry/profile-card.json +1 -1
- package/registry/progress.json +1 -1
- package/registry/promise-card.json +1 -1
- package/registry/radio-group.json +1 -1
- package/registry/rail-nav.json +493 -0
- package/registry/recipes.json +1 -1
- package/registry/scroll-stage.json +1 -1
- package/registry/search-field.json +1 -1
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/settings-layout.json +104 -9
- package/registry/showcase.json +1 -1
- package/registry/site-footer.json +49 -17
- package/registry/sites.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/skip-link.json +2 -2
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +1 -1
- package/registry/stat.json +1 -1
- package/registry/status-page.json +1 -1
- package/registry/step-progress.json +1 -1
- package/registry/step-showcase.json +296 -0
- package/registry/stepper.json +1 -1
- package/registry/swipe-deck.json +1 -1
- package/registry/switch.json +1 -1
- package/registry/tabs.json +2 -2
- package/registry/tag-input.json +1 -1
- package/registry/tag-selector.json +1 -1
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +1 -1
- package/registry/toast.json +1 -1
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/tree-view.json +1 -1
- package/registry/update-prompt.json +1 -1
- package/registry/verified-badge.json +1 -1
- package/registry/vertical-video.json +1 -1
- package/registry/video-player.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/registry/virtual.json +1 -1
- package/registry/waveform.json +296 -0
- package/dist/chunk-2FRWNSRO.js.map +0 -1
- package/dist/chunk-3BC4XQ6C.js.map +0 -1
- package/dist/chunk-3GODX3D6.js.map +0 -1
- package/dist/chunk-3IN6TOPM.js.map +0 -1
- package/dist/chunk-4LOMIQVX.js.map +0 -1
- package/dist/chunk-G3ETON2A.js.map +0 -1
- package/dist/chunk-IZ7MV6HM.js.map +0 -1
- package/dist/chunk-LIPK4UCS.js.map +0 -1
- package/dist/chunk-OWC2LZD2.js.map +0 -1
- package/dist/chunk-ZNMFG62E.js.map +0 -1
- /package/dist/{chunk-5MH64NIL.js.map → chunk-2L67YTNV.js.map} +0 -0
- /package/dist/{chunk-FKBHWS4N.js.map → chunk-CEJDH6SA.js.map} +0 -0
- /package/dist/{chunk-5Z7FWCV2.js.map → chunk-HBZPJ3EP.js.map} +0 -0
- /package/dist/{chunk-C2BRIFJG.js.map → chunk-HJFRHYCI.js.map} +0 -0
- /package/dist/{chunk-BTMFZ66D.js.map → chunk-KM6VAKIE.js.map} +0 -0
- /package/dist/{chunk-DGQMDJXK.js.map → chunk-LZNZLCOE.js.map} +0 -0
package/dist/genui.js
ADDED
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
CardBody,
|
|
4
|
+
CardRoot,
|
|
5
|
+
CardTitle,
|
|
6
|
+
Skeleton
|
|
7
|
+
} from "./chunk-MQPC3P4T.js";
|
|
8
|
+
import {
|
|
9
|
+
DataTable
|
|
10
|
+
} from "./chunk-F7FVPPBB.js";
|
|
11
|
+
import "./chunk-7Z4KHPFC.js";
|
|
12
|
+
import "./chunk-JXLDUDTD.js";
|
|
13
|
+
import "./chunk-DZU6RMYD.js";
|
|
14
|
+
import "./chunk-KVDB4GXV.js";
|
|
15
|
+
import "./chunk-CEJDH6SA.js";
|
|
16
|
+
import "./chunk-7UCPGXKN.js";
|
|
17
|
+
import "./chunk-D3T54RSL.js";
|
|
18
|
+
import "./chunk-J3NC6ER4.js";
|
|
19
|
+
import {
|
|
20
|
+
cn
|
|
21
|
+
} from "./chunk-NSLXEDIS.js";
|
|
22
|
+
import "./chunk-REPTKUJ6.js";
|
|
23
|
+
import "./chunk-ZIXB33X7.js";
|
|
24
|
+
import "./chunk-FZBWEDQI.js";
|
|
25
|
+
import "./chunk-CPA5CF35.js";
|
|
26
|
+
|
|
27
|
+
// src/genui/catalog.tsx
|
|
28
|
+
import { formatCompact, formatMoney, formatNumber, formatPercent } from "@krizaka/intl";
|
|
29
|
+
|
|
30
|
+
// src/alert/alert.tsx
|
|
31
|
+
import { tv } from "tailwind-variants";
|
|
32
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
33
|
+
var alertVariants = tv({
|
|
34
|
+
slots: {
|
|
35
|
+
root: "relative flex w-full items-start gap-3 rounded-xl border p-4 text-sm text-fg",
|
|
36
|
+
icon: "mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center [&>svg]:h-5 [&>svg]:w-5",
|
|
37
|
+
content: "flex min-w-0 flex-1 flex-col gap-1",
|
|
38
|
+
title: "font-semibold text-fg",
|
|
39
|
+
description: "text-fg-secondary",
|
|
40
|
+
action: "flex shrink-0 items-center gap-2 self-center"
|
|
41
|
+
},
|
|
42
|
+
variants: {
|
|
43
|
+
tone: {
|
|
44
|
+
info: { root: "border-info/40 bg-info/10", icon: "text-info" },
|
|
45
|
+
success: { root: "border-success/40 bg-success/10", icon: "text-success" },
|
|
46
|
+
warning: { root: "border-warning/50 bg-warning/10", icon: "text-warning" },
|
|
47
|
+
danger: { root: "border-danger/50 bg-danger/10", icon: "text-danger" }
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
defaultVariants: { tone: "info" }
|
|
51
|
+
});
|
|
52
|
+
function Alert({ tone = "info", icon, title, action, className, children, ...props }) {
|
|
53
|
+
const s = alertVariants({ tone });
|
|
54
|
+
return /* @__PURE__ */ jsxs("div", { role: tone === "danger" || tone === "warning" ? "alert" : "status", "data-tone": tone, className: s.root({ className }), ...props, children: [
|
|
55
|
+
icon && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: s.icon(), children: icon }),
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: s.content(), children: [
|
|
57
|
+
title && /* @__PURE__ */ jsx("p", { className: s.title(), children: title }),
|
|
58
|
+
children && /* @__PURE__ */ jsx("div", { className: s.description(), children })
|
|
59
|
+
] }),
|
|
60
|
+
action && /* @__PURE__ */ jsx("div", { className: s.action(), children: action })
|
|
61
|
+
] });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/genui/spec.ts
|
|
65
|
+
var GENUI_VERSION = "v0.9";
|
|
66
|
+
var GENUI_CATALOG_ID = "krizaka:genui/v1";
|
|
67
|
+
var GENUI_LIMITS = {
|
|
68
|
+
/** Components per surface. */
|
|
69
|
+
components: 300,
|
|
70
|
+
/** Nesting depth from the root. */
|
|
71
|
+
depth: 12,
|
|
72
|
+
/** Characters in one string. */
|
|
73
|
+
string: 4e3,
|
|
74
|
+
/** Items in one array of the data model. */
|
|
75
|
+
array: 1e3,
|
|
76
|
+
/** Nesting depth of a data model value. */
|
|
77
|
+
dataDepth: 12,
|
|
78
|
+
/** Values (objects, arrays, scalars) in one data model update. */
|
|
79
|
+
dataNodes: 5e4,
|
|
80
|
+
/** Segments of a data path. */
|
|
81
|
+
pathSegments: 16
|
|
82
|
+
};
|
|
83
|
+
var ID = /^[A-Za-z0-9_-]{1,64}$/;
|
|
84
|
+
var MESSAGE_KEYS = ["createSurface", "updateComponents", "updateDataModel", "deleteSurface"];
|
|
85
|
+
var FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
86
|
+
var fail = (error) => ({ ok: false, error });
|
|
87
|
+
function isPlainObject(value) {
|
|
88
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
89
|
+
const proto = Object.getPrototypeOf(value);
|
|
90
|
+
return proto === Object.prototype || proto === null;
|
|
91
|
+
}
|
|
92
|
+
function onlyKeys(value, allowed, where) {
|
|
93
|
+
for (const key of Object.keys(value)) if (!allowed.includes(key)) return `${where}: unknown key "${key}"`;
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
function checkId(value, where) {
|
|
97
|
+
return typeof value === "string" && ID.test(value) ? null : `${where}: an id is 1-64 characters of [A-Za-z0-9_-]`;
|
|
98
|
+
}
|
|
99
|
+
function parsePath(path) {
|
|
100
|
+
if (typeof path !== "string" || path !== "/" && !path.startsWith("/") || path.length > 512) return fail("a path is a JSON pointer: /a/b");
|
|
101
|
+
if (path === "/") return { ok: true, value: [] };
|
|
102
|
+
const segments = path.slice(1).split("/").map((s) => s.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
103
|
+
if (segments.length > GENUI_LIMITS.pathSegments) return fail(`a path has at most ${GENUI_LIMITS.pathSegments} segments`);
|
|
104
|
+
for (const s of segments) {
|
|
105
|
+
if (s === "" || FORBIDDEN_SEGMENTS.has(s)) return fail(`a path may not hold the segment "${s}"`);
|
|
106
|
+
}
|
|
107
|
+
return { ok: true, value: segments };
|
|
108
|
+
}
|
|
109
|
+
function isBinding(value) {
|
|
110
|
+
return isPlainObject(value) && Object.keys(value).length === 1 && typeof value.path === "string";
|
|
111
|
+
}
|
|
112
|
+
function sanitizeData(value) {
|
|
113
|
+
let nodes = 0;
|
|
114
|
+
const walk = (v, depth) => {
|
|
115
|
+
if (++nodes > GENUI_LIMITS.dataNodes) return fail(`the data holds more than ${GENUI_LIMITS.dataNodes} values`);
|
|
116
|
+
if (depth > GENUI_LIMITS.dataDepth) return fail(`the data nests deeper than ${GENUI_LIMITS.dataDepth}`);
|
|
117
|
+
if (v === null || typeof v === "boolean") return { ok: true, value: v };
|
|
118
|
+
if (typeof v === "number") return Number.isFinite(v) ? { ok: true, value: v } : fail("a number must be finite");
|
|
119
|
+
if (typeof v === "string") return v.length <= GENUI_LIMITS.string ? { ok: true, value: v } : fail(`a string has at most ${GENUI_LIMITS.string} characters`);
|
|
120
|
+
if (Array.isArray(v)) {
|
|
121
|
+
if (v.length > GENUI_LIMITS.array) return fail(`an array has at most ${GENUI_LIMITS.array} items`);
|
|
122
|
+
const out = [];
|
|
123
|
+
for (const item of v) {
|
|
124
|
+
const r = walk(item, depth + 1);
|
|
125
|
+
if (!r.ok) return r;
|
|
126
|
+
out.push(r.value);
|
|
127
|
+
}
|
|
128
|
+
return { ok: true, value: out };
|
|
129
|
+
}
|
|
130
|
+
if (isPlainObject(v)) {
|
|
131
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
132
|
+
for (const [key, item] of Object.entries(v)) {
|
|
133
|
+
if (FORBIDDEN_SEGMENTS.has(key)) return fail(`a key may not be "${key}"`);
|
|
134
|
+
const r = walk(item, depth + 1);
|
|
135
|
+
if (!r.ok) return r;
|
|
136
|
+
out[key] = r.value;
|
|
137
|
+
}
|
|
138
|
+
return { ok: true, value: out };
|
|
139
|
+
}
|
|
140
|
+
return fail("the data is plain JSON only");
|
|
141
|
+
};
|
|
142
|
+
return walk(value, 0);
|
|
143
|
+
}
|
|
144
|
+
function validateMessage(input, catalog) {
|
|
145
|
+
if (!isPlainObject(input)) return fail("a message is a JSON object");
|
|
146
|
+
if (input.version !== GENUI_VERSION) return fail(`version must be "${GENUI_VERSION}"`);
|
|
147
|
+
const present = MESSAGE_KEYS.filter((k) => k in input);
|
|
148
|
+
if (present.length !== 1) return fail("a message holds exactly one of createSurface, updateComponents, updateDataModel, deleteSurface");
|
|
149
|
+
const kind = present[0];
|
|
150
|
+
const extra = onlyKeys(input, ["version", kind], "message");
|
|
151
|
+
if (extra) return fail(extra);
|
|
152
|
+
const body = input[kind];
|
|
153
|
+
if (!isPlainObject(body)) return fail(`${kind} is an object`);
|
|
154
|
+
const surface = checkId(body.surfaceId, `${kind}.surfaceId`);
|
|
155
|
+
if (surface) return fail(surface);
|
|
156
|
+
switch (kind) {
|
|
157
|
+
case "createSurface": {
|
|
158
|
+
const keys = onlyKeys(body, ["surfaceId", "catalogId", "theme", "sendDataModel"], kind);
|
|
159
|
+
if (keys) return fail(keys);
|
|
160
|
+
if (body.catalogId !== GENUI_CATALOG_ID) return fail(`catalogId must be "${GENUI_CATALOG_ID}"`);
|
|
161
|
+
return { ok: true, value: { version: GENUI_VERSION, createSurface: { surfaceId: body.surfaceId, catalogId: GENUI_CATALOG_ID } } };
|
|
162
|
+
}
|
|
163
|
+
case "updateComponents": {
|
|
164
|
+
const keys = onlyKeys(body, ["surfaceId", "components"], kind);
|
|
165
|
+
if (keys) return fail(keys);
|
|
166
|
+
if (!Array.isArray(body.components) || body.components.length > GENUI_LIMITS.components) {
|
|
167
|
+
return fail(`components is an array of at most ${GENUI_LIMITS.components}`);
|
|
168
|
+
}
|
|
169
|
+
const components = [];
|
|
170
|
+
for (const raw of body.components) {
|
|
171
|
+
if (!isPlainObject(raw)) return fail("a component is an object");
|
|
172
|
+
const id = checkId(raw.id, "component.id");
|
|
173
|
+
if (id) return fail(id);
|
|
174
|
+
if (typeof raw.component !== "string" || !Object.hasOwn(catalog, raw.component)) {
|
|
175
|
+
return fail(`component "${String(raw.id)}": "${String(raw.component)}" is not in the catalog`);
|
|
176
|
+
}
|
|
177
|
+
const clean = sanitizeData(raw);
|
|
178
|
+
if (!clean.ok) return fail(`component "${raw.id}": ${clean.error}`);
|
|
179
|
+
const component = { ...clean.value };
|
|
180
|
+
const problem = catalog[raw.component].check(component);
|
|
181
|
+
if (problem) return fail(`component "${raw.id}" (${raw.component}): ${problem}`);
|
|
182
|
+
components.push(component);
|
|
183
|
+
}
|
|
184
|
+
return { ok: true, value: { version: GENUI_VERSION, updateComponents: { surfaceId: body.surfaceId, components } } };
|
|
185
|
+
}
|
|
186
|
+
case "updateDataModel": {
|
|
187
|
+
const keys = onlyKeys(body, ["surfaceId", "path", "value"], kind);
|
|
188
|
+
if (keys) return fail(keys);
|
|
189
|
+
const path = body.path === void 0 ? "/" : body.path;
|
|
190
|
+
const parsed = parsePath(path);
|
|
191
|
+
if (!parsed.ok) return parsed;
|
|
192
|
+
if (!("value" in body)) return { ok: true, value: { version: GENUI_VERSION, updateDataModel: { surfaceId: body.surfaceId, path } } };
|
|
193
|
+
const clean = sanitizeData(body.value);
|
|
194
|
+
if (!clean.ok) return clean;
|
|
195
|
+
return { ok: true, value: { version: GENUI_VERSION, updateDataModel: { surfaceId: body.surfaceId, path, value: clean.value } } };
|
|
196
|
+
}
|
|
197
|
+
default: {
|
|
198
|
+
const keys = onlyKeys(body, ["surfaceId"], kind);
|
|
199
|
+
if (keys) return fail(keys);
|
|
200
|
+
return { ok: true, value: { version: GENUI_VERSION, deleteSurface: { surfaceId: body.surfaceId } } };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function allowKeys(component, keys) {
|
|
205
|
+
return onlyKeys(component, ["id", "component", ...keys], "properties");
|
|
206
|
+
}
|
|
207
|
+
function checkText(value, name, required) {
|
|
208
|
+
if (value === void 0) return required ? `${name} is required` : null;
|
|
209
|
+
if (isBinding(value)) return parsePath(value.path).ok ? null : `${name}: a bad path`;
|
|
210
|
+
return typeof value === "string" ? null : `${name} is a string`;
|
|
211
|
+
}
|
|
212
|
+
function checkEnum(value, name, allowed, required = false) {
|
|
213
|
+
if (value === void 0) return required ? `${name} is required` : null;
|
|
214
|
+
return typeof value === "string" && allowed.includes(value) ? null : `${name} is one of ${allowed.join(", ")}`;
|
|
215
|
+
}
|
|
216
|
+
function checkChildren(value, name = "children") {
|
|
217
|
+
if (!Array.isArray(value) || value.length > GENUI_LIMITS.components) return `${name} is an array of component ids`;
|
|
218
|
+
for (const id of value) if (checkId(id, name)) return `${name} holds ids only`;
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
function checkBinding(value, name) {
|
|
222
|
+
if (!isBinding(value)) return `${name} is a binding { "path": "/\u2026" }`;
|
|
223
|
+
return parsePath(value.path).ok ? null : `${name}: a bad path`;
|
|
224
|
+
}
|
|
225
|
+
function checkNumber(value, name, required) {
|
|
226
|
+
if (value === void 0) return required ? `${name} is required` : null;
|
|
227
|
+
if (isBinding(value)) return parsePath(value.path).ok ? null : `${name}: a bad path`;
|
|
228
|
+
return typeof value === "number" && Number.isFinite(value) ? null : `${name} is a number`;
|
|
229
|
+
}
|
|
230
|
+
var GENUI_FORMATS = ["number", "integer", "compact", "percent", "money"];
|
|
231
|
+
function checkCurrency(value, required) {
|
|
232
|
+
if (value === void 0) return required ? "currency is required with the money format" : null;
|
|
233
|
+
return typeof value === "string" && /^[A-Z]{3}$/.test(value) ? null : "currency is a three-letter code (CAD)";
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/genui/catalog.tsx
|
|
237
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
238
|
+
var first = (...problems) => problems.find((p) => p !== null) ?? null;
|
|
239
|
+
function asText(value) {
|
|
240
|
+
if (typeof value === "string") return value.slice(0, GENUI_LIMITS.string);
|
|
241
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
242
|
+
return "";
|
|
243
|
+
}
|
|
244
|
+
function formatGenUiValue(value, format, locale, currency) {
|
|
245
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return asText(value);
|
|
246
|
+
switch (format) {
|
|
247
|
+
case "integer":
|
|
248
|
+
return formatNumber(Math.round(value), { locale, maximumFractionDigits: 0 });
|
|
249
|
+
case "compact":
|
|
250
|
+
return formatCompact(value, { locale });
|
|
251
|
+
case "percent":
|
|
252
|
+
return formatPercent(value, { locale, maximumFractionDigits: 1 });
|
|
253
|
+
case "money":
|
|
254
|
+
return currency ? formatMoney(Math.round(value), { currency, locale }) : formatNumber(value, { locale });
|
|
255
|
+
default:
|
|
256
|
+
return formatNumber(value, { locale, maximumFractionDigits: 2 });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
var TONES = ["info", "success", "warning", "danger"];
|
|
260
|
+
var VARIANTS = ["body", "heading", "caption"];
|
|
261
|
+
var column = {
|
|
262
|
+
check: (c) => first(allowKeys(c, ["children"]), checkChildren(c.children)),
|
|
263
|
+
render: (c, ctx) => /* @__PURE__ */ jsx2("div", { className: "flex min-w-0 flex-col gap-4", children: ctx.children(c.children) })
|
|
264
|
+
};
|
|
265
|
+
var row = {
|
|
266
|
+
check: (c) => first(allowKeys(c, ["children"]), checkChildren(c.children)),
|
|
267
|
+
render: (c, ctx) => /* @__PURE__ */ jsx2("div", { className: "grid min-w-0 gap-4 [grid-template-columns:repeat(auto-fit,minmax(12rem,1fr))]", children: ctx.children(c.children) })
|
|
268
|
+
};
|
|
269
|
+
var text = {
|
|
270
|
+
check: (c) => first(allowKeys(c, ["text", "variant"]), checkText(c.text, "text", true), checkEnum(c.variant, "variant", VARIANTS)),
|
|
271
|
+
render: (c, ctx) => {
|
|
272
|
+
const value = asText(ctx.resolve(c.text));
|
|
273
|
+
if (c.variant === "heading") return /* @__PURE__ */ jsx2("h3", { className: "text-base font-semibold text-fg", children: value });
|
|
274
|
+
if (c.variant === "caption") return /* @__PURE__ */ jsx2("p", { className: "text-xs text-fg-muted", children: value });
|
|
275
|
+
return /* @__PURE__ */ jsx2("p", { className: "text-sm text-fg", children: value });
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var card = {
|
|
279
|
+
check: (c) => first(allowKeys(c, ["title", "child"]), checkText(c.title, "title", false), c.child === void 0 ? null : checkId(c.child, "child")),
|
|
280
|
+
render: (c, ctx) => /* @__PURE__ */ jsx2(CardRoot, { children: /* @__PURE__ */ jsxs2(CardBody, { children: [
|
|
281
|
+
c.title !== void 0 && /* @__PURE__ */ jsx2(CardTitle, { children: asText(ctx.resolve(c.title)) }),
|
|
282
|
+
c.child !== void 0 && /* @__PURE__ */ jsx2("div", { className: "mt-3", children: ctx.child(c.child) })
|
|
283
|
+
] }) })
|
|
284
|
+
};
|
|
285
|
+
var callout = {
|
|
286
|
+
check: (c) => first(allowKeys(c, ["tone", "title", "text"]), checkEnum(c.tone, "tone", TONES), checkText(c.title, "title", false), checkText(c.text, "text", false)),
|
|
287
|
+
render: (c, ctx) => /* @__PURE__ */ jsx2(Alert, { tone: c.tone ?? "info", title: c.title === void 0 ? void 0 : asText(ctx.resolve(c.title)), children: c.text === void 0 ? void 0 : asText(ctx.resolve(c.text)) })
|
|
288
|
+
};
|
|
289
|
+
function checkColumns(value) {
|
|
290
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > 12) return "columns is an array of 1 to 12";
|
|
291
|
+
for (const raw of value) {
|
|
292
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return "a column is an object";
|
|
293
|
+
const col = raw;
|
|
294
|
+
const keys = Object.keys(col).find((k) => !["key", "label", "format", "currency"].includes(k));
|
|
295
|
+
if (keys) return `a column has no key "${keys}"`;
|
|
296
|
+
if (typeof col.key !== "string" || !/^[A-Za-z0-9_]{1,64}$/.test(col.key)) return "a column key is 1-64 characters of [A-Za-z0-9_]";
|
|
297
|
+
if (typeof col.label !== "string" || col.label.length > 120) return "a column label is a string";
|
|
298
|
+
const problem = first(checkEnum(col.format, "format", GENUI_FORMATS), checkCurrency(col.currency, col.format === "money"));
|
|
299
|
+
if (problem) return problem;
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
function TableView({ c, ctx }) {
|
|
304
|
+
const columns = c.columns;
|
|
305
|
+
const raw = ctx.resolve(c.rows);
|
|
306
|
+
const rows = Array.isArray(raw) ? raw.slice(0, GENUI_LIMITS.array).flatMap((r, i) => r !== null && typeof r === "object" && !Array.isArray(r) ? [{ ...r, __genuiRow: String(i) }] : []) : [];
|
|
307
|
+
const cols = columns.map((col) => ({
|
|
308
|
+
id: col.key,
|
|
309
|
+
header: col.label,
|
|
310
|
+
sortable: true,
|
|
311
|
+
type: col.format ? "number" : "text",
|
|
312
|
+
value: (r) => {
|
|
313
|
+
const v = r[col.key];
|
|
314
|
+
return typeof v === "number" || typeof v === "string" ? v : null;
|
|
315
|
+
},
|
|
316
|
+
cell: (r) => formatGenUiValue(r[col.key], col.format, ctx.locale, col.currency)
|
|
317
|
+
}));
|
|
318
|
+
if (rows.length === 0) return /* @__PURE__ */ jsx2("p", { className: "text-sm text-fg-muted", children: ctx.labels.noData });
|
|
319
|
+
return /* @__PURE__ */ jsx2(DataTable, { rows, columns: cols, getRowId: (r) => r.__genuiRow, caption: c.caption === void 0 ? ctx.labels.surface : asText(ctx.resolve(c.caption)), showCaption: c.caption !== void 0 });
|
|
320
|
+
}
|
|
321
|
+
var table = {
|
|
322
|
+
check: (c) => first(allowKeys(c, ["caption", "columns", "rows"]), checkText(c.caption, "caption", false), checkColumns(c.columns), checkBinding(c.rows, "rows")),
|
|
323
|
+
render: (c, ctx) => /* @__PURE__ */ jsx2(TableView, { c, ctx })
|
|
324
|
+
};
|
|
325
|
+
var baseGenUiCatalog = { Column: column, Row: row, Text: text, Card: card, Callout: callout, Table: table };
|
|
326
|
+
|
|
327
|
+
// src/genui/store.ts
|
|
328
|
+
var emptyGenUiState = { surfaces: /* @__PURE__ */ new Map(), order: [], errors: [] };
|
|
329
|
+
var withError = (state, error) => ({ ...state, errors: [...state.errors, error] });
|
|
330
|
+
function setAt(root, segments, value, remove) {
|
|
331
|
+
if (segments.length === 0) return remove ? /* @__PURE__ */ Object.create(null) : value;
|
|
332
|
+
const [head, ...rest] = segments;
|
|
333
|
+
if (Array.isArray(root)) {
|
|
334
|
+
const index = Number(head);
|
|
335
|
+
if (!Number.isInteger(index) || index < 0 || index > root.length || index >= GENUI_LIMITS.array) return root;
|
|
336
|
+
const copy = [...root];
|
|
337
|
+
if (remove && rest.length === 0) copy.splice(index, 1);
|
|
338
|
+
else copy[index] = setAt(root[index], rest, value, remove);
|
|
339
|
+
return copy;
|
|
340
|
+
}
|
|
341
|
+
const base = Object.assign(/* @__PURE__ */ Object.create(null), root !== null && typeof root === "object" ? root : {});
|
|
342
|
+
if (remove && rest.length === 0) delete base[head];
|
|
343
|
+
else base[head] = setAt(base[head], rest, value, remove);
|
|
344
|
+
return base;
|
|
345
|
+
}
|
|
346
|
+
function readPath(data, path) {
|
|
347
|
+
const parsed = parsePath(path);
|
|
348
|
+
if (!parsed.ok) return void 0;
|
|
349
|
+
let cursor = data;
|
|
350
|
+
for (const segment of parsed.value) {
|
|
351
|
+
if (cursor === null || typeof cursor !== "object") return void 0;
|
|
352
|
+
if (!Object.hasOwn(cursor, segment)) return void 0;
|
|
353
|
+
cursor = cursor[segment];
|
|
354
|
+
}
|
|
355
|
+
return cursor;
|
|
356
|
+
}
|
|
357
|
+
function applyMessage(state, message) {
|
|
358
|
+
if ("createSurface" in message) {
|
|
359
|
+
const { surfaceId: surfaceId2 } = message.createSurface;
|
|
360
|
+
if (state.surfaces.has(surfaceId2)) return withError(state, `surface "${surfaceId2}" already exists`);
|
|
361
|
+
const surfaces2 = new Map(state.surfaces);
|
|
362
|
+
surfaces2.set(surfaceId2, { id: surfaceId2, components: /* @__PURE__ */ new Map(), data: /* @__PURE__ */ Object.create(null) });
|
|
363
|
+
return { ...state, surfaces: surfaces2, order: [...state.order, surfaceId2] };
|
|
364
|
+
}
|
|
365
|
+
if ("deleteSurface" in message) {
|
|
366
|
+
const surfaces2 = new Map(state.surfaces);
|
|
367
|
+
surfaces2.delete(message.deleteSurface.surfaceId);
|
|
368
|
+
return { ...state, surfaces: surfaces2, order: state.order.filter((id) => id !== message.deleteSurface.surfaceId) };
|
|
369
|
+
}
|
|
370
|
+
const surfaceId = "updateComponents" in message ? message.updateComponents.surfaceId : message.updateDataModel.surfaceId;
|
|
371
|
+
const surface = state.surfaces.get(surfaceId);
|
|
372
|
+
if (!surface) return withError(state, `surface "${surfaceId}" was not created`);
|
|
373
|
+
const surfaces = new Map(state.surfaces);
|
|
374
|
+
if ("updateComponents" in message) {
|
|
375
|
+
const components = new Map(surface.components);
|
|
376
|
+
for (const component of message.updateComponents.components) components.set(component.id, component);
|
|
377
|
+
if (components.size > GENUI_LIMITS.components) return withError(state, `surface "${surfaceId}" holds more than ${GENUI_LIMITS.components} components`);
|
|
378
|
+
surfaces.set(surfaceId, { ...surface, components });
|
|
379
|
+
} else {
|
|
380
|
+
const { path, value } = message.updateDataModel;
|
|
381
|
+
const parsed = parsePath(path);
|
|
382
|
+
if (!parsed.ok) return withError(state, parsed.error);
|
|
383
|
+
surfaces.set(surfaceId, { ...surface, data: setAt(surface.data, parsed.value, value, !("value" in message.updateDataModel)) });
|
|
384
|
+
}
|
|
385
|
+
return { ...state, surfaces };
|
|
386
|
+
}
|
|
387
|
+
function leadingObject(text2) {
|
|
388
|
+
if (!text2.startsWith("{")) return null;
|
|
389
|
+
let depth = 0;
|
|
390
|
+
let inString = false;
|
|
391
|
+
for (let i = 0; i < text2.length; i++) {
|
|
392
|
+
const c = text2[i];
|
|
393
|
+
if (inString) {
|
|
394
|
+
if (c === "\\") i++;
|
|
395
|
+
else if (c === '"') inString = false;
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (c === '"') inString = true;
|
|
399
|
+
else if (c === "{" || c === "[") depth++;
|
|
400
|
+
else if (c === "}" || c === "]") {
|
|
401
|
+
depth--;
|
|
402
|
+
if (depth === 0) return /^[\s}\]]*$/.test(text2.slice(i + 1)) ? text2.slice(0, i + 1) : null;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
function applyLine(state, line, catalog) {
|
|
408
|
+
const text2 = line.trim();
|
|
409
|
+
if (!text2) return state;
|
|
410
|
+
let json;
|
|
411
|
+
try {
|
|
412
|
+
json = JSON.parse(text2);
|
|
413
|
+
} catch {
|
|
414
|
+
const head = leadingObject(text2);
|
|
415
|
+
if (head === null) return withError(state, "a line is not JSON");
|
|
416
|
+
try {
|
|
417
|
+
json = JSON.parse(head);
|
|
418
|
+
} catch {
|
|
419
|
+
return withError(state, "a line is not JSON");
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
const result = validateMessage(json, catalog);
|
|
423
|
+
return result.ok ? applyMessage(state, result.value) : withError(state, result.error);
|
|
424
|
+
}
|
|
425
|
+
var FENCE = /```a2ui[^\n]*\n/;
|
|
426
|
+
function extractGenUi(text2) {
|
|
427
|
+
const open = FENCE.exec(text2);
|
|
428
|
+
if (!open) return { lines: [], closed: false, prose: text2, found: false };
|
|
429
|
+
const start = open.index + open[0].length;
|
|
430
|
+
const end = text2.indexOf("\n```", start - 1);
|
|
431
|
+
const closed = end >= 0;
|
|
432
|
+
const body = closed ? text2.slice(start, end) : text2.slice(start);
|
|
433
|
+
const parts = body.split("\n");
|
|
434
|
+
const lines = closed ? parts : parts.slice(0, -1);
|
|
435
|
+
const after = closed ? text2.slice(end + 4).replace(/^[^\n]*\n?/, "") : "";
|
|
436
|
+
const prose = [text2.slice(0, open.index).trim(), after.trim()].filter(Boolean).join("\n\n");
|
|
437
|
+
return { lines: lines.filter((l) => l.trim()), closed, prose, found: true };
|
|
438
|
+
}
|
|
439
|
+
function readStream(text2, catalog) {
|
|
440
|
+
const { lines, prose, found } = extractGenUi(text2);
|
|
441
|
+
const state = lines.reduce((s, line) => applyLine(s, line, catalog), emptyGenUiState);
|
|
442
|
+
return { ...state, prose, found };
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// src/genui/surface.tsx
|
|
446
|
+
import * as React from "react";
|
|
447
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
448
|
+
var genUiLabels = { loading: "Building the view\u2026", surface: "Generated view", noData: "No data" };
|
|
449
|
+
function GenUiSurface({ surface, catalog, streaming = false, labels, locale = "en", onError, className }) {
|
|
450
|
+
const words = { ...genUiLabels, ...labels };
|
|
451
|
+
const problems = [];
|
|
452
|
+
const seen = /* @__PURE__ */ new Set();
|
|
453
|
+
const draw = (id, depth) => {
|
|
454
|
+
if (typeof id !== "string") return null;
|
|
455
|
+
if (depth > GENUI_LIMITS.depth) {
|
|
456
|
+
problems.push(`"${id}" is deeper than ${GENUI_LIMITS.depth}`);
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
if (seen.has(id)) {
|
|
460
|
+
problems.push(`"${id}" is drawn twice (a cycle or two parents)`);
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
const component = surface.components.get(id);
|
|
464
|
+
if (!component) {
|
|
465
|
+
if (!streaming) problems.push(`"${id}" never arrived`);
|
|
466
|
+
return streaming ? /* @__PURE__ */ jsx3(Skeleton, { className: "h-10 w-full rounded-lg" }, id) : null;
|
|
467
|
+
}
|
|
468
|
+
const entry = Object.hasOwn(catalog, component.component) ? catalog[component.component] : void 0;
|
|
469
|
+
if (!entry) return null;
|
|
470
|
+
seen.add(id);
|
|
471
|
+
const context = {
|
|
472
|
+
child: (c) => draw(c, depth + 1),
|
|
473
|
+
children: (ids) => Array.isArray(ids) ? ids.map((c) => /* @__PURE__ */ jsx3(React.Fragment, { children: draw(c, depth + 1) }, String(c))) : [],
|
|
474
|
+
resolve: (value) => isBinding(value) ? readPath(surface.data, value.path) : value,
|
|
475
|
+
labels: words,
|
|
476
|
+
locale
|
|
477
|
+
};
|
|
478
|
+
return /* @__PURE__ */ jsx3(React.Fragment, { children: entry.render(component, context) }, id);
|
|
479
|
+
};
|
|
480
|
+
const root = draw("root", 0);
|
|
481
|
+
React.useEffect(() => {
|
|
482
|
+
if (onError) for (const problem of problems) onError(problem);
|
|
483
|
+
}, [surface, streaming]);
|
|
484
|
+
return /* @__PURE__ */ jsx3("section", { "aria-label": words.surface, "aria-busy": streaming || void 0, "data-genui-surface": surface.id, className: cn("flex flex-col gap-4", className), children: root ?? (streaming ? /* @__PURE__ */ jsx3(Skeleton, { className: "h-24 w-full rounded-xl" }) : null) });
|
|
485
|
+
}
|
|
486
|
+
function GenUiStream({ text: text2, catalog, streaming, renderProse, fallback, onError, ...rest }) {
|
|
487
|
+
const state = React.useMemo(() => readStream(text2, catalog), [text2, catalog]);
|
|
488
|
+
const reported = React.useRef(0);
|
|
489
|
+
React.useEffect(() => {
|
|
490
|
+
if (!onError) return;
|
|
491
|
+
for (const error of state.errors.slice(reported.current)) onError(error);
|
|
492
|
+
reported.current = state.errors.length;
|
|
493
|
+
}, [state, onError]);
|
|
494
|
+
const prose = (value) => renderProse ? renderProse(value) : value.split(/\n{2,}/).map((p, i) => /* @__PURE__ */ jsx3("p", { children: p }, i));
|
|
495
|
+
const surfaces = state.order.map((id) => state.surfaces.get(id)).filter((s) => !!s && s.components.has("root"));
|
|
496
|
+
if (!state.found || !streaming && surfaces.length === 0) return /* @__PURE__ */ jsx3(Fragment2, { children: fallback ? fallback(text2) : prose(text2) });
|
|
497
|
+
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-4", "data-genui-stream": "", children: [
|
|
498
|
+
state.prose && prose(state.prose),
|
|
499
|
+
surfaces.map((surface) => /* @__PURE__ */ jsx3(GenUiSurface, { surface, catalog, streaming, onError, ...rest }, surface.id)),
|
|
500
|
+
streaming && surfaces.length === 0 && /* @__PURE__ */ jsx3(Skeleton, { className: "h-24 w-full rounded-xl" })
|
|
501
|
+
] });
|
|
502
|
+
}
|
|
503
|
+
export {
|
|
504
|
+
GENUI_CATALOG_ID,
|
|
505
|
+
GENUI_FORMATS,
|
|
506
|
+
GENUI_LIMITS,
|
|
507
|
+
GENUI_VERSION,
|
|
508
|
+
GenUiStream,
|
|
509
|
+
GenUiSurface,
|
|
510
|
+
allowKeys,
|
|
511
|
+
applyLine,
|
|
512
|
+
applyMessage,
|
|
513
|
+
baseGenUiCatalog,
|
|
514
|
+
checkBinding,
|
|
515
|
+
checkChildren,
|
|
516
|
+
checkCurrency,
|
|
517
|
+
checkEnum,
|
|
518
|
+
checkId,
|
|
519
|
+
checkNumber,
|
|
520
|
+
checkText,
|
|
521
|
+
emptyGenUiState,
|
|
522
|
+
extractGenUi,
|
|
523
|
+
formatGenUiValue,
|
|
524
|
+
genUiLabels,
|
|
525
|
+
isBinding,
|
|
526
|
+
leadingObject,
|
|
527
|
+
parsePath,
|
|
528
|
+
readPath,
|
|
529
|
+
readStream,
|
|
530
|
+
sanitizeData,
|
|
531
|
+
validateMessage
|
|
532
|
+
};
|
|
533
|
+
//# sourceMappingURL=genui.js.map
|