@sableui/react 0.6.1 → 0.7.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/AGENTS.md +2 -2
- package/CHANGELOG.md +285 -0
- package/CONTRIBUTING.md +16 -10
- package/DESIGN.md +3 -3
- package/README.md +3 -3
- package/bin/sable-lint.mjs +18 -0
- package/bin/sable.mjs +470 -62
- package/dist/blocks/api-keys-block.js +44 -0
- package/dist/blocks/api-keys-block.meta.js +21 -0
- package/dist/blocks/chat-thread-block.js +17 -0
- package/dist/blocks/chat-thread-block.meta.js +20 -0
- package/dist/blocks/command-palette-block.js +24 -0
- package/dist/blocks/command-palette-block.meta.js +21 -0
- package/dist/blocks/cta-band-block.js +27 -0
- package/dist/blocks/cta-band-block.meta.js +20 -0
- package/dist/blocks/danger-zone-block.js +39 -0
- package/dist/blocks/danger-zone-block.meta.js +21 -0
- package/dist/blocks/device-comparison-block.js +69 -0
- package/dist/blocks/device-comparison-block.meta.js +21 -0
- package/dist/blocks/event-card-block.js +40 -0
- package/dist/blocks/event-card-block.meta.js +21 -0
- package/dist/blocks/faq-block.js +38 -0
- package/dist/blocks/faq-block.meta.js +20 -0
- package/dist/blocks/feature-grid-block.js +38 -0
- package/dist/blocks/feature-grid-block.meta.js +21 -0
- package/dist/blocks/feedback-form-block.js +30 -0
- package/dist/blocks/feedback-form-block.meta.js +21 -0
- package/dist/blocks/goal-progress-block.js +24 -0
- package/dist/blocks/goal-progress-block.meta.js +21 -0
- package/dist/blocks/hero-block.js +33 -0
- package/dist/blocks/hero-block.meta.js +21 -0
- package/dist/blocks/index.js +162 -1964
- package/dist/blocks/invite-team-block.js +36 -0
- package/dist/blocks/invite-team-block.meta.js +20 -0
- package/dist/blocks/invoice-history-block.js +41 -0
- package/dist/blocks/invoice-history-block.meta.js +21 -0
- package/dist/blocks/kpi-sparkline-block.js +29 -0
- package/dist/blocks/kpi-sparkline-block.meta.js +20 -0
- package/dist/blocks/media-player-block.js +68 -0
- package/dist/blocks/media-player-block.meta.js +21 -0
- package/dist/blocks/newsletter-block.js +35 -0
- package/dist/blocks/newsletter-block.meta.js +21 -0
- package/dist/blocks/not-found-block.js +27 -0
- package/dist/blocks/not-found-block.meta.js +20 -0
- package/dist/blocks/notification-list-block.js +32 -0
- package/dist/blocks/notification-list-block.meta.js +21 -0
- package/dist/blocks/notification-settings-block.js +25 -0
- package/dist/blocks/notification-settings-block.meta.js +20 -0
- package/dist/blocks/order-tracking-block.js +26 -0
- package/dist/blocks/order-tracking-block.meta.js +20 -0
- package/dist/blocks/pricing-card-block.js +46 -0
- package/dist/blocks/pricing-card-block.meta.js +21 -0
- package/dist/blocks/pricing-table-block.js +88 -0
- package/dist/blocks/pricing-table-block.meta.js +20 -0
- package/dist/blocks/product-card-block.js +26 -0
- package/dist/blocks/product-card-block.meta.js +21 -0
- package/dist/blocks/profile-card-block.js +58 -0
- package/dist/blocks/profile-card-block.meta.js +21 -0
- package/dist/blocks/profile-form-block.js +70 -0
- package/dist/blocks/profile-form-block.meta.js +21 -0
- package/dist/blocks/revenue-breakdown-block.js +38 -0
- package/dist/blocks/revenue-breakdown-block.meta.js +21 -0
- package/dist/blocks/sign-in-block.js +38 -0
- package/dist/blocks/sign-in-block.meta.js +21 -0
- package/dist/blocks/sign-up-block.js +48 -0
- package/dist/blocks/sign-up-block.meta.js +21 -0
- package/dist/blocks/site-footer-block.js +54 -0
- package/dist/blocks/site-footer-block.meta.js +20 -0
- package/dist/blocks/stat-row-block.js +28 -0
- package/dist/blocks/stat-row-block.meta.js +21 -0
- package/dist/blocks/steps-block.js +37 -0
- package/dist/blocks/steps-block.meta.js +20 -0
- package/dist/blocks/task-list-block.js +52 -0
- package/dist/blocks/task-list-block.meta.js +21 -0
- package/dist/blocks/team-members-block.js +49 -0
- package/dist/blocks/team-members-block.meta.js +21 -0
- package/dist/blocks/testimonial-block.js +49 -0
- package/dist/blocks/testimonial-block.meta.js +20 -0
- package/dist/blocks/traffic-sources-block.js +39 -0
- package/dist/blocks/traffic-sources-block.meta.js +21 -0
- package/dist/blocks/traffic-trend-block.js +61 -0
- package/dist/blocks/traffic-trend-block.meta.js +21 -0
- package/dist/blocks/upload-list-block.js +39 -0
- package/dist/blocks/upload-list-block.meta.js +21 -0
- package/dist/blocks/verify-code-block.js +28 -0
- package/dist/blocks/verify-code-block.meta.js +21 -0
- package/dist/blocks/wallet-block.js +48 -0
- package/dist/blocks/wallet-block.meta.js +21 -0
- package/dist/components/accordion/accordion.js +63 -0
- package/dist/components/accordion/accordion.meta.js +155 -0
- package/dist/components/accordion/index.js +15 -0
- package/dist/components/app-header/app-header.js +30 -0
- package/dist/components/app-header/app-header.meta.js +88 -0
- package/dist/components/app-header/index.js +7 -0
- package/dist/components/app-shell/app-shell-dock.js +37 -0
- package/dist/components/app-shell/app-shell.js +67 -0
- package/dist/components/app-shell/app-shell.meta.js +176 -0
- package/dist/components/app-shell/index.js +7 -0
- package/dist/components/area-chart/area-chart.js +10 -0
- package/dist/components/area-chart/area-chart.meta.js +218 -0
- package/dist/components/area-chart/index.js +7 -0
- package/dist/components/attachment/attachment.js +176 -0
- package/dist/components/attachment/attachment.meta.js +179 -0
- package/dist/components/attachment/attachment.variants.js +47 -0
- package/dist/components/attachment/index.js +7 -0
- package/dist/components/avatar/avatar.js +192 -0
- package/dist/components/avatar/avatar.meta.js +233 -0
- package/dist/components/avatar/avatar.variants.js +44 -0
- package/dist/components/avatar/index.js +22 -0
- package/dist/components/badge/badge.js +26 -0
- package/dist/components/badge/badge.meta.js +171 -0
- package/dist/components/badge/badge.variants.js +103 -0
- package/dist/components/badge/index.js +11 -0
- package/dist/components/banner/banner.js +76 -0
- package/dist/components/banner/banner.meta.js +172 -0
- package/dist/components/banner/banner.variants.js +44 -0
- package/dist/components/banner/index.js +9 -0
- package/dist/components/bar-chart/bar-chart.js +10 -0
- package/dist/components/bar-chart/bar-chart.meta.js +245 -0
- package/dist/components/bar-chart/index.js +7 -0
- package/dist/components/bottom-nav/bottom-nav.js +63 -0
- package/dist/components/bottom-nav/bottom-nav.meta.js +95 -0
- package/dist/components/bottom-nav/index.js +11 -0
- package/dist/components/breadcrumbs/breadcrumbs.js +90 -0
- package/dist/components/breadcrumbs/breadcrumbs.meta.js +111 -0
- package/dist/components/breadcrumbs/index.js +17 -0
- package/dist/components/browser/browser.js +39 -0
- package/dist/components/browser/browser.meta.js +80 -0
- package/dist/components/browser/index.js +7 -0
- package/dist/components/bubble/bubble.js +110 -0
- package/dist/components/bubble/bubble.meta.js +158 -0
- package/dist/components/bubble/bubble.variants.js +90 -0
- package/dist/components/bubble/index.js +13 -0
- package/dist/components/button/button.js +87 -0
- package/dist/components/button/button.meta.js +302 -0
- package/dist/components/button/button.variants.js +137 -0
- package/dist/components/button/index.js +9 -0
- package/dist/components/calendar/calendar.js +89 -0
- package/dist/components/calendar/calendar.meta.js +136 -0
- package/dist/components/calendar/index.js +7 -0
- package/dist/components/card/card.js +200 -0
- package/dist/components/card/card.meta.js +212 -0
- package/dist/components/card/index.js +23 -0
- package/dist/components/carousel/carousel.js +428 -0
- package/dist/components/carousel/carousel.meta.js +100 -0
- package/dist/components/carousel/index.js +7 -0
- package/dist/components/chat-composer/chat-composer.js +174 -0
- package/dist/components/chat-composer/chat-composer.meta.js +241 -0
- package/dist/components/chat-composer/chat-composer.variants.js +17 -0
- package/dist/components/chat-composer/index.js +7 -0
- package/dist/components/checkbox/checkbox-mark.js +28 -0
- package/dist/components/checkbox/checkbox.js +30 -0
- package/dist/components/checkbox/checkbox.meta.js +127 -0
- package/dist/components/checkbox/index.js +7 -0
- package/dist/components/checkbox-card/checkbox-card.js +94 -0
- package/dist/components/checkbox-card/checkbox-card.meta.js +154 -0
- package/dist/components/checkbox-card/checkbox-card.variants.js +43 -0
- package/dist/components/checkbox-card/index.js +11 -0
- package/dist/components/code/code.js +19 -0
- package/dist/components/code/code.meta.js +71 -0
- package/dist/components/code/index.js +7 -0
- package/dist/components/code-block/code-block.js +84 -0
- package/dist/components/code-block/code-block.meta.js +103 -0
- package/dist/components/code-block/index.js +8 -0
- package/dist/components/collapsible/collapsible.js +38 -0
- package/dist/components/collapsible/collapsible.meta.js +117 -0
- package/dist/components/collapsible/index.js +15 -0
- package/dist/components/color-field/color-field.js +293 -0
- package/dist/components/color-field/color-field.meta.js +142 -0
- package/dist/components/color-field/color.js +69 -0
- package/dist/components/color-field/index.js +15 -0
- package/dist/components/combobox/combobox.js +486 -0
- package/dist/components/combobox/combobox.meta.js +217 -0
- package/dist/components/combobox/index.js +37 -0
- package/dist/components/command-menu/command-menu-trigger.js +122 -0
- package/dist/components/command-menu/command-menu.js +433 -0
- package/dist/components/command-menu/command-menu.meta.js +279 -0
- package/dist/components/command-menu/index.js +21 -0
- package/dist/components/context-card/context-card.js +62 -0
- package/dist/components/context-card/context-card.meta.js +106 -0
- package/dist/components/context-card/index.js +17 -0
- package/dist/components/context-menu/context-menu.js +92 -0
- package/dist/components/context-menu/context-menu.meta.js +138 -0
- package/dist/components/context-menu/index.js +23 -0
- package/dist/components/data-table/data-table.js +142 -0
- package/dist/components/data-table/data-table.meta.js +146 -0
- package/dist/components/data-table/index.js +9 -0
- package/dist/components/date-picker/date-picker.js +196 -0
- package/dist/components/date-picker/date-picker.meta.js +164 -0
- package/dist/components/date-picker/index.js +7 -0
- package/dist/components/date-tile/date-tile.js +29 -0
- package/dist/components/date-tile/date-tile.meta.js +72 -0
- package/dist/components/date-tile/index.js +7 -0
- package/dist/components/destructive-action-modal/destructive-action-modal.js +130 -0
- package/dist/components/destructive-action-modal/destructive-action-modal.meta.js +136 -0
- package/dist/components/destructive-action-modal/index.js +9 -0
- package/dist/components/dialog/dialog.js +207 -0
- package/dist/components/dialog/dialog.meta.js +239 -0
- package/dist/components/dialog/index.js +45 -0
- package/dist/components/disclosure-picker/disclosure-picker.js +417 -0
- package/dist/components/disclosure-picker/disclosure-picker.meta.js +213 -0
- package/dist/components/disclosure-picker/index.js +21 -0
- package/dist/components/empty-state/empty-state.js +52 -0
- package/dist/components/empty-state/empty-state.meta.js +158 -0
- package/dist/components/empty-state/index.js +7 -0
- package/dist/components/entity/entity.js +70 -0
- package/dist/components/entity/entity.meta.js +108 -0
- package/dist/components/entity/entity.variants.js +16 -0
- package/dist/components/entity/index.js +7 -0
- package/dist/components/feedback/feedback.js +93 -0
- package/dist/components/feedback/feedback.meta.js +109 -0
- package/dist/components/feedback/index.js +7 -0
- package/dist/components/fieldset/fieldset.js +80 -0
- package/dist/components/fieldset/fieldset.meta.js +160 -0
- package/dist/components/fieldset/index.js +17 -0
- package/dist/components/file-dropzone/file-dropzone.js +193 -0
- package/dist/components/file-dropzone/file-dropzone.meta.js +210 -0
- package/dist/components/file-dropzone/file-dropzone.variants.js +26 -0
- package/dist/components/file-dropzone/index.js +13 -0
- package/dist/components/font-picker/font-picker.js +77 -0
- package/dist/components/font-picker/font-picker.meta.js +119 -0
- package/dist/components/font-picker/index.js +7 -0
- package/dist/components/form/form.js +145 -0
- package/dist/components/form/form.meta.js +142 -0
- package/dist/components/form/index.js +11 -0
- package/dist/components/gliding-highlight/gliding-highlight.js +50 -0
- package/dist/components/gliding-highlight/gliding-highlight.meta.js +135 -0
- package/dist/components/gliding-highlight/index.js +9 -0
- package/dist/components/gradient-art/gradient-art.js +168 -0
- package/dist/components/gradient-art/gradient-art.meta.js +81 -0
- package/dist/components/gradient-art/index.js +7 -0
- package/dist/components/gradient-art/renderer.js +336 -0
- package/dist/components/inline-status/index.js +7 -0
- package/dist/components/inline-status/inline-status.js +33 -0
- package/dist/components/inline-status/inline-status.meta.js +83 -0
- package/dist/components/inline-status/inline-status.variants.js +18 -0
- package/dist/components/input/index.js +7 -0
- package/dist/components/input/input.js +33 -0
- package/dist/components/input/input.meta.js +155 -0
- package/dist/components/kbd/index.js +8 -0
- package/dist/components/kbd/kbd.js +54 -0
- package/dist/components/kbd/kbd.meta.js +95 -0
- package/dist/components/label/index.js +7 -0
- package/dist/components/label/label.js +51 -0
- package/dist/components/label/label.meta.js +98 -0
- package/dist/components/line-chart/index.js +7 -0
- package/dist/components/line-chart/line-chart.js +10 -0
- package/dist/components/line-chart/line-chart.meta.js +222 -0
- package/dist/components/marker/index.js +7 -0
- package/dist/components/marker/marker.js +39 -0
- package/dist/components/marker/marker.meta.js +132 -0
- package/dist/components/marker/marker.variants.js +25 -0
- package/dist/components/marquee/index.js +7 -0
- package/dist/components/marquee/marquee.js +146 -0
- package/dist/components/marquee/marquee.meta.js +106 -0
- package/dist/components/media-image/index.js +7 -0
- package/dist/components/media-image/media-image.js +56 -0
- package/dist/components/media-image/media-image.meta.js +92 -0
- package/dist/components/media-tile/index.js +7 -0
- package/dist/components/media-tile/media-tile.js +135 -0
- package/dist/components/media-tile/media-tile.meta.js +133 -0
- package/dist/components/media-tile/media-tile.variants.js +48 -0
- package/dist/components/menu/index.js +33 -0
- package/dist/components/menu/menu.js +168 -0
- package/dist/components/menu/menu.meta.js +176 -0
- package/dist/components/message/index.js +7 -0
- package/dist/components/message/message.js +83 -0
- package/dist/components/message/message.meta.js +150 -0
- package/dist/components/message/message.variants.js +41 -0
- package/dist/components/message-scroller/index.js +9 -0
- package/dist/components/message-scroller/message-scroller.js +300 -0
- package/dist/components/message-scroller/message-scroller.meta.js +172 -0
- package/dist/components/meter/index.js +20 -0
- package/dist/components/meter/meter.js +112 -0
- package/dist/components/meter/meter.meta.js +227 -0
- package/dist/components/meter/meter.variants.js +61 -0
- package/dist/components/middle-truncate/index.js +7 -0
- package/dist/components/middle-truncate/middle-truncate.js +28 -0
- package/dist/components/middle-truncate/middle-truncate.meta.js +77 -0
- package/dist/components/note/index.js +9 -0
- package/dist/components/note/note.js +73 -0
- package/dist/components/note/note.meta.js +112 -0
- package/dist/components/note/note.variants.js +22 -0
- package/dist/components/notification-badge/index.js +15 -0
- package/dist/components/notification-badge/notification-badge.js +48 -0
- package/dist/components/notification-badge/notification-badge.meta.js +107 -0
- package/dist/components/notification-badge/notification-badge.variants.js +57 -0
- package/dist/components/number-field/index.js +7 -0
- package/dist/components/number-field/number-field.js +70 -0
- package/dist/components/number-field/number-field.meta.js +109 -0
- package/dist/components/otp-field/index.js +7 -0
- package/dist/components/otp-field/otp-field.js +70 -0
- package/dist/components/otp-field/otp-field.meta.js +197 -0
- package/dist/components/overflow-menu/index.js +7 -0
- package/dist/components/overflow-menu/overflow-menu.js +26 -0
- package/dist/components/overflow-menu/overflow-menu.meta.js +100 -0
- package/dist/components/page-header/index.js +7 -0
- package/dist/components/page-header/page-header.js +34 -0
- package/dist/components/page-header/page-header.meta.js +104 -0
- package/dist/components/page-loader/index.js +7 -0
- package/dist/components/page-loader/page-loader.js +37 -0
- package/dist/components/page-loader/page-loader.meta.js +85 -0
- package/dist/components/pagination/index.js +7 -0
- package/dist/components/pagination/pagination.js +105 -0
- package/dist/components/pagination/pagination.meta.js +141 -0
- package/dist/components/panel-group/index.js +10 -0
- package/dist/components/panel-group/panel-group.js +168 -0
- package/dist/components/panel-group/panel-group.meta.js +153 -0
- package/dist/components/panel-section/index.js +9 -0
- package/dist/components/panel-section/panel-section.js +115 -0
- package/dist/components/panel-section/panel-section.meta.js +156 -0
- package/dist/components/phone/index.js +7 -0
- package/dist/components/phone/phone.js +50 -0
- package/dist/{chunk-KFZ43RKU.js → components/phone/phone.meta.js} +3 -50
- package/dist/{chunk-NEQNXI2G.js → components/phone/status-icons.js} +4 -4
- package/dist/components/pie-chart/index.js +7 -0
- package/dist/components/pie-chart/pie-chart.js +191 -0
- package/dist/components/pie-chart/pie-chart.meta.js +210 -0
- package/dist/components/pill/index.js +9 -0
- package/dist/components/pill/pill.js +24 -0
- package/dist/components/pill/pill.meta.js +108 -0
- package/dist/components/pill/pill.variants.js +65 -0
- package/dist/components/popover/index.js +23 -0
- package/dist/components/popover/popover.js +100 -0
- package/dist/components/popover/popover.meta.js +136 -0
- package/dist/components/progress/index.js +19 -0
- package/dist/components/progress/progress.js +70 -0
- package/dist/components/progress/progress.meta.js +171 -0
- package/dist/components/progress/progress.variants.js +17 -0
- package/dist/components/radar-chart/index.js +7 -0
- package/dist/components/radar-chart/radar-chart.js +161 -0
- package/dist/components/radar-chart/radar-chart.meta.js +204 -0
- package/dist/components/radial-chart/index.js +7 -0
- package/dist/components/radial-chart/radial-chart.js +175 -0
- package/dist/components/radial-chart/radial-chart.meta.js +216 -0
- package/dist/components/radio/index.js +8 -0
- package/dist/components/radio/radio.js +39 -0
- package/dist/components/radio/radio.meta.js +104 -0
- package/dist/components/radio-card/index.js +7 -0
- package/dist/components/radio-card/radio-card.js +81 -0
- package/dist/components/radio-card/radio-card.meta.js +144 -0
- package/dist/components/radio-card/radio-card.variants.js +43 -0
- package/dist/components/relative-time/index.js +7 -0
- package/dist/components/relative-time/relative-time.js +47 -0
- package/dist/components/relative-time/relative-time.meta.js +77 -0
- package/dist/components/scroller/index.js +7 -0
- package/dist/components/scroller/scroller.js +111 -0
- package/dist/components/scroller/scroller.meta.js +118 -0
- package/dist/components/scrub-field/index.js +7 -0
- package/dist/components/scrub-field/scrub-field.js +124 -0
- package/dist/components/scrub-field/scrub-field.meta.js +139 -0
- package/dist/components/search-input/index.js +7 -0
- package/dist/components/search-input/search-input.js +91 -0
- package/dist/components/search-input/search-input.meta.js +129 -0
- package/dist/components/section-header/index.js +7 -0
- package/dist/components/section-header/section-header.js +39 -0
- package/dist/components/section-header/section-header.meta.js +174 -0
- package/dist/components/segmented-bar/index.js +14 -0
- package/dist/components/segmented-bar/segmented-bar.js +26 -0
- package/dist/components/segmented-bar/segmented-bar.meta.js +108 -0
- package/dist/components/segmented-bar/segmented-bar.variants.js +39 -0
- package/dist/components/select/index.js +25 -0
- package/dist/components/select/select.js +191 -0
- package/dist/components/select/select.meta.js +189 -0
- package/dist/components/separator/index.js +7 -0
- package/dist/components/separator/separator.js +42 -0
- package/dist/components/separator/separator.meta.js +84 -0
- package/dist/components/settings-menu/index.js +11 -0
- package/dist/components/settings-menu/settings-menu.js +101 -0
- package/dist/components/settings-menu/settings-menu.meta.js +177 -0
- package/dist/components/settings-menu/settings-menu.variants.js +15 -0
- package/dist/components/sheet/index.js +29 -0
- package/dist/components/sheet/sheet.js +121 -0
- package/dist/components/sheet/sheet.meta.js +167 -0
- package/dist/components/sheet/sheet.variants.js +21 -0
- package/dist/components/show-more/index.js +7 -0
- package/dist/components/show-more/show-more.js +87 -0
- package/dist/components/show-more/show-more.meta.js +79 -0
- package/dist/components/side-nav/index.js +13 -0
- package/dist/components/side-nav/side-nav.js +75 -0
- package/dist/components/side-nav/side-nav.meta.js +139 -0
- package/dist/components/side-nav/side-nav.variants.js +33 -0
- package/dist/components/sidebar/index.js +21 -0
- package/dist/components/sidebar/sidebar.js +196 -0
- package/dist/components/sidebar/sidebar.meta.js +118 -0
- package/dist/components/skeleton/index.js +7 -0
- package/dist/components/skeleton/skeleton.js +16 -0
- package/dist/components/skeleton/skeleton.meta.js +90 -0
- package/dist/components/slider/index.js +21 -0
- package/dist/components/slider/slider.js +115 -0
- package/dist/components/slider/slider.meta.js +214 -0
- package/dist/components/sparkline/index.js +7 -0
- package/dist/components/sparkline/sparkline.js +84 -0
- package/dist/components/sparkline/sparkline.meta.js +147 -0
- package/dist/components/spinner/index.js +7 -0
- package/dist/components/spinner/spinner.js +59 -0
- package/dist/components/spinner/spinner.meta.js +118 -0
- package/dist/components/status-bar/index.js +9 -0
- package/dist/components/status-bar/status-bar.js +40 -0
- package/dist/components/status-bar/status-bar.meta.js +117 -0
- package/dist/components/status-dot/index.js +9 -0
- package/dist/components/status-dot/status-dot.js +40 -0
- package/dist/components/status-dot/status-dot.meta.js +113 -0
- package/dist/components/status-dot/status-dot.variants.js +28 -0
- package/dist/components/stepper/index.js +17 -0
- package/dist/components/stepper/stepper.js +161 -0
- package/dist/components/stepper/stepper.meta.js +190 -0
- package/dist/components/stepper/stepper.variants.js +72 -0
- package/dist/components/streaming-text/index.js +7 -0
- package/dist/components/streaming-text/streaming-text.js +55 -0
- package/dist/components/streaming-text/streaming-text.meta.js +147 -0
- package/dist/components/switch/index.js +7 -0
- package/dist/components/switch/switch.js +26 -0
- package/dist/components/switch/switch.meta.js +133 -0
- package/dist/components/table/index.js +23 -0
- package/dist/components/table/table.js +117 -0
- package/dist/components/table/table.meta.js +143 -0
- package/dist/components/tabs/index.js +17 -0
- package/dist/components/tabs/tabs.js +58 -0
- package/dist/components/tabs/tabs.meta.js +120 -0
- package/dist/components/textarea/index.js +7 -0
- package/dist/components/textarea/textarea.js +38 -0
- package/dist/components/textarea/textarea.meta.js +117 -0
- package/dist/components/theme-selector/index.js +11 -0
- package/dist/components/theme-selector/theme-selector.js +145 -0
- package/dist/components/theme-selector/theme-selector.meta.js +181 -0
- package/dist/components/theme-switcher/index.js +7 -0
- package/dist/components/theme-switcher/theme-switcher.js +106 -0
- package/dist/components/theme-switcher/theme-switcher.meta.js +99 -0
- package/dist/components/thinking-orb/index.js +9 -0
- package/dist/components/thinking-orb/thinking-orb.js +126 -0
- package/dist/components/thinking-orb/thinking-orb.meta.js +142 -0
- package/dist/components/thinking-orb/thinking-orb.render.js +252 -0
- package/dist/components/toast/index.js +29 -0
- package/dist/components/toast/toast.js +254 -0
- package/dist/components/toast/toast.meta.js +261 -0
- package/dist/components/toggle/index.js +13 -0
- package/dist/components/toggle/toggle.js +51 -0
- package/dist/components/toggle/toggle.meta.js +129 -0
- package/dist/components/toolbar/index.js +27 -0
- package/dist/components/toolbar/toolbar.js +80 -0
- package/dist/components/toolbar/toolbar.meta.js +272 -0
- package/dist/components/toolbar/toolbar.variants.js +16 -0
- package/dist/components/tooltip/index.js +21 -0
- package/dist/components/tooltip/tooltip.js +74 -0
- package/dist/components/tooltip/tooltip.meta.js +156 -0
- package/dist/components/tree/index.js +12 -0
- package/dist/components/tree/tree.js +364 -0
- package/dist/components/tree/tree.meta.js +334 -0
- package/dist/components/video/index.js +7 -0
- package/dist/components/video/video.js +59 -0
- package/dist/components/video/video.meta.js +81 -0
- package/dist/components/workspace/index.js +9 -0
- package/dist/components/workspace/workspace.js +79 -0
- package/dist/components/workspace/workspace.meta.js +183 -0
- package/dist/foundations/accessibility.js +107 -0
- package/dist/foundations/index.js +25 -792
- package/dist/foundations/motion.js +135 -0
- package/dist/foundations/scrolling.js +62 -0
- package/dist/foundations/shape.js +113 -0
- package/dist/foundations/spacing.js +121 -0
- package/dist/foundations/surfaces.js +107 -0
- package/dist/foundations/types.js +0 -0
- package/dist/foundations/typography.js +152 -0
- package/dist/icon/Icon.js +30 -0
- package/dist/icon/IconProvider.js +27 -0
- package/dist/icon/compose.js +13 -0
- package/dist/icon/index.d.ts +13 -5
- package/dist/icon/index.js +13 -2
- package/dist/icon/registry.js +0 -0
- package/dist/icon-sets/brands.generated.js +123 -0
- package/dist/icon-sets/brands.js +10 -123
- package/dist/icon-sets/reicon.d.ts +3 -1
- package/dist/icon-sets/reicon.js +209 -1
- package/dist/index.d.ts +611 -33
- package/dist/index.js +211 -11351
- package/dist/ios/chrome.js +36 -0
- package/dist/ios/index.js +19 -315
- package/dist/ios/liquid-glass.js +103 -0
- package/dist/ios/native-app.js +46 -0
- package/dist/ios/navigation.js +63 -0
- package/dist/ios/phone-frame.js +64 -0
- package/dist/ios/preview-theme.js +83 -0
- package/dist/ios/preview.js +10 -137
- package/dist/ios/sheet.js +85 -0
- package/dist/ios/theme.js +19 -0
- package/dist/layout/AspectBox.js +27 -0
- package/dist/layout/Bleed.js +15 -0
- package/dist/layout/Center.js +21 -0
- package/dist/layout/Columns.js +70 -0
- package/dist/layout/Grid.js +50 -0
- package/dist/layout/GridOverlay.js +41 -0
- package/dist/layout/Page.js +11 -0
- package/dist/layout/Region.js +39 -0
- package/dist/layout/Row.js +45 -0
- package/dist/layout/SafeArea.js +26 -0
- package/dist/layout/Spacer.js +9 -0
- package/dist/layout/SplitPane.js +55 -0
- package/dist/layout/Stack.js +42 -0
- package/dist/layout/_responsive.js +16 -0
- package/dist/layout/_safeArea.js +18 -0
- package/dist/layout/index.d.ts +25 -6
- package/dist/layout/index.js +14 -2
- package/dist/lib/anchored-scroll.js +7 -0
- package/dist/lib/bleed.js +7 -0
- package/dist/lib/chart/cartesian.js +365 -0
- package/dist/lib/chart/chart-frame.js +163 -0
- package/dist/lib/chart/chart-legend.js +13 -0
- package/dist/lib/chart/chart-tooltip.js +38 -0
- package/dist/lib/chart/format.js +19 -0
- package/dist/lib/chart/geometry.js +114 -0
- package/dist/lib/chart/motion.js +34 -0
- package/dist/lib/chart/scale.js +72 -0
- package/dist/lib/chart/types.js +45 -0
- package/dist/lib/chart/use-arrival.js +41 -0
- package/dist/{chunk-SRQWQUTW.js → lib/cn.js} +5 -5
- package/dist/lib/component-guidance.js +210 -0
- package/dist/lib/density.js +54 -0
- package/dist/lib/field-shell.js +11 -0
- package/dist/lib/glyphs.js +9 -0
- package/dist/lib/heading-row.js +36 -0
- package/dist/lib/highlight-glide.js +84 -0
- package/dist/lib/hit-target.js +5 -0
- package/dist/lib/meta.js +0 -0
- package/dist/lib/portal-theme-scope.js +74 -0
- package/dist/{chunk-FKZXAFIY.js → lib/presentation.js} +8 -3
- package/dist/lib/refs.js +14 -0
- package/dist/lib/scrub-gesture.js +50 -0
- package/dist/lib/segmented.js +13 -0
- package/dist/lib/selection-card.js +41 -0
- package/dist/lib/status-tone.js +13 -0
- package/dist/lib/taxonomy.js +214 -0
- package/dist/lib/trim-label.js +20 -0
- package/dist/lib/use-copy.js +27 -0
- package/dist/lib/use-edge-fade.js +32 -0
- package/dist/lib/use-isomorphic-layout-effect.js +8 -0
- package/dist/lib/use-resize-observer.js +18 -0
- package/dist/lib/use-scroll-activity.js +52 -0
- package/dist/lib/use-wheel-to-horizontal.js +65 -0
- package/dist/motion/MotionProvider.js +75 -0
- package/dist/motion/Presence.js +112 -0
- package/dist/motion/Reveal.js +42 -0
- package/dist/motion/TextReveal.js +61 -0
- package/dist/motion/index.js +24 -0
- package/dist/motion/useInView.js +36 -0
- package/dist/motion/useReducedMotion.js +25 -0
- package/dist/motion/viewTransition.js +47 -0
- package/dist/patterns/auth-page.js +90 -0
- package/dist/patterns/auth-page.meta.js +27 -0
- package/dist/patterns/brand-landing-page.js +341 -0
- package/dist/patterns/brand-landing-page.meta.js +28 -0
- package/dist/patterns/chat-panel.js +185 -0
- package/dist/patterns/chat-panel.meta.js +31 -0
- package/dist/patterns/dashboard-page.js +332 -0
- package/dist/patterns/dashboard-page.meta.js +29 -0
- package/dist/patterns/feed-page.js +205 -0
- package/dist/patterns/feed-page.meta.js +25 -0
- package/dist/patterns/index.js +34 -2140
- package/dist/patterns/landing-page.js +356 -0
- package/dist/patterns/landing-page.meta.js +26 -0
- package/dist/patterns/list-detail-page.js +373 -0
- package/dist/patterns/list-detail-page.meta.js +24 -0
- package/dist/patterns/settings-page.js +268 -0
- package/dist/patterns/settings-page.meta.js +27 -0
- package/dist/presets/index.js +43 -185
- package/dist/styles.css +118 -3
- package/dist/{theme-provider-kQszHYji.d.ts → theme-provider-S0NVJs2Y.d.ts} +6 -1
- package/dist/{chunk-NETUFI34.js → themes/_contract.js} +14 -2
- package/dist/themes/atelier/index.js +17 -1
- package/dist/themes/contrast.js +288 -0
- package/dist/themes/ember/ember.css +6 -6
- package/dist/themes/ember/index.js +16 -1
- package/dist/themes/index.d.ts +1 -1
- package/dist/themes/index.js +3 -8
- package/dist/themes/meridian/index.js +16 -1
- package/dist/themes/poppy/index.js +17 -1
- package/dist/themes/prism/index.js +17 -1
- package/dist/themes/prism/prism.css +2 -2
- package/dist/themes/registry.js +59 -0
- package/dist/themes/sable/index.js +16 -1
- package/dist/{chunk-EFLC4NA3.js → themes/theme-provider.js} +38 -54
- package/dist/themes/verdant/index.js +17 -1
- package/llms/blocks/media-player-block.md +20 -7
- package/llms/blocks/product-card-block.md +6 -4
- package/llms/blocks/task-list-block.md +1 -1
- package/llms/blocks/verify-code-block.md +1 -1
- package/llms/components/app-shell.md +5 -2
- package/llms/components/avatar.md +25 -3
- package/llms/components/button.md +20 -1
- package/llms/components/card.md +1 -1
- package/llms/components/disclosure-picker.md +168 -0
- package/llms/components/font-picker.md +104 -0
- package/llms/components/media-image.md +98 -0
- package/llms/components/media-tile.md +143 -0
- package/llms/components/page-header.md +6 -5
- package/llms/components/section-header.md +144 -0
- package/llms/components/sheet.md +10 -0
- package/llms/components/sidebar.md +4 -3
- package/llms/components/slider.md +14 -2
- package/llms/components/theme-selector.md +44 -4
- package/llms/components/tree.md +3 -3
- package/llms/layout/grid.md +24 -3
- package/llms/patterns/dashboard-page.md +3 -6
- package/llms/patterns/feed-page.md +4 -4
- package/llms/patterns/list-detail-page.md +1 -0
- package/llms/patterns/settings-page.md +2 -5
- package/llms/reference/utilities.md +84 -4
- package/llms/tasks/converting-an-app.md +14 -4
- package/llms/tasks/reviewing-a-design.md +15 -0
- package/llms-full.txt +981 -65
- package/llms.txt +27 -10
- package/package.json +1 -1
- package/registry.json +2324 -171
- package/scripts/agent-setup.mjs +90 -0
- package/scripts/design-presets.mjs +46 -4
- package/scripts/grade.mjs +195 -29
- package/scripts/lint-rules.mjs +486 -10
- package/scripts/review-evidence.mjs +28 -1
- package/skills/sable/SKILL.md +56 -22
- package/targets/ios.json +45 -0
- package/dist/chunk-3IWZYBGH.js +0 -398
- package/dist/chunk-7MG4SHYX.js +0 -15
- package/dist/chunk-7QSDYBXO.js +0 -7421
- package/dist/chunk-ADLLDWLW.js +0 -15
- package/dist/chunk-C4Z3CF54.js +0 -15
- package/dist/chunk-EDXLM7YL.js +0 -5078
- package/dist/chunk-EHH4MHO6.js +0 -14
- package/dist/chunk-K7RUHUGC.js +0 -14
- package/dist/chunk-KO3NAEBF.js +0 -15
- package/dist/chunk-L4IEIQQA.js +0 -14
- package/dist/chunk-QJ6FWTUG.js +0 -40
- package/dist/chunk-VVW4UCDI.js +0 -4908
- package/dist/chunk-XAZGMY73.js +0 -187
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// src/components/gliding-highlight/gliding-highlight.meta.ts
|
|
2
|
+
var glidingHighlightMeta = {
|
|
3
|
+
name: "GlidingHighlight",
|
|
4
|
+
summary: "One highlight that travels to the active item, instead of each item toggling its own background. Measured, not assumed, so rows of unequal height stay exact.",
|
|
5
|
+
status: "stable",
|
|
6
|
+
keywords: [
|
|
7
|
+
"highlight",
|
|
8
|
+
"active",
|
|
9
|
+
"selection",
|
|
10
|
+
"indicator",
|
|
11
|
+
"menu",
|
|
12
|
+
"list",
|
|
13
|
+
"glide",
|
|
14
|
+
"slide",
|
|
15
|
+
"thumb",
|
|
16
|
+
"hover"
|
|
17
|
+
],
|
|
18
|
+
usage: {
|
|
19
|
+
description: "Use GlidingHighlight for a set of items where one is active at a time and the pointer or arrow keys move between them \u2014 a menu, an option list, a command palette, a segmented control. It replaces per-item `hover:bg-*` with a single element that moves.",
|
|
20
|
+
bestPractices: [
|
|
21
|
+
{
|
|
22
|
+
guidance: "do",
|
|
23
|
+
description: "Pass `hovered ?? selected`. The fallback is what makes the pointer leaving a menu return the highlight to the current choice instead of dropping it, so the reader's place is never lost."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
guidance: "do",
|
|
27
|
+
description: "Reach for it wherever a list is keyboard-navigable. The gain is largest for arrow keys: a background that teleports between rows makes the eye re-find the highlight at every step, where one that moves can be tracked while it travels \u2014 which is what keeps a long list readable in motion rather than only at rest."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
guidance: "do",
|
|
31
|
+
description: "Keep selection semantics on the items \u2014 `aria-selected`, `aria-current`, `data-selected`. The highlight is `aria-hidden` decoration over whatever the children already announce."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
guidance: "dont",
|
|
35
|
+
description: "Do not use it for items that are not mutually exclusive. A travelling highlight says 'one of these, and it is this one'; over a multi-select list it contradicts the checkboxes beside it, and only one of the two can be right."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
guidance: "dont",
|
|
39
|
+
description: "Do not put non-item chrome among the direct children \u2014 a group heading, a separator, a footer hint. Every direct child is a measurable row, so `active` counts them, and the highlight lands one row off from the index the caller is reasoning about. Wrap the items in their own GlidingHighlight, or move the chrome outside."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
guidance: "dont",
|
|
43
|
+
description: "Do not drive it from a scroll position or a timer. It is an affordance for a set with a discrete active member; a highlight that moves without an item becoming active reads as the interface selecting things on its own."
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
anatomy: [
|
|
47
|
+
{
|
|
48
|
+
name: "Container",
|
|
49
|
+
required: true,
|
|
50
|
+
description: "Positioning context for the highlight. Each direct child is measured as one item."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "Highlight",
|
|
54
|
+
required: true,
|
|
55
|
+
description: "The travelling element. `aria-hidden`, absolutely positioned, invisible until something is active."
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
related: {
|
|
60
|
+
components: ["Menu", "Select", "Combobox", "CommandMenu", "SideNav"]
|
|
61
|
+
},
|
|
62
|
+
props: [
|
|
63
|
+
{
|
|
64
|
+
name: "active",
|
|
65
|
+
type: "number | null",
|
|
66
|
+
description: "Index of the item the highlight sits behind, or `null` for none. Pass `hovered ?? selected`."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "orientation",
|
|
70
|
+
type: '"vertical" | "horizontal"',
|
|
71
|
+
description: "Deprecated and ignored: the highlight measures both axes, so a horizontal row needs no flag.",
|
|
72
|
+
deprecated: "nothing \u2014 omit it"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "onPointerLeave",
|
|
76
|
+
type: "PointerEventHandler (and every other div prop)",
|
|
77
|
+
description: "The container is a plain div, so its props pass through. For a hover-following list, reset the hovered index here so the highlight returns to the selected row when the pointer leaves."
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "highlightClassName",
|
|
81
|
+
type: "string",
|
|
82
|
+
description: "Class for the travelling highlight itself, for changing its fill or radius. The radius defaults to `sable-frame-inner`, so inside a `sable-frame` container it nests concentrically; in any other rounded, inset container pass `rounded-concentric-<outer>/<inset>` here and on the rows. The container's own `className` styles the list."
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
tokensUsed: ["accent"],
|
|
86
|
+
motion: [
|
|
87
|
+
{
|
|
88
|
+
slot: "arrival",
|
|
89
|
+
recipe: "none",
|
|
90
|
+
part: "Highlight",
|
|
91
|
+
why: "It deliberately does not animate in. Fading it up at rest position \u2014 usually row 0 \u2014 makes a menu look like it opened with the first item pre-selected, which is a claim about state that is not true. It stays invisible until something is genuinely active."
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
slot: "response",
|
|
95
|
+
recipe: "none",
|
|
96
|
+
part: "Container",
|
|
97
|
+
why: "The container is not the control; the items are, and they own their own pointer states. This draws the result."
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
slot: "transition",
|
|
101
|
+
recipe: "motion-interactive",
|
|
102
|
+
part: "Highlight",
|
|
103
|
+
why: "The travel IS the component \u2014 a highlight that jumps is just a background toggle with extra machinery. Position, size and opacity ride one declaration so a tall row's height cannot catch up after its position has, which would read as the highlight stretching into place rather than moving."
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
slot: "activity",
|
|
107
|
+
recipe: "none",
|
|
108
|
+
part: "Highlight",
|
|
109
|
+
why: "Nothing here is indeterminate. A list still loading its options shows a Skeleton in place of the rows."
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
a11y: [
|
|
113
|
+
"The highlight is `aria-hidden` and carries no semantics \u2014 it renders selection, it does not declare it. Keep `aria-selected` / `aria-current` on the items themselves.",
|
|
114
|
+
"Pointer-free by construction (`pointer-events-none`), so it can never intercept a click meant for the item beneath it.",
|
|
115
|
+
"Works with roving-tabindex and `aria-activedescendant` lists alike: it reads an index the caller already owns, and does not manage focus.",
|
|
116
|
+
"Under reduced motion or with MotionProvider off, the highlight moves instantly rather than gliding \u2014 the active item is still shown, which is the part that carries meaning."
|
|
117
|
+
],
|
|
118
|
+
examples: [
|
|
119
|
+
{
|
|
120
|
+
label: "A hoverable menu, returning home on leave",
|
|
121
|
+
code: '<GlidingHighlight active={hovered ?? selected} className="sable-frame sable-surface sable-surface-popover sable-frame-popover" onPointerLeave={() => setHovered(null)}>{items.map((item, i) => (<button key={item.id} type="button" className="sable-frame-inner px-2 py-1.5 text-start" onPointerEnter={() => setHovered(i)} onClick={() => setSelected(i)}>{item.label}</button>))}</GlidingHighlight>'
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
label: "Horizontal, as a segmented control",
|
|
125
|
+
code: '<GlidingHighlight active={tab} className="sable-well flex gap-1 rounded-md p-1" highlightClassName="rounded-concentric-md/1">{tabs.map((t, i) => (<button key={t} type="button" className="rounded-concentric-md/1 px-3 py-1" onClick={() => setTab(i)}>{t}</button>))}</GlidingHighlight>'
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
label: "Keyboard navigation \u2014 the case it exists for",
|
|
129
|
+
code: '<GlidingHighlight active={cursor} onKeyDown={(e) => { if (e.key === "ArrowDown") setCursor((c) => (c + 1) % rows.length) }}>{rows.map((r) => (<div key={r.id} role="option" aria-selected={false}>{r.label}</div>))}</GlidingHighlight>'
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
};
|
|
133
|
+
export {
|
|
134
|
+
glidingHighlightMeta
|
|
135
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/gradient-art/gradient-art.tsx
|
|
4
|
+
import { useEffect, useRef } from "react";
|
|
5
|
+
import { cn } from "../../lib/cn.js";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
var ART_SLOTS = ["var(--art-1)", "var(--art-2)", "var(--art-3)", "var(--art-4)", "var(--art-5)", "var(--art-6)"];
|
|
8
|
+
var ART_GROUND = "var(--art-ground)";
|
|
9
|
+
var lifted = (tone) => `oklch(from var(--tone-${tone}) clamp(0.5, calc(l + 0.16), 0.9) max(calc(c * 1.25), 0.1) h)`;
|
|
10
|
+
var ground = (tone) => `color-mix(in oklab, var(--primary) 55%, oklch(from var(--tone-${tone}) 0.3 c h))`;
|
|
11
|
+
function seedValue(seed) {
|
|
12
|
+
if (seed == null) return 0.37;
|
|
13
|
+
if (typeof seed === "number") return Math.abs(seed * 0.618034) % 1;
|
|
14
|
+
let hash = 2166136261;
|
|
15
|
+
for (let i = 0; i < seed.length; i++) {
|
|
16
|
+
hash ^= seed.charCodeAt(i);
|
|
17
|
+
hash = Math.imul(hash, 16777619);
|
|
18
|
+
}
|
|
19
|
+
return (hash >>> 0) / 4294967296;
|
|
20
|
+
}
|
|
21
|
+
function fallback(palette, groundColor, seed) {
|
|
22
|
+
const spots = palette.map((color, i) => {
|
|
23
|
+
const angle = (seed + i / palette.length) * Math.PI * 2;
|
|
24
|
+
const x = Math.round(50 + Math.cos(angle) * 38);
|
|
25
|
+
const y = Math.round(50 + Math.sin(angle) * 38);
|
|
26
|
+
return `radial-gradient(in oklab at ${x}% ${y}%, ${color}, transparent 60%)`;
|
|
27
|
+
});
|
|
28
|
+
return [...spots, groundColor].join(", ");
|
|
29
|
+
}
|
|
30
|
+
function rotate(items, seed) {
|
|
31
|
+
if (items.length < 2) return [...items];
|
|
32
|
+
const shift = Math.floor(seed * 7919) % items.length;
|
|
33
|
+
return [...items.slice(shift), ...items.slice(0, shift)];
|
|
34
|
+
}
|
|
35
|
+
var HUE_TURN = 20;
|
|
36
|
+
var LIGHT_STEP = 0.04;
|
|
37
|
+
function nudge(color, seed) {
|
|
38
|
+
const frac = (n) => n - Math.floor(n);
|
|
39
|
+
const dh = ((frac(seed * 7.31) * 2 - 1) * HUE_TURN).toFixed(1);
|
|
40
|
+
const dl = ((frac(seed * 13.7) * 2 - 1) * LIGHT_STEP).toFixed(3);
|
|
41
|
+
return `oklch(from ${color} clamp(0, calc(l + ${dl}), 1) c calc(h + ${dh}))`;
|
|
42
|
+
}
|
|
43
|
+
function param(style, name, fallbackValue) {
|
|
44
|
+
const n = Number.parseFloat(style.getPropertyValue(name));
|
|
45
|
+
return Number.isFinite(n) ? Math.min(1, Math.max(0, n)) : fallbackValue;
|
|
46
|
+
}
|
|
47
|
+
var MAX_PIXELS = 15e5;
|
|
48
|
+
function GradientArt({ variant = "mesh", tones, seed, className, style, children, ...props }) {
|
|
49
|
+
const root = useRef(null);
|
|
50
|
+
const canvas = useRef(null);
|
|
51
|
+
const probes = useRef(null);
|
|
52
|
+
const value = seedValue(seed);
|
|
53
|
+
const palette = (tones?.length ? tones.map(lifted) : ART_SLOTS).map((color) => nudge(color, value));
|
|
54
|
+
const groundColor = nudge(tones?.length ? ground(tones[0]) : ART_GROUND, value);
|
|
55
|
+
const paletteKey = palette.join(" ");
|
|
56
|
+
const background = fallback(rotate(palette, value), groundColor, value);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
const element = root.current;
|
|
59
|
+
const target = canvas.current;
|
|
60
|
+
const swatches = probes.current;
|
|
61
|
+
if (!element || !target || !swatches) return;
|
|
62
|
+
if (typeof IntersectionObserver === "undefined" || typeof ResizeObserver === "undefined") return;
|
|
63
|
+
let cancelled = false;
|
|
64
|
+
let teardown;
|
|
65
|
+
import("./renderer.js").then(
|
|
66
|
+
(renderer) => {
|
|
67
|
+
if (!cancelled) teardown = start(renderer);
|
|
68
|
+
},
|
|
69
|
+
() => {
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
return () => {
|
|
73
|
+
cancelled = true;
|
|
74
|
+
teardown?.();
|
|
75
|
+
};
|
|
76
|
+
function start({ artSupported, cssColorToRgba, onArtInvalidate, onThemeChange, paintArt }) {
|
|
77
|
+
if (!element || !target || !swatches || !artSupported()) return;
|
|
78
|
+
let visible = false;
|
|
79
|
+
let frame = 0;
|
|
80
|
+
let last = "";
|
|
81
|
+
const paint = () => {
|
|
82
|
+
frame = 0;
|
|
83
|
+
if (!visible) return;
|
|
84
|
+
const rect = element.getBoundingClientRect();
|
|
85
|
+
if (!rect.width || !rect.height) return;
|
|
86
|
+
let ratio = Math.min(window.devicePixelRatio || 1, 2);
|
|
87
|
+
const pixels = rect.width * rect.height * ratio * ratio;
|
|
88
|
+
if (pixels > MAX_PIXELS) ratio *= Math.sqrt(MAX_PIXELS / pixels);
|
|
89
|
+
const width = Math.max(1, Math.round(rect.width * ratio));
|
|
90
|
+
const height = Math.max(1, Math.round(rect.height * ratio));
|
|
91
|
+
const resolve = (probe) => cssColorToRgba(getComputedStyle(probe).color);
|
|
92
|
+
const [groundProbe, ...colorProbes] = Array.from(swatches.children);
|
|
93
|
+
const colors = rotate(
|
|
94
|
+
colorProbes.map(resolve).filter((c) => c != null && c[3] > 0.01),
|
|
95
|
+
value
|
|
96
|
+
);
|
|
97
|
+
const groundRgba = groundProbe ? resolve(groundProbe) : null;
|
|
98
|
+
if (!colors.length) return;
|
|
99
|
+
const own = getComputedStyle(element);
|
|
100
|
+
const character = { warp: param(own, "--art-warp", 0.8), softness: param(own, "--art-softness", 0.88), grain: param(own, "--art-grain", 0) };
|
|
101
|
+
const key = JSON.stringify([variant, value, width, height, colors, groundRgba, character]);
|
|
102
|
+
if (key === last) return;
|
|
103
|
+
const ordered = variant === "grain" && groundRgba ? [groundRgba, ...colors] : colors;
|
|
104
|
+
if (paintArt(target, { variant, colors: ordered, seed: value, width, height, pixelRatio: ratio, ...character })) {
|
|
105
|
+
last = key;
|
|
106
|
+
target.dataset.painted = "";
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const schedule = () => {
|
|
110
|
+
if (!frame) frame = requestAnimationFrame(paint);
|
|
111
|
+
};
|
|
112
|
+
const repaint = () => {
|
|
113
|
+
last = "";
|
|
114
|
+
schedule();
|
|
115
|
+
};
|
|
116
|
+
const intersection = new IntersectionObserver(
|
|
117
|
+
([entry]) => {
|
|
118
|
+
visible = entry.isIntersecting;
|
|
119
|
+
if (visible) schedule();
|
|
120
|
+
},
|
|
121
|
+
{ rootMargin: "200px" }
|
|
122
|
+
);
|
|
123
|
+
intersection.observe(element);
|
|
124
|
+
const resize = new ResizeObserver(schedule);
|
|
125
|
+
resize.observe(element);
|
|
126
|
+
const offTheme = onThemeChange(schedule);
|
|
127
|
+
const offInvalidate = onArtInvalidate(repaint);
|
|
128
|
+
return () => {
|
|
129
|
+
cancelAnimationFrame(frame);
|
|
130
|
+
intersection.disconnect();
|
|
131
|
+
resize.disconnect();
|
|
132
|
+
offTheme();
|
|
133
|
+
offInvalidate();
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}, [variant, value, paletteKey]);
|
|
137
|
+
return /* @__PURE__ */ jsxs(
|
|
138
|
+
"div",
|
|
139
|
+
{
|
|
140
|
+
ref: root,
|
|
141
|
+
"data-slot": "gradient-art",
|
|
142
|
+
"data-variant": variant,
|
|
143
|
+
className: cn("relative isolate overflow-hidden", className),
|
|
144
|
+
style: { background, ...style },
|
|
145
|
+
...props,
|
|
146
|
+
children: [
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
"canvas",
|
|
149
|
+
{
|
|
150
|
+
ref: canvas,
|
|
151
|
+
"aria-hidden": true,
|
|
152
|
+
className: "pointer-events-none absolute inset-0 -z-10 size-full opacity-0 motion-interactive data-[painted]:opacity-100",
|
|
153
|
+
style: { transitionProperty: "opacity" }
|
|
154
|
+
}
|
|
155
|
+
),
|
|
156
|
+
/* @__PURE__ */ jsxs("span", { ref: probes, hidden: true, children: [
|
|
157
|
+
/* @__PURE__ */ jsx("span", { style: { color: groundColor } }),
|
|
158
|
+
palette.map((color) => /* @__PURE__ */ jsx("span", { style: { color } }, color))
|
|
159
|
+
] }),
|
|
160
|
+
children
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
GradientArt.displayName = "GradientArt";
|
|
166
|
+
export {
|
|
167
|
+
GradientArt
|
|
168
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// src/components/gradient-art/gradient-art.meta.ts
|
|
2
|
+
var gradientArtMeta = {
|
|
3
|
+
name: "GradientArt",
|
|
4
|
+
summary: "Placeholder artwork painted by a static WebGL shader from the preset's own art direction (the --art-* tokens: palette, ground, warp, softness, grain) \u2014 Ember burns, Prism airbrushes, Meridian is grainy monochrome \u2014 with a CSS gradient underneath for prerendered pages and browsers without WebGL2.",
|
|
5
|
+
status: "beta",
|
|
6
|
+
keywords: ["gradient", "mesh gradient", "grain", "shader", "artwork", "placeholder image", "cover", "banner", "avatar fallback", "generative"],
|
|
7
|
+
usage: {
|
|
8
|
+
description: "Use GradientArt where a real image belongs but none exists yet, or where the image is decoration: a product cover before upload, a profile banner, an album tile, an avatar with no photo. It reads the theme's own tokens, so it follows every preset, mode and live edit; `seed` fixes each item's composition so a list of covers or avatars stays individually recognisable.",
|
|
9
|
+
bestPractices: [
|
|
10
|
+
{
|
|
11
|
+
guidance: "do",
|
|
12
|
+
description: "Pass a stable `seed` per item \u2014 the name for an avatar, the title for a cover. Each item then keeps the same art across renders, reloads and themes, which is what lets someone recognise it."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
guidance: "do",
|
|
16
|
+
description: "Size it with layout classes (`aspect-[4/3]`, `h-20`, `size-10 rounded-full`) and put any glyph or initials inside as children; they render above the art."
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
guidance: "do",
|
|
20
|
+
description: "Keep the default `mesh` for covers, tiles and avatars. Reach for `grain` where a printed, tactile surface suits \u2014 a banner, a hero card \u2014 and keep one variant per surface type so art reads as a system."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
guidance: "dont",
|
|
24
|
+
description: "Do not put body text over it. The art spans the palette's lightest and most saturated tones, so no single ink is guaranteed to clear contrast across it; reserve overlays for a short label on a scrim or an avatar's initials."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
guidance: "dont",
|
|
28
|
+
description: "Do not pass colours, and reach for `tones` rarely. The art follows the preset's --art-* tokens on purpose; to change how a product's art looks, set the --theme-art-* hooks in its theme or preset, so every cover, banner and avatar changes together."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
guidance: "dont",
|
|
32
|
+
description: "Do not use it as a page or hero background. It paints at the element's pixel size, so a full-viewport instance costs a large frame on every theme change; it is sized for covers, banners and tiles."
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
related: { components: ["Avatar", "Card", "AspectBox"] },
|
|
37
|
+
props: [
|
|
38
|
+
{ name: "variant", type: '"mesh" | "grain"', default: '"mesh"', description: "mesh: soft spots of colour pulled together by gentle waves. grain: glowing light over deep corners with a printed texture." },
|
|
39
|
+
{
|
|
40
|
+
name: "tones",
|
|
41
|
+
type: '("info" | "standard" | "collectible" | "edition" | "warning")[]',
|
|
42
|
+
description: "Paint these `--tone-*` colours instead of the preset's art palette. Leave unset to follow the preset's art direction."
|
|
43
|
+
},
|
|
44
|
+
{ name: "seed", type: "string | number", description: "Fixes the composition: the same seed paints the same art in every theme. Pass a stable id." },
|
|
45
|
+
{ name: "children", type: "ReactNode", description: "Rendered above the art \u2014 initials, a glyph, a short label." },
|
|
46
|
+
{ name: "className", type: "string", description: "Size and shape: aspect, height, rounding." }
|
|
47
|
+
],
|
|
48
|
+
variants: { variant: ["mesh", "grain"] },
|
|
49
|
+
tokensUsed: ["art-1", "art-2", "art-3", "art-4", "art-5", "art-6", "art-ground", "art-warp", "art-softness", "art-grain", "primary", "tone-info", "tone-standard", "tone-collectible", "tone-edition", "tone-warning"],
|
|
50
|
+
motion: [
|
|
51
|
+
{
|
|
52
|
+
slot: "arrival",
|
|
53
|
+
recipe: "motion-interactive",
|
|
54
|
+
part: "canvas",
|
|
55
|
+
why: "The shader frame fades in over the CSS gradient it replaces, so the swap from fallback to shader reads as the art settling rather than a flash."
|
|
56
|
+
},
|
|
57
|
+
{ slot: "response", recipe: "none", part: "root", why: "Artwork, not a control: it does not react to the pointer." },
|
|
58
|
+
{
|
|
59
|
+
slot: "transition",
|
|
60
|
+
recipe: "custom",
|
|
61
|
+
part: "canvas",
|
|
62
|
+
why: "A theme change repaints the frame in place on the next animation frame; there are no states to move between."
|
|
63
|
+
},
|
|
64
|
+
{ slot: "activity", recipe: "none", part: "root", why: "Static by design: nothing animates between paints, so it costs nothing while idle and respects reduced motion without a branch." }
|
|
65
|
+
],
|
|
66
|
+
a11y: [
|
|
67
|
+
"Decorative by default: the canvas is aria-hidden. When the art stands for something (an avatar), label the element that contains it, not the art.",
|
|
68
|
+
"Children render above the art in the normal reading order, so initials or a label are announced as usual."
|
|
69
|
+
],
|
|
70
|
+
examples: [
|
|
71
|
+
{ label: "Product cover", code: '<GradientArt seed="Untitled (gold rush)" className="aspect-[4/3] rounded-lg" />' },
|
|
72
|
+
{ label: "Grain banner", code: '<GradientArt variant="grain" seed="juno" tones={["info", "edition"]} className="h-20 rounded-md" />' },
|
|
73
|
+
{
|
|
74
|
+
label: "Avatar with initials",
|
|
75
|
+
code: '<GradientArt seed="Mara Okafor" className="grid size-10 place-items-center rounded-full text-label-md text-overlay-foreground">MO</GradientArt>'
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
export {
|
|
80
|
+
gradientArtMeta
|
|
81
|
+
};
|