@sableui/react 0.6.2 → 0.7.1
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 +315 -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 +203 -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 +34 -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 +618 -34
- 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 +30 -8
- 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 +24 -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 +215 -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.d.ts +7 -1
- package/dist/presets/index.js +53 -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/traffic-sources-block.md +1 -1
- package/llms/blocks/traffic-trend-block.md +5 -3
- 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/pie-chart.md +2 -2
- package/llms/components/radial-chart.md +1 -1
- 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/layout/region.md +16 -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/building-a-page.md +34 -3
- package/llms/tasks/converting-an-app.md +14 -4
- package/llms/tasks/creating-a-preset.md +4 -1
- package/llms/tasks/reviewing-a-design.md +19 -0
- package/llms/tasks/using-presets.md +19 -0
- package/llms-full.txt +1066 -78
- package/llms.txt +26 -9
- package/package.json +1 -1
- package/registry.json +2342 -164
- package/scripts/agent-setup.mjs +90 -0
- package/scripts/design-presets.mjs +59 -6
- 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 +67 -24
- 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
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `@utility` and `@custom-variant` layer in `styles.css`: what each one is, when to reach for it, and what you would hand-write without it. Generated from `src/utilities/utility-docs.ts`; the full data is `registry.json → utilities`; one entry at a time with `sable utility <name>`.
|
|
4
4
|
|
|
5
|
-
- **Typography:** The paired `text-*` page tiers (`text-heading-1`, `text-body-md`, `text-label-sm`, `text-mono-md`, …) are documented as `registry.json → tokens.typography` (named without the `text-` prefix). `sable token typography`.
|
|
6
|
-
- **Motion:** The `motion-*` and `animate-*` recipes are listed in `registry.json → tokens.motion.recipes`, with the slot model in `registry.json → motionLayer`. `sable docs motion`.
|
|
5
|
+
- **Typography:** The paired `text-*` page tiers (`text-heading-1`, `text-body-md`, `text-label-sm`, `text-mono-md`, …) are documented as `registry.json → tokens.typography` (named without the `text-` prefix). Retrieve one with `sable utility text-heading-1`, all with `sable token typography`.
|
|
7
6
|
|
|
8
7
|
### relative surface (6)
|
|
9
8
|
|
|
@@ -131,12 +130,93 @@ The `@utility` and `@custom-variant` layer in `styles.css`: what each one is, wh
|
|
|
131
130
|
- **Instead of** An animated fade or a hand-written `mask-image` gradient. Use `StreamingText` first; this is for a stream rendered without it.
|
|
132
131
|
- `<span className="stream-tail">{latestChunk}</span>`
|
|
133
132
|
|
|
134
|
-
###
|
|
133
|
+
### motion (24)
|
|
134
|
+
|
|
135
|
+
- **`motion-interactive`** — The transition for interactive chrome: colour, background, border, shadow, opacity, fill, stroke, scale and translate at the fast duration and standard easing. Also removes the mobile tap delay and the platform's grey tap flash. *Use for:* On anything clickable that changes on hover, focus, press or selection: a custom row, a tile, a link, an app-owned button. It is the `response` slot, and the only transition declarer such an element needs.
|
|
136
|
+
- **Instead of** Tailwind's colour-only or all-property transition utilities with a hand-picked duration. Those ignore --motion-scale, skip the transform properties `motion-press` needs, and leave the 300ms tap delay on touch screens. sable-lint's `static-interactive` fires on a hover style with no recipe.
|
|
137
|
+
- `<a href="/inbox" className="motion-interactive link-underline text-primary">Inbox</a>`
|
|
138
|
+
- **`motion-press`** — A small tactile settle (scale 0.97) while the element is pressed. Skips disabled elements. Declares only the pressed state, not a transition. *Use for:* A pressable surface that is not a Sable Button (Button already has it): a tile, a card that acts as a button, an icon control.
|
|
139
|
+
- **Instead of** An `active:` scale utility with its own transition, which fights `motion-interactive` for the transition property and keeps animating with motion off.
|
|
140
|
+
- `<button type="button" className="motion-interactive motion-press sable-surface sable-frame sable-frame-r-lg sable-frame-p-4">Open</button>`
|
|
141
|
+
- **`motion-fade`** — Opacity-only enter and exit, keyed to Base UI's `data-starting-style` / `data-ending-style`: fades in at the enter duration, out at the exit duration. *Use for:* Scrims, backdrops and overlays that should appear without moving. The element rests visible; the data attributes supply the from and to.
|
|
142
|
+
- **Instead of** A keyframe fade or a conditional opacity class, which cannot animate the exit of an element Base UI is unmounting.
|
|
143
|
+
- `<div className="motion-fade fixed inset-0 bg-overlay" />`
|
|
144
|
+
- **`motion-pop`** — Enter with a slight scale from the anchor edge (spring easing) and exit faster without overshoot, keyed to `data-starting-style` / `data-ending-style`. Scales from Base UI's `--transform-origin`. *Use for:* Anchored or centred floating surfaces: popovers, menus, selects, tooltips, dialogs, command menus. Sable's own overlays already carry it.
|
|
145
|
+
- **Instead of** A custom zoom keyframe, or a spring on exit, which draws the eye to what the user just dismissed.
|
|
146
|
+
- `<div className="motion-pop sable-surface-popover bg-popover text-popover-foreground rounded-lg shadow-lg">…</div>`
|
|
147
|
+
- **`motion-slide-up`** — Fade plus a 0.5rem rise on enter, reversed faster on exit, keyed to `data-starting-style` / `data-ending-style`. The suffix is the travel direction on enter. *Use for:* A surface arriving from below: a toast at the bottom of the screen, a bottom bar, a banner under its trigger.
|
|
148
|
+
- **Instead of** A translate keyframe with a literal duration, which keeps moving under reduced motion.
|
|
149
|
+
- `<div className="motion-slide-up sable-surface rounded-lg">Saved</div>`
|
|
150
|
+
- **`motion-slide-down`** — Fade plus a 0.5rem drop on enter, reversed faster on exit, keyed to `data-starting-style` / `data-ending-style`. *Use for:* A surface arriving from above: a top toast, a dropdown panel that reads better sliding than scaling.
|
|
151
|
+
- **Instead of** A translate keyframe with a literal duration.
|
|
152
|
+
- `<div className="motion-slide-down sable-surface rounded-lg">Connected</div>`
|
|
153
|
+
- **`motion-slide-left`** — Fade plus a 0.5rem travel leftward on enter (it starts offset to the right), reversed faster on exit. *Use for:* A surface arriving from the right edge: a side panel, a right-anchored toast.
|
|
154
|
+
- **Instead of** A translate keyframe with a literal duration.
|
|
155
|
+
- `<aside className="motion-slide-left sable-surface">…</aside>`
|
|
156
|
+
- **`motion-slide-right`** — Fade plus a 0.5rem travel rightward on enter (it starts offset to the left), reversed faster on exit. *Use for:* A surface arriving from the left edge: a navigation drawer, a left-anchored toast.
|
|
157
|
+
- **Instead of** A translate keyframe with a literal duration.
|
|
158
|
+
- `<nav className="motion-slide-right sable-surface">…</nav>`
|
|
159
|
+
- **`motion-disclosure`** — Height plus fade for a panel that opens and closes: carries the overflow, the transition and the content fade. The component sets the target height and zeroes it on the starting/ending style. *Use for:* A hand-built expanding region. Accordion and Collapsible already use it; reach for them first.
|
|
160
|
+
- **Instead of** Animating max-height to a guessed number, or a show/hide with no transition. Height is the one sanctioned non-compositor property.
|
|
161
|
+
- `<div className="motion-disclosure h-[var(--collapsible-panel-height)]">…</div>`
|
|
162
|
+
- **`motion-icon-swap`** — Cross-fades two glyphs stacked in one cell when a control's icon changes with its state: the outgoing one shrinks and blurs out, the incoming one resolves in. The inactive glyph is the one marked `aria-hidden="true"` (or `data-active="false"`). *Use for:* Play/pause, mute/unmute, outline/fill, copy/check, menu/close: one control whose icon changes. Keep both icons mounted; the correct accessibility markup is also the animation hook.
|
|
163
|
+
- **Instead of** Rendering one icon or the other (it snaps between two frames), or absolutely positioning the second icon, which collapses the wrapper. Under reduced motion the swap is instant and the glyph still changes.
|
|
164
|
+
- `<span className="motion-icon-swap"><Icon name="play" aria-hidden={playing} /><Icon name="pause" aria-hidden={!playing} /></span>`
|
|
165
|
+
- **`motion-spin`** — A continuous rotation for a spinner glyph, scaled by --motion-scale so reduced motion freezes it. *Use for:* A loading glyph that is not the Spinner component (use Spinner first), such as an icon inside a busy button.
|
|
166
|
+
- **Instead of** Tailwind's built-in spin animation, which ignores --motion-scale. sable-lint's `builtin-animate` flags it.
|
|
167
|
+
- `<Icon name="spinner" className="motion-spin" />`
|
|
168
|
+
- **`motion-orbit`** — A slow continuous rotation (24s by default) for ambient line art. `--motion-orbit-duration` sets the speed and `--motion-orbit-direction` the direction; it rotates about the centre of any viewBox. *Use for:* The idle loop of an illustration or schematic after it draws on, usually with `motion-draw` on the same figure.
|
|
169
|
+
- **Instead of** `motion-spin`, which is a loader's speed, or a hand-written keyframe that keeps turning under reduced motion.
|
|
170
|
+
- `<svg className="motion-orbit [--motion-orbit-duration:40s]" viewBox="0 0 200 200">…</svg>`
|
|
171
|
+
- **`motion-pulse`** — A soft looping opacity pulse, scaled by --motion-scale. *Use for:* A live or pending indicator: a recording dot, an unsaved marker, a pending status.
|
|
172
|
+
- **Instead of** Tailwind's built-in pulse animation, which ignores --motion-scale. For a loading placeholder use Skeleton or `motion-shimmer`.
|
|
173
|
+
- `<span className="motion-pulse size-2 rounded-full bg-destructive" />`
|
|
174
|
+
- **`motion-shimmer`** — The skeleton sweep: one band of light that passes across every skeleton on screen in sequence, because the gradient is fixed to the viewport. Rests off-screen, so with motion off a skeleton is a calm block. *Use for:* A hand-built loading placeholder. The Skeleton component already uses it.
|
|
175
|
+
- **Instead of** A pulse on each block, or a per-box gradient, where a short line and a tall card sweep at different speeds.
|
|
176
|
+
- `<div className="motion-shimmer h-4 w-48 rounded-md bg-muted" />`
|
|
177
|
+
- **`motion-text-shimmer`** — The sweep run through the glyphs instead of behind them, for a live status line. The gradient goes muted to foreground and back, so the text stays readable on every frame. *Use for:* Status text while work is happening: "Thinking…", "Searching", "Generating response".
|
|
178
|
+
- **Instead of** `motion-shimmer` on text, which paints a band behind real words and reads as a skeleton. Named `motion-*`, not `text-*`, so tailwind-merge does not drop the colour class beside it.
|
|
179
|
+
- `<span className="motion-text-shimmer text-body-sm">Thinking…</span>`
|
|
180
|
+
- **`motion-dot-bounce`** — A looping vertical bounce for one dot of a typing or waiting indicator. Offset each dot with an animation delay. *Use for:* A three-dot typing indicator in a chat or assistant surface.
|
|
181
|
+
- **Instead of** Tailwind's built-in bounce animation, which ignores --motion-scale.
|
|
182
|
+
- `<span className="motion-dot-bounce size-1.5 rounded-full bg-muted-foreground" />`
|
|
183
|
+
- **`motion-ping`** — A looping ring that expands and fades from a point, scaled by --motion-scale. *Use for:* Drawing attention to a live point: a new-activity dot, a location marker, a beacon behind a status dot.
|
|
184
|
+
- **Instead of** Tailwind's built-in ping animation, which ignores --motion-scale.
|
|
185
|
+
- `<span className="motion-ping absolute inset-0 rounded-full bg-success" />`
|
|
186
|
+
- **`animate-fade-in`** — A one-shot fade in on mount at the base duration, decelerating, with `both` fill so there is no flash before it starts. *Use for:* Content that appears once when a route or panel mounts.
|
|
187
|
+
- **Instead of** A keyframe with a literal duration. For content entering on scroll use Reveal (`motion-reveal`).
|
|
188
|
+
- `<section className="animate-fade-in">…</section>`
|
|
189
|
+
- **`animate-fade-up`** — A one-shot fade plus rise on mount at the slow duration, decelerating, with `both` fill. *Use for:* A page section or list arriving from below on mount.
|
|
190
|
+
- **Instead of** A translate keyframe with a literal duration. For scroll-triggered entrances use Reveal.
|
|
191
|
+
- `<div className="animate-fade-up">…</div>`
|
|
192
|
+
- **`animate-fade-down`** — A one-shot fade plus drop on mount at the slow duration, decelerating, with `both` fill. *Use for:* Content arriving from above on mount, such as a notice under a header.
|
|
193
|
+
- **Instead of** A translate keyframe with a literal duration.
|
|
194
|
+
- `<div className="animate-fade-down">…</div>`
|
|
195
|
+
- **`motion-stream-in`** — Each token of a live stream resolves in from a slight blur once, on mount. Knows nothing of the final length, so there is no stagger. *Use for:* Wrapping each arriving chunk of a streamed response. StreamingText already does it.
|
|
196
|
+
- **Instead of** The reveal recipes, which stage text that is already there, or a typewriter effect.
|
|
197
|
+
- `<span key={chunk.id} className="motion-stream-in">{chunk.text}</span>`
|
|
198
|
+
- **`motion-caret`** — A caret that blinks only when idle and holds steady while `data-streaming="true"`, so the blink returning signals the stream has finished. *Use for:* The cursor at the end of streamed or typed text.
|
|
199
|
+
- **Instead of** A caret that blinks while text is arriving, which sets two competing rhythms.
|
|
200
|
+
- `<span className="motion-caret" data-streaming={streaming} aria-hidden="true">▍</span>`
|
|
201
|
+
- **`motion-reveal`** — Fade plus a 0.75rem rise when `data-reveal` flips from "out" to "in". Out of view it rests hidden and nudged down; with motion off the content stays visible. *Use for:* Through the Reveal and TextReveal components, which set `data-reveal` when the element scrolls into view. Use the class directly only on an element whose `data-reveal` you set yourself.
|
|
202
|
+
- **Instead of** An IntersectionObserver plus hand-written opacity classes.
|
|
203
|
+
- `<Reveal><Card>…</Card></Reveal>`
|
|
204
|
+
- **`motion-draw`** — Draws an SVG path on when an ancestor's `data-reveal` flips to "in". The path needs `pathLength="1"`. `--motion-draw-duration` and `--motion-draw-delay` (both scaled by --motion-scale) set its pace and stagger. *Use for:* Line art and schematics inside a Reveal. Stagger sibling paths with `--motion-draw-delay`.
|
|
205
|
+
- **Instead of** A hand-written dash-offset animation with literal timing, which keeps animating, or keeps its delay, under reduced motion.
|
|
206
|
+
- `<Reveal><svg viewBox="0 0 100 100"><path className="motion-draw" pathLength="1" d="M10 50 L90 50" /></svg></Reveal>`
|
|
207
|
+
|
|
208
|
+
### helper (5)
|
|
135
209
|
|
|
136
210
|
- **`hit-target`** — Grows an element's tap target to 44px with a transparent `::after`, without moving its layout by a pixel. `--hit-target-size` overrides the size. *Use for:* A deliberately small mark — a tag's remove ×, a tiny disclosure, a toast close — that must still meet the WCAG touch floor. Shrink it (`[--hit-target-size:32px]`) where targets sit side by side, or the later one steals the taps.
|
|
137
211
|
- **Instead of** Padding the glyph up (moves it off the row's grid and pushes siblings) or a bigger icon. Never on an `<input>` or other replaced element — pseudo-elements silently do nothing there; wrap it in a label.
|
|
138
212
|
- `<button className="hit-target text-muted-foreground" aria-label="Remove"><Icon name="xmark" /></button>`
|
|
139
|
-
- **`
|
|
213
|
+
- **`reveal-on-hover`** — Hides a row or tile action until its item is hovered or holds focus — on hover-capable devices only. Touch and no-hover devices always show it, and it fades with opacity, so it never leaves the tab order or the accessibility tree. The item is the nearest ancestor with `group` (or `data-reveal-scope`); an open popup keeps its trigger visible. `--reveal-offset` adds a short rise. *Use for:* Secondary per-item actions in a dense list or grid — a tile's play button, a row's overflow menu or visibility toggle — where showing every action at rest would turn the list into a wall of controls. Put `group` on the item (the row, the tile), not on the list, and the class on the action or its wrapper.
|
|
214
|
+
- **Instead of** `opacity-0 group-hover:opacity-100` (hidden forever on a phone), `hidden group-hover:flex` (drops it from the tab order and the accessibility tree), or a hand-written `[@media(hover:hover)]:opacity-0` pair (snaps, and misses focus and open menus). Not for a primary action — that stays visible.
|
|
215
|
+
- `<li className="group flex items-center gap-2"><span className="flex-1">Track</span><Button variant="ghost" size="icon-sm" aria-label="Like Track" className="reveal-on-hover"><Icon name="heart" /></Button></li>`
|
|
216
|
+
- **`stretched-link`** — Makes one link cover its whole item with a transparent `::after`, so a tile or card is clickable everywhere while its other links and buttons stay separate controls. Focus draws the ring on the overlay, rounded by `--stretched-link-radius`. *Use for:* A card, tile or row that IS a link but also holds a second control — a subtitle link to the artist, a play button, a menu. Put it on the primary link (usually the title), `relative` on the item, and `relative z-10` on every other control.
|
|
217
|
+
- **Instead of** Wrapping the item in an `<a>` or `Card render={<a />}` — invalid as soon as it nests another link or button, which browsers re-parent and screen readers read as one long link. Not with `hit-target` on the same element (both own `::after`).
|
|
218
|
+
- `<article className="relative [--stretched-link-radius:var(--radius-lg)]"><a href="/albums/1" className="stretched-link">Low tide</a><a href="/artists/2" className="relative z-10">Juno Avery</a></article>`
|
|
219
|
+
- **`link-underline`** — An underline drawn from the font's own metrics (position and thickness `from-font`) with ink skipping descenders, so it retunes when a theme swaps typeface. Also carries the link's focus-visible outline in `--ring`, so a plain `<a>` meets the focus floor without app CSS. *Use for:* Every plain text link — inline in running text or standalone ("Forgot password?"). Pair with `motion-interactive` for a colour change on hover.
|
|
140
220
|
- **Instead of** `underline underline-offset-4 decoration-2` — tuned to one face and wrong for the next theme's. Animating thickness or offset is not supported; a growing underline is a separate pseudo-element.
|
|
141
221
|
- `<a href="/terms" className="link-underline motion-interactive text-primary">terms</a>`
|
|
142
222
|
- **`checkerboard`** — The transparency checkerboard, painted from `--panel` and a derived darker step so it reads in both modes. `--checkerboard-size` (default 16px) and `--checkerboard-alt` tune it. *Use for:* Behind anything that can be translucent: a colour swatch with alpha, an image or artboard preview, an alpha slider track.
|
|
@@ -30,9 +30,9 @@ designs. Record the reason for the chosen composition.
|
|
|
30
30
|
</AppShell>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
- **Never a global `max-width`.** Width is
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
- **Never a global `max-width`.** Width is chosen per route by what the person
|
|
34
|
+
does there (below). A form region is narrow because a 700px text input is
|
|
35
|
+
harder to use, not more generous.
|
|
36
36
|
- **Measure ≠ width.** Cap prose line length in `ch` (`--measure-prose`)
|
|
37
37
|
independently of the region's layout width.
|
|
38
38
|
- **The 12-column grid lives *inside* a region**, for genuinely multi-column
|
|
@@ -40,6 +40,37 @@ designs. Record the reason for the chosen composition.
|
|
|
40
40
|
- **Chrome is off the grid.** `Sidebar` and rails are fixed-width, outside the
|
|
41
41
|
content grid.
|
|
42
42
|
|
|
43
|
+
## Choosing a width
|
|
44
|
+
|
|
45
|
+
Pick each route's `max` by what the person mainly does on it:
|
|
46
|
+
|
|
47
|
+
| They mainly… | `max` | Why |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| read long text | `prose` on the text, inside `content` | line length sets readability: cap the text, not the page |
|
|
50
|
+
| fill in a form | `form` | narrow fields are faster to scan and fill |
|
|
51
|
+
| scroll one stream | `feed` | one column, one eye path |
|
|
52
|
+
| review one record, or settings | `content` | labels stay close to their values |
|
|
53
|
+
| scan and compare rows, cards or charts | `wide` | room for columns without stretching the gaps between them |
|
|
54
|
+
| work across panes, a board, an editor or a map | omit it (fluid), or `full` | the extra width goes to the parts that use it |
|
|
55
|
+
|
|
56
|
+
- **Go fluid only when a flexible part uses the space**: a table's main column,
|
|
57
|
+
a canvas, a board, a reading pane. If extra width only widens the gaps between
|
|
58
|
+
fixed columns (a date drifting away from its subject), cap it.
|
|
59
|
+
- **In a fluid page, cap text by line length** (`--measure-prose`, or
|
|
60
|
+
`Center max="prose"`), not by page width.
|
|
61
|
+
- **Sibling routes in one nav share a width**, so the header doesn't jump as
|
|
62
|
+
people move between them. A detail view may differ.
|
|
63
|
+
- **`full` is the largest cap, not edge to edge.** It keeps the page inset;
|
|
64
|
+
`bleed` is edge to edge.
|
|
65
|
+
- **A cap is a ceiling.** It applies only once the viewport minus app chrome is
|
|
66
|
+
wider than it: beside a 256px sidebar, `wide` (1280px) starts at about 1536px,
|
|
67
|
+
so at 1440px `wide`, `full` and fluid look the same. Judge widths at 1920px and
|
|
68
|
+
2560px, and record each route's width and reason in the brief.
|
|
69
|
+
- **A product's widths belong in its theme.** A preset may set `page-inset` and
|
|
70
|
+
`region-*` (`form`, `feed`, `content`, `wide`, `full`) in `tokens.shared`
|
|
71
|
+
(a copy in `light` or `dark` wins over it); keep the role names and change
|
|
72
|
+
the values.
|
|
73
|
+
|
|
43
74
|
## Typography: pick the tier by ROLE, not by size
|
|
44
75
|
|
|
45
76
|
| tier | for | not |
|
|
@@ -53,12 +53,22 @@ probably keeping a layout that Sable would have given you.
|
|
|
53
53
|
|
|
54
54
|
## 4. Icons
|
|
55
55
|
|
|
56
|
-
**
|
|
57
|
-
|
|
58
|
-
IconProvider. To add domain-specific names while retaining Reicon:
|
|
56
|
+
**Mount an icon set once at the root.** `<Icon>` has no built-in fallback:
|
|
57
|
+
without an `IconProvider`, icons render nothing (a development build warns once).
|
|
59
58
|
|
|
60
59
|
```tsx
|
|
61
|
-
import { IconProvider
|
|
60
|
+
import { IconProvider } from "@sableui/react"
|
|
61
|
+
import { reiconIconSet } from "@sableui/react/icons/reicon"
|
|
62
|
+
<IconProvider set={reiconIconSet}>{app}</IconProvider>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
To use another icon package, map Sable's semantic names in an app-owned IconSet
|
|
66
|
+
and pass it instead; the app then ships none of Reicon. To add domain-specific
|
|
67
|
+
names while retaining Reicon:
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { IconProvider, composeIconSets } from "@sableui/react"
|
|
71
|
+
import { reiconIconSet } from "@sableui/react/icons/reicon"
|
|
62
72
|
<IconProvider set={composeIconSets(appExtras, reiconIconSet)} />
|
|
63
73
|
```
|
|
64
74
|
|
|
@@ -13,7 +13,10 @@ cannot establish animation timing, hidden behavior, or an unseen responsive stat
|
|
|
13
13
|
Choose an original direction suitable for the user's future product. Map that
|
|
14
14
|
direction onto the installed Sable token vocabulary. Preserve readable semantic
|
|
15
15
|
roles and supported control behavior rather than recoloring every primitive
|
|
16
|
-
independently. Load fonts through the consuming project's font setup.
|
|
16
|
+
independently. Load fonts through the consuming project's font setup. Page widths
|
|
17
|
+
are optional: set `page-inset` and the `region-*` caps (`form`, `feed`, `content`,
|
|
18
|
+
`wide`, `full`) in `tokens.shared` only when the direction calls for a different
|
|
19
|
+
page proportion, and keep each cap's role.
|
|
17
20
|
|
|
18
21
|
```bash
|
|
19
22
|
pnpm exec sable preset --template
|
|
@@ -10,6 +10,10 @@ Save the surface brief, then capture the rendered route at a desktop width of at
|
|
|
10
10
|
least 1024px and a mobile width of at most 480px. Record the actual viewport,
|
|
11
11
|
route/state, supported color mode, and motion setting with each artifact. Inspect
|
|
12
12
|
the whole route as well as its first viewport. Ensure fonts and media have loaded.
|
|
13
|
+
Also capture a route that sets a width cap, or goes fluid, at 1920px: a cap applies
|
|
14
|
+
only once the viewport minus app chrome exceeds it, so at 1024–1440px `wide`,
|
|
15
|
+
`full` and fluid usually look the same and the width decision never shows. Add
|
|
16
|
+
2560px for a fluid route.
|
|
13
17
|
Use a recording or an observed interaction report for behavior that a still cannot
|
|
14
18
|
show. Include reduced motion and every color mode the surface promises to support.
|
|
15
19
|
|
|
@@ -47,6 +51,21 @@ those values into artifact records only after inspecting the corresponding files
|
|
|
47
51
|
replacing a capture at the same path then makes the review incomplete. Neither
|
|
48
52
|
the source fingerprint nor an artifact hash proves someone inspected the screen.
|
|
49
53
|
|
|
54
|
+
The template starts with one example screenshot and one example report artifact.
|
|
55
|
+
Replace them with your own captures; as shipped they point at no file and fail
|
|
56
|
+
validation. Each artifact record has these fields:
|
|
57
|
+
|
|
58
|
+
| Field | Meaning |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `id` | A unique name that dimensions, checks and iterations cite in `evidence`. |
|
|
61
|
+
| `kind` | `screenshot`, `recording`, or `report` (a written observation, such as a keyboard walkthrough). |
|
|
62
|
+
| `path` | The capture file, relative to the review JSON. It must exist and be non-empty. |
|
|
63
|
+
| `sha256` | The file's hash, copied from `review.artifactHashes` after you inspect the file. |
|
|
64
|
+
| `state` | The route and state captured, such as "checkout, payment error". |
|
|
65
|
+
| `viewport` | `{ width, height }` in pixels. Screenshots and recordings only. You need one at 1024 wide or more and one at 480 wide or less. |
|
|
66
|
+
| `colorMode` | `light` or `dark`. Screenshots and recordings only. |
|
|
67
|
+
| `motion` | `full` or `reduced`. Screenshots and recordings only. At least one artifact must be captured with reduced motion. |
|
|
68
|
+
|
|
50
69
|
## Review these eight dimensions
|
|
51
70
|
|
|
52
71
|
| Dimension id | Look for concrete evidence |
|
|
@@ -76,6 +76,25 @@ Use a unique preset ID so it cannot override a bundled theme or another record.
|
|
|
76
76
|
Record any intentional adaptation and run the validation and rendered review in
|
|
77
77
|
[building-with-sable.md](./building-with-sable.md).
|
|
78
78
|
|
|
79
|
+
## Apply to an existing app
|
|
80
|
+
|
|
81
|
+
A preset pasted into an agent for a running app (Canvas's “Copy for agent”) is a
|
|
82
|
+
restyle: the job ends with the app built and rendered in the preset, not with a
|
|
83
|
+
saved file. Replace, don't add beside:
|
|
84
|
+
|
|
85
|
+
1. Save it to `.sable/presets/<id>.json`, overwriting an earlier revision of the
|
|
86
|
+
same ID, and run `sable preset --check`.
|
|
87
|
+
2. Regenerate its CSS with `sable preset --css` and import it after Sable's
|
|
88
|
+
stylesheet. Remove the stylesheet of a theme it replaces when nothing else uses it.
|
|
89
|
+
3. Load the families its `fonts` stacks name through the app's existing font
|
|
90
|
+
setup, and drop the old theme's font loading when no other code uses it.
|
|
91
|
+
An unloaded family falls back to a system face without any error.
|
|
92
|
+
4. Point SableThemeProvider's `defaultThemeId` at the preset ID and
|
|
93
|
+
`defaultPreference` at its `defaultMode`, unless the user asked for another
|
|
94
|
+
mode. A bundled theme left as the default keeps the app on the old look.
|
|
95
|
+
5. Run the app's build and type check, then `sable check`, and review the result
|
|
96
|
+
in both modes.
|
|
97
|
+
|
|
79
98
|
## Upgrade the package and skill
|
|
80
99
|
|
|
81
100
|
```bash
|