@brandsync/wc 0.0.11 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +5869 -1633
- package/dist/brandsync-wc/brandsync-wc.css +20 -0
- package/dist/brandsync-wc/brandsync-wc.esm.js +1 -1
- package/dist/brandsync-wc/p-00bb9bda.entry.js +1 -0
- package/dist/brandsync-wc/{p-8dff4f24.entry.js → p-0847f5c0.entry.js} +1 -1
- package/dist/brandsync-wc/p-0ba35c3b.entry.js +1 -0
- package/dist/brandsync-wc/{p-073e5fee.entry.js → p-0f3cb0c4.entry.js} +1 -1
- package/dist/brandsync-wc/p-10f6f3cd.entry.js +1 -0
- package/dist/brandsync-wc/{p-c6d330c3.entry.js → p-111974df.entry.js} +1 -1
- package/dist/brandsync-wc/p-11f3fceb.entry.js +1 -0
- package/dist/brandsync-wc/p-171fed0c.entry.js +1 -0
- package/dist/brandsync-wc/{p-dd224cb3.entry.js → p-18813680.entry.js} +1 -1
- package/dist/brandsync-wc/p-1b7c9928.entry.js +1 -0
- package/dist/brandsync-wc/p-1ce7dd64.entry.js +1 -0
- package/dist/brandsync-wc/p-2063a6d6.entry.js +1 -0
- package/dist/brandsync-wc/{p-4ca15322.entry.js → p-20c24179.entry.js} +1 -1
- package/dist/brandsync-wc/{p-b174403d.entry.js → p-321ed4d3.entry.js} +1 -1
- package/dist/brandsync-wc/p-38aad266.entry.js +1 -0
- package/dist/brandsync-wc/p-43e37883.entry.js +1 -0
- package/dist/brandsync-wc/p-55a8d4b5.entry.js +1 -0
- package/dist/brandsync-wc/p-59ac2495.entry.js +1 -0
- package/dist/brandsync-wc/p-5ae9e60e.entry.js +1 -0
- package/dist/brandsync-wc/p-6b469b2d.entry.js +1 -0
- package/dist/brandsync-wc/p-6d85fba4.entry.js +1 -0
- package/dist/brandsync-wc/p-6e95eb36.entry.js +1 -0
- package/dist/brandsync-wc/{p-84ae4420.entry.js → p-73217b90.entry.js} +1 -1
- package/dist/brandsync-wc/p-752c04c8.entry.js +1 -0
- package/dist/brandsync-wc/p-79af762c.entry.js +1 -0
- package/dist/brandsync-wc/p-81d49240.entry.js +1 -0
- package/dist/brandsync-wc/p-91551e7b.entry.js +1 -0
- package/dist/brandsync-wc/p-917a5bbc.entry.js +1 -0
- package/dist/brandsync-wc/{p-0b858120.entry.js → p-9876e83c.entry.js} +1 -1
- package/dist/brandsync-wc/p-9bcd99aa.entry.js +1 -0
- package/dist/brandsync-wc/{p-d1dc2ced.entry.js → p-9c4768aa.entry.js} +1 -1
- package/dist/brandsync-wc/{p-DP_bvuvB.js → p-Do3l4of3.js} +2 -2
- package/dist/brandsync-wc/p-aa43d478.entry.js +1 -0
- package/dist/brandsync-wc/p-c3079ad7.entry.js +1 -0
- package/dist/brandsync-wc/{p-74a4dd91.entry.js → p-c3c383dc.entry.js} +1 -1
- package/dist/brandsync-wc/p-cc79e75f.entry.js +1 -0
- package/dist/brandsync-wc/p-ce7fc368.entry.js +1 -0
- package/dist/brandsync-wc/{p-030a8ba7.entry.js → p-d3265e70.entry.js} +1 -1
- package/dist/brandsync-wc/p-d55bbcec.entry.js +1 -0
- package/dist/brandsync-wc/{p-1bf0b2d5.entry.js → p-e93e944b.entry.js} +1 -1
- package/dist/brandsync-wc/{p-7a605d98.entry.js → p-eb04c578.entry.js} +1 -1
- package/dist/brandsync-wc/{p-3c8fbaa8.entry.js → p-f0ae2740.entry.js} +1 -1
- package/dist/brandsync-wc/p-f4f22015.entry.js +1 -0
- package/dist/cjs/brandsync-wc.cjs.js +2 -2
- package/dist/cjs/bs-ai-disclaimer.cjs.entry.js +3 -2
- package/dist/cjs/bs-ai-greeting.cjs.entry.js +2 -2
- package/dist/cjs/bs-ai-thinking.cjs.entry.js +2 -2
- package/dist/cjs/bs-attachment-list.cjs.entry.js +2 -2
- package/dist/cjs/bs-attachment.cjs.entry.js +3 -3
- package/dist/cjs/bs-avatar.cjs.entry.js +60 -0
- package/dist/cjs/bs-badge.cjs.entry.js +1 -1
- package/dist/cjs/bs-breadcrumb-overflow.cjs.entry.js +56 -0
- package/dist/cjs/bs-breadcrumb.cjs.entry.js +33 -0
- package/dist/cjs/bs-breadcrumbs.cjs.entry.js +49 -0
- package/dist/cjs/bs-button-skeleton.cjs.entry.js +2 -2
- package/dist/cjs/bs-button.cjs.entry.js +3 -3
- package/dist/cjs/bs-card.cjs.entry.js +10 -3
- package/dist/cjs/bs-chatbot-feedback.cjs.entry.js +2 -2
- package/dist/cjs/bs-chatbot-header.cjs.entry.js +2 -2
- package/dist/cjs/bs-chatbot-response-action.cjs.entry.js +2 -2
- package/dist/cjs/bs-chatbot-sources-drawer.cjs.entry.js +2 -2
- package/dist/cjs/bs-chatbot-suggestion-button.cjs.entry.js +2 -2
- package/dist/cjs/bs-checkbox-skeleton.cjs.entry.js +20 -0
- package/dist/cjs/bs-checkbox.cjs.entry.js +14 -3
- package/dist/cjs/bs-composer-status-banner.cjs.entry.js +14 -2
- package/dist/cjs/bs-composer.cjs.entry.js +37 -4
- package/dist/cjs/bs-data-table.cjs.entry.js +3 -3
- package/dist/cjs/bs-dialog.cjs.entry.js +110 -0
- package/dist/cjs/bs-icon-button.cjs.entry.js +40 -0
- package/dist/cjs/bs-inline-tab.cjs.entry.js +69 -0
- package/dist/cjs/bs-input.cjs.entry.js +24 -12
- package/dist/cjs/bs-logo.cjs.entry.js +165 -0
- package/dist/cjs/{bs-menu_2.cjs.entry.js → bs-menu-item.cjs.entry.js} +2 -15
- package/dist/cjs/bs-menu.cjs.entry.js +17 -0
- package/dist/cjs/bs-navigation-drawer-item.cjs.entry.js +104 -0
- package/dist/cjs/bs-navigation-drawer.cjs.entry.js +87 -0
- package/dist/cjs/bs-navigation-header.cjs.entry.js +44 -0
- package/dist/cjs/bs-pagination.cjs.entry.js +85 -0
- package/dist/cjs/bs-radio.cjs.entry.js +49 -0
- package/dist/cjs/bs-slider.cjs.entry.js +191 -0
- package/dist/cjs/bs-snackbar.cjs.entry.js +41 -0
- package/dist/cjs/bs-source-link.cjs.entry.js +3 -3
- package/dist/cjs/bs-switch.cjs.entry.js +57 -0
- package/dist/cjs/bs-tab.cjs.entry.js +80 -0
- package/dist/cjs/bs-tabs.cjs.entry.js +39 -0
- package/dist/cjs/bs-tooltip.cjs.entry.js +2 -2
- package/dist/cjs/{index-CGrdFg95.js → index-DHVw-IPK.js} +2 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/collection/collection-manifest.json +21 -3
- package/dist/collection/components/bs-ai-chatbot/bs-ai-chatbot.stories.js +26 -11
- package/dist/collection/components/bs-ai-disclaimer/bs-ai-disclaimer.js +2 -1
- package/dist/collection/components/bs-ai-greeting/bs-ai-greeting.js +1 -1
- package/dist/collection/components/bs-ai-thinking/bs-ai-thinking.js +1 -1
- package/dist/collection/components/bs-attachment/bs-attachment.css +12 -33
- package/dist/collection/components/bs-attachment/bs-attachment.js +4 -10
- package/dist/collection/components/bs-attachment-list/bs-attachment-list.js +1 -1
- package/dist/collection/components/bs-avatar/bs-avatar.cmp.test.js +54 -0
- package/dist/collection/components/bs-avatar/bs-avatar.css +197 -0
- package/dist/collection/components/bs-avatar/bs-avatar.js +251 -0
- package/dist/collection/components/bs-avatar/bs-avatar.stories.js +67 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumb/bs-breadcrumb.cmp.test.js +62 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumb/bs-breadcrumb.css +93 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumb/bs-breadcrumb.js +130 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumb-overflow/bs-breadcrumb-overflow.cmp.test.js +118 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumb-overflow/bs-breadcrumb-overflow.css +125 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumb-overflow/bs-breadcrumb-overflow.js +192 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumbs/bs-breadcrumbs.cmp.test.js +58 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumbs/bs-breadcrumbs.css +18 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumbs/bs-breadcrumbs.js +129 -0
- package/dist/collection/components/bs-breadcrumb/bs-breadcrumbs/bs-breadcrumbs.stories.js +84 -0
- package/dist/collection/components/bs-button/{bs-button.cmp.test.js → bs-button/bs-button.cmp.test.js} +26 -0
- package/dist/collection/components/bs-button/{bs-button.css → bs-button/bs-button.css} +57 -6
- package/dist/collection/components/bs-button/{bs-button.js → bs-button/bs-button.js} +10 -5
- package/dist/collection/components/bs-button/{bs-button.stories.js → bs-button/bs-button.stories.js} +2 -27
- package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.cmp.test.js +83 -0
- package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.css +346 -0
- package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.js +185 -0
- package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.stories.js +74 -0
- package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.js +3 -3
- package/dist/collection/components/bs-card/bs-card.cmp.test.js +19 -0
- package/dist/collection/components/bs-card/bs-card.css +37 -5
- package/dist/collection/components/bs-card/bs-card.js +18 -2
- package/dist/collection/components/bs-card/bs-card.stories.js +17 -1
- package/dist/collection/components/bs-chatbot-feedback/bs-chatbot-feedback.js +1 -1
- package/dist/collection/components/bs-chatbot-header/bs-chatbot-header.js +1 -1
- package/dist/collection/components/bs-chatbot-response-action/bs-chatbot-response-action.js +1 -1
- package/dist/collection/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.css +1 -1
- package/dist/collection/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.js +1 -1
- package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.js +1 -1
- package/dist/collection/components/bs-checkbox/bs-checkbox-skeleton/bs-checkbox-skeleton.cmp.test.js +23 -0
- package/dist/collection/components/bs-checkbox/bs-checkbox-skeleton/bs-checkbox-skeleton.css +64 -0
- package/dist/collection/components/bs-checkbox/bs-checkbox-skeleton/bs-checkbox-skeleton.js +81 -0
- package/dist/collection/components/bs-checkbox/bs-checkbox-skeleton/bs-checkbox-skeleton.stories.js +25 -0
- package/dist/collection/components/bs-checkbox/bs-checkbox.cmp.test.js +10 -0
- package/dist/collection/components/bs-checkbox/bs-checkbox.css +7 -1
- package/dist/collection/components/bs-checkbox/bs-checkbox.js +32 -1
- package/dist/collection/components/bs-checkbox/bs-checkbox.stories.js +12 -0
- package/dist/collection/components/bs-composer/bs-composer.cmp.test.js +48 -7
- package/dist/collection/components/bs-composer/bs-composer.css +15 -0
- package/dist/collection/components/bs-composer/bs-composer.js +38 -4
- package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.cmp.test.js +47 -1
- package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.js +20 -1
- package/dist/collection/components/bs-data-table/bs-data-table.js +2 -2
- package/dist/collection/components/{bs-modal/bs-modal.cmp.test.js → bs-dialog/bs-dialog.cmp.test.js} +63 -19
- package/dist/collection/components/bs-dialog/bs-dialog.css +130 -0
- package/dist/collection/components/bs-dialog/bs-dialog.js +273 -0
- package/dist/collection/components/bs-dialog/bs-dialog.stories.js +115 -0
- package/dist/collection/components/bs-input/bs-input.cmp.test.js +20 -0
- package/dist/collection/components/bs-input/bs-input.css +80 -2
- package/dist/collection/components/bs-input/bs-input.js +28 -10
- package/dist/collection/components/bs-input/bs-input.stories.js +14 -11
- package/dist/collection/components/bs-logo/brandsync-logo-full-dark.js +44 -0
- package/dist/collection/components/bs-logo/brandsync-logo-full-light.js +40 -0
- package/dist/collection/components/bs-logo/brandsync-logo-mark.js +17 -0
- package/dist/collection/components/bs-logo/bs-logo.cmp.test.js +113 -0
- package/dist/collection/components/bs-logo/bs-logo.css +79 -0
- package/dist/collection/components/bs-logo/bs-logo.js +193 -0
- package/dist/collection/components/bs-logo/bs-logo.stories.js +69 -0
- package/dist/collection/components/bs-menu/bs-menu.js +1 -1
- package/dist/collection/components/bs-menu-item/bs-menu-item.js +1 -1
- package/dist/collection/components/bs-pagination/bs-pagination.cmp.test.js +102 -0
- package/dist/collection/components/bs-pagination/bs-pagination.css +120 -0
- package/dist/collection/components/bs-pagination/bs-pagination.js +233 -0
- package/dist/collection/components/bs-pagination/bs-pagination.stories.js +43 -0
- package/dist/collection/components/bs-radio/bs-radio.cmp.test.js +76 -0
- package/dist/collection/components/bs-radio/bs-radio.css +164 -0
- package/dist/collection/components/bs-radio/bs-radio.js +170 -0
- package/dist/collection/components/bs-radio/bs-radio.stories.js +56 -0
- package/dist/collection/components/bs-slider/bs-slider.cmp.test.js +139 -0
- package/dist/collection/components/bs-slider/bs-slider.css +409 -0
- package/dist/collection/components/bs-slider/bs-slider.js +499 -0
- package/dist/collection/components/bs-slider/bs-slider.stories.js +70 -0
- package/dist/collection/components/bs-snackbar/bs-snackbar.cmp.test.js +77 -0
- package/dist/collection/components/bs-snackbar/bs-snackbar.css +321 -0
- package/dist/collection/components/bs-snackbar/bs-snackbar.js +172 -0
- package/dist/collection/components/bs-snackbar/bs-snackbar.stories.js +59 -0
- package/dist/collection/components/bs-source-link/bs-source-link.js +2 -2
- package/dist/collection/components/bs-switch/bs-switch.cmp.test.js +71 -0
- package/dist/collection/components/bs-switch/bs-switch.css +196 -0
- package/dist/collection/components/bs-switch/bs-switch.js +185 -0
- package/dist/collection/components/bs-switch/bs-switch.stories.js +60 -0
- package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.cmp.test.js +104 -0
- package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.css +163 -0
- package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.js +192 -0
- package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.stories.js +95 -0
- package/dist/collection/components/bs-tab/bs-tab/bs-tab.cmp.test.js +120 -0
- package/dist/collection/components/bs-tab/bs-tab/bs-tab.css +216 -0
- package/dist/collection/components/bs-tab/bs-tab/bs-tab.js +232 -0
- package/dist/collection/components/bs-tab/bs-tab/bs-tab.stories.js +138 -0
- package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.cmp.test.js +61 -0
- package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.css +39 -0
- package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.js +133 -0
- package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.stories.js +39 -0
- package/dist/collection/components/bs-tooltip/bs-tooltip.js +1 -1
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.cmp.test.js +143 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.css +257 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.js +281 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.stories.js +274 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.cmp.test.js +172 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.css +325 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.js +314 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.stories.js +78 -0
- package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.cmp.test.js +77 -0
- package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.css +106 -0
- package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.js +188 -0
- package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.stories.js +446 -0
- package/dist/components/bs-ai-disclaimer.js +1 -1
- package/dist/components/bs-ai-greeting.js +1 -1
- package/dist/components/bs-ai-thinking.js +1 -1
- package/dist/components/bs-attachment-list.js +1 -1
- package/dist/components/bs-attachment.js +1 -1
- package/dist/components/bs-avatar.d.ts +11 -0
- package/dist/components/bs-avatar.js +1 -0
- package/dist/components/bs-badge.js +1 -1
- package/dist/components/bs-breadcrumb-overflow.d.ts +11 -0
- package/dist/components/bs-breadcrumb-overflow.js +1 -0
- package/dist/components/bs-breadcrumb.d.ts +11 -0
- package/dist/components/bs-breadcrumb.js +1 -0
- package/dist/components/bs-breadcrumbs.d.ts +11 -0
- package/dist/components/bs-breadcrumbs.js +1 -0
- package/dist/components/bs-button-skeleton.js +1 -1
- package/dist/components/bs-button.js +1 -1
- package/dist/components/bs-card.js +1 -1
- package/dist/components/bs-chatbot-feedback.js +1 -1
- package/dist/components/bs-chatbot-header.js +1 -1
- package/dist/components/bs-chatbot-response-action.js +1 -1
- package/dist/components/bs-chatbot-sources-drawer.js +1 -1
- package/dist/components/bs-chatbot-suggestion-button.js +1 -1
- package/dist/components/bs-checkbox-skeleton.d.ts +11 -0
- package/dist/components/bs-checkbox-skeleton.js +1 -0
- package/dist/components/bs-checkbox.js +1 -1
- package/dist/components/bs-composer-status-banner.js +1 -1
- package/dist/components/bs-composer.js +1 -1
- package/dist/components/bs-data-table.js +1 -1
- package/dist/components/bs-dialog.d.ts +11 -0
- package/dist/components/bs-dialog.js +1 -0
- package/dist/components/bs-icon-button.d.ts +11 -0
- package/dist/components/bs-icon-button.js +1 -0
- package/dist/components/bs-inline-tab.d.ts +11 -0
- package/dist/components/bs-inline-tab.js +1 -0
- package/dist/components/bs-input.js +1 -1
- package/dist/components/{bs-modal.d.ts → bs-logo.d.ts} +4 -4
- package/dist/components/bs-logo.js +1 -0
- package/dist/components/bs-menu-item.js +1 -1
- package/dist/components/bs-menu.js +1 -1
- package/dist/components/bs-navigation-drawer-item.d.ts +11 -0
- package/dist/components/bs-navigation-drawer-item.js +1 -0
- package/dist/components/bs-navigation-drawer.d.ts +11 -0
- package/dist/components/bs-navigation-drawer.js +1 -0
- package/dist/components/bs-navigation-header.d.ts +11 -0
- package/dist/components/bs-navigation-header.js +1 -0
- package/dist/components/bs-pagination.d.ts +11 -0
- package/dist/components/bs-pagination.js +1 -0
- package/dist/components/bs-radio.d.ts +11 -0
- package/dist/components/bs-radio.js +1 -0
- package/dist/components/bs-slider.d.ts +11 -0
- package/dist/components/bs-slider.js +1 -0
- package/dist/components/bs-snackbar.d.ts +11 -0
- package/dist/components/bs-snackbar.js +1 -0
- package/dist/components/bs-source-link.js +1 -1
- package/dist/components/bs-switch.d.ts +11 -0
- package/dist/components/bs-switch.js +1 -0
- package/dist/components/bs-tab.d.ts +11 -0
- package/dist/components/bs-tab.js +1 -0
- package/dist/components/bs-tabs.d.ts +11 -0
- package/dist/components/bs-tabs.js +1 -0
- package/dist/components/bs-tooltip.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/p-BFcVSpES.js +1 -0
- package/dist/components/{p-D1cYtKyN.js → p-BJZYe7M4.js} +1 -1
- package/dist/components/p-BKaZWFE1.js +1 -0
- package/dist/components/{p-BUbGEXL7.js → p-BtX5URLk.js} +1 -1
- package/dist/components/{p-B9PrXIl_.js → p-CgaPcyEJ.js} +1 -1
- package/dist/components/{p-D2HDHZjz.js → p-qK1XlpTA.js} +1 -1
- package/dist/esm/brandsync-wc.js +3 -3
- package/dist/esm/bs-ai-disclaimer.entry.js +3 -2
- package/dist/esm/bs-ai-greeting.entry.js +2 -2
- package/dist/esm/bs-ai-thinking.entry.js +2 -2
- package/dist/esm/bs-attachment-list.entry.js +2 -2
- package/dist/esm/bs-attachment.entry.js +3 -3
- package/dist/esm/bs-avatar.entry.js +58 -0
- package/dist/esm/bs-badge.entry.js +1 -1
- package/dist/esm/bs-breadcrumb-overflow.entry.js +54 -0
- package/dist/esm/bs-breadcrumb.entry.js +31 -0
- package/dist/esm/bs-breadcrumbs.entry.js +47 -0
- package/dist/esm/bs-button-skeleton.entry.js +2 -2
- package/dist/esm/bs-button.entry.js +3 -3
- package/dist/esm/bs-card.entry.js +10 -3
- package/dist/esm/bs-chatbot-feedback.entry.js +2 -2
- package/dist/esm/bs-chatbot-header.entry.js +2 -2
- package/dist/esm/bs-chatbot-response-action.entry.js +2 -2
- package/dist/esm/bs-chatbot-sources-drawer.entry.js +2 -2
- package/dist/esm/bs-chatbot-suggestion-button.entry.js +2 -2
- package/dist/esm/bs-checkbox-skeleton.entry.js +18 -0
- package/dist/esm/bs-checkbox.entry.js +14 -3
- package/dist/esm/bs-composer-status-banner.entry.js +14 -2
- package/dist/esm/bs-composer.entry.js +37 -4
- package/dist/esm/bs-data-table.entry.js +3 -3
- package/dist/esm/bs-dialog.entry.js +108 -0
- package/dist/esm/bs-icon-button.entry.js +38 -0
- package/dist/esm/bs-inline-tab.entry.js +67 -0
- package/dist/esm/bs-input.entry.js +24 -12
- package/dist/esm/bs-logo.entry.js +163 -0
- package/dist/esm/{bs-menu_2.entry.js → bs-menu-item.entry.js} +3 -15
- package/dist/esm/bs-menu.entry.js +15 -0
- package/dist/esm/bs-navigation-drawer-item.entry.js +102 -0
- package/dist/esm/bs-navigation-drawer.entry.js +85 -0
- package/dist/esm/bs-navigation-header.entry.js +42 -0
- package/dist/esm/bs-pagination.entry.js +83 -0
- package/dist/esm/bs-radio.entry.js +47 -0
- package/dist/esm/bs-slider.entry.js +189 -0
- package/dist/esm/bs-snackbar.entry.js +39 -0
- package/dist/esm/bs-source-link.entry.js +3 -3
- package/dist/esm/bs-switch.entry.js +55 -0
- package/dist/esm/bs-tab.entry.js +78 -0
- package/dist/esm/bs-tabs.entry.js +37 -0
- package/dist/esm/bs-tooltip.entry.js +2 -2
- package/dist/esm/{index-DP_bvuvB.js → index-Do3l4of3.js} +2 -2
- package/dist/esm/loader.js +3 -3
- package/dist/types/components/bs-attachment/bs-attachment.d.ts +3 -9
- package/dist/types/components/bs-avatar/bs-avatar.d.ts +67 -0
- package/dist/types/components/bs-avatar/bs-avatar.stories.d.ts +20 -0
- package/dist/types/components/bs-breadcrumb/bs-breadcrumb/bs-breadcrumb.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-breadcrumb/bs-breadcrumb/bs-breadcrumb.d.ts +44 -0
- package/dist/types/components/bs-breadcrumb/bs-breadcrumb-overflow/bs-breadcrumb-overflow.d.ts +69 -0
- package/dist/types/components/bs-breadcrumb/bs-breadcrumbs/bs-breadcrumbs.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-breadcrumb/bs-breadcrumbs/bs-breadcrumbs.d.ts +45 -0
- package/dist/types/components/bs-breadcrumb/bs-breadcrumbs/bs-breadcrumbs.stories.d.ts +14 -0
- package/dist/types/components/bs-button/bs-button/bs-button.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-button/{bs-button.d.ts → bs-button/bs-button.d.ts} +5 -0
- package/dist/types/components/bs-button/{bs-button.stories.d.ts → bs-button/bs-button.stories.d.ts} +0 -2
- package/dist/types/components/bs-button/bs-icon-button/bs-icon-button.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-button/bs-icon-button/bs-icon-button.d.ts +51 -0
- package/dist/types/components/bs-button/bs-icon-button/bs-icon-button.stories.d.ts +16 -0
- package/dist/types/components/bs-button-skeleton/bs-button-skeleton.d.ts +1 -1
- package/dist/types/components/bs-button-skeleton/bs-button-skeleton.stories.d.ts +1 -1
- package/dist/types/components/bs-card/bs-card.d.ts +10 -1
- package/dist/types/components/bs-card/bs-card.stories.d.ts +1 -0
- package/dist/types/components/bs-checkbox/bs-checkbox-skeleton/bs-checkbox-skeleton.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-checkbox/bs-checkbox-skeleton/bs-checkbox-skeleton.d.ts +36 -0
- package/dist/types/components/bs-checkbox/bs-checkbox-skeleton/bs-checkbox-skeleton.stories.d.ts +10 -0
- package/dist/types/components/bs-checkbox/bs-checkbox.d.ts +11 -0
- package/dist/types/components/bs-checkbox/bs-checkbox.stories.d.ts +1 -0
- package/dist/types/components/bs-composer/bs-composer.d.ts +26 -2
- package/dist/types/components/bs-composer-status-banner/bs-composer-status-banner.d.ts +14 -0
- package/dist/types/components/bs-dialog/bs-dialog.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-dialog/bs-dialog.d.ts +74 -0
- package/dist/types/components/{bs-modal/bs-modal.stories.d.ts → bs-dialog/bs-dialog.stories.d.ts} +5 -3
- package/dist/types/components/bs-input/bs-input.d.ts +8 -1
- package/dist/types/components/bs-logo/brandsync-logo-full-dark.d.ts +1 -0
- package/dist/types/components/bs-logo/brandsync-logo-full-light.d.ts +1 -0
- package/dist/types/components/bs-logo/brandsync-logo-mark.d.ts +1 -0
- package/dist/types/components/bs-logo/bs-logo.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-logo/bs-logo.d.ts +73 -0
- package/dist/types/components/bs-logo/bs-logo.stories.d.ts +17 -0
- package/dist/types/components/bs-pagination/bs-pagination.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-pagination/bs-pagination.d.ts +51 -0
- package/dist/types/components/bs-pagination/bs-pagination.stories.d.ts +14 -0
- package/dist/types/components/bs-radio/bs-radio.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-radio/bs-radio.d.ts +45 -0
- package/dist/types/components/bs-radio/bs-radio.stories.d.ts +16 -0
- package/dist/types/components/bs-slider/bs-slider.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-slider/bs-slider.d.ts +109 -0
- package/dist/types/components/bs-slider/bs-slider.stories.d.ts +24 -0
- package/dist/types/components/bs-snackbar/bs-snackbar.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-snackbar/bs-snackbar.d.ts +51 -0
- package/dist/types/components/bs-snackbar/bs-snackbar.stories.d.ts +16 -0
- package/dist/types/components/bs-switch/bs-switch.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-switch/bs-switch.d.ts +45 -0
- package/dist/types/components/bs-switch/bs-switch.stories.d.ts +17 -0
- package/dist/types/components/bs-tab/bs-inline-tab/bs-inline-tab.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-tab/bs-inline-tab/bs-inline-tab.d.ts +65 -0
- package/dist/types/components/bs-tab/bs-inline-tab/bs-inline-tab.stories.d.ts +22 -0
- package/dist/types/components/bs-tab/bs-tab/bs-tab.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-tab/bs-tab/bs-tab.d.ts +74 -0
- package/dist/types/components/bs-tab/bs-tab/bs-tab.stories.d.ts +30 -0
- package/dist/types/components/bs-tab/bs-tabs/bs-tabs.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-tab/bs-tabs/bs-tabs.d.ts +45 -0
- package/dist/types/components/bs-tab/bs-tabs/bs-tabs.stories.d.ts +13 -0
- package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.cmp.test.d.ts +1 -0
- package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.d.ts +104 -0
- package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.stories.d.ts +19 -0
- package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.cmp.test.d.ts +1 -0
- package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.d.ts +103 -0
- package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.stories.d.ts +20 -0
- package/dist/types/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.cmp.test.d.ts +1 -0
- package/dist/types/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.d.ts +60 -0
- package/dist/types/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.stories.d.ts +25 -0
- package/dist/types/components.d.ts +2908 -114
- package/package.json +1 -1
- package/dist/brandsync-wc/p-2598ca88.entry.js +0 -1
- package/dist/brandsync-wc/p-3dd9b814.entry.js +0 -1
- package/dist/brandsync-wc/p-41edb0a2.entry.js +0 -1
- package/dist/brandsync-wc/p-6254dcbe.entry.js +0 -1
- package/dist/brandsync-wc/p-7131d0a1.entry.js +0 -1
- package/dist/brandsync-wc/p-8c302968.entry.js +0 -1
- package/dist/brandsync-wc/p-8d78171b.entry.js +0 -1
- package/dist/brandsync-wc/p-93e44903.entry.js +0 -1
- package/dist/brandsync-wc/p-aa45d877.entry.js +0 -1
- package/dist/cjs/bs-modal.cjs.entry.js +0 -69
- package/dist/collection/components/bs-modal/bs-modal.css +0 -66
- package/dist/collection/components/bs-modal/bs-modal.js +0 -198
- package/dist/collection/components/bs-modal/bs-modal.stories.js +0 -38
- package/dist/components/bs-modal.js +0 -1
- package/dist/esm/bs-modal.entry.js +0 -67
- package/dist/types/components/bs-modal/bs-modal.d.ts +0 -45
- /package/dist/types/components/{bs-button/bs-button.cmp.test.d.ts → bs-avatar/bs-avatar.cmp.test.d.ts} +0 -0
- /package/dist/types/components/{bs-modal/bs-modal.cmp.test.d.ts → bs-breadcrumb/bs-breadcrumb-overflow/bs-breadcrumb-overflow.cmp.test.d.ts} +0 -0
|
@@ -2,7 +2,7 @@ import { render, h, describe, it, expect } from "@stencil/vitest";
|
|
|
2
2
|
describe('bs-composer', () => {
|
|
3
3
|
it('renders with idle state defaults: ai variant placeholder, enabled mic/action buttons', async () => {
|
|
4
4
|
const { root } = await render(h("bs-composer", null));
|
|
5
|
-
const input = root.shadowRoot.querySelector('
|
|
5
|
+
const input = root.shadowRoot.querySelector('textarea');
|
|
6
6
|
expect(input).toEqualAttribute('placeholder', 'Ask Genie something...');
|
|
7
7
|
expect(input).not.toHaveAttribute('disabled');
|
|
8
8
|
const mic = root.shadowRoot.querySelector('[part="mic"]');
|
|
@@ -13,22 +13,22 @@ describe('bs-composer', () => {
|
|
|
13
13
|
});
|
|
14
14
|
it('uses the human variant default placeholder', async () => {
|
|
15
15
|
const { root } = await render(h("bs-composer", { variant: "human" }));
|
|
16
|
-
const input = root.shadowRoot.querySelector('
|
|
16
|
+
const input = root.shadowRoot.querySelector('textarea');
|
|
17
17
|
expect(input).toEqualAttribute('placeholder', 'Message your support agent...');
|
|
18
18
|
});
|
|
19
19
|
it('overrides the variant default placeholder when placeholder is set', async () => {
|
|
20
20
|
const { root } = await render(h("bs-composer", { variant: "ai", placeholder: "Custom prompt" }));
|
|
21
|
-
const input = root.shadowRoot.querySelector('
|
|
21
|
+
const input = root.shadowRoot.querySelector('textarea');
|
|
22
22
|
expect(input).toEqualAttribute('placeholder', 'Custom prompt');
|
|
23
23
|
});
|
|
24
24
|
it('reflects the value prop to the native input', async () => {
|
|
25
25
|
const { root } = await render(h("bs-composer", { value: "hello there" }));
|
|
26
|
-
const input = root.shadowRoot.querySelector('
|
|
26
|
+
const input = root.shadowRoot.querySelector('textarea');
|
|
27
27
|
expect(input.value).toBe('hello there');
|
|
28
28
|
});
|
|
29
29
|
it('sets aria-label on the input from the ariaLabel prop', async () => {
|
|
30
30
|
const { root } = await render(h("bs-composer", { ariaLabel: "Message" }));
|
|
31
|
-
const input = root.shadowRoot.querySelector('
|
|
31
|
+
const input = root.shadowRoot.querySelector('textarea');
|
|
32
32
|
expect(input).toEqualAttribute('aria-label', 'Message');
|
|
33
33
|
});
|
|
34
34
|
it('renders consumer-supplied content in the actions-end slot, after the primary action button', async () => {
|
|
@@ -59,12 +59,53 @@ describe('bs-composer', () => {
|
|
|
59
59
|
it('emits bsInput with the current value as the user types', async () => {
|
|
60
60
|
const { root, spyOnEvent } = await render(h("bs-composer", null));
|
|
61
61
|
const spy = spyOnEvent('bsInput');
|
|
62
|
-
const input = root.shadowRoot.querySelector('
|
|
62
|
+
const input = root.shadowRoot.querySelector('textarea');
|
|
63
63
|
input.value = 'a';
|
|
64
64
|
input.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
65
65
|
expect(spy).toHaveReceivedEventTimes(1);
|
|
66
66
|
expect(spy).toHaveReceivedEventDetail('a');
|
|
67
67
|
});
|
|
68
|
+
describe('auto-grow', () => {
|
|
69
|
+
it('grows taller as multi-line content is typed', async () => {
|
|
70
|
+
const { root } = await render(h("bs-composer", null));
|
|
71
|
+
const textarea = root.shadowRoot.querySelector('textarea');
|
|
72
|
+
const oneLineHeight = textarea.getBoundingClientRect().height;
|
|
73
|
+
textarea.value = 'line one\nline two\nline three';
|
|
74
|
+
textarea.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
75
|
+
const threeLineHeight = textarea.getBoundingClientRect().height;
|
|
76
|
+
expect(threeLineHeight).toBeGreaterThan(oneLineHeight);
|
|
77
|
+
});
|
|
78
|
+
it('caps growth at --bs-composer-input-max-lines and scrolls internally beyond that', async () => {
|
|
79
|
+
const { root } = await render(h("bs-composer", null));
|
|
80
|
+
const textarea = root.shadowRoot.querySelector('textarea');
|
|
81
|
+
const lineHeight = textarea.getBoundingClientRect().height;
|
|
82
|
+
const fifteenLines = Array.from({ length: 15 }, (_, i) => `line ${i}`).join('\n');
|
|
83
|
+
textarea.value = fifteenLines;
|
|
84
|
+
textarea.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
85
|
+
const cappedHeight = textarea.getBoundingClientRect().height;
|
|
86
|
+
// 10 lines' worth of height, not 15 -- the default max-lines is 10 (see bs-composer.css).
|
|
87
|
+
expect(cappedHeight).toBeCloseTo(lineHeight * 10, 0);
|
|
88
|
+
expect(textarea.scrollHeight).toBeGreaterThan(textarea.clientHeight);
|
|
89
|
+
});
|
|
90
|
+
it('resizes to fit an initial multi-line value prop, not just user typing', async () => {
|
|
91
|
+
// Measure each render's height before the other render() call runs -- a second render() in
|
|
92
|
+
// the same test can detach the first instance from the layout tree, which would make its
|
|
93
|
+
// getBoundingClientRect() report 0 rather than its real (but by-then-detached) height.
|
|
94
|
+
const single = await render(h("bs-composer", { value: "one line" }));
|
|
95
|
+
const singleLineHeight = single.root.shadowRoot.querySelector('textarea').getBoundingClientRect().height;
|
|
96
|
+
const multi = await render(h("bs-composer", { value: 'line one\nline two\nline three' }));
|
|
97
|
+
const multiLineHeight = multi.root.shadowRoot.querySelector('textarea').getBoundingClientRect().height;
|
|
98
|
+
expect(multiLineHeight).toBeGreaterThan(singleLineHeight);
|
|
99
|
+
});
|
|
100
|
+
it('re-runs the resize when the value prop is updated programmatically (not via typing)', async () => {
|
|
101
|
+
const { root, setProps, waitForChanges } = await render(h("bs-composer", { value: "one line" }));
|
|
102
|
+
const textarea = root.shadowRoot.querySelector('textarea');
|
|
103
|
+
const oneLineHeight = textarea.getBoundingClientRect().height;
|
|
104
|
+
await setProps({ value: 'line one\nline two\nline three\nline four' });
|
|
105
|
+
await waitForChanges();
|
|
106
|
+
expect(textarea.getBoundingClientRect().height).toBeGreaterThan(oneLineHeight);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
68
109
|
it('emits bsAttach when the attach button is clicked', async () => {
|
|
69
110
|
const { root, spyOnEvent } = await render(h("bs-composer", null));
|
|
70
111
|
const spy = spyOnEvent('bsAttach');
|
|
@@ -107,7 +148,7 @@ describe('bs-composer', () => {
|
|
|
107
148
|
describe('state="disabled"', () => {
|
|
108
149
|
it('natively disables both the mic and action buttons and the text input', async () => {
|
|
109
150
|
const { root } = await render(h("bs-composer", { state: "disabled" }));
|
|
110
|
-
expect(root.shadowRoot.querySelector('
|
|
151
|
+
expect(root.shadowRoot.querySelector('textarea')).toHaveAttribute('disabled');
|
|
111
152
|
expect(root.shadowRoot.querySelector('[part="mic"]')).toHaveAttribute('disabled');
|
|
112
153
|
expect(root.shadowRoot.querySelector('[part="action"]')).toHaveAttribute('disabled');
|
|
113
154
|
});
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
--bs-composer-subtle-pressed: var(--bs-color-neutral-container-pressed);
|
|
23
23
|
|
|
24
24
|
--bs-composer-waveform-color: var(--bs-border-default);
|
|
25
|
+
|
|
26
|
+
--bs-composer-input-max-lines: 10;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
.bs-composer {
|
|
@@ -62,12 +64,25 @@
|
|
|
62
64
|
.bs-composer__input {
|
|
63
65
|
flex: 1;
|
|
64
66
|
min-width: 0;
|
|
67
|
+
box-sizing: border-box;
|
|
68
|
+
/* Browsers apply their own default padding to <textarea> (Chromium: 2px) -- zero it out so the
|
|
69
|
+
auto-grow height math (line-height * number of lines) isn't thrown off by unaccounted-for
|
|
70
|
+
padding. */
|
|
71
|
+
padding: 0;
|
|
65
72
|
border: none;
|
|
66
73
|
outline: none;
|
|
74
|
+
resize: none;
|
|
67
75
|
background: transparent;
|
|
68
76
|
color: var(--bs-input-text);
|
|
69
77
|
font-family: inherit;
|
|
70
78
|
font-size: var(--bs-font-size-md);
|
|
79
|
+
/* Explicit, not the textarea's default line-height -- the auto-grow max-height below is computed
|
|
80
|
+
in terms of this exact value times --bs-composer-input-max-lines, so it has to be pinned down. */
|
|
81
|
+
line-height: calc(var(--bs-line-height-body-md) * 1px);
|
|
82
|
+
/* Grows with content (see bs-composer.tsx's resizeInput) up to this many lines' worth of height,
|
|
83
|
+
then scrolls internally instead of growing the whole composer further. */
|
|
84
|
+
max-height: calc(var(--bs-composer-input-max-lines) * var(--bs-line-height-body-md) * 1px);
|
|
85
|
+
overflow-y: auto;
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
.bs-composer__input::placeholder {
|
|
@@ -37,7 +37,7 @@ const WAVEFORM_BAR_HEIGHTS = [
|
|
|
37
37
|
* roughly match `--bs-composer-button-size` to align visually.
|
|
38
38
|
* @part attachments - The wrapper around the `attachments` slot.
|
|
39
39
|
* @part attach - The "+" attach button.
|
|
40
|
-
* @part input - The native text `<
|
|
40
|
+
* @part input - The native text `<textarea>`.
|
|
41
41
|
* @part mic - The secondary icon button (microphone, or the stop-recording square while `state="recording"`).
|
|
42
42
|
* @part action - The primary circular action button (send, stop, or confirm depending on `state`).
|
|
43
43
|
* @prop --bs-composer-radius - Corner radius of the container. Aliased to `--bs-border-radius-150`.
|
|
@@ -57,9 +57,11 @@ const WAVEFORM_BAR_HEIGHTS = [
|
|
|
57
57
|
* @prop --bs-composer-mic-icon-disabled - Aliased to `--bs-icon-disabled`.
|
|
58
58
|
* @prop --bs-composer-subtle-hover - Background of the attach/mic buttons on hover (subtle-button treatment, same as `bs-button`'s `subtle` variant). Aliased to `--bs-color-neutral-container`.
|
|
59
59
|
* @prop --bs-composer-subtle-pressed - Background of the attach/mic buttons when pressed. Aliased to `--bs-color-neutral-container-pressed`.
|
|
60
|
+
* @prop --bs-composer-input-max-lines - How many lines the text field grows to before scrolling internally instead of growing further. Aliased to `10`.
|
|
60
61
|
*/
|
|
61
62
|
export class BsComposer {
|
|
62
63
|
el;
|
|
64
|
+
inputEl;
|
|
63
65
|
/**
|
|
64
66
|
* Which flavor of composer this is: changes the *default* placeholder text (set `placeholder`
|
|
65
67
|
* directly to override it) and, per the Figma design, renders the container border dashed
|
|
@@ -70,7 +72,12 @@ export class BsComposer {
|
|
|
70
72
|
/** Overrides the variant's default placeholder. */
|
|
71
73
|
placeholder;
|
|
72
74
|
/** Current text value. Native `input` events don't cross the Shadow DOM boundary, so this
|
|
73
|
-
* component re-dispatches them as a `bsInput` custom event instead.
|
|
75
|
+
* component re-dispatches them as a `bsInput` custom event instead.
|
|
76
|
+
*
|
|
77
|
+
* The field is a `<textarea>` (not a single-line `<input>`) that grows with its content, up to
|
|
78
|
+
* `--bs-composer-input-max-lines` (10 by default) -- beyond that it scrolls internally instead
|
|
79
|
+
* of growing further. Setting `value` as a prop (not just typing) also re-triggers the resize,
|
|
80
|
+
* so e.g. programmatically clearing the field after submit correctly shrinks it back down. */
|
|
74
81
|
value = '';
|
|
75
82
|
/**
|
|
76
83
|
* Which of the four mutually-exclusive composer states to render: `idle` (send, enabled),
|
|
@@ -107,11 +114,38 @@ export class BsComposer {
|
|
|
107
114
|
componentWillLoad() {
|
|
108
115
|
this.hasAttachments = Array.from(this.el.childNodes).some(node => node.nodeType === Node.ELEMENT_NODE && node.getAttribute('slot') === 'attachments');
|
|
109
116
|
}
|
|
117
|
+
componentDidLoad() {
|
|
118
|
+
this.resizeInput();
|
|
119
|
+
}
|
|
120
|
+
/** Re-runs the auto-grow calculation after every re-render -- notably including a `value` prop
|
|
121
|
+
* change from the outside (e.g. a consumer clearing the field after submit, or pre-filling it),
|
|
122
|
+
* not just while the user is typing. This has to be `componentDidUpdate`, not a `@Watch('value')`
|
|
123
|
+
* callback: `@Watch` fires as soon as the prop is reassigned, which is BEFORE Stencil's next
|
|
124
|
+
* render actually pushes the new value into the textarea's DOM `.value` -- reading `scrollHeight`
|
|
125
|
+
* at that point still reflects the OLD content, so the resize would silently no-op. */
|
|
126
|
+
componentDidUpdate() {
|
|
127
|
+
this.resizeInput();
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Grows the textarea to fit its content, up to `--bs-composer-input-max-lines` worth of height
|
|
131
|
+
* (CSS `max-height` clamps the visual result and `overflow-y: auto` takes over beyond that --
|
|
132
|
+
* see bs-composer.css). Resetting `height` to `auto` first is required before reading
|
|
133
|
+
* `scrollHeight`, otherwise a shrinking edit (e.g. deleting a line) would never shrink the
|
|
134
|
+
* textarea back down -- `scrollHeight` only ever reports the larger of "current height" and
|
|
135
|
+
* "content height" if the height isn't cleared first.
|
|
136
|
+
*/
|
|
137
|
+
resizeInput() {
|
|
138
|
+
if (!this.inputEl)
|
|
139
|
+
return;
|
|
140
|
+
this.inputEl.style.height = 'auto';
|
|
141
|
+
this.inputEl.style.height = `${this.inputEl.scrollHeight}px`;
|
|
142
|
+
}
|
|
110
143
|
onAttachmentsSlotchange = (ev) => {
|
|
111
144
|
this.hasAttachments = ev.target.assignedNodes().length > 0;
|
|
112
145
|
};
|
|
113
146
|
onInput = (ev) => {
|
|
114
147
|
const value = ev.target.value;
|
|
148
|
+
this.resizeInput();
|
|
115
149
|
this.bsInput.emit(value);
|
|
116
150
|
};
|
|
117
151
|
onAttachClick = () => {
|
|
@@ -149,7 +183,7 @@ export class BsComposer {
|
|
|
149
183
|
const placeholder = this.placeholder ?? DEFAULT_PLACEHOLDERS[this.variant];
|
|
150
184
|
const disabled = this.state === 'disabled';
|
|
151
185
|
const recording = this.state === 'recording';
|
|
152
|
-
return (h("div", { key: '
|
|
186
|
+
return (h("div", { key: 'ee8e0a250798b3b5f9da6acde497779581c3b9ca', class: `bs-composer bs-composer--${this.state} bs-composer--${this.variant}` }, h("div", { key: 'fe37e3bd240379513c97022b77635121ae100826', part: "attachments", class: `bs-composer__attachments-row ${this.hasAttachments ? 'bs-composer__attachments-row--visible' : ''}` }, h("slot", { key: 'c6237cef8ebf742d6a68d513bd4366226317ec43', name: "attachments", onSlotchange: this.onAttachmentsSlotchange })), h("div", { key: 'e88d294aba83e6a4c11f35095ae4efd58aeb9586', class: "bs-composer__text-row" }, h("textarea", { key: 'c6a123b0134e74fed67ec590a7ee9c0eaa238318', ref: el => (this.inputEl = el), part: "input", class: "bs-composer__input", rows: 1, value: this.value, placeholder: placeholder, disabled: disabled, "aria-label": this.ariaLabel, onInput: this.onInput })), h("div", { key: 'aab617b78bfd3bcd33d43f08669f6f1688238388', class: "bs-composer__controls-row" }, h("button", { key: 'db8147a8841c08786c725052fdbaa366718c9a2e', type: "button", part: "attach", class: "bs-composer__attach", "aria-label": "Attach", onClick: this.onAttachClick }, h(PlusIcon, { key: 'cc13f52bfc496bd2a530012917b098fe10dff27b' })), recording ? (h("span", { class: "bs-composer__waveform", "aria-hidden": "true" }, WAVEFORM_BAR_HEIGHTS.map(height => (h("span", { class: "bs-composer__waveform-bar", style: { '--bs-composer-bar-height': `${height}px` } }))))) : (h("span", { class: "bs-composer__spacer" })), h("button", { key: '372d2751ea5dab5793314aa4469ef80ab28536a5', type: "button", part: "mic", class: `bs-composer__mic ${recording ? 'bs-composer__mic--recording' : ''}`, "aria-label": recording ? 'Stop recording' : 'Start voice input', disabled: disabled, onClick: this.onMicClick }, recording ? h(StopIcon, null) : h(MicIcon, null)), h("button", { key: '4694605f9e970097290d0eabbc1d4815c3b3bfe2', type: "button", part: "action", class: `bs-composer__action bs-composer__action--${this.state}`, "aria-label": this.actionLabel(), disabled: disabled, onClick: this.onActionClick }, this.renderActionIcon()), h("slot", { key: '71976baf242f384a2c69ef8561dda47d0a3739ae', name: "actions-end" }))));
|
|
153
187
|
}
|
|
154
188
|
static get is() { return "bs-composer"; }
|
|
155
189
|
static get encapsulation() { return "shadow"; }
|
|
@@ -223,7 +257,7 @@ export class BsComposer {
|
|
|
223
257
|
"optional": false,
|
|
224
258
|
"docs": {
|
|
225
259
|
"tags": [],
|
|
226
|
-
"text": "Current text value. Native `input` events don't cross the Shadow DOM boundary, so this\ncomponent re-dispatches them as a `bsInput` custom event instead."
|
|
260
|
+
"text": "Current text value. Native `input` events don't cross the Shadow DOM boundary, so this\ncomponent re-dispatches them as a `bsInput` custom event instead.\n\nThe field is a `<textarea>` (not a single-line `<input>`) that grows with its content, up to\n`--bs-composer-input-max-lines` (10 by default) -- beyond that it scrolls internally instead\nof growing further. Setting `value` as a prop (not just typing) also re-triggers the resize,\nso e.g. programmatically clearing the field after submit correctly shrinks it back down."
|
|
227
261
|
},
|
|
228
262
|
"getter": false,
|
|
229
263
|
"setter": false,
|
package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.cmp.test.js
CHANGED
|
@@ -1,10 +1,56 @@
|
|
|
1
1
|
import { render, h, describe, it, expect } from "@stencil/vitest";
|
|
2
2
|
describe('bs-composer-status-banner', () => {
|
|
3
|
-
it('renders the message and a default
|
|
3
|
+
it('renders the message and a default icon', async () => {
|
|
4
4
|
const { root } = await render(h("bs-composer-status-banner", { message: "Something went wrong" }));
|
|
5
5
|
expect(root).toHaveTextContent('Something went wrong');
|
|
6
6
|
expect(root.shadowRoot.querySelector('[part="icon"] svg')).not.toBeNull();
|
|
7
7
|
});
|
|
8
|
+
describe('accessibility', () => {
|
|
9
|
+
it('sets role="alert" for type="error" (the default)', async () => {
|
|
10
|
+
const { root } = await render(h("bs-composer-status-banner", null));
|
|
11
|
+
expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'alert');
|
|
12
|
+
});
|
|
13
|
+
it('sets role="alert" for type="warning"', async () => {
|
|
14
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "warning" }));
|
|
15
|
+
expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'alert');
|
|
16
|
+
});
|
|
17
|
+
it('sets role="status" for type="info"', async () => {
|
|
18
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "info" }));
|
|
19
|
+
expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'status');
|
|
20
|
+
});
|
|
21
|
+
it('sets role="status" for type="neutral"', async () => {
|
|
22
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "neutral" }));
|
|
23
|
+
expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'status');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('default icon per type', () => {
|
|
27
|
+
it('shows the warning-triangle icon for type="error"', async () => {
|
|
28
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "error" }));
|
|
29
|
+
const svg = root.shadowRoot.querySelector('[part="icon"] svg');
|
|
30
|
+
expect(svg.querySelector('circle[r="0.75"]')).not.toBeNull();
|
|
31
|
+
});
|
|
32
|
+
it('shows the warning-triangle icon for type="warning"', async () => {
|
|
33
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "warning" }));
|
|
34
|
+
const svg = root.shadowRoot.querySelector('[part="icon"] svg');
|
|
35
|
+
expect(svg.querySelector('circle[r="0.75"]')).not.toBeNull();
|
|
36
|
+
});
|
|
37
|
+
it('shows the clock icon for type="info"', async () => {
|
|
38
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "info" }));
|
|
39
|
+
const svg = root.shadowRoot.querySelector('[part="icon"] svg');
|
|
40
|
+
expect(svg.querySelector('circle[r="7.25"]')).not.toBeNull();
|
|
41
|
+
});
|
|
42
|
+
it('shows the clock icon for type="neutral"', async () => {
|
|
43
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "neutral" }));
|
|
44
|
+
const svg = root.shadowRoot.querySelector('[part="icon"] svg');
|
|
45
|
+
expect(svg.querySelector('circle[r="7.25"]')).not.toBeNull();
|
|
46
|
+
});
|
|
47
|
+
it('a slotted icon still overrides the type-based default', async () => {
|
|
48
|
+
const { root } = await render(h("bs-composer-status-banner", { type: "error" }, h("svg", { slot: "icon", class: "custom-icon" })));
|
|
49
|
+
const slot = root.shadowRoot.querySelector('slot[name="icon"]');
|
|
50
|
+
expect(slot.assignedElements()).toHaveLength(1);
|
|
51
|
+
expect(slot.assignedElements()[0]).toHaveClass('custom-icon');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
8
54
|
it('does not render the icon when showIcon is false', async () => {
|
|
9
55
|
const { root } = await render(h("bs-composer-status-banner", { showIcon: false }));
|
|
10
56
|
expect(root.shadowRoot.querySelector('[part="icon"]')).toBeNull();
|
|
@@ -13,6 +13,13 @@ import { h } from "@stencil/core";
|
|
|
13
13
|
* - A toast/snackbar notification unrelated to the composer -- this component is not
|
|
14
14
|
* self-dismissing and has no positioning of its own (it's a static block, not an overlay).
|
|
15
15
|
*
|
|
16
|
+
* ## Accessibility
|
|
17
|
+
* Sets `role="status"` for `type="info"`/`type="neutral"` and `role="alert"` for
|
|
18
|
+
* `type="error"`/`type="warning"` on its own root element automatically -- no opt-in prop needed.
|
|
19
|
+
* Both roles carry implicit ARIA live-region semantics (`status` is polite, `alert` is assertive),
|
|
20
|
+
* so a screen reader announces the message as soon as this banner is inserted into the DOM,
|
|
21
|
+
* without a consumer having to remember to add `role`/`aria-live` themselves.
|
|
22
|
+
*
|
|
16
23
|
* @slot icon - Overrides the default leading icon. Only rendered when `showIcon` is true.
|
|
17
24
|
* @part icon - The leading icon wrapper.
|
|
18
25
|
* @part message - The message text.
|
|
@@ -87,8 +94,19 @@ export class BsComposerStatusBanner {
|
|
|
87
94
|
onCloseClick = () => {
|
|
88
95
|
this.bsClose.emit();
|
|
89
96
|
};
|
|
97
|
+
/** `error`/`warning` need immediate, interrupting announcement (`alert`); `info`/`neutral` only
|
|
98
|
+
* need a polite one (`status`) -- matches the Figma Accessibility guidelines for this component. */
|
|
99
|
+
roleForType() {
|
|
100
|
+
return this.type === 'error' || this.type === 'warning' ? 'alert' : 'status';
|
|
101
|
+
}
|
|
102
|
+
/** Clock reads as "waiting/pending", a reasonable default for info/neutral notices -- but is a
|
|
103
|
+
* weak match for error/warning, which get a warning-triangle icon instead. Either default is
|
|
104
|
+
* still overridable via the `icon` slot. */
|
|
105
|
+
renderDefaultIcon() {
|
|
106
|
+
return this.type === 'error' || this.type === 'warning' ? h(WarningIcon, null) : h(ClockIcon, null);
|
|
107
|
+
}
|
|
90
108
|
render() {
|
|
91
|
-
return (h("div", { key: '
|
|
109
|
+
return (h("div", { key: 'f8f5ae2de96dc534f4e9c9a5f46fe28e3da57939', role: this.roleForType(), class: `bs-composer-status-banner bs-composer-status-banner--${this.type}` }, h("div", { key: '28d77b1058c375afaba827f4dd4563b6cff058e4', class: "bs-composer-status-banner__message-group" }, this.showIcon && (h("span", { key: 'aaa867907b3610a1e2a9be087d2d077cd1252503', part: "icon", class: "bs-composer-status-banner__icon" }, h("slot", { key: '1d0db69c42e4a23978655e86e16b9624f05a8edb', name: "icon" }, this.renderDefaultIcon()))), h("p", { key: 'bdad9aaf7efa1d96afd07c9d214d7a2ee369c010', part: "message", class: "bs-composer-status-banner__message" }, this.message)), this.showButton && (h("button", { key: 'cf949f6cada1c35d91ebc7ec81c56ea9e9255c30', type: "button", part: "action", class: "bs-composer-status-banner__action", onClick: this.onActionClick }, this.actionLabel)), this.allowClose && (h("button", { key: '5108346a07f7bb3c23ea94c213f395212497b4e8', type: "button", part: "close", class: "bs-composer-status-banner__close", "aria-label": "Dismiss", onClick: this.onCloseClick }, h(CloseIcon, { key: '7651748165308c30394ea312f227ff83eb7b1d1a' })))));
|
|
92
110
|
}
|
|
93
111
|
static get is() { return "bs-composer-status-banner"; }
|
|
94
112
|
static get encapsulation() { return "shadow"; }
|
|
@@ -267,4 +285,5 @@ export class BsComposerStatusBanner {
|
|
|
267
285
|
}
|
|
268
286
|
}
|
|
269
287
|
const ClockIcon = () => (h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("circle", { cx: "10", cy: "10", r: "7.25", stroke: "currentColor", "stroke-width": "1.3" }), h("path", { d: "M10 5.83V10L12.5 11.67", stroke: "currentColor", "stroke-width": "1.3", "stroke-linecap": "round", "stroke-linejoin": "round" })));
|
|
288
|
+
const WarningIcon = () => (h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M10 3L18 17H2L10 3Z", stroke: "currentColor", "stroke-width": "1.3", "stroke-linejoin": "round" }), h("path", { d: "M10 8V11.5", stroke: "currentColor", "stroke-width": "1.3", "stroke-linecap": "round" }), h("circle", { cx: "10", cy: "14", r: "0.75", fill: "currentColor" })));
|
|
270
289
|
const CloseIcon = () => (h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M15 5L5 15", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { d: "M15 15L5 5", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" })));
|
|
@@ -54,11 +54,11 @@ export class BsDataTable {
|
|
|
54
54
|
this.bsRowSelect.emit({ id: row.id, selected });
|
|
55
55
|
};
|
|
56
56
|
render() {
|
|
57
|
-
return (h("table", { key: '
|
|
57
|
+
return (h("table", { key: 'fa798fc4873097b91f1e5527836c9607630535ad', part: "table", class: "bs-data-table" }, h("thead", { key: '4ce731b46239412e2f87167ca678c0a9376a67dd', part: "head" }, h("tr", { key: '74fd0fb91c96b62e7ea97f85fb9e215ab5883af5' }, this.selectable && h("th", { key: '595ffb64be9ddb12851acc704e503653c623a385', class: "bs-data-table__select-col" }), this.columns.map(column => {
|
|
58
58
|
const isSorted = this.sortColumn === column.key;
|
|
59
59
|
const ariaSort = column.sortable ? (isSorted ? (this.sortDirection === 'asc' ? 'ascending' : 'descending') : 'none') : undefined;
|
|
60
60
|
return (h("th", { part: "header-cell", class: "bs-data-table__header-cell", "aria-sort": ariaSort }, column.sortable ? (h("button", { type: "button", class: "bs-data-table__sort-button", onClick: () => this.onHeaderClick(column) }, column.label, isSorted && h("span", { class: "bs-data-table__sort-indicator" }, this.sortDirection === 'asc' ? ' ▲' : ' ▼'))) : (column.label)));
|
|
61
|
-
}))), h("tbody", { key: '
|
|
61
|
+
}))), h("tbody", { key: '1e46254b85803cbd3925b6a4bbc9ca0205816753', part: "body" }, this.rows.map(row => (h("tr", { part: "row", class: "bs-data-table__row" }, this.selectable && (h("td", { class: "bs-data-table__select-col" }, h("input", { type: "checkbox", checked: this.selectedIds.has(row.id), onChange: ev => this.onRowCheckboxChange(row, ev) }))), this.columns.map(column => this.cellRenderer ? (
|
|
62
62
|
// cellRenderer is a developer-supplied, trusted function (JS-property-only, never
|
|
63
63
|
// derived from untrusted input) -- its HTML output is intentionally not escaped,
|
|
64
64
|
// same trust model as React's dangerouslySetInnerHTML.
|
package/dist/collection/components/{bs-modal/bs-modal.cmp.test.js → bs-dialog/bs-dialog.cmp.test.js}
RENAMED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { render, h, describe, it, expect, afterEach } from "@stencil/vitest";
|
|
2
|
-
describe('bs-
|
|
2
|
+
describe('bs-dialog', () => {
|
|
3
3
|
afterEach(() => {
|
|
4
4
|
document.querySelectorAll('button[data-test-trigger]').forEach(el => el.remove());
|
|
5
5
|
});
|
|
6
6
|
it('renders nothing when closed (default)', async () => {
|
|
7
|
-
const { root } = await render(h("bs-
|
|
7
|
+
const { root } = await render(h("bs-dialog", { heading: "Confirm booking" }, "Body"));
|
|
8
8
|
expect(root.shadowRoot.querySelector('[part="backdrop"]')).toBeNull();
|
|
9
9
|
expect(root.shadowRoot.querySelector('[part="dialog"]')).toBeNull();
|
|
10
10
|
});
|
|
11
11
|
it('renders the backdrop and dialog with correct a11y attributes when open', async () => {
|
|
12
|
-
const { root } = await render(h("bs-
|
|
12
|
+
const { root } = await render(h("bs-dialog", { open: true, heading: "Confirm booking" }, "Body content"));
|
|
13
13
|
const backdrop = root.shadowRoot.querySelector('[part="backdrop"]');
|
|
14
14
|
const dialog = root.shadowRoot.querySelector('[part="dialog"]');
|
|
15
15
|
expect(backdrop).toBeTruthy();
|
|
@@ -21,27 +21,71 @@ describe('bs-modal', () => {
|
|
|
21
21
|
});
|
|
22
22
|
['sm', 'md', 'lg'].forEach(size => {
|
|
23
23
|
it(`applies the "${size}" size class to the dialog`, async () => {
|
|
24
|
-
const { root } = await render(h("bs-
|
|
24
|
+
const { root } = await render(h("bs-dialog", { open: true, size: size }, "Body"));
|
|
25
25
|
const dialog = root.shadowRoot.querySelector('[part="dialog"]');
|
|
26
|
-
expect(dialog).toHaveClass(`bs-
|
|
26
|
+
expect(dialog).toHaveClass(`bs-dialog__dialog--${size}`);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
it('defaults to the "md" size', async () => {
|
|
30
|
-
const { root } = await render(h("bs-
|
|
30
|
+
const { root } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
31
31
|
const dialog = root.shadowRoot.querySelector('[part="dialog"]');
|
|
32
|
-
expect(dialog).toHaveClass('bs-
|
|
32
|
+
expect(dialog).toHaveClass('bs-dialog__dialog--md');
|
|
33
33
|
});
|
|
34
34
|
it('only shows the footer bar when the footer slot has content', async () => {
|
|
35
|
-
const { root: withoutFooter } = await render(h("bs-
|
|
35
|
+
const { root: withoutFooter } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
36
36
|
const footerWithout = withoutFooter.shadowRoot.querySelector('[part="footer"]');
|
|
37
|
-
expect(footerWithout).not.toHaveClass('bs-
|
|
38
|
-
const { root: withFooter } = await render(h("bs-
|
|
37
|
+
expect(footerWithout).not.toHaveClass('bs-dialog__footer--visible');
|
|
38
|
+
const { root: withFooter } = await render(h("bs-dialog", { open: true }, "Body", h("button", { slot: "footer" }, "Confirm")));
|
|
39
39
|
const footerWith = withFooter.shadowRoot.querySelector('[part="footer"]');
|
|
40
|
-
expect(footerWith).toHaveClass('bs-
|
|
40
|
+
expect(footerWith).toHaveClass('bs-dialog__footer--visible');
|
|
41
41
|
expect(withFooter).toHaveTextContent('Confirm');
|
|
42
42
|
});
|
|
43
|
+
describe('image slot', () => {
|
|
44
|
+
it('has no visible image wrapper and an inline close button when the image slot is empty', async () => {
|
|
45
|
+
const { root } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
46
|
+
const image = root.shadowRoot.querySelector('[part="image"]');
|
|
47
|
+
expect(image).not.toHaveClass('bs-dialog__image--visible');
|
|
48
|
+
const header = root.shadowRoot.querySelector('[part="header"]');
|
|
49
|
+
expect(header.querySelector('[part="close"]')).not.toBeNull();
|
|
50
|
+
expect(root.shadowRoot.querySelector('.bs-dialog__close--floating')).toBeNull();
|
|
51
|
+
});
|
|
52
|
+
it('shows the image wrapper and floats the close button when the image slot has content', async () => {
|
|
53
|
+
const { root } = await render(h("bs-dialog", { open: true }, "Body", h("img", { slot: "image", src: "hero.jpg", alt: "" })));
|
|
54
|
+
const image = root.shadowRoot.querySelector('[part="image"]');
|
|
55
|
+
expect(image).toHaveClass('bs-dialog__image--visible');
|
|
56
|
+
const floating = root.shadowRoot.querySelector('.bs-dialog__close--floating');
|
|
57
|
+
expect(floating).not.toBeNull();
|
|
58
|
+
const header = root.shadowRoot.querySelector('[part="header"]');
|
|
59
|
+
expect(header.querySelector('[part="close"]')).toBeNull();
|
|
60
|
+
// Exactly one close button total, not both the floating and inline variants at once.
|
|
61
|
+
expect(root.shadowRoot.querySelectorAll('[part="close"]').length).toBe(1);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe('centered layout', () => {
|
|
65
|
+
it('reflects the centered attribute, defaulting to false', async () => {
|
|
66
|
+
const { root } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
67
|
+
expect(root).not.toHaveAttribute('centered');
|
|
68
|
+
});
|
|
69
|
+
it('renders an icon wrapper, centers the header/body, and floats the close button', async () => {
|
|
70
|
+
const { root } = await render(h("bs-dialog", { open: true, centered: true, heading: "All set" }, "Body", h("span", { slot: "icon" }, "\u2713")));
|
|
71
|
+
expect(root).toHaveAttribute('centered');
|
|
72
|
+
const icon = root.shadowRoot.querySelector('[part="icon"]');
|
|
73
|
+
expect(icon).not.toBeNull();
|
|
74
|
+
expect(icon).toHaveClass('bs-dialog__icon--visible');
|
|
75
|
+
const header = root.shadowRoot.querySelector('[part="header"]');
|
|
76
|
+
expect(header).toHaveClass('bs-dialog__header--centered');
|
|
77
|
+
const body = root.shadowRoot.querySelector('[part="body"]');
|
|
78
|
+
expect(body).toHaveClass('bs-dialog__body--centered');
|
|
79
|
+
expect(header.querySelector('[part="close"]')).toBeNull();
|
|
80
|
+
expect(root.shadowRoot.querySelector('.bs-dialog__close--floating')).not.toBeNull();
|
|
81
|
+
});
|
|
82
|
+
it('does not render an icon wrapper at all when not centered, even with a slotted icon', async () => {
|
|
83
|
+
const { root } = await render(h("bs-dialog", { open: true }, "Body", h("span", { slot: "icon" }, "\u2713")));
|
|
84
|
+
expect(root.shadowRoot.querySelector('[part="icon"]')).toBeNull();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
43
87
|
it('closes and emits bsClose when the close button is clicked', async () => {
|
|
44
|
-
const { root, spyOnEvent, waitForChanges } = await render(h("bs-
|
|
88
|
+
const { root, spyOnEvent, waitForChanges } = await render(h("bs-dialog", { open: true, heading: "Confirm booking" }, "Body"));
|
|
45
89
|
const closeSpy = spyOnEvent('bsClose');
|
|
46
90
|
const closeButton = root.shadowRoot.querySelector('[part="close"]');
|
|
47
91
|
closeButton.click();
|
|
@@ -51,7 +95,7 @@ describe('bs-modal', () => {
|
|
|
51
95
|
expect(root.shadowRoot.querySelector('[part="dialog"]')).toBeNull();
|
|
52
96
|
});
|
|
53
97
|
it('closes when the backdrop itself is clicked, but not when the dialog inside it is clicked', async () => {
|
|
54
|
-
const { root, spyOnEvent, waitForChanges } = await render(h("bs-
|
|
98
|
+
const { root, spyOnEvent, waitForChanges } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
55
99
|
const closeSpy = spyOnEvent('bsClose');
|
|
56
100
|
const dialog = root.shadowRoot.querySelector('[part="dialog"]');
|
|
57
101
|
dialog.click();
|
|
@@ -65,7 +109,7 @@ describe('bs-modal', () => {
|
|
|
65
109
|
expect(root).not.toHaveAttribute('open');
|
|
66
110
|
});
|
|
67
111
|
it('closes on Escape keydown while open', async () => {
|
|
68
|
-
const { root, spyOnEvent, waitForChanges } = await render(h("bs-
|
|
112
|
+
const { root, spyOnEvent, waitForChanges } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
69
113
|
const closeSpy = spyOnEvent('bsClose');
|
|
70
114
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
71
115
|
await waitForChanges();
|
|
@@ -73,14 +117,14 @@ describe('bs-modal', () => {
|
|
|
73
117
|
expect(root).not.toHaveAttribute('open');
|
|
74
118
|
});
|
|
75
119
|
it('does not react to Escape when closed', async () => {
|
|
76
|
-
const { spyOnEvent, waitForChanges } = await render(h("bs-
|
|
120
|
+
const { spyOnEvent, waitForChanges } = await render(h("bs-dialog", null, "Body"));
|
|
77
121
|
const closeSpy = spyOnEvent('bsClose');
|
|
78
122
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
79
123
|
await waitForChanges();
|
|
80
124
|
expect(closeSpy.length).toBe(0);
|
|
81
125
|
});
|
|
82
126
|
it('moves focus into the dialog when opened', async () => {
|
|
83
|
-
const { root } = await render(h("bs-
|
|
127
|
+
const { root } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
84
128
|
const dialog = root.shadowRoot.querySelector('[part="dialog"]');
|
|
85
129
|
expect(root.shadowRoot.activeElement).toBe(dialog);
|
|
86
130
|
});
|
|
@@ -89,7 +133,7 @@ describe('bs-modal', () => {
|
|
|
89
133
|
outside.setAttribute('data-test-trigger', '');
|
|
90
134
|
outside.textContent = 'outside';
|
|
91
135
|
document.body.appendChild(outside);
|
|
92
|
-
const { root } = await render(h("bs-
|
|
136
|
+
const { root } = await render(h("bs-dialog", { open: true }, "Body"));
|
|
93
137
|
const dialog = root.shadowRoot.querySelector('[part="dialog"]');
|
|
94
138
|
outside.focus();
|
|
95
139
|
expect(root.shadowRoot.activeElement).toBe(dialog);
|
|
@@ -97,11 +141,11 @@ describe('bs-modal', () => {
|
|
|
97
141
|
it('captures the previously focused element on open and restores focus to it on close', async () => {
|
|
98
142
|
const trigger = document.createElement('button');
|
|
99
143
|
trigger.setAttribute('data-test-trigger', '');
|
|
100
|
-
trigger.textContent = 'open
|
|
144
|
+
trigger.textContent = 'open dialog';
|
|
101
145
|
document.body.appendChild(trigger);
|
|
102
146
|
trigger.focus();
|
|
103
147
|
expect(document.activeElement).toBe(trigger);
|
|
104
|
-
const { root, setProps, waitForChanges } = await render(h("bs-
|
|
148
|
+
const { root, setProps, waitForChanges } = await render(h("bs-dialog", null, "Body"));
|
|
105
149
|
await setProps({ open: true });
|
|
106
150
|
const dialog = root.shadowRoot.querySelector('[part="dialog"]');
|
|
107
151
|
expect(root.shadowRoot.activeElement).toBe(dialog);
|