@0001-labs/design-system-1 0.3.0-alpha.13 → 0.3.0-alpha.14
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/DS1/0-face/calendar.ts +194 -0
- package/DS1/0-face/carousel.ts +623 -0
- package/DS1/0-face/component-visibility.ts +13 -0
- package/DS1/0-face/copy-text.ts +96 -0
- package/DS1/0-face/device.ts +8 -58
- package/DS1/0-face/dialog-swipe.ts +249 -0
- package/DS1/0-face/dialogs.ts +208 -0
- package/DS1/0-face/drawer.ts +258 -0
- package/DS1/0-face/feedback-words.ts +36 -0
- package/DS1/0-face/feedback.ts +40 -0
- package/DS1/0-face/format.ts +700 -0
- package/DS1/0-face/generated/toast-assets.ts +18 -0
- package/DS1/0-face/grid-fit.ts +1 -1
- package/DS1/0-face/grid.ts +3 -2
- package/DS1/0-face/header.ts +78 -0
- package/DS1/0-face/i18n.ts +93 -18
- package/DS1/0-face/keys.ts +276 -0
- package/DS1/0-face/languages.ts +4 -4
- package/DS1/0-face/layout-inspector.ts +6 -6
- package/DS1/0-face/library-styles.ts +33 -0
- package/DS1/0-face/load-toaster.ts +7 -0
- package/DS1/0-face/preference-options.ts +29 -0
- package/DS1/0-face/preferences.ts +3 -11
- package/DS1/0-face/pricing.ts +98 -43
- package/DS1/0-face/scaling.ts +160 -4
- package/DS1/0-face/shared-words.ts +9 -4
- package/DS1/0-face/sidebar.ts +201 -0
- package/DS1/0-face/theme-bootstrap.js +184 -0
- package/DS1/0-face/theme.ts +89 -47
- package/DS1/0-face/toast-queue.ts +157 -0
- package/DS1/0-face/toaster.ts +384 -0
- package/DS1/0-face/tooltips.ts +157 -15
- package/DS1/0-face/translations/da.json +60 -1
- package/DS1/0-face/translations/de.json +60 -1
- package/DS1/0-face/translations/en.json +60 -1
- package/DS1/0-face/translations/es.json +60 -1
- package/DS1/0-face/translations/fi.json +60 -1
- package/DS1/0-face/translations/fr.json +60 -1
- package/DS1/0-face/translations/is.json +60 -1
- package/DS1/0-face/translations/it.json +60 -1
- package/DS1/0-face/translations/ja.json +60 -1
- package/DS1/0-face/translations/ko.json +60 -1
- package/DS1/0-face/translations/nb.json +60 -1
- package/DS1/0-face/translations/pt-BR.json +60 -1
- package/DS1/0-face/translations/pt.json +60 -1
- package/DS1/0-face/translations/sv.json +60 -1
- package/DS1/0-face/translations/zh.json +60 -1
- package/DS1/0-face/translations-format.ts +3 -4
- package/DS1/1-root/card.css +192 -0
- package/DS1/1-root/carousel.css +136 -0
- package/DS1/1-root/cjk.css +23 -0
- package/DS1/1-root/component-metrics.css +1 -0
- package/DS1/1-root/component-tokens.css +51 -8
- package/DS1/1-root/controls.css +887 -14
- package/DS1/1-root/dialog-placement.css +191 -0
- package/DS1/1-root/document.css +183 -0
- package/DS1/1-root/drawer.css +83 -0
- package/DS1/1-root/empty.css +83 -0
- package/DS1/1-root/figures.css +141 -0
- package/DS1/1-root/fonts/Iosevka-LICENSE.md +3 -1
- package/DS1/1-root/fonts/Iosevka-Regular.woff2 +0 -0
- package/DS1/1-root/fonts.css +69 -0
- package/DS1/1-root/footer.css +186 -0
- package/DS1/1-root/header.css +165 -0
- package/DS1/1-root/kbd.css +46 -0
- package/DS1/1-root/library-tokens.ts +91 -0
- package/DS1/1-root/measures.ts +53 -0
- package/DS1/1-root/notice.css +165 -0
- package/DS1/1-root/one.css +14 -84
- package/DS1/1-root/one.semantic.css +200 -148
- package/DS1/1-root/palette.css +58 -0
- package/DS1/1-root/palette.ts +19 -0
- package/DS1/1-root/progress.css +356 -0
- package/DS1/1-root/prose.css +202 -0
- package/DS1/1-root/row.css +297 -0
- package/DS1/1-root/table.css +111 -0
- package/DS1/1-root/text.css +70 -0
- package/DS1/2-core/button-split.ts +55 -0
- package/DS1/2-core/chart/chart.css +169 -0
- package/DS1/2-core/chart/grid-chart.ts +554 -0
- package/DS1/2-core/ds-avatar.ts +25 -6
- package/DS1/2-core/ds-badge.ts +10 -10
- package/DS1/2-core/ds-button.ts +111 -26
- package/DS1/2-core/ds-card.ts +135 -105
- package/DS1/2-core/ds-chart.ts +327 -0
- package/DS1/2-core/ds-composer.ts +8 -2
- package/DS1/2-core/ds-cycle.ts +97 -21
- package/DS1/2-core/ds-empty.ts +120 -0
- package/DS1/2-core/ds-icon.ts +11 -2
- package/DS1/2-core/ds-input.ts +165 -6
- package/DS1/2-core/ds-kbd.ts +78 -0
- package/DS1/2-core/ds-loading.ts +72 -0
- package/DS1/2-core/ds-notice.ts +180 -0
- package/DS1/2-core/ds-progress.ts +380 -0
- package/DS1/2-core/ds-spacing-handle.ts +22 -0
- package/DS1/2-core/ds-stat.ts +174 -0
- package/DS1/2-core/ds-switch.ts +1 -0
- package/DS1/2-core/ds-text.ts +15 -2
- package/DS1/2-core/ds-toast.ts +354 -0
- package/DS1/2-core/figures.ts +105 -0
- package/DS1/2-core/generated/ds-icon-map.ts +234 -128
- package/DS1/2-core/generated/icon-avatar.ts +2 -0
- package/DS1/2-core/generated/icons-extra.ts +118 -65
- package/DS1/2-core/generated/icons-immediate.ts +1 -1
- package/DS1/2-core/spacing-handle.ts +95 -0
- package/DS1/2-core/styles/ds-avatar.css +9 -8
- package/DS1/2-core/styles/ds-button-host.css +26 -3
- package/DS1/2-core/styles/ds-button-split.css +67 -0
- package/DS1/2-core/styles/ds-button.css +49 -15
- package/DS1/2-core/styles/ds-card.css +34 -0
- package/DS1/2-core/styles/ds-composer.css +13 -0
- package/DS1/2-core/styles/ds-cycle.css +69 -0
- package/DS1/2-core/styles/ds-empty.css +18 -0
- package/DS1/2-core/styles/ds-gap.css +1 -0
- package/DS1/2-core/styles/ds-icon.css +1 -0
- package/DS1/2-core/styles/ds-input.css +59 -6
- package/DS1/2-core/styles/ds-kbd.css +12 -0
- package/DS1/2-core/styles/ds-loading.css +13 -0
- package/DS1/2-core/styles/ds-notice.css +30 -0
- package/DS1/2-core/styles/ds-progress.css +25 -0
- package/DS1/2-core/styles/ds-select.css +2 -2
- package/DS1/2-core/styles/ds-spacing-handle.css +8 -0
- package/DS1/2-core/styles/ds-split.css +2 -62
- package/DS1/2-core/styles/ds-stat.css +34 -0
- package/DS1/2-core/styles/ds-switch.css +16 -1
- package/DS1/2-core/styles/ds-text.css +43 -12
- package/DS1/2-core/styles/ds-toast.css +182 -0
- package/DS1/2-core/styles/ds-tooltip.css +1 -0
- package/DS1/3-unit/calendar-base.ts +263 -0
- package/DS1/3-unit/ds-accordion.ts +9 -1
- package/DS1/3-unit/ds-avatar-group.ts +1 -0
- package/DS1/3-unit/ds-calendar-large.ts +349 -0
- package/DS1/3-unit/ds-calendar.ts +344 -0
- package/DS1/3-unit/ds-carousel.ts +368 -0
- package/DS1/3-unit/ds-date-picker.ts +540 -0
- package/DS1/3-unit/ds-form.ts +45 -37
- package/DS1/3-unit/ds-list.ts +48 -1
- package/DS1/3-unit/ds-matrix.ts +318 -0
- package/DS1/3-unit/ds-menu.ts +8 -4
- package/DS1/3-unit/ds-row.ts +84 -1
- package/DS1/3-unit/ds-sidebar.ts +280 -0
- package/DS1/3-unit/ds-table.ts +75 -34
- package/DS1/3-unit/styles/ds-accordion.css +1 -0
- package/DS1/3-unit/styles/ds-avatar-group.css +2 -4
- package/DS1/3-unit/styles/ds-calendar-large.css +165 -0
- package/DS1/3-unit/styles/ds-calendar.css +238 -0
- package/DS1/3-unit/styles/ds-carousel.css +30 -0
- package/DS1/3-unit/styles/ds-date-picker.css +124 -0
- package/DS1/3-unit/styles/ds-list.css +1 -0
- package/DS1/3-unit/styles/ds-matrix.css +203 -0
- package/DS1/3-unit/styles/ds-menu.css +31 -6
- package/DS1/3-unit/styles/ds-row.css +84 -2
- package/DS1/3-unit/styles/ds-sidebar.css +117 -0
- package/DS1/3-unit/styles/ds-table.css +3 -74
- package/DS1/4-page/ds-dialog.ts +40 -4
- package/DS1/4-page/ds-document.ts +240 -0
- package/DS1/4-page/ds-footer.ts +165 -0
- package/DS1/4-page/ds-grid.ts +39 -59
- package/DS1/4-page/ds-header.ts +171 -0
- package/DS1/4-page/ds-page.ts +184 -0
- package/DS1/4-page/email.ts +2 -3
- package/DS1/4-page/styles/ds-container.css +1 -0
- package/DS1/4-page/styles/ds-document.css +18 -0
- package/DS1/4-page/styles/ds-footer.css +29 -0
- package/DS1/4-page/styles/ds-grid.css +31 -85
- package/DS1/4-page/styles/ds-header.css +57 -0
- package/DS1/4-page/styles/ds-page.css +214 -0
- package/DS1/components.ts +7 -1
- package/DS1/index.ts +26 -6
- package/DS1/react/avatar.ts +4 -5
- package/DS1/react/button-split.ts +29 -0
- package/DS1/react/button.ts +32 -13
- package/DS1/react/carousel.ts +76 -0
- package/DS1/react/dialog.ts +36 -5
- package/DS1/react/document.ts +14 -0
- package/DS1/react/empty.ts +32 -0
- package/DS1/react/footer.ts +17 -0
- package/DS1/react/header.ts +15 -0
- package/DS1/react/input.ts +28 -17
- package/DS1/react/kbd.ts +21 -0
- package/DS1/react/loading.ts +18 -0
- package/DS1/react/notice.ts +59 -0
- package/DS1/react/page.ts +13 -0
- package/DS1/react/progress.ts +99 -0
- package/DS1/react/sidebar.ts +60 -0
- package/DS1/react/spacing-handle.ts +21 -0
- package/DS1/react/stat.ts +73 -0
- package/DS1/react/toast.ts +82 -0
- package/DS1/x-icon/Tabler-LICENSE.md +27 -0
- package/DS1/x-icon/airtable.svg +5 -0
- package/DS1/x-icon/attach.svg +3 -0
- package/DS1/x-icon/audio.svg +3 -0
- package/DS1/x-icon/bag-alt.svg +3 -0
- package/DS1/x-icon/bank.svg +3 -0
- package/DS1/x-icon/banknote.svg +3 -0
- package/DS1/x-icon/bolt.svg +3 -0
- package/DS1/x-icon/book-alt.svg +3 -0
- package/DS1/x-icon/book.svg +4 -0
- package/DS1/x-icon/box.svg +3 -0
- package/DS1/x-icon/briefcase.svg +3 -0
- package/DS1/x-icon/building.svg +4 -0
- package/DS1/x-icon/car.svg +3 -0
- package/DS1/x-icon/card.svg +3 -0
- package/DS1/x-icon/cart.svg +3 -0
- package/DS1/x-icon/{ezo-item-button-start.svg → chevron-left.svg} +1 -1
- package/DS1/x-icon/{ezo-android-screen-stats.svg → chevron-right.svg} +1 -1
- package/DS1/x-icon/cloud.svg +3 -0
- package/DS1/x-icon/coffee.svg +3 -0
- package/DS1/x-icon/coins.svg +3 -0
- package/DS1/x-icon/cursor.svg +3 -0
- package/DS1/x-icon/curve.svg +7 -0
- package/DS1/x-icon/dislike.svg +4 -0
- package/DS1/x-icon/dot-bank.svg +3 -0
- package/DS1/x-icon/dot-banknote.svg +3 -0
- package/DS1/x-icon/dot-banknotes.svg +3 -0
- package/DS1/x-icon/dot-card.svg +3 -0
- package/DS1/x-icon/dot-coin.svg +3 -0
- package/DS1/x-icon/dot-coins.svg +3 -0
- package/DS1/x-icon/dot-receipt.svg +3 -0
- package/DS1/x-icon/dot-safe.svg +3 -0
- package/DS1/x-icon/dot-transfer.svg +3 -0
- package/DS1/x-icon/dot-wallet.svg +3 -0
- package/DS1/x-icon/download.svg +4 -0
- package/DS1/x-icon/drive.svg +5 -0
- package/DS1/x-icon/drop.svg +3 -0
- package/DS1/x-icon/dropbox.svg +3 -0
- package/DS1/x-icon/dumbbell.svg +3 -0
- package/DS1/x-icon/eye-off.svg +3 -0
- package/DS1/x-icon/eye.svg +3 -0
- package/DS1/x-icon/facebook.svg +3 -0
- package/DS1/x-icon/figma.svg +5 -0
- package/DS1/x-icon/flame.svg +3 -0
- package/DS1/x-icon/flip.svg +5 -0
- package/DS1/x-icon/food.svg +3 -0
- package/DS1/x-icon/fuel.svg +3 -0
- package/DS1/x-icon/game.svg +3 -0
- package/DS1/x-icon/gift.svg +3 -0
- package/DS1/x-icon/github.svg +3 -0
- package/DS1/x-icon/heart.svg +3 -0
- package/DS1/x-icon/history.svg +3 -0
- package/DS1/x-icon/home-alt.svg +3 -0
- package/DS1/x-icon/income.svg +3 -0
- package/DS1/x-icon/info.svg +5 -0
- package/DS1/x-icon/instagram.svg +5 -0
- package/DS1/x-icon/jpbank.svg +3 -0
- package/DS1/x-icon/key.svg +4 -0
- package/DS1/x-icon/keyboard.svg +3 -0
- package/DS1/x-icon/like.svg +4 -0
- package/DS1/x-icon/linkedin.svg +7 -0
- package/DS1/x-icon/loom.svg +6 -0
- package/DS1/x-icon/map.svg +4 -0
- package/DS1/x-icon/medical.svg +3 -0
- package/DS1/x-icon/{ezo-android-screen-lists.svg → minus.svg} +1 -1
- package/DS1/x-icon/moon.svg +3 -0
- package/DS1/x-icon/move.svg +3 -0
- package/DS1/x-icon/music-alt.svg +3 -0
- package/DS1/x-icon/music.svg +5 -0
- package/DS1/x-icon/notion.svg +6 -0
- package/DS1/x-icon/offline.svg +3 -0
- package/DS1/x-icon/pause.svg +4 -0
- package/DS1/x-icon/paw.svg +3 -0
- package/DS1/x-icon/pdf.svg +3 -0
- package/DS1/x-icon/people.svg +5 -0
- package/DS1/x-icon/percent.svg +3 -0
- package/DS1/x-icon/phone.svg +3 -0
- package/DS1/x-icon/pill.svg +3 -0
- package/DS1/x-icon/plane.svg +3 -0
- package/DS1/x-icon/postal.svg +3 -0
- package/DS1/x-icon/present.svg +4 -0
- package/DS1/x-icon/reaction.svg +5 -0
- package/DS1/x-icon/receipt.svg +3 -0
- package/DS1/x-icon/refresh.svg +3 -0
- package/DS1/x-icon/refund.svg +3 -0
- package/DS1/x-icon/repeat.svg +3 -0
- package/DS1/x-icon/rotate.svg +4 -0
- package/DS1/x-icon/safe.svg +3 -0
- package/DS1/x-icon/school-alt.svg +3 -0
- package/DS1/x-icon/shield-alt.svg +3 -0
- package/DS1/x-icon/shield.svg +4 -0
- package/DS1/x-icon/shirt.svg +3 -0
- package/DS1/x-icon/shop.svg +3 -0
- package/DS1/x-icon/sign-in.svg +3 -0
- package/DS1/x-icon/sign-out.svg +3 -0
- package/DS1/x-icon/slack.svg +6 -0
- package/DS1/x-icon/sparkle.svg +3 -0
- package/DS1/x-icon/start.svg +4 -0
- package/DS1/x-icon/{ezo-item-button-reopen.svg → stop.svg} +1 -1
- package/DS1/x-icon/sun.svg +3 -0
- package/DS1/x-icon/system.svg +4 -0
- package/DS1/x-icon/tag.svg +3 -0
- package/DS1/x-icon/ticket.svg +3 -0
- package/DS1/x-icon/title-struck.svg +4 -0
- package/DS1/x-icon/train.svg +3 -0
- package/DS1/x-icon/transfer.svg +3 -0
- package/DS1/x-icon/tv.svg +3 -0
- package/DS1/x-icon/upload.svg +4 -0
- package/DS1/x-icon/video.svg +4 -0
- package/DS1/x-icon/vimeo.svg +3 -0
- package/DS1/x-icon/wallet.svg +3 -0
- package/DS1/x-icon/wifi.svg +3 -0
- package/DS1/x-icon/window.svg +4 -0
- package/DS1/x-icon/wrench.svg +3 -0
- package/DS1/x-icon/x-brand.svg +4 -0
- package/DS1/x-icon/youtube.svg +4 -0
- package/README.md +3 -3
- package/dist/0-face/calendar.d.ts +75 -0
- package/dist/0-face/calendar.d.ts.map +1 -0
- package/dist/0-face/calendar.js +149 -0
- package/dist/0-face/carousel.d.ts +174 -0
- package/dist/0-face/carousel.d.ts.map +1 -0
- package/dist/0-face/carousel.js +583 -0
- package/dist/0-face/component-visibility.d.ts +7 -0
- package/dist/0-face/component-visibility.d.ts.map +1 -0
- package/dist/0-face/component-visibility.js +10 -0
- package/dist/0-face/copy-text.d.ts +11 -0
- package/dist/0-face/copy-text.d.ts.map +1 -0
- package/dist/0-face/copy-text.js +97 -0
- package/dist/0-face/device.d.ts +3 -7
- package/dist/0-face/device.d.ts.map +1 -1
- package/dist/0-face/device.js +7 -41
- package/dist/0-face/dialog-swipe.d.ts +49 -0
- package/dist/0-face/dialog-swipe.d.ts.map +1 -0
- package/dist/0-face/dialog-swipe.js +239 -0
- package/dist/0-face/dialogs.d.ts +33 -0
- package/dist/0-face/dialogs.d.ts.map +1 -0
- package/dist/0-face/dialogs.js +173 -0
- package/dist/0-face/drawer.d.ts +64 -0
- package/dist/0-face/drawer.d.ts.map +1 -0
- package/dist/0-face/drawer.js +256 -0
- package/dist/0-face/feedback-words.d.ts +21 -0
- package/dist/0-face/feedback-words.d.ts.map +1 -0
- package/dist/0-face/feedback-words.js +30 -0
- package/dist/0-face/feedback.d.ts +41 -0
- package/dist/0-face/feedback.d.ts.map +1 -0
- package/dist/0-face/feedback.js +35 -0
- package/dist/0-face/format.d.ts +166 -0
- package/dist/0-face/format.d.ts.map +1 -0
- package/dist/0-face/format.js +445 -0
- package/dist/0-face/generated/toast-assets.d.ts +11 -0
- package/dist/0-face/generated/toast-assets.d.ts.map +1 -0
- package/dist/0-face/generated/toast-assets.js +14 -0
- package/dist/0-face/grid-fit.js +1 -1
- package/dist/0-face/grid.d.ts.map +1 -1
- package/dist/0-face/grid.js +2 -1
- package/dist/0-face/header.d.ts +38 -0
- package/dist/0-face/header.d.ts.map +1 -0
- package/dist/0-face/header.js +80 -0
- package/dist/0-face/i18n.d.ts +32 -2
- package/dist/0-face/i18n.d.ts.map +1 -1
- package/dist/0-face/i18n.js +65 -19
- package/dist/0-face/keys.d.ts +104 -0
- package/dist/0-face/keys.d.ts.map +1 -0
- package/dist/0-face/keys.js +253 -0
- package/dist/0-face/languages.d.ts +2 -2
- package/dist/0-face/languages.js +3 -3
- package/dist/0-face/layout-inspector.js +6 -6
- package/dist/0-face/library-styles.d.ts +7 -0
- package/dist/0-face/library-styles.d.ts.map +1 -0
- package/dist/0-face/library-styles.js +29 -0
- package/dist/0-face/load-toaster.d.ts +8 -0
- package/dist/0-face/load-toaster.d.ts.map +1 -0
- package/dist/0-face/load-toaster.js +7 -0
- package/dist/0-face/preference-options.d.ts +34 -0
- package/dist/0-face/preference-options.d.ts.map +1 -0
- package/dist/0-face/preference-options.js +1 -0
- package/dist/0-face/preferences.d.ts +3 -12
- package/dist/0-face/preferences.d.ts.map +1 -1
- package/dist/0-face/pricing.d.ts +19 -9
- package/dist/0-face/pricing.d.ts.map +1 -1
- package/dist/0-face/pricing.js +81 -40
- package/dist/0-face/scaling.d.ts +71 -1
- package/dist/0-face/scaling.d.ts.map +1 -1
- package/dist/0-face/scaling.js +108 -3
- package/dist/0-face/shared-words.d.ts +9 -4
- package/dist/0-face/shared-words.d.ts.map +1 -1
- package/dist/0-face/sidebar.d.ts +69 -0
- package/dist/0-face/sidebar.d.ts.map +1 -0
- package/dist/0-face/sidebar.js +191 -0
- package/dist/0-face/theme-bootstrap.d.ts +1 -0
- package/dist/0-face/theme-bootstrap.d.ts.map +1 -0
- package/dist/0-face/theme-bootstrap.js +214 -0
- package/dist/0-face/theme.d.ts +32 -0
- package/dist/0-face/theme.d.ts.map +1 -1
- package/dist/0-face/theme.js +69 -43
- package/dist/0-face/toast-queue.d.ts +110 -0
- package/dist/0-face/toast-queue.d.ts.map +1 -0
- package/dist/0-face/toast-queue.js +98 -0
- package/dist/0-face/toaster.d.ts +27 -0
- package/dist/0-face/toaster.d.ts.map +1 -0
- package/dist/0-face/toaster.js +373 -0
- package/dist/0-face/tooltips.d.ts +24 -1
- package/dist/0-face/tooltips.d.ts.map +1 -1
- package/dist/0-face/tooltips.js +155 -16
- package/dist/0-face/translations/da.json +60 -1
- package/dist/0-face/translations/de.json +60 -1
- package/dist/0-face/translations/en.json +60 -1
- package/dist/0-face/translations/es.json +60 -1
- package/dist/0-face/translations/fi.json +60 -1
- package/dist/0-face/translations/fr.json +60 -1
- package/dist/0-face/translations/is.json +60 -1
- package/dist/0-face/translations/it.json +60 -1
- package/dist/0-face/translations/ja.json +60 -1
- package/dist/0-face/translations/ko.json +60 -1
- package/dist/0-face/translations/nb.json +60 -1
- package/dist/0-face/translations/pt-BR.json +60 -1
- package/dist/0-face/translations/pt.json +60 -1
- package/dist/0-face/translations/sv.json +60 -1
- package/dist/0-face/translations/zh.json +60 -1
- package/dist/0-face/translations-format.d.ts.map +1 -1
- package/dist/0-face/translations-format.js +3 -4
- package/dist/0-face/tree.d.ts +69 -0
- package/dist/0-face/tree.d.ts.map +1 -0
- package/dist/0-face/tree.js +191 -0
- package/dist/1-root/library-tokens.d.ts +31 -0
- package/dist/1-root/library-tokens.d.ts.map +1 -0
- package/dist/1-root/library-tokens.js +84 -0
- package/dist/1-root/measures.d.ts +52 -0
- package/dist/1-root/measures.d.ts.map +1 -0
- package/dist/1-root/measures.js +49 -0
- package/dist/1-root/palette.d.ts +5 -0
- package/dist/1-root/palette.d.ts.map +1 -1
- package/dist/1-root/palette.js +18 -0
- package/dist/2-core/button-split.d.ts +21 -0
- package/dist/2-core/button-split.d.ts.map +1 -0
- package/dist/2-core/button-split.js +48 -0
- package/dist/2-core/chart/grid-chart.d.ts +113 -0
- package/dist/2-core/chart/grid-chart.d.ts.map +1 -0
- package/dist/2-core/chart/grid-chart.js +466 -0
- package/dist/2-core/ds-avatar.d.ts +20 -3
- package/dist/2-core/ds-avatar.d.ts.map +1 -1
- package/dist/2-core/ds-avatar.js +19 -5
- package/dist/2-core/ds-badge.js +10 -13
- package/dist/2-core/ds-banner.d.ts +23 -7
- package/dist/2-core/ds-banner.d.ts.map +1 -1
- package/dist/2-core/ds-banner.js +48 -12
- package/dist/2-core/ds-button.d.ts +76 -0
- package/dist/2-core/ds-button.d.ts.map +1 -1
- package/dist/2-core/ds-button.js +101 -26
- package/dist/2-core/ds-card.d.ts +76 -11
- package/dist/2-core/ds-card.d.ts.map +1 -1
- package/dist/2-core/ds-card.js +129 -105
- package/dist/2-core/ds-chart.d.ts +105 -0
- package/dist/2-core/ds-chart.d.ts.map +1 -0
- package/dist/2-core/ds-chart.js +390 -0
- package/dist/2-core/ds-composer.d.ts +7 -0
- package/dist/2-core/ds-composer.d.ts.map +1 -1
- package/dist/2-core/ds-composer.js +1 -1
- package/dist/2-core/ds-cycle.d.ts +36 -2
- package/dist/2-core/ds-cycle.d.ts.map +1 -1
- package/dist/2-core/ds-cycle.js +95 -18
- package/dist/2-core/ds-empty.d.ts +74 -0
- package/dist/2-core/ds-empty.d.ts.map +1 -0
- package/dist/2-core/ds-empty.js +96 -0
- package/dist/2-core/ds-icon.d.ts +6 -0
- package/dist/2-core/ds-icon.d.ts.map +1 -1
- package/dist/2-core/ds-icon.js +12 -2
- package/dist/2-core/ds-input.d.ts +39 -1
- package/dist/2-core/ds-input.d.ts.map +1 -1
- package/dist/2-core/ds-input.js +150 -6
- package/dist/2-core/ds-kbd.d.ts +48 -0
- package/dist/2-core/ds-kbd.d.ts.map +1 -0
- package/dist/2-core/ds-kbd.js +65 -0
- package/dist/2-core/ds-language.d.ts +8 -1
- package/dist/2-core/ds-language.d.ts.map +1 -1
- package/dist/2-core/ds-language.js +2 -2
- package/dist/2-core/ds-loading.d.ts +40 -0
- package/dist/2-core/ds-loading.d.ts.map +1 -0
- package/dist/2-core/ds-loading.js +63 -0
- package/dist/2-core/ds-meter.d.ts +103 -0
- package/dist/2-core/ds-meter.d.ts.map +1 -0
- package/dist/2-core/ds-meter.js +124 -0
- package/dist/2-core/ds-notice.d.ts +103 -0
- package/dist/2-core/ds-notice.d.ts.map +1 -0
- package/dist/2-core/ds-notice.js +152 -0
- package/dist/2-core/ds-pagedots.d.ts +64 -7
- package/dist/2-core/ds-pagedots.d.ts.map +1 -1
- package/dist/2-core/ds-pagedots.js +124 -18
- package/dist/2-core/ds-progress.d.ts +200 -0
- package/dist/2-core/ds-progress.d.ts.map +1 -0
- package/dist/2-core/ds-progress.js +319 -0
- package/dist/2-core/ds-spacing-handle.d.ts +25 -0
- package/dist/2-core/ds-spacing-handle.d.ts.map +1 -0
- package/dist/2-core/ds-spacing-handle.js +25 -0
- package/dist/2-core/ds-split.d.ts +4 -67
- package/dist/2-core/ds-split.d.ts.map +1 -1
- package/dist/2-core/ds-split.js +4 -98
- package/dist/2-core/ds-stat.d.ts +126 -0
- package/dist/2-core/ds-stat.d.ts.map +1 -0
- package/dist/2-core/ds-stat.js +137 -0
- package/dist/2-core/ds-steps.d.ts +72 -0
- package/dist/2-core/ds-steps.d.ts.map +1 -0
- package/dist/2-core/ds-steps.js +114 -0
- package/dist/2-core/ds-switch.d.ts +1 -0
- package/dist/2-core/ds-switch.d.ts.map +1 -1
- package/dist/2-core/ds-switch.js +1 -0
- package/dist/2-core/ds-text.d.ts +15 -2
- package/dist/2-core/ds-text.d.ts.map +1 -1
- package/dist/2-core/ds-text.js +13 -0
- package/dist/2-core/ds-textarea.d.ts.map +1 -1
- package/dist/2-core/ds-textarea.js +1 -0
- package/dist/2-core/ds-toast.d.ts +139 -0
- package/dist/2-core/ds-toast.d.ts.map +1 -0
- package/dist/2-core/ds-toast.js +329 -0
- package/dist/2-core/ds-toggle.d.ts +11 -0
- package/dist/2-core/ds-toggle.d.ts.map +1 -0
- package/dist/2-core/ds-toggle.js +10 -0
- package/dist/2-core/figures.d.ts +56 -0
- package/dist/2-core/figures.d.ts.map +1 -0
- package/dist/2-core/figures.js +70 -0
- package/dist/2-core/generated/ds-icon-map.d.ts +118 -65
- package/dist/2-core/generated/ds-icon-map.d.ts.map +1 -1
- package/dist/2-core/generated/ds-icon-map.js +234 -128
- package/dist/2-core/generated/icon-avatar.d.ts +2 -0
- package/dist/2-core/generated/icon-avatar.d.ts.map +1 -0
- package/dist/2-core/generated/icon-avatar.js +2 -0
- package/dist/2-core/generated/icons-extra.d.ts.map +1 -1
- package/dist/2-core/generated/icons-extra.js +118 -65
- package/dist/2-core/generated/icons-immediate.d.ts +1 -1
- package/dist/2-core/generated/icons-immediate.d.ts.map +1 -1
- package/dist/2-core/generated/icons-immediate.js +1 -1
- package/dist/2-core/spacing-handle.d.ts +28 -0
- package/dist/2-core/spacing-handle.d.ts.map +1 -0
- package/dist/2-core/spacing-handle.js +146 -0
- package/dist/3-unit/calendar-base.d.ts +149 -0
- package/dist/3-unit/calendar-base.d.ts.map +1 -0
- package/dist/3-unit/calendar-base.js +172 -0
- package/dist/3-unit/ds-accordion.d.ts +9 -0
- package/dist/3-unit/ds-accordion.d.ts.map +1 -1
- package/dist/3-unit/ds-accordion.js +7 -1
- package/dist/3-unit/ds-avatar-group.d.ts +1 -0
- package/dist/3-unit/ds-avatar-group.d.ts.map +1 -1
- package/dist/3-unit/ds-calendar-large.d.ts +138 -0
- package/dist/3-unit/ds-calendar-large.d.ts.map +1 -0
- package/dist/3-unit/ds-calendar-large.js +305 -0
- package/dist/3-unit/ds-calendar.d.ts +175 -0
- package/dist/3-unit/ds-calendar.d.ts.map +1 -0
- package/dist/3-unit/ds-calendar.js +303 -0
- package/dist/3-unit/ds-carousel.d.ts +182 -0
- package/dist/3-unit/ds-carousel.d.ts.map +1 -0
- package/dist/3-unit/ds-carousel.js +327 -0
- package/dist/3-unit/ds-date-picker.d.ts +203 -0
- package/dist/3-unit/ds-date-picker.d.ts.map +1 -0
- package/dist/3-unit/ds-date-picker.js +499 -0
- package/dist/3-unit/ds-form.d.ts.map +1 -1
- package/dist/3-unit/ds-form.js +38 -28
- package/dist/3-unit/ds-list.d.ts +12 -0
- package/dist/3-unit/ds-list.d.ts.map +1 -1
- package/dist/3-unit/ds-list.js +52 -1
- package/dist/3-unit/ds-matrix.d.ts +146 -0
- package/dist/3-unit/ds-matrix.d.ts.map +1 -0
- package/dist/3-unit/ds-matrix.js +248 -0
- package/dist/3-unit/ds-menu.d.ts +1 -1
- package/dist/3-unit/ds-menu.d.ts.map +1 -1
- package/dist/3-unit/ds-menu.js +7 -4
- package/dist/3-unit/ds-row.d.ts +66 -0
- package/dist/3-unit/ds-row.d.ts.map +1 -1
- package/dist/3-unit/ds-row.js +80 -1
- package/dist/3-unit/ds-sidebar.d.ts +108 -0
- package/dist/3-unit/ds-sidebar.d.ts.map +1 -0
- package/dist/3-unit/ds-sidebar.js +268 -0
- package/dist/3-unit/ds-table.d.ts +28 -10
- package/dist/3-unit/ds-table.d.ts.map +1 -1
- package/dist/3-unit/ds-table.js +53 -25
- package/dist/3-unit/ds-tree.d.ts +69 -0
- package/dist/3-unit/ds-tree.d.ts.map +1 -0
- package/dist/3-unit/ds-tree.js +136 -0
- package/dist/4-page/ds-dialog.d.ts +16 -1
- package/dist/4-page/ds-dialog.d.ts.map +1 -1
- package/dist/4-page/ds-dialog.js +39 -3
- package/dist/4-page/ds-document.d.ts +98 -0
- package/dist/4-page/ds-document.d.ts.map +1 -0
- package/dist/4-page/ds-document.js +213 -0
- package/dist/4-page/ds-footer.d.ts +100 -0
- package/dist/4-page/ds-footer.d.ts.map +1 -0
- package/dist/4-page/ds-footer.js +119 -0
- package/dist/4-page/ds-grid.d.ts +32 -12
- package/dist/4-page/ds-grid.d.ts.map +1 -1
- package/dist/4-page/ds-grid.js +30 -39
- package/dist/4-page/ds-header.d.ts +84 -0
- package/dist/4-page/ds-header.d.ts.map +1 -0
- package/dist/4-page/ds-header.js +143 -0
- package/dist/4-page/ds-layout.d.ts +1 -0
- package/dist/4-page/ds-layout.d.ts.map +1 -1
- package/dist/4-page/ds-layout.js +1 -1
- package/dist/4-page/ds-page.d.ts +110 -0
- package/dist/4-page/ds-page.d.ts.map +1 -0
- package/dist/4-page/ds-page.js +155 -0
- package/dist/4-page/email.d.ts +2 -3
- package/dist/4-page/email.d.ts.map +1 -1
- package/dist/4-page/email.js +2 -3
- package/dist/components.d.ts +4 -1
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +4 -1
- package/dist/design-system-1.bundle.js +11304 -4322
- package/dist/design-system-1.bundle.js.map +1 -1
- package/dist/design-system-1.bundle.min.js +8867 -4132
- package/dist/design-system-1.bundle.min.js.map +1 -1
- package/dist/design-system-1.css +1 -1
- package/dist/feedback.js +541 -0
- package/dist/feedback.js.map +1 -0
- package/dist/icons-extra-B4Iotc7s.js +298 -0
- package/dist/icons-extra-B4Iotc7s.js.map +1 -0
- package/dist/icons-extra-C4sCgoUj.js +185 -0
- package/dist/icons-extra-C4sCgoUj.js.map +1 -0
- package/dist/icons-extra-DSav6uTU.js +300 -0
- package/dist/icons-extra-DSav6uTU.js.map +1 -0
- package/dist/icons-extra-Dc_yVWIz.js +1024 -0
- package/dist/icons-extra-Dc_yVWIz.js.map +1 -0
- package/dist/icons-extra-cfzoudMf.js +1030 -0
- package/dist/icons-extra-cfzoudMf.js.map +1 -0
- package/dist/icons-extra-g_xpwZhZ.js +631 -0
- package/dist/icons-extra-g_xpwZhZ.js.map +1 -0
- package/dist/index.d.ts +23 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -6
- package/dist/react/avatar.d.ts +5 -9
- package/dist/react/avatar.d.ts.map +1 -1
- package/dist/react/avatar.js +2 -2
- package/dist/react/button-split.d.ts +19 -0
- package/dist/react/button-split.d.ts.map +1 -0
- package/dist/react/button-split.js +35 -0
- package/dist/react/button.d.ts +18 -7
- package/dist/react/button.d.ts.map +1 -1
- package/dist/react/button.js +13 -4
- package/dist/react/carousel.d.ts +63 -0
- package/dist/react/carousel.d.ts.map +1 -0
- package/dist/react/carousel.js +47 -0
- package/dist/react/choice.d.ts +1 -1
- package/dist/react/context-menu.d.ts +337 -337
- package/dist/react/dialog.d.ts +684 -678
- package/dist/react/dialog.d.ts.map +1 -1
- package/dist/react/dialog.js +29 -3
- package/dist/react/document.d.ts +11 -0
- package/dist/react/document.d.ts.map +1 -0
- package/dist/react/document.js +10 -0
- package/dist/react/empty.d.ts +34 -0
- package/dist/react/empty.d.ts.map +1 -0
- package/dist/react/empty.js +8 -0
- package/dist/react/file-picker.d.ts +1 -1
- package/dist/react/footer.d.ts +13 -0
- package/dist/react/footer.d.ts.map +1 -0
- package/dist/react/footer.js +12 -0
- package/dist/react/header.d.ts +12 -0
- package/dist/react/header.d.ts.map +1 -0
- package/dist/react/header.js +11 -0
- package/dist/react/input.d.ts +31 -9
- package/dist/react/input.d.ts.map +1 -1
- package/dist/react/input.js +94 -94
- package/dist/react/kbd.d.ts +26 -0
- package/dist/react/kbd.d.ts.map +1 -0
- package/dist/react/kbd.js +8 -0
- package/dist/react/loading.d.ts +14 -0
- package/dist/react/loading.d.ts.map +1 -0
- package/dist/react/loading.js +14 -0
- package/dist/react/meter.d.ts +64 -0
- package/dist/react/meter.d.ts.map +1 -0
- package/dist/react/meter.js +15 -0
- package/dist/react/notice.d.ts +45 -0
- package/dist/react/notice.d.ts.map +1 -0
- package/dist/react/notice.js +34 -0
- package/dist/react/page.d.ts +10 -0
- package/dist/react/page.d.ts.map +1 -0
- package/dist/react/page.js +9 -0
- package/dist/react/progress.d.ts +107 -0
- package/dist/react/progress.d.ts.map +1 -0
- package/dist/react/progress.js +47 -0
- package/dist/react/sidebar.d.ts +44 -0
- package/dist/react/sidebar.d.ts.map +1 -0
- package/dist/react/sidebar.js +41 -0
- package/dist/react/spacing-handle.d.ts +13 -0
- package/dist/react/spacing-handle.d.ts.map +1 -0
- package/dist/react/spacing-handle.js +18 -0
- package/dist/react/split.d.ts +6 -14
- package/dist/react/split.d.ts.map +1 -1
- package/dist/react/split.js +5 -31
- package/dist/react/stat.d.ts +78 -0
- package/dist/react/stat.d.ts.map +1 -0
- package/dist/react/stat.js +25 -0
- package/dist/react/steps.d.ts +36 -0
- package/dist/react/steps.d.ts.map +1 -0
- package/dist/react/steps.js +10 -0
- package/dist/react/toast.d.ts +37 -0
- package/dist/react/toast.d.ts.map +1 -0
- package/dist/react/toast.js +55 -0
- package/dist/react/tree.d.ts +31 -0
- package/dist/react/tree.d.ts.map +1 -0
- package/dist/react/tree.js +37 -0
- package/dist/shared-words-BfnT24Fe.js +1635 -0
- package/dist/shared-words-BfnT24Fe.js.map +1 -0
- package/dist/shared-words-CyZYc_De.js +1818 -0
- package/dist/shared-words-CyZYc_De.js.map +1 -0
- package/dist/shared-words-DAVSET4Z.js +1800 -0
- package/dist/shared-words-DAVSET4Z.js.map +1 -0
- package/dist/shared-words-UCvnkctb.js +1653 -0
- package/dist/shared-words-UCvnkctb.js.map +1 -0
- package/package.json +16 -5
- package/DS1/2-core/ds-banner.ts +0 -122
- package/DS1/2-core/ds-date.ts +0 -24
- package/DS1/2-core/ds-language.ts +0 -94
- package/DS1/2-core/ds-pagedots.ts +0 -52
- package/DS1/2-core/ds-split.ts +0 -122
- package/DS1/2-core/ds-textarea.ts +0 -136
- package/DS1/2-core/styles/ds-banner.css +0 -77
- package/DS1/2-core/styles/ds-date.css +0 -9
- package/DS1/2-core/styles/ds-language.css +0 -78
- package/DS1/2-core/styles/ds-pagedots.css +0 -31
- package/DS1/2-core/styles/ds-textarea.css +0 -27
- package/DS1/4-page/ds-layout.ts +0 -949
- package/DS1/4-page/styles/ds-layout.css +0 -246
- package/DS1/react/split.ts +0 -42
- package/DS1/x-icon/ezo-accordion-chevron.svg +0 -11
- package/DS1/x-icon/ezo-account-close.svg +0 -1
- package/DS1/x-icon/ezo-android-screen-archive.svg +0 -4
- package/DS1/x-icon/ezo-android-screen-calendar.svg +0 -6
- package/DS1/x-icon/ezo-android-screen-camera.svg +0 -5
- package/DS1/x-icon/ezo-android-screen-check.svg +0 -3
- package/DS1/x-icon/ezo-android-screen-compose.svg +0 -4
- package/DS1/x-icon/ezo-android-screen-globe.svg +0 -1
- package/DS1/x-icon/ezo-android-screen-shared.svg +0 -5
- package/DS1/x-icon/ezo-android-screen-store.svg +0 -4
- package/DS1/x-icon/ezo-android-screen-views.svg +0 -4
- package/DS1/x-icon/ezo-android-screen-work.svg +0 -3
- package/DS1/x-icon/ezo-arrow-cursor.svg +0 -8
- package/DS1/x-icon/ezo-block-accordion.svg +0 -1
- package/DS1/x-icon/ezo-block-divider.svg +0 -1
- package/DS1/x-icon/ezo-block-group.svg +0 -1
- package/DS1/x-icon/ezo-block-image.svg +0 -1
- package/DS1/x-icon/ezo-block-section.svg +0 -1
- package/DS1/x-icon/ezo-block-table.svg +0 -1
- package/DS1/x-icon/ezo-code.svg +0 -14
- package/DS1/x-icon/ezo-down.svg +0 -3
- package/DS1/x-icon/ezo-figma-premium-star.svg +0 -5
- package/DS1/x-icon/ezo-item-button-complete.svg +0 -4
- package/DS1/x-icon/ezo-item-button-header.svg +0 -3
- package/DS1/x-icon/ezo-item-button-open.svg +0 -3
- package/DS1/x-icon/ezo-item-button-star.svg +0 -3
- package/DS1/x-icon/ezo-item-button-unheader.svg +0 -7
- package/DS1/x-icon/ezo-item-button-unstar.svg +0 -5
- package/DS1/x-icon/ezo-item-star.svg +0 -5
- package/DS1/x-icon/ezo-left.svg +0 -3
- package/DS1/x-icon/ezo-logo.svg +0 -1
- package/DS1/x-icon/ezo-mic.svg +0 -8
- package/DS1/x-icon/ezo-move-column.svg +0 -14
- package/DS1/x-icon/ezo-move-row.svg +0 -18
- package/DS1/x-icon/ezo-navigation-check.svg +0 -1
- package/DS1/x-icon/ezo-note-back.svg +0 -5
- package/DS1/x-icon/ezo-note-menu-complete.svg +0 -11
- package/DS1/x-icon/ezo-note-menu-delete.svg +0 -4
- package/DS1/x-icon/ezo-note-menu-duplicate.svg +0 -8
- package/DS1/x-icon/ezo-note-menu-note.svg +0 -5
- package/DS1/x-icon/ezo-note-menu-page.svg +0 -3
- package/DS1/x-icon/ezo-note-menu-star.svg +0 -5
- package/DS1/x-icon/ezo-note-menu-start.svg +0 -6
- package/DS1/x-icon/ezo-note-menu-stop.svg +0 -6
- package/DS1/x-icon/ezo-note-more.svg +0 -7
- package/DS1/x-icon/ezo-note-star.svg +0 -5
- package/DS1/x-icon/ezo-pattern-call-to-action.svg +0 -1
- package/DS1/x-icon/ezo-play.svg +0 -5
- package/DS1/x-icon/ezo-premium-star.svg +0 -5
- package/DS1/x-icon/ezo-setting-1xdots.svg +0 -13
- package/DS1/x-icon/ezo-setting-1xgrid.svg +0 -10
- package/DS1/x-icon/ezo-setting-1xlines.svg +0 -7
- package/DS1/x-icon/ezo-setting-2xdots.svg +0 -8
- package/DS1/x-icon/ezo-setting-2xgrid.svg +0 -8
- package/DS1/x-icon/ezo-setting-2xlines.svg +0 -6
- package/DS1/x-icon/ezo-setting-blank.svg +0 -5
- package/DS1/x-icon/ezo-store-chevron.svg +0 -1
- package/DS1/x-icon/ezo-upgrade-close.svg +0 -5
- package/DS1/x-icon/product-sources.json +0 -2557
- /package/DS1/x-icon/{ezo-password-visibility-see.svg → password-see.svg} +0 -0
- /package/DS1/x-icon/{ezo-password-visibility-unsee.svg → password-unsee.svg} +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The toasts' queue: Sonner's `toast()` calls and the observer that carries
|
|
3
|
+
* them to whatever draws the stack, with no framework.
|
|
4
|
+
*
|
|
5
|
+
* BASED ON SONNER, the React toast library by Emil Kowalski
|
|
6
|
+
* (https://sonner.emilkowal.ski, https://github.com/emilkowalski/sonner, MIT
|
|
7
|
+
* licence). The calls, their options and their ids are Sonner's, so Sonner's
|
|
8
|
+
* documentation describes them.
|
|
9
|
+
*
|
|
10
|
+
* Two toasters draw what it sends, in the same look: `<ds-toast>`
|
|
11
|
+
* (`2-core/ds-toast.ts`, Lit) and the page toaster (`0-face/toaster.ts`, no
|
|
12
|
+
* framework). A page shows one stack whichever it loads: a `<ds-toast>` in the
|
|
13
|
+
* page takes every toast, the page toaster draws only when there is none, and
|
|
14
|
+
* `toast()` with no toaster listening adds a `<ds-toast>` when the element is
|
|
15
|
+
* registered and the page toaster otherwise.
|
|
16
|
+
*
|
|
17
|
+
* The queue lives on `globalThis`, so two copies of this module (a product
|
|
18
|
+
* that vendors Design system 1 in two folders) still feed one stack.
|
|
19
|
+
*
|
|
20
|
+
* Where it departs from Sonner: an error is announced assertively unless it
|
|
21
|
+
* says `important: false`.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export type ToastId = string | number;
|
|
25
|
+
export type ToastType = "default" | "success" | "info" | "warning" | "error" | "loading";
|
|
26
|
+
export type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
27
|
+
/**
|
|
28
|
+
* A button in a toast. Clicking it closes the toast unless `onClick` calls
|
|
29
|
+
* `preventDefault()`, as in Sonner. With `href` it is a link instead (not in
|
|
30
|
+
* Sonner), which still closes the toast as the page follows it.
|
|
31
|
+
*/
|
|
32
|
+
export interface ToastButton { label: string; onClick?: (event: MouseEvent) => void; href?: string }
|
|
33
|
+
export interface ToastOptions {
|
|
34
|
+
/** Reuse an id to update a toast in place, as Sonner does. */
|
|
35
|
+
id?: ToastId;
|
|
36
|
+
description?: string;
|
|
37
|
+
/** Milliseconds; `Infinity` keeps the toast until it is dismissed. */
|
|
38
|
+
duration?: number;
|
|
39
|
+
/** A Design system 1 icon name, replacing the type's icon. */
|
|
40
|
+
icon?: string;
|
|
41
|
+
action?: ToastButton;
|
|
42
|
+
cancel?: ToastButton;
|
|
43
|
+
/** False keeps the toast from being swiped or closed by a person. */
|
|
44
|
+
dismissible?: boolean;
|
|
45
|
+
closeButton?: boolean;
|
|
46
|
+
/** Announced assertively instead of politely. Errors are, unless this is false. */
|
|
47
|
+
important?: boolean;
|
|
48
|
+
onDismiss?: (toast: ToastData) => void;
|
|
49
|
+
onAutoClose?: (toast: ToastData) => void;
|
|
50
|
+
}
|
|
51
|
+
export interface ToastData extends ToastOptions { id: ToastId; title: string; type: ToastType }
|
|
52
|
+
type Message<T> = string | ((value: T) => string);
|
|
53
|
+
export interface ToastPromiseMessages<T> extends ToastOptions {
|
|
54
|
+
loading: string;
|
|
55
|
+
success: Message<T>;
|
|
56
|
+
error: Message<unknown>;
|
|
57
|
+
finally?: () => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** What a toaster hears: a toast to show or update, or a dismissal (every toast when the id is undefined). */
|
|
61
|
+
export type ToastSignal = { toast: ToastData } | { dismiss: ToastId | undefined };
|
|
62
|
+
type Listener = (signal: ToastSignal) => void;
|
|
63
|
+
|
|
64
|
+
/** Sonner's constants, shared by both toasters; its gap and offset are rounded to squares in the stylesheet. */
|
|
65
|
+
export const TOAST_DURATION = 4000;
|
|
66
|
+
export const VISIBLE_TOASTS = 3;
|
|
67
|
+
export const TIME_BEFORE_UNMOUNT = 200;
|
|
68
|
+
export const SWIPE_THRESHOLD = 45;
|
|
69
|
+
export const SWIPE_VELOCITY = 0.11;
|
|
70
|
+
/** The Design system 1 icon each type shows. */
|
|
71
|
+
export const TOAST_ICONS: Partial<Record<ToastType, string>> = { success: "check", info: "notifications", warning: "warning", error: "warning" };
|
|
72
|
+
|
|
73
|
+
interface Queue {
|
|
74
|
+
/** `<ds-toast>` elements: when one listens, it takes every toast. */
|
|
75
|
+
toasters: Set<Listener>;
|
|
76
|
+
/** The page toaster, which draws only while no `<ds-toast>` listens. */
|
|
77
|
+
fallbacks: Set<Listener>;
|
|
78
|
+
lastId: number;
|
|
79
|
+
mountFallback?: () => void;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const QUEUE = Symbol.for("design-system-1.toasts");
|
|
83
|
+
|
|
84
|
+
function queue(): Queue {
|
|
85
|
+
const scope = globalThis as unknown as Record<symbol, Queue | undefined>;
|
|
86
|
+
return (scope[QUEUE] ??= { toasters: new Set(), fallbacks: new Set(), lastId: 0 });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Listen for toasts. A `<ds-toast>` listens as a toaster; the page toaster
|
|
91
|
+
* listens as the fallback, hearing new toasts only while no toaster listens.
|
|
92
|
+
* Returns the function that stops listening.
|
|
93
|
+
*/
|
|
94
|
+
export function listenForToasts(listener: Listener, { fallback = false }: { fallback?: boolean } = {}): () => void {
|
|
95
|
+
const listeners = fallback ? queue().fallbacks : queue().toasters;
|
|
96
|
+
listeners.add(listener);
|
|
97
|
+
return () => { listeners.delete(listener); };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Whether a toast shown now is drawn: a toaster listens, the page toaster is
|
|
102
|
+
* loaded, or `<ds-toast>` is registered (and so is added to the page).
|
|
103
|
+
*/
|
|
104
|
+
export function toasterListening(): boolean {
|
|
105
|
+
const state = queue();
|
|
106
|
+
return state.toasters.size > 0 || state.fallbacks.size > 0 || !!state.mountFallback || (typeof customElements !== "undefined" && !!customElements.get("ds-toast"));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** How the page toaster mounts itself when a toast arrives and nothing draws it. */
|
|
110
|
+
export function setFallbackToaster(mount: () => void): void {
|
|
111
|
+
queue().mountFallback = mount;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function show(title: string, type: ToastType, options: ToastOptions = {}): ToastId {
|
|
115
|
+
const state = queue();
|
|
116
|
+
const id = options.id ?? ++state.lastId;
|
|
117
|
+
if (!state.toasters.size && typeof document !== "undefined" && document.body) {
|
|
118
|
+
if (typeof customElements !== "undefined" && customElements.get("ds-toast")) document.body.appendChild(document.createElement("ds-toast"));
|
|
119
|
+
else if (!state.fallbacks.size) state.mountFallback?.();
|
|
120
|
+
}
|
|
121
|
+
const important = options.important ?? (type === "error" ? true : undefined);
|
|
122
|
+
const data: ToastData = { ...options, ...(important === undefined ? {} : { important }), id, title, type };
|
|
123
|
+
// A copy: a listener may add or remove listeners while it hears the toast.
|
|
124
|
+
for (const listener of Array.from(state.toasters.size ? state.toasters : state.fallbacks)) listener({ toast: data });
|
|
125
|
+
return id;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Show a toast, as Sonner's `toast()`. Returns its id. */
|
|
129
|
+
export const toast = Object.assign(
|
|
130
|
+
(title: string, options?: ToastOptions): ToastId => show(title, "default", options),
|
|
131
|
+
{
|
|
132
|
+
message: (title: string, options?: ToastOptions): ToastId => show(title, "default", options),
|
|
133
|
+
success: (title: string, options?: ToastOptions): ToastId => show(title, "success", options),
|
|
134
|
+
info: (title: string, options?: ToastOptions): ToastId => show(title, "info", options),
|
|
135
|
+
warning: (title: string, options?: ToastOptions): ToastId => show(title, "warning", options),
|
|
136
|
+
error: (title: string, options?: ToastOptions): ToastId => show(title, "error", options),
|
|
137
|
+
loading: (title: string, options?: ToastOptions): ToastId => show(title, "loading", options),
|
|
138
|
+
/** A loading toast that becomes a success or an error when the promise settles. */
|
|
139
|
+
promise<T>(promise: Promise<T> | (() => Promise<T>), messages: ToastPromiseMessages<T>): ToastId {
|
|
140
|
+
const { loading, success, error, finally: done, ...options } = messages;
|
|
141
|
+
const id = show(loading, "loading", options);
|
|
142
|
+
Promise.resolve(typeof promise === "function" ? promise() : promise)
|
|
143
|
+
.then(
|
|
144
|
+
value => { show(typeof success === "function" ? success(value) : success, "success", { ...options, id }); },
|
|
145
|
+
reason => { show(typeof error === "function" ? error(reason) : error, "error", { ...options, id }); },
|
|
146
|
+
)
|
|
147
|
+
.finally(() => done?.());
|
|
148
|
+
return id;
|
|
149
|
+
},
|
|
150
|
+
/** Dismiss one toast, or every toast without an id. */
|
|
151
|
+
dismiss(id?: ToastId): ToastId | undefined {
|
|
152
|
+
const state = queue();
|
|
153
|
+
for (const listener of [...state.toasters, ...state.fallbacks]) listener({ dismiss: id });
|
|
154
|
+
return id;
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
);
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The page toaster: Sonner's toast stack on a page without Lit or any other
|
|
3
|
+
* framework. Import it (or `0-face/feedback.ts`) and call `toast()`; nothing
|
|
4
|
+
* else goes in the page.
|
|
5
|
+
*
|
|
6
|
+
* BASED ON SONNER, the React toast library by Emil Kowalski
|
|
7
|
+
* (https://sonner.emilkowal.ski, https://github.com/emilkowalski/sonner, MIT
|
|
8
|
+
* licence), as `<ds-toast>` is: the same calls, options, stacking, timers,
|
|
9
|
+
* hover and focus pauses, swipe, Alt+T and 400ms slide and fade.
|
|
10
|
+
*
|
|
11
|
+
* It shares the look rather than wrapping the element: it draws the element's
|
|
12
|
+
* markup in a shadow root of its own with the element's stylesheet
|
|
13
|
+
* (`2-core/styles/ds-toast.css`, as plain text in `./generated/toast-assets.ts`,
|
|
14
|
+
* which `scripts/toast-assets.mjs` writes from it), so the two cannot drift
|
|
15
|
+
* apart, and it needs no Lit, which a page without Lit does not have. It is
|
|
16
|
+
* plain TypeScript: no `?inline` or `?raw` import, so any bundler and type
|
|
17
|
+
* check reads it. It shares the queue too
|
|
18
|
+
* (`0-face/toast-queue.ts`): where a `<ds-toast>` is in the page, that element
|
|
19
|
+
* takes every toast and this one stays quiet, so a page never shows two stacks.
|
|
20
|
+
*
|
|
21
|
+
* Its region is in the page before the first toast arrives, a polite live
|
|
22
|
+
* region in which each toast is announced, and an error assertively. Only
|
|
23
|
+
* `transform` and `opacity` animate, and nothing moves with reduced motion.
|
|
24
|
+
*/
|
|
25
|
+
import { feedbackWord } from "./feedback-words";
|
|
26
|
+
import { toastIcons, toastStyles } from "./generated/toast-assets";
|
|
27
|
+
import {
|
|
28
|
+
SWIPE_THRESHOLD,
|
|
29
|
+
SWIPE_VELOCITY,
|
|
30
|
+
TIME_BEFORE_UNMOUNT,
|
|
31
|
+
TOAST_DURATION,
|
|
32
|
+
TOAST_ICONS,
|
|
33
|
+
VISIBLE_TOASTS,
|
|
34
|
+
listenForToasts,
|
|
35
|
+
setFallbackToaster,
|
|
36
|
+
} from "./toast-queue";
|
|
37
|
+
import type { ToastButton, ToastData, ToastId, ToastPosition, ToastSignal } from "./toast-queue";
|
|
38
|
+
|
|
39
|
+
export { toast } from "./toast-queue";
|
|
40
|
+
export type { ToastButton, ToastData, ToastId, ToastOptions, ToastPosition, ToastPromiseMessages, ToastType } from "./toast-queue";
|
|
41
|
+
|
|
42
|
+
/** Sonner's `<Toaster />` props, for the page toaster. */
|
|
43
|
+
export interface ToasterOptions {
|
|
44
|
+
/** `top-left`, `top-center`, `top-right`, `bottom-left`, `bottom-center` or `bottom-right` (the default). */
|
|
45
|
+
position?: ToastPosition;
|
|
46
|
+
/** Keep the toasts spread out instead of stacked. */
|
|
47
|
+
expand?: boolean;
|
|
48
|
+
/** How many show at once; three by default. */
|
|
49
|
+
visibleToasts?: number;
|
|
50
|
+
/** Milliseconds each toast stays; 4000 by default. */
|
|
51
|
+
duration?: number;
|
|
52
|
+
/** A close button on every toast. */
|
|
53
|
+
closeButton?: boolean;
|
|
54
|
+
/** Fill success, info, warning and error toasts with their colour. */
|
|
55
|
+
richColors?: boolean;
|
|
56
|
+
/** The region's accessible name; the shared word "Notifications" by default. */
|
|
57
|
+
label?: string;
|
|
58
|
+
/** The close button's accessible name; the shared word "Close" by default. */
|
|
59
|
+
closeLabel?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The icons the page carries: the types' own and the close button's, in the text's colour. */
|
|
63
|
+
const INK = /(fill|stroke)=("|')(#1E1E1E|#2A2A2A|#000000|#000|black)\2/gi;
|
|
64
|
+
const SVGS: Record<string, string> = Object.fromEntries(
|
|
65
|
+
Object.entries(toastIcons)
|
|
66
|
+
.map(([name, svg]) => [name, svg.replace(INK, '$1="currentColor"')]),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
interface Item { data: ToastData; mounted: boolean; removed: boolean; swipeOut: boolean; index: number; offset: number; element?: HTMLLIElement; drawn?: string }
|
|
70
|
+
interface Timer { remaining: number; started: number; handle?: ReturnType<typeof setTimeout> }
|
|
71
|
+
|
|
72
|
+
let settings: ToasterOptions = {};
|
|
73
|
+
let current: PageToaster | undefined;
|
|
74
|
+
|
|
75
|
+
/** Set the page toaster's options, as Sonner's `<Toaster />` props. Toasts already shown take them at once. */
|
|
76
|
+
export function configureToaster(options: ToasterOptions): void {
|
|
77
|
+
settings = { ...settings, ...options };
|
|
78
|
+
current?.render();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const frame = (callback: () => void) => typeof requestAnimationFrame === "function" ? requestAnimationFrame(callback) : setTimeout(callback, 16);
|
|
82
|
+
|
|
83
|
+
function element<K extends keyof HTMLElementTagNameMap>(name: K, attributes: Record<string, string> = {}, text?: string): HTMLElementTagNameMap[K] {
|
|
84
|
+
const node = document.createElement(name);
|
|
85
|
+
for (const [key, value] of Object.entries(attributes)) node.setAttribute(key, value);
|
|
86
|
+
if (text !== undefined) node.textContent = text;
|
|
87
|
+
return node;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function icon(name: string, className: string): HTMLSpanElement | undefined {
|
|
91
|
+
const svg = SVGS[name];
|
|
92
|
+
if (!svg) return undefined;
|
|
93
|
+
const span = element("span", { class: className, "aria-hidden": "true" });
|
|
94
|
+
span.innerHTML = svg;
|
|
95
|
+
return span;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
class PageToaster {
|
|
99
|
+
readonly host = element("div", { "data-ds-toaster": "" });
|
|
100
|
+
private readonly section = element("section", { "aria-live": "polite", "aria-relevant": "additions text", "aria-atomic": "false" });
|
|
101
|
+
private readonly list = element("ol", { tabindex: "-1" });
|
|
102
|
+
private items: Item[] = [];
|
|
103
|
+
private heights = new Map<ToastId, number>();
|
|
104
|
+
private timers = new Map<ToastId, Timer>();
|
|
105
|
+
private hovered = false;
|
|
106
|
+
private focused = false;
|
|
107
|
+
private interacting = false;
|
|
108
|
+
private mounting = false;
|
|
109
|
+
private swipe?: { id: ToastId; start: number; time: number; amount: number };
|
|
110
|
+
private resizes = typeof ResizeObserver === "undefined" ? undefined : new ResizeObserver(() => this.measure());
|
|
111
|
+
|
|
112
|
+
constructor() {
|
|
113
|
+
const root = this.host.attachShadow({ mode: "open" });
|
|
114
|
+
root.appendChild(element("style", {}, toastStyles));
|
|
115
|
+
root.appendChild(this.section);
|
|
116
|
+
this.section.appendChild(this.list);
|
|
117
|
+
this.list.addEventListener("pointerenter", () => { this.hovered = true; this.render(); });
|
|
118
|
+
this.list.addEventListener("pointerleave", () => { if (!this.interacting) { this.hovered = false; this.render(); } });
|
|
119
|
+
this.list.addEventListener("focusin", () => { this.focused = true; this.render(); });
|
|
120
|
+
this.list.addEventListener("focusout", event => {
|
|
121
|
+
if (!(event.relatedTarget instanceof Node && root.contains(event.relatedTarget))) { this.focused = false; this.render(); }
|
|
122
|
+
});
|
|
123
|
+
document.addEventListener("keydown", this.hotkey);
|
|
124
|
+
document.addEventListener("visibilitychange", this.syncTimers);
|
|
125
|
+
window.addEventListener("language-changed", () => this.render());
|
|
126
|
+
listenForToasts(this.receive, { fallback: true });
|
|
127
|
+
this.attach();
|
|
128
|
+
this.render();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Back in the page if something took it out, at the end of the body. */
|
|
132
|
+
attach() {
|
|
133
|
+
if (!this.host.isConnected && document.body) document.body.appendChild(this.host);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private get live(): Item[] { return this.items.filter(item => !item.removed); }
|
|
137
|
+
private get position(): ToastPosition { return settings.position ?? "bottom-right"; }
|
|
138
|
+
private get expanded(): boolean { return !!settings.expand || ((this.hovered || this.focused) && this.live.length > 0); }
|
|
139
|
+
private get paused(): boolean { return this.hovered || this.focused || this.interacting || document.hidden; }
|
|
140
|
+
|
|
141
|
+
private receive = (signal: ToastSignal) => {
|
|
142
|
+
if ("dismiss" in signal) {
|
|
143
|
+
for (const item of this.live) if (signal.dismiss === undefined || item.data.id === signal.dismiss) this.removeToast(item.data.id);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
this.attach();
|
|
147
|
+
const data = signal.toast;
|
|
148
|
+
const existing = this.live.find(item => item.data.id === data.id);
|
|
149
|
+
if (existing) {
|
|
150
|
+
// An update keeps what it does not change and starts its time again, as in Sonner.
|
|
151
|
+
existing.data = { ...existing.data, ...data };
|
|
152
|
+
this.clearTimer(data.id);
|
|
153
|
+
} else {
|
|
154
|
+
this.items = [{ data, mounted: false, removed: false, swipeOut: false, index: 0, offset: 0 }, ...this.items.filter(item => item.data.id !== data.id)];
|
|
155
|
+
}
|
|
156
|
+
this.render();
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
private removeToast(id: ToastId, how: "dismiss" | "auto" | "swipe" = "dismiss") {
|
|
160
|
+
const item = this.live.find(entry => entry.data.id === id);
|
|
161
|
+
if (!item) return;
|
|
162
|
+
this.clearTimer(id);
|
|
163
|
+
this.heights.delete(id);
|
|
164
|
+
(how === "auto" ? item.data.onAutoClose : item.data.onDismiss)?.(item.data);
|
|
165
|
+
item.removed = true;
|
|
166
|
+
item.swipeOut = how === "swipe";
|
|
167
|
+
this.render();
|
|
168
|
+
setTimeout(() => {
|
|
169
|
+
this.items = this.items.filter(entry => entry !== item);
|
|
170
|
+
this.render();
|
|
171
|
+
}, TIME_BEFORE_UNMOUNT);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private clearTimer(id: ToastId) {
|
|
175
|
+
clearTimeout(this.timers.get(id)?.handle);
|
|
176
|
+
this.timers.delete(id);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Sonner's timers: each toast keeps its remaining time while the stack is paused. */
|
|
180
|
+
private syncTimers = () => {
|
|
181
|
+
const now = Date.now();
|
|
182
|
+
for (const item of this.live) {
|
|
183
|
+
const { id, type } = item.data;
|
|
184
|
+
const duration = item.data.duration ?? settings.duration ?? TOAST_DURATION;
|
|
185
|
+
if (type === "loading" || duration === Infinity) { this.clearTimer(id); continue; }
|
|
186
|
+
let timer = this.timers.get(id);
|
|
187
|
+
if (!timer) { timer = { remaining: duration, started: now }; this.timers.set(id, timer); }
|
|
188
|
+
if (this.paused && timer.handle !== undefined) {
|
|
189
|
+
clearTimeout(timer.handle);
|
|
190
|
+
timer.handle = undefined;
|
|
191
|
+
timer.remaining -= now - timer.started;
|
|
192
|
+
} else if (!this.paused && timer.handle === undefined) {
|
|
193
|
+
timer.started = now;
|
|
194
|
+
timer.handle = setTimeout(() => this.removeToast(id, "auto"), Math.max(0, timer.remaining));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
private hotkey = (event: KeyboardEvent) => {
|
|
200
|
+
if (event.altKey && event.code === "KeyT" && this.live.length) {
|
|
201
|
+
this.focused = true;
|
|
202
|
+
this.list.focus();
|
|
203
|
+
this.render();
|
|
204
|
+
} else if (event.key === "Escape" && this.focused) {
|
|
205
|
+
this.focused = false;
|
|
206
|
+
this.render();
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
private measure() {
|
|
211
|
+
let changed = false;
|
|
212
|
+
for (const item of this.live) {
|
|
213
|
+
const toast = item.element;
|
|
214
|
+
const body = toast?.querySelector<HTMLElement>(".body");
|
|
215
|
+
if (!toast || !body) continue;
|
|
216
|
+
const height = body.offsetHeight + toast.offsetHeight - toast.clientHeight;
|
|
217
|
+
if (this.heights.get(item.data.id) !== height) { this.heights.set(item.data.id, height); changed = true; }
|
|
218
|
+
}
|
|
219
|
+
if (changed) this.layout();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private press(event: MouseEvent, id: ToastId, button: ToastButton) {
|
|
223
|
+
button.onClick?.(event);
|
|
224
|
+
if (button.href || !event.defaultPrevented) this.removeToast(id);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private button(id: ToastId, button: ToastButton, kind: "cancel" | "action"): HTMLElement {
|
|
228
|
+
const node: HTMLElement = button.href ? element("a", { class: `button ${kind}`, href: button.href }, button.label) : element("button", { class: `button ${kind}`, type: "button" }, button.label);
|
|
229
|
+
node.addEventListener("click", event => this.press(event, id, button));
|
|
230
|
+
return node;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** The toast's words and buttons, drawn again only when they change. */
|
|
234
|
+
private draw(item: Item) {
|
|
235
|
+
const { data } = item;
|
|
236
|
+
const dismissible = data.dismissible !== false;
|
|
237
|
+
const closeButton = (data.closeButton ?? settings.closeButton ?? false) && dismissible;
|
|
238
|
+
const closeLabel = settings.closeLabel ?? feedbackWord("Close");
|
|
239
|
+
const key = JSON.stringify([data.title, data.description, data.type, data.icon, data.action?.label, data.action?.href, data.cancel?.label, data.cancel?.href, closeButton, closeLabel]);
|
|
240
|
+
const previous = item.element?.querySelector<HTMLElement>(".body");
|
|
241
|
+
if (item.drawn === key && previous) return;
|
|
242
|
+
item.drawn = key;
|
|
243
|
+
if (previous) this.resizes?.unobserve(previous);
|
|
244
|
+
const body = element("div", { class: "body", "data-id": String(data.id) });
|
|
245
|
+
const symbol = data.type === "loading" ? element("span", { class: "icon", "aria-hidden": "true" }) : icon(data.icon ?? TOAST_ICONS[data.type] ?? "", "icon");
|
|
246
|
+
if (data.type === "loading") symbol!.appendChild(element("span", { class: "spinner" }));
|
|
247
|
+
const content = element("div", { class: "content" });
|
|
248
|
+
content.appendChild(element("div", { class: "title" }, data.title));
|
|
249
|
+
if (data.description) content.appendChild(element("div", { class: "description" }, data.description));
|
|
250
|
+
if (symbol) body.appendChild(symbol);
|
|
251
|
+
body.appendChild(content);
|
|
252
|
+
if (data.cancel) body.appendChild(this.button(data.id, data.cancel, "cancel"));
|
|
253
|
+
if (data.action) body.appendChild(this.button(data.id, data.action, "action"));
|
|
254
|
+
if (closeButton) {
|
|
255
|
+
const close = element("button", { class: "close", type: "button", "aria-label": closeLabel });
|
|
256
|
+
close.innerHTML = SVGS.close!;
|
|
257
|
+
close.addEventListener("click", () => this.removeToast(data.id));
|
|
258
|
+
body.appendChild(close);
|
|
259
|
+
}
|
|
260
|
+
item.element!.replaceChildren(body);
|
|
261
|
+
this.resizes?.observe(body);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private create(item: Item): HTMLLIElement {
|
|
265
|
+
const toast = element("li", { class: "toast", role: "status", tabindex: "0", "aria-atomic": "true" });
|
|
266
|
+
const id = item.data.id;
|
|
267
|
+
toast.addEventListener("pointerdown", event => {
|
|
268
|
+
const now = this.live.find(entry => entry.data.id === id);
|
|
269
|
+
if (!now || now.data.dismissible === false || now.data.type === "loading") return;
|
|
270
|
+
if ((event.composedPath()[0] as Element | undefined)?.closest?.("button, a")) return;
|
|
271
|
+
toast.setPointerCapture?.(event.pointerId);
|
|
272
|
+
this.swipe = { id, start: event.clientY, time: Date.now(), amount: 0 };
|
|
273
|
+
this.interacting = true;
|
|
274
|
+
this.syncTimers();
|
|
275
|
+
});
|
|
276
|
+
toast.addEventListener("pointermove", event => {
|
|
277
|
+
if (!this.swipe || this.swipe.id !== id) return;
|
|
278
|
+
const toward = this.position.startsWith("top") ? -1 : 1;
|
|
279
|
+
// Only towards the edge the toast came from.
|
|
280
|
+
this.swipe.amount = Math.max(0, (event.clientY - this.swipe.start) * toward);
|
|
281
|
+
toast.dataset.swiping = "true";
|
|
282
|
+
toast.style.setProperty("--swipe", `${this.swipe.amount * toward}px`);
|
|
283
|
+
});
|
|
284
|
+
const release = () => {
|
|
285
|
+
const swipe = this.swipe;
|
|
286
|
+
if (!swipe || swipe.id !== id) return;
|
|
287
|
+
this.swipe = undefined;
|
|
288
|
+
this.interacting = false;
|
|
289
|
+
delete toast.dataset.swiping;
|
|
290
|
+
const velocity = swipe.amount / Math.max(1, Date.now() - swipe.time);
|
|
291
|
+
if (swipe.amount >= SWIPE_THRESHOLD || velocity > SWIPE_VELOCITY) this.removeToast(id, "swipe");
|
|
292
|
+
else toast.style.setProperty("--swipe", "0px");
|
|
293
|
+
this.syncTimers();
|
|
294
|
+
};
|
|
295
|
+
toast.addEventListener("pointerup", release);
|
|
296
|
+
toast.addEventListener("pointercancel", release);
|
|
297
|
+
return toast;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** Draw the stack: every toast's place, and each toast's words where they changed. */
|
|
301
|
+
render() {
|
|
302
|
+
if (!this.live.length) { this.hovered = false; this.focused = false; }
|
|
303
|
+
this.section.setAttribute("aria-label", `${settings.label ?? feedbackWord("Notifications")} alt+T`);
|
|
304
|
+
this.host.toggleAttribute("rich-colors", !!settings.richColors);
|
|
305
|
+
for (const item of this.items) {
|
|
306
|
+
item.element ??= this.create(item);
|
|
307
|
+
this.draw(item);
|
|
308
|
+
}
|
|
309
|
+
this.items.forEach((item, index) => {
|
|
310
|
+
if (this.list.children[index] !== item.element) this.list.insertBefore(item.element!, this.list.children[index] ?? null);
|
|
311
|
+
});
|
|
312
|
+
// A copy: the live collection shrinks as children leave.
|
|
313
|
+
for (const child of Array.from(this.list.children)) {
|
|
314
|
+
if (this.items.some(item => item.element === child)) continue;
|
|
315
|
+
const body = child.querySelector(".body");
|
|
316
|
+
if (body) this.resizes?.unobserve(body);
|
|
317
|
+
child.remove();
|
|
318
|
+
}
|
|
319
|
+
this.layout();
|
|
320
|
+
this.measure();
|
|
321
|
+
this.syncTimers();
|
|
322
|
+
if (!this.mounting && this.items.some(item => !item.mounted)) {
|
|
323
|
+
// Mount on the next frame so the toast slides in from its edge.
|
|
324
|
+
this.mounting = true;
|
|
325
|
+
frame(() => {
|
|
326
|
+
this.mounting = false;
|
|
327
|
+
for (const item of this.items) item.mounted = true;
|
|
328
|
+
this.layout();
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Each toast's index and offset, counting live toasts only; one leaving keeps where it was. */
|
|
334
|
+
private layout() {
|
|
335
|
+
let offset = 0;
|
|
336
|
+
this.live.forEach((item, index) => {
|
|
337
|
+
item.index = index;
|
|
338
|
+
item.offset = offset;
|
|
339
|
+
offset += this.heights.get(item.data.id) ?? 0;
|
|
340
|
+
});
|
|
341
|
+
const live = this.live;
|
|
342
|
+
const frontHeight = live.length ? this.heights.get(live[0]!.data.id) ?? 0 : 0;
|
|
343
|
+
const expanded = this.expanded;
|
|
344
|
+
const [y, x] = this.position.split("-") as ["top" | "bottom", "left" | "center" | "right"];
|
|
345
|
+
Object.assign(this.list.dataset, { y, x, expanded: String(expanded) });
|
|
346
|
+
this.list.style.setProperty("--height", `${expanded ? offset : frontHeight}px`);
|
|
347
|
+
this.list.style.setProperty("--gaps", String(expanded ? Math.max(0, live.length - 1) : 0));
|
|
348
|
+
const visible = settings.visibleToasts ?? VISIBLE_TOASTS;
|
|
349
|
+
for (const item of this.items) {
|
|
350
|
+
const toast = item.element!;
|
|
351
|
+
toast.setAttribute("aria-live", item.data.important ? "assertive" : "polite");
|
|
352
|
+
Object.assign(toast.dataset, {
|
|
353
|
+
type: item.data.type,
|
|
354
|
+
front: String(item.index === 0),
|
|
355
|
+
mounted: String(item.mounted),
|
|
356
|
+
removed: String(item.removed),
|
|
357
|
+
swipeOut: String(item.swipeOut),
|
|
358
|
+
visible: String(item.index < visible),
|
|
359
|
+
});
|
|
360
|
+
toast.style.setProperty("--index", String(item.index));
|
|
361
|
+
toast.style.setProperty("--offset", `${item.offset}px`);
|
|
362
|
+
toast.style.setProperty("--front-height", `${frontHeight}px`);
|
|
363
|
+
toast.style.zIndex = String(this.items.length - item.index);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/** The page toaster, put in the page when it is first needed. */
|
|
369
|
+
export function pageToaster(): HTMLElement | undefined {
|
|
370
|
+
if (typeof document === "undefined" || !document.body) return undefined;
|
|
371
|
+
current ??= new PageToaster();
|
|
372
|
+
current.attach();
|
|
373
|
+
return current.host;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
setFallbackToaster(() => { pageToaster(); });
|
|
377
|
+
|
|
378
|
+
// The region is in the page before the first toast, so the first is announced
|
|
379
|
+
// too; not where a `<ds-toast>` already draws the toasts.
|
|
380
|
+
if (typeof document !== "undefined") {
|
|
381
|
+
const ready = () => { if (typeof customElements === "undefined" || !customElements.get("ds-toast")) pageToaster(); };
|
|
382
|
+
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", ready, { once: true });
|
|
383
|
+
else ready();
|
|
384
|
+
}
|