@brandsync/wc 0.0.12 → 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 +1672 -226
- 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-64e2a7d7.entry.js → p-0847f5c0.entry.js} +1 -1
- package/dist/brandsync-wc/p-0ba35c3b.entry.js +1 -0
- package/dist/brandsync-wc/{p-2a65aabb.entry.js → p-0f3cb0c4.entry.js} +1 -1
- package/dist/brandsync-wc/{p-72a33f88.entry.js → p-10f6f3cd.entry.js} +1 -1
- package/dist/brandsync-wc/{p-88a0abee.entry.js → p-111974df.entry.js} +1 -1
- package/dist/brandsync-wc/{p-ef8522b5.entry.js → p-11f3fceb.entry.js} +1 -1
- package/dist/brandsync-wc/p-171fed0c.entry.js +1 -0
- package/dist/brandsync-wc/{p-57fdbb76.entry.js → p-18813680.entry.js} +1 -1
- package/dist/brandsync-wc/{p-f04db1b0.entry.js → p-1b7c9928.entry.js} +1 -1
- 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-1900f6ce.entry.js → p-20c24179.entry.js} +1 -1
- package/dist/brandsync-wc/{p-6e854e92.entry.js → p-321ed4d3.entry.js} +1 -1
- package/dist/brandsync-wc/{p-0eee5477.entry.js → p-38aad266.entry.js} +1 -1
- package/dist/brandsync-wc/{p-1c6fa697.entry.js → p-43e37883.entry.js} +1 -1
- package/dist/brandsync-wc/{p-8049f9f2.entry.js → p-55a8d4b5.entry.js} +1 -1
- 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-8b662ee3.entry.js → p-6b469b2d.entry.js} +1 -1
- package/dist/brandsync-wc/{p-56c66448.entry.js → p-6d85fba4.entry.js} +1 -1
- package/dist/brandsync-wc/{p-46ddc8e1.entry.js → p-6e95eb36.entry.js} +1 -1
- package/dist/brandsync-wc/{p-20dbc6a1.entry.js → p-73217b90.entry.js} +1 -1
- package/dist/brandsync-wc/p-752c04c8.entry.js +1 -0
- package/dist/brandsync-wc/{p-12ec9e92.entry.js → p-79af762c.entry.js} +1 -1
- package/dist/brandsync-wc/p-81d49240.entry.js +1 -0
- package/dist/brandsync-wc/{p-3b31f7c7.entry.js → p-91551e7b.entry.js} +1 -1
- package/dist/brandsync-wc/p-917a5bbc.entry.js +1 -0
- package/dist/brandsync-wc/{p-dd09d335.entry.js → p-9876e83c.entry.js} +1 -1
- package/dist/brandsync-wc/{p-c320b6b4.entry.js → p-9bcd99aa.entry.js} +1 -1
- package/dist/brandsync-wc/{p-d4e3ca77.entry.js → p-9c4768aa.entry.js} +1 -1
- package/dist/brandsync-wc/{p-DST5-cTx.js → p-Do3l4of3.js} +2 -2
- package/dist/brandsync-wc/{p-0fa017ce.entry.js → p-aa43d478.entry.js} +1 -1
- package/dist/brandsync-wc/{p-a5b15061.entry.js → p-c3079ad7.entry.js} +1 -1
- package/dist/brandsync-wc/{p-23457a21.entry.js → p-c3c383dc.entry.js} +1 -1
- package/dist/brandsync-wc/{p-b24a980b.entry.js → p-cc79e75f.entry.js} +1 -1
- package/dist/brandsync-wc/p-ce7fc368.entry.js +1 -0
- package/dist/brandsync-wc/{p-2c51d738.entry.js → p-d3265e70.entry.js} +1 -1
- package/dist/brandsync-wc/p-d55bbcec.entry.js +1 -0
- package/dist/brandsync-wc/{p-1adc59be.entry.js → p-e93e944b.entry.js} +1 -1
- package/dist/brandsync-wc/{p-aba300a9.entry.js → p-eb04c578.entry.js} +1 -1
- package/dist/brandsync-wc/p-f0ae2740.entry.js +1 -0
- 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 +2 -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 +1 -1
- 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 +2 -2
- 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 +2 -2
- package/dist/cjs/bs-composer-status-banner.cjs.entry.js +2 -2
- package/dist/cjs/bs-composer.cjs.entry.js +2 -2
- 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 +2 -2
- package/dist/cjs/bs-inline-tab.cjs.entry.js +2 -2
- package/dist/cjs/bs-input.cjs.entry.js +24 -12
- package/dist/cjs/bs-logo.cjs.entry.js +1 -1
- 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 +3 -3
- package/dist/cjs/bs-navigation-drawer.cjs.entry.js +8 -2
- package/dist/cjs/bs-navigation-header.cjs.entry.js +2 -2
- package/dist/cjs/bs-pagination.cjs.entry.js +85 -0
- package/dist/cjs/bs-radio.cjs.entry.js +2 -2
- package/dist/cjs/bs-slider.cjs.entry.js +2 -2
- 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 +2 -2
- package/dist/cjs/bs-tab.cjs.entry.js +2 -2
- package/dist/cjs/bs-tabs.cjs.entry.js +2 -2
- package/dist/cjs/bs-tooltip.cjs.entry.js +2 -2
- package/dist/cjs/{index-B3sdhEGk.js → index-DHVw-IPK.js} +1 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/collection/collection-manifest.json +8 -1
- package/dist/collection/components/bs-ai-disclaimer/bs-ai-disclaimer.js +1 -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-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/bs-button.js +1 -1
- package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.js +1 -1
- package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.js +1 -1
- 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.js +1 -1
- package/dist/collection/components/bs-checkbox/bs-checkbox.stories.js +12 -0
- package/dist/collection/components/bs-composer/bs-composer.js +1 -1
- package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.js +1 -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-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.js +1 -1
- package/dist/collection/components/bs-slider/bs-slider.js +1 -1
- 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.js +1 -1
- package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.js +1 -1
- package/dist/collection/components/bs-tab/bs-tab/bs-tab.js +1 -1
- package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.js +1 -1
- 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 +12 -0
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.js +34 -6
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.stories.js +74 -2
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.css +5 -5
- package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.js +1 -1
- package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.js +1 -1
- package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.stories.js +258 -1
- 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-modal.d.ts → bs-avatar.d.ts} +4 -4
- 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.js +1 -1
- package/dist/components/bs-inline-tab.js +1 -1
- package/dist/components/bs-input.js +1 -1
- package/dist/components/bs-logo.js +1 -1
- package/dist/components/bs-menu-item.js +1 -1
- package/dist/components/bs-menu.js +1 -1
- package/dist/components/bs-navigation-drawer-item.js +1 -1
- package/dist/components/bs-navigation-drawer.js +1 -1
- package/dist/components/bs-navigation-header.js +1 -1
- package/dist/components/bs-pagination.d.ts +11 -0
- package/dist/components/bs-pagination.js +1 -0
- package/dist/components/bs-radio.js +1 -1
- package/dist/components/bs-slider.js +1 -1
- 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.js +1 -1
- package/dist/components/bs-tab.js +1 -1
- package/dist/components/bs-tabs.js +1 -1
- package/dist/components/bs-tooltip.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/{p-BAOJc0V0.js → p-BFcVSpES.js} +1 -1
- package/dist/components/{p-Be1Pfcnm.js → p-BJZYe7M4.js} +1 -1
- package/dist/components/{p-CaWqTQBZ.js → p-BKaZWFE1.js} +1 -1
- package/dist/components/{p-DivZLd6i.js → p-BtX5URLk.js} +1 -1
- package/dist/components/{p-BqYyMGrB.js → p-CgaPcyEJ.js} +1 -1
- package/dist/components/{p-xfx69LQx.js → p-qK1XlpTA.js} +1 -1
- package/dist/esm/brandsync-wc.js +3 -3
- package/dist/esm/bs-ai-disclaimer.entry.js +2 -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 +1 -1
- 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 +2 -2
- 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 +2 -2
- package/dist/esm/bs-composer-status-banner.entry.js +2 -2
- package/dist/esm/bs-composer.entry.js +2 -2
- 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 +2 -2
- package/dist/esm/bs-inline-tab.entry.js +2 -2
- package/dist/esm/bs-input.entry.js +24 -12
- package/dist/esm/bs-logo.entry.js +1 -1
- 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 +3 -3
- package/dist/esm/bs-navigation-drawer.entry.js +8 -2
- package/dist/esm/bs-navigation-header.entry.js +2 -2
- package/dist/esm/bs-pagination.entry.js +83 -0
- package/dist/esm/bs-radio.entry.js +2 -2
- package/dist/esm/bs-slider.entry.js +2 -2
- 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 +2 -2
- package/dist/esm/bs-tab.entry.js +2 -2
- package/dist/esm/bs-tabs.entry.js +2 -2
- package/dist/esm/bs-tooltip.entry.js +2 -2
- package/dist/esm/{index-DST5-cTx.js → index-Do3l4of3.js} +1 -1
- package/dist/esm/loader.js +3 -3
- 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.cmp.test.d.ts +1 -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-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.stories.d.ts +1 -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-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-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/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.d.ts +13 -5
- package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.stories.d.ts +3 -0
- package/dist/types/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.stories.d.ts +4 -0
- package/dist/types/components.d.ts +1109 -104
- package/package.json +1 -1
- package/dist/brandsync-wc/p-09aa03d1.entry.js +0 -1
- package/dist/brandsync-wc/p-1cf715aa.entry.js +0 -1
- package/dist/brandsync-wc/p-266f5dde.entry.js +0 -1
- package/dist/brandsync-wc/p-8ded1eb6.entry.js +0 -1
- package/dist/brandsync-wc/p-b289450a.entry.js +0 -1
- package/dist/brandsync-wc/p-b8a2f882.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-modal/bs-modal.cmp.test.d.ts → bs-avatar/bs-avatar.cmp.test.d.ts} +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { h } from "@stencil/core";
|
|
2
|
+
/**
|
|
3
|
+
* An overlay dialog that interrupts the current flow for a focused task or confirmation.
|
|
4
|
+
* Closes itself on backdrop click, Escape, or its own close button, and emits `bsClose`.
|
|
5
|
+
*
|
|
6
|
+
* ## When to use
|
|
7
|
+
* - Confirming a consequential action (e.g. "Confirm booking") before it takes effect.
|
|
8
|
+
* - A short, focused task that doesn't warrant navigating to a new page.
|
|
9
|
+
*
|
|
10
|
+
* ## When not to use
|
|
11
|
+
* - For non-blocking status messages — use a toast/notification instead of interrupting the user.
|
|
12
|
+
* - For a long, multi-step flow — a full page or a dedicated route is usually a better fit than a
|
|
13
|
+
* dialog that just gets taller and taller.
|
|
14
|
+
*
|
|
15
|
+
* Two additional slots cover the Figma "Dialog" component's other states: `image` (a hero image
|
|
16
|
+
* across the top, close button floats over it instead of sitting in the header row) and `icon`
|
|
17
|
+
* (only rendered when `centered` is set, e.g. a success checkmark above a centered heading). The
|
|
18
|
+
* close button "floats" (absolute-positioned, top-right of the dialog, with its own background)
|
|
19
|
+
* whenever `centered` is true or the `image` slot has content -- otherwise it's the plain inline
|
|
20
|
+
* button in the header row next to the heading, same as before this addition.
|
|
21
|
+
*
|
|
22
|
+
* @slot - Default slot: the dialog body content.
|
|
23
|
+
* @slot image - Optional hero image across the top of the dialog. Presence of assigned content
|
|
24
|
+
* switches the close button to float over it; doesn't affect layout when empty.
|
|
25
|
+
* @slot icon - Optional icon shown above the heading, only rendered at all when `centered` is true.
|
|
26
|
+
* @slot footer - Optional footer content (typically action buttons).
|
|
27
|
+
* @part backdrop - The full-viewport overlay behind the dialog.
|
|
28
|
+
* @part dialog - The dialog box itself.
|
|
29
|
+
* @part image - The hero image wrapper (only visible when the `image` slot has content).
|
|
30
|
+
* @part icon - The icon wrapper (only rendered when `centered` is true).
|
|
31
|
+
* @part header - The header row (heading + close button, when the close button isn't floating).
|
|
32
|
+
* @part close - The close button (inline in the header, or floating -- see the class doc above).
|
|
33
|
+
* @part body - The body content wrapper.
|
|
34
|
+
* @part footer - The footer wrapper (only visible when the footer slot has content).
|
|
35
|
+
*/
|
|
36
|
+
export class BsDialog {
|
|
37
|
+
/** Mutable + reflected so the component can close itself (backdrop click, Escape, close button)
|
|
38
|
+
* the same way a native `<dialog>` does, while still emitting `bsClose` for the consumer to react to. */
|
|
39
|
+
open = false;
|
|
40
|
+
heading;
|
|
41
|
+
size = 'md';
|
|
42
|
+
/** Switches to the Figma "Icon Centered" layout: heading/body text centered, the `icon` slot
|
|
43
|
+
* rendered above the heading, and the close button floating top-right of the dialog instead of
|
|
44
|
+
* inline in the header row. Doesn't hide a slotted `image` if one is also provided -- Figma's
|
|
45
|
+
* spec doesn't show the two combined, so this is unspecified rather than actively blocked.
|
|
46
|
+
* Reflected so consumers/CSS can target `bs-dialog[centered]`. */
|
|
47
|
+
centered = false;
|
|
48
|
+
bsClose;
|
|
49
|
+
/** Tracks whether the `footer` slot has assigned content, so the footer bar (border + padding)
|
|
50
|
+
* only renders when there's actually something to put in it. */
|
|
51
|
+
hasFooter = false;
|
|
52
|
+
/** Tracks whether the `image` slot has assigned content -- drives both whether the image wrapper
|
|
53
|
+
* is visible and whether the close button floats over it (see `floatingClose` in `render()`). */
|
|
54
|
+
hasImage = false;
|
|
55
|
+
/** Tracks whether the `icon` slot has assigned content, so the icon wrapper only reserves layout
|
|
56
|
+
* space when there's actually an icon -- same pattern as `bs-tab`'s `hasIcon`. Only relevant when
|
|
57
|
+
* `centered` is true, since the icon wrapper isn't rendered at all otherwise. */
|
|
58
|
+
hasIcon = false;
|
|
59
|
+
onFooterSlotchange = (ev) => {
|
|
60
|
+
this.hasFooter = ev.target.assignedNodes().length > 0;
|
|
61
|
+
};
|
|
62
|
+
onImageSlotchange = (ev) => {
|
|
63
|
+
this.hasImage = ev.target.assignedNodes().length > 0;
|
|
64
|
+
};
|
|
65
|
+
onIconSlotchange = (ev) => {
|
|
66
|
+
this.hasIcon = ev.target.assignedNodes().length > 0;
|
|
67
|
+
};
|
|
68
|
+
dialogRef;
|
|
69
|
+
previouslyFocused;
|
|
70
|
+
previousBodyOverflow;
|
|
71
|
+
wasOpen = false;
|
|
72
|
+
close = () => {
|
|
73
|
+
this.open = false;
|
|
74
|
+
this.bsClose.emit();
|
|
75
|
+
};
|
|
76
|
+
onKeydown(ev) {
|
|
77
|
+
if (this.open && ev.key === 'Escape') {
|
|
78
|
+
this.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
onBackdropClick = (ev) => {
|
|
82
|
+
if (ev.target === ev.currentTarget) {
|
|
83
|
+
this.close();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
// Simple focus containment: rather than manually enumerating focusable elements (which can't
|
|
87
|
+
// reliably walk into slotted children's own Shadow DOM anyway), redirect any focus that lands
|
|
88
|
+
// outside the dialog back to it. composedPath() correctly reports elements across Shadow DOM
|
|
89
|
+
// boundaries, unlike a plain `.contains()` check.
|
|
90
|
+
onFocusIn(ev) {
|
|
91
|
+
if (this.open && this.dialogRef && !ev.composedPath().includes(this.dialogRef)) {
|
|
92
|
+
this.dialogRef.focus();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
componentDidRender() {
|
|
96
|
+
if (this.open && !this.wasOpen) {
|
|
97
|
+
this.previouslyFocused = document.activeElement;
|
|
98
|
+
this.dialogRef?.focus();
|
|
99
|
+
// Locks the page behind the dialog from scrolling while it's open -- a fixed-position
|
|
100
|
+
// backdrop/dialog doesn't block scroll on its own, since scroll input still targets whatever
|
|
101
|
+
// element is under the pointer/has focus, not the topmost painted layer.
|
|
102
|
+
this.previousBodyOverflow = document.body.style.overflow;
|
|
103
|
+
document.body.style.overflow = 'hidden';
|
|
104
|
+
}
|
|
105
|
+
else if (!this.open && this.wasOpen) {
|
|
106
|
+
this.previouslyFocused?.focus();
|
|
107
|
+
document.body.style.overflow = this.previousBodyOverflow ?? '';
|
|
108
|
+
}
|
|
109
|
+
this.wasOpen = this.open;
|
|
110
|
+
}
|
|
111
|
+
disconnectedCallback() {
|
|
112
|
+
// Covers the case where the host is removed from the DOM entirely while still open (e.g. a
|
|
113
|
+
// consumer conditionally rendering `<bs-dialog>` itself rather than toggling `open`) -- without
|
|
114
|
+
// this, the page would be left permanently unscrollable since componentDidRender's own
|
|
115
|
+
// open->closed transition never runs.
|
|
116
|
+
if (this.wasOpen) {
|
|
117
|
+
document.body.style.overflow = this.previousBodyOverflow ?? '';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
render() {
|
|
121
|
+
if (!this.open) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
// The close button floats (absolute, over the top of the dialog) whenever there's a hero image
|
|
125
|
+
// to sit over, or the centered layout has no header row to put an inline close button in.
|
|
126
|
+
const floatingClose = this.centered || this.hasImage;
|
|
127
|
+
return (h("div", { part: "backdrop", class: "bs-dialog__backdrop", onClick: this.onBackdropClick }, h("div", { ref: el => (this.dialogRef = el), tabIndex: -1, part: "dialog", class: `bs-dialog__dialog bs-dialog__dialog--${this.size}`, role: "dialog", "aria-modal": "true", "aria-label": this.heading }, floatingClose && (h("bs-icon-button", { part: "close", class: "bs-dialog__close--floating", variant: "neutral", size: "md", "aria-label": "Close", onClick: this.close }, h(CloseIcon, null))), h("div", { part: "image", class: `bs-dialog__image ${this.hasImage ? 'bs-dialog__image--visible' : ''}` }, h("slot", { name: "image", onSlotchange: this.onImageSlotchange })), this.centered && (h("div", { part: "icon", class: `bs-dialog__icon ${this.hasIcon ? 'bs-dialog__icon--visible' : ''}` }, h("slot", { name: "icon", onSlotchange: this.onIconSlotchange }))), h("div", { part: "header", class: `bs-dialog__header ${this.centered ? 'bs-dialog__header--centered' : ''}` }, h("span", { class: "bs-dialog__heading" }, this.heading), !floatingClose && (h("bs-icon-button", { part: "close", variant: "subtle", size: "md", "aria-label": "Close", onClick: this.close }, h(CloseIcon, null)))), h("div", { part: "body", class: `bs-dialog__body ${this.centered ? 'bs-dialog__body--centered' : ''}` }, h("slot", null)), h("div", { part: "footer", class: `bs-dialog__footer ${this.hasFooter ? 'bs-dialog__footer--visible' : ''}` }, h("slot", { name: "footer", onSlotchange: this.onFooterSlotchange })))));
|
|
128
|
+
}
|
|
129
|
+
static get is() { return "bs-dialog"; }
|
|
130
|
+
static get encapsulation() { return "shadow"; }
|
|
131
|
+
static get originalStyleUrls() {
|
|
132
|
+
return {
|
|
133
|
+
"$": ["bs-dialog.css"]
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
static get styleUrls() {
|
|
137
|
+
return {
|
|
138
|
+
"$": ["bs-dialog.css"]
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
static get properties() {
|
|
142
|
+
return {
|
|
143
|
+
"open": {
|
|
144
|
+
"type": "boolean",
|
|
145
|
+
"mutable": true,
|
|
146
|
+
"complexType": {
|
|
147
|
+
"original": "boolean",
|
|
148
|
+
"resolved": "boolean",
|
|
149
|
+
"references": {}
|
|
150
|
+
},
|
|
151
|
+
"required": false,
|
|
152
|
+
"optional": false,
|
|
153
|
+
"docs": {
|
|
154
|
+
"tags": [],
|
|
155
|
+
"text": "Mutable + reflected so the component can close itself (backdrop click, Escape, close button)\nthe same way a native `<dialog>` does, while still emitting `bsClose` for the consumer to react to."
|
|
156
|
+
},
|
|
157
|
+
"getter": false,
|
|
158
|
+
"setter": false,
|
|
159
|
+
"reflect": true,
|
|
160
|
+
"attribute": "open",
|
|
161
|
+
"defaultValue": "false"
|
|
162
|
+
},
|
|
163
|
+
"heading": {
|
|
164
|
+
"type": "string",
|
|
165
|
+
"mutable": false,
|
|
166
|
+
"complexType": {
|
|
167
|
+
"original": "string",
|
|
168
|
+
"resolved": "string",
|
|
169
|
+
"references": {}
|
|
170
|
+
},
|
|
171
|
+
"required": false,
|
|
172
|
+
"optional": true,
|
|
173
|
+
"docs": {
|
|
174
|
+
"tags": [],
|
|
175
|
+
"text": ""
|
|
176
|
+
},
|
|
177
|
+
"getter": false,
|
|
178
|
+
"setter": false,
|
|
179
|
+
"reflect": false,
|
|
180
|
+
"attribute": "heading"
|
|
181
|
+
},
|
|
182
|
+
"size": {
|
|
183
|
+
"type": "string",
|
|
184
|
+
"mutable": false,
|
|
185
|
+
"complexType": {
|
|
186
|
+
"original": "BsDialogSize",
|
|
187
|
+
"resolved": "\"lg\" | \"md\" | \"sm\"",
|
|
188
|
+
"references": {
|
|
189
|
+
"BsDialogSize": {
|
|
190
|
+
"location": "local",
|
|
191
|
+
"path": "/Users/vivka/brandsync-web-components/src/components/bs-dialog/bs-dialog.tsx",
|
|
192
|
+
"id": "src/components/bs-dialog/bs-dialog.tsx::BsDialogSize"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"required": false,
|
|
197
|
+
"optional": false,
|
|
198
|
+
"docs": {
|
|
199
|
+
"tags": [],
|
|
200
|
+
"text": ""
|
|
201
|
+
},
|
|
202
|
+
"getter": false,
|
|
203
|
+
"setter": false,
|
|
204
|
+
"reflect": false,
|
|
205
|
+
"attribute": "size",
|
|
206
|
+
"defaultValue": "'md'"
|
|
207
|
+
},
|
|
208
|
+
"centered": {
|
|
209
|
+
"type": "boolean",
|
|
210
|
+
"mutable": false,
|
|
211
|
+
"complexType": {
|
|
212
|
+
"original": "boolean",
|
|
213
|
+
"resolved": "boolean",
|
|
214
|
+
"references": {}
|
|
215
|
+
},
|
|
216
|
+
"required": false,
|
|
217
|
+
"optional": false,
|
|
218
|
+
"docs": {
|
|
219
|
+
"tags": [],
|
|
220
|
+
"text": "Switches to the Figma \"Icon Centered\" layout: heading/body text centered, the `icon` slot\nrendered above the heading, and the close button floating top-right of the dialog instead of\ninline in the header row. Doesn't hide a slotted `image` if one is also provided -- Figma's\nspec doesn't show the two combined, so this is unspecified rather than actively blocked.\nReflected so consumers/CSS can target `bs-dialog[centered]`."
|
|
221
|
+
},
|
|
222
|
+
"getter": false,
|
|
223
|
+
"setter": false,
|
|
224
|
+
"reflect": true,
|
|
225
|
+
"attribute": "centered",
|
|
226
|
+
"defaultValue": "false"
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
static get states() {
|
|
231
|
+
return {
|
|
232
|
+
"hasFooter": {},
|
|
233
|
+
"hasImage": {},
|
|
234
|
+
"hasIcon": {}
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
static get events() {
|
|
238
|
+
return [{
|
|
239
|
+
"method": "bsClose",
|
|
240
|
+
"name": "bsClose",
|
|
241
|
+
"bubbles": true,
|
|
242
|
+
"cancelable": true,
|
|
243
|
+
"composed": true,
|
|
244
|
+
"docs": {
|
|
245
|
+
"tags": [],
|
|
246
|
+
"text": ""
|
|
247
|
+
},
|
|
248
|
+
"complexType": {
|
|
249
|
+
"original": "void",
|
|
250
|
+
"resolved": "void",
|
|
251
|
+
"references": {}
|
|
252
|
+
}
|
|
253
|
+
}];
|
|
254
|
+
}
|
|
255
|
+
static get listeners() {
|
|
256
|
+
return [{
|
|
257
|
+
"name": "keydown",
|
|
258
|
+
"method": "onKeydown",
|
|
259
|
+
"target": "document",
|
|
260
|
+
"capture": false,
|
|
261
|
+
"passive": false
|
|
262
|
+
}, {
|
|
263
|
+
"name": "focusin",
|
|
264
|
+
"method": "onFocusIn",
|
|
265
|
+
"target": "document",
|
|
266
|
+
"capture": false,
|
|
267
|
+
"passive": false
|
|
268
|
+
}];
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// 16x16 native viewBox, matching bs-attachment's own CloseIcon proportions (two crossing diagonal
|
|
272
|
+
// strokes) -- shared between both close button variants above rather than duplicated inline.
|
|
273
|
+
const CloseIcon = () => (h("svg", { viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M12.5 3.5L3.5 12.5", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { d: "M12.5 12.5L3.5 3.5", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" })));
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { componentDescription, propDescription } from "../../stories-utils";
|
|
2
|
+
const meta = {
|
|
3
|
+
title: 'Components/bs-dialog',
|
|
4
|
+
parameters: {
|
|
5
|
+
docs: {
|
|
6
|
+
description: { component: componentDescription('bs-dialog') },
|
|
7
|
+
// bs-dialog's backdrop/dialog are `position: fixed`, which resolves against the nearest
|
|
8
|
+
// *viewport*. Storybook's Docs page normally inlines every story's markup directly into the
|
|
9
|
+
// long, single-scroll Docs page itself -- so "fixed" ends up relative to that entire page's
|
|
10
|
+
// iframe (which Storybook grows to fit ALL of it, often several thousand px tall), not the
|
|
11
|
+
// small visible slice of it a reader is actually looking at. That's what produced a phantom
|
|
12
|
+
// page-level scrollbar with the dialog rendering off in the wrong spot when reviewed on the
|
|
13
|
+
// Docs page (worked fine on each story's own isolated Canvas view, which doesn't have this
|
|
14
|
+
// problem). `inline: false` renders each Canvas in its own separate, normally-sized iframe
|
|
15
|
+
// instead, giving `position: fixed` the correctly-scoped small viewport to resolve against.
|
|
16
|
+
story: { inline: false, height: '650px' },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
argTypes: {
|
|
20
|
+
heading: { control: 'text', description: propDescription('bs-dialog', 'heading') },
|
|
21
|
+
size: { control: 'select', options: ['sm', 'md', 'lg'], description: propDescription('bs-dialog', 'size') },
|
|
22
|
+
},
|
|
23
|
+
args: {
|
|
24
|
+
heading: 'Confirm booking',
|
|
25
|
+
size: 'md',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export default meta;
|
|
29
|
+
export const Default = {
|
|
30
|
+
render: args => {
|
|
31
|
+
const container = document.createElement('div');
|
|
32
|
+
const trigger = document.createElement('bs-button');
|
|
33
|
+
trigger.textContent = 'Open dialog';
|
|
34
|
+
const dialog = document.createElement('bs-dialog');
|
|
35
|
+
dialog.heading = args.heading;
|
|
36
|
+
dialog.size = args.size;
|
|
37
|
+
dialog.innerHTML = `
|
|
38
|
+
<p>Meeting Room 4B, 2:00pm - 3:00pm. This will send a calendar invite to all attendees.</p>
|
|
39
|
+
<bs-button slot="footer" variant="subtle" size="sm">Cancel</bs-button>
|
|
40
|
+
<bs-button slot="footer" size="sm">Confirm</bs-button>
|
|
41
|
+
`;
|
|
42
|
+
trigger.addEventListener('click', () => {
|
|
43
|
+
dialog.open = true;
|
|
44
|
+
});
|
|
45
|
+
dialog.addEventListener('bsClose', () => {
|
|
46
|
+
dialog.open = false;
|
|
47
|
+
});
|
|
48
|
+
container.appendChild(trigger);
|
|
49
|
+
container.appendChild(dialog);
|
|
50
|
+
return container;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
// A real photo (Unsplash, free-to-use license) matching the "premium commercial space" copy below
|
|
54
|
+
// -- trades the previous inline-SVG placeholder's zero-network-dependency guarantee for a demo that
|
|
55
|
+
// actually looks like the Figma spec's hero image. Verified this URL resolves (200, image/jpeg)
|
|
56
|
+
// before using it.
|
|
57
|
+
const placeholderImage = 'https://images.unsplash.com/photo-1660496247667-3fb697c396af?fm=jpg&q=80&w=920&h=400&fit=crop&auto=format';
|
|
58
|
+
export const WithImage = {
|
|
59
|
+
name: 'With image',
|
|
60
|
+
render: args => {
|
|
61
|
+
const container = document.createElement('div');
|
|
62
|
+
const trigger = document.createElement('bs-button');
|
|
63
|
+
trigger.textContent = 'Open dialog';
|
|
64
|
+
const dialog = document.createElement('bs-dialog');
|
|
65
|
+
dialog.heading = args.heading;
|
|
66
|
+
dialog.size = args.size;
|
|
67
|
+
dialog.innerHTML = `
|
|
68
|
+
<img slot="image" src="${placeholderImage}" alt="" />
|
|
69
|
+
<p>Sunset Towers is a premium commercial space located in the heart of the city. It offers flexible office layouts, modern amenities, and 24/7 security.</p>
|
|
70
|
+
<bs-button slot="footer" variant="subtle" size="sm">Cancel</bs-button>
|
|
71
|
+
<bs-button slot="footer" size="sm">Confirm</bs-button>
|
|
72
|
+
`;
|
|
73
|
+
trigger.addEventListener('click', () => {
|
|
74
|
+
dialog.open = true;
|
|
75
|
+
});
|
|
76
|
+
dialog.addEventListener('bsClose', () => {
|
|
77
|
+
dialog.open = false;
|
|
78
|
+
});
|
|
79
|
+
container.appendChild(trigger);
|
|
80
|
+
container.appendChild(dialog);
|
|
81
|
+
return container;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
const checkCircleIcon = `
|
|
85
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
86
|
+
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.5" />
|
|
87
|
+
<path d="M8 12.5L10.5 15L16 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
88
|
+
</svg>
|
|
89
|
+
`;
|
|
90
|
+
export const Centered = {
|
|
91
|
+
render: args => {
|
|
92
|
+
const container = document.createElement('div');
|
|
93
|
+
const trigger = document.createElement('bs-button');
|
|
94
|
+
trigger.textContent = 'Open dialog';
|
|
95
|
+
const dialog = document.createElement('bs-dialog');
|
|
96
|
+
dialog.heading = args.heading;
|
|
97
|
+
dialog.size = args.size;
|
|
98
|
+
dialog.centered = true;
|
|
99
|
+
dialog.innerHTML = `
|
|
100
|
+
<span slot="icon" style="color: var(--bs-color-primary-default)">${checkCircleIcon}</span>
|
|
101
|
+
<p>Sunset Towers is a premium commercial space located in the heart of the city. It offers flexible office layouts, modern amenities, and 24/7 security.</p>
|
|
102
|
+
<bs-button slot="footer" variant="subtle" size="sm">Cancel</bs-button>
|
|
103
|
+
<bs-button slot="footer" size="sm">Confirm</bs-button>
|
|
104
|
+
`;
|
|
105
|
+
trigger.addEventListener('click', () => {
|
|
106
|
+
dialog.open = true;
|
|
107
|
+
});
|
|
108
|
+
dialog.addEventListener('bsClose', () => {
|
|
109
|
+
dialog.open = false;
|
|
110
|
+
});
|
|
111
|
+
container.appendChild(trigger);
|
|
112
|
+
container.appendChild(dialog);
|
|
113
|
+
return container;
|
|
114
|
+
},
|
|
115
|
+
};
|
|
@@ -349,6 +349,21 @@ describe('bs-input', () => {
|
|
|
349
349
|
select.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
350
350
|
expect(bsTitleChangeSpy).toHaveReceivedEventDetail('Mr.');
|
|
351
351
|
});
|
|
352
|
+
it('renders the title select and the text input in two separate [part="field"] boxes, not one shared field', async () => {
|
|
353
|
+
const { root } = await render(h("bs-input", { type: "initials", titleOptions: ['Mrs.', 'Mr.'] }));
|
|
354
|
+
const fields = root.shadowRoot.querySelectorAll('[part="field"]');
|
|
355
|
+
expect(fields).toHaveLength(2);
|
|
356
|
+
expect(fields[0]).toHaveClass('bs-input__field--initials-title');
|
|
357
|
+
expect(fields[0].querySelector('select')).not.toBeNull();
|
|
358
|
+
expect(fields[1]).toHaveClass('bs-input__field--initials-value');
|
|
359
|
+
expect(fields[1].querySelector('input')).not.toBeNull();
|
|
360
|
+
});
|
|
361
|
+
it('applies the error class to both the title box and the value box', async () => {
|
|
362
|
+
const { root } = await render(h("bs-input", { type: "initials", titleOptions: ['Mrs.'], error: "Required" }));
|
|
363
|
+
const fields = root.shadowRoot.querySelectorAll('[part="field"]');
|
|
364
|
+
expect(fields[0]).toHaveClass('bs-input__field--error');
|
|
365
|
+
expect(fields[1]).toHaveClass('bs-input__field--error');
|
|
366
|
+
});
|
|
352
367
|
});
|
|
353
368
|
describe('type="country"', () => {
|
|
354
369
|
it('renders a country select followed by a text input', async () => {
|
|
@@ -393,5 +408,10 @@ describe('bs-input', () => {
|
|
|
393
408
|
cells[0].dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
|
|
394
409
|
expect(bsChangeSpy).toHaveReceivedEventDetail('4');
|
|
395
410
|
});
|
|
411
|
+
it('applies the error class to the pin field when error is set', async () => {
|
|
412
|
+
const { root } = await render(h("bs-input", { type: "pin", length: 4, error: "Invalid code" }));
|
|
413
|
+
const field = root.shadowRoot.querySelector('[part="field"]');
|
|
414
|
+
expect(field).toHaveClass('bs-input__field--error');
|
|
415
|
+
});
|
|
396
416
|
});
|
|
397
417
|
});
|
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
* @prop --bs-input-error-color: Error message text color. Aliased to --bs-input-error.
|
|
24
24
|
* @prop --bs-input-chip-bg: Chip pill background for type="chip". Aliased to --bs-input-bg-disabled.
|
|
25
25
|
* @prop --bs-input-chip-text: Chip pill text color for type="chip". Aliased to --bs-input-text.
|
|
26
|
+
* @prop --bs-input-initials-title-width: Width of the title box for type="initials" (e.g.
|
|
27
|
+
* "Mrs."/"Mr."/"Dr."). A literal 80px, not aliased to a spacing token -- Figma specs this
|
|
28
|
+
* sub-field as a fixed, compact width regardless of option content (node 10306:101047), not
|
|
29
|
+
* content-based sizing. Applied to the box itself (`.bs-input__field--initials-title`), not the
|
|
30
|
+
* `<select>` directly -- see that class's own comment for why type="initials" renders two
|
|
31
|
+
* separate bordered boxes instead of sharing one field the way every other composite type does.
|
|
32
|
+
* @prop --bs-input-initials-gap: Gap between the title box and the name box for type="initials".
|
|
33
|
+
* Aliased to --bs-spacing-50 (4px), matching Figma's own gap-[4px] on this same pairing exactly.
|
|
26
34
|
*/
|
|
27
35
|
:host {
|
|
28
36
|
display: block;
|
|
@@ -56,6 +64,9 @@
|
|
|
56
64
|
|
|
57
65
|
--bs-input-chip-bg: var(--bs-input-bg-disabled);
|
|
58
66
|
--bs-input-chip-text: var(--bs-input-text);
|
|
67
|
+
|
|
68
|
+
--bs-input-initials-title-width: 80px;
|
|
69
|
+
--bs-input-initials-gap: var(--bs-spacing-50);
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
.bs-input {
|
|
@@ -329,8 +340,10 @@
|
|
|
329
340
|
min-width: 60px;
|
|
330
341
|
}
|
|
331
342
|
|
|
332
|
-
/*
|
|
333
|
-
|
|
343
|
+
/* Country composite select (type="country") -- unlike type="initials" below, this shares one
|
|
344
|
+
field box with its adjacent text input (no confirmed Figma spec yet for splitting it into two
|
|
345
|
+
separate boxes the same way), so its own <select> still needs the flex/width override here to
|
|
346
|
+
keep it from stretching to fill the shared row via .bs-input__control's own `flex: 1`. */
|
|
334
347
|
.bs-input__country-select {
|
|
335
348
|
flex-shrink: 0;
|
|
336
349
|
width: auto;
|
|
@@ -342,6 +355,67 @@
|
|
|
342
355
|
font-family: inherit;
|
|
343
356
|
}
|
|
344
357
|
|
|
358
|
+
/* Suppress the browser's own select arrow (varies by OS/browser -- e.g. an up+down double
|
|
359
|
+
arrow on some platforms) in favor of a single chevron-down rendered via renderSelectChevron(),
|
|
360
|
+
matching type="dropdown"'s own chevron. */
|
|
361
|
+
.bs-input__title-select,
|
|
362
|
+
.bs-input__country-select {
|
|
363
|
+
appearance: none;
|
|
364
|
+
-webkit-appearance: none;
|
|
365
|
+
-moz-appearance: none;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.bs-input__title-select::-ms-expand,
|
|
369
|
+
.bs-input__country-select::-ms-expand {
|
|
370
|
+
display: none;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.bs-input__select-chevron {
|
|
374
|
+
flex-shrink: 0;
|
|
375
|
+
width: var(--bs-input-icon-size);
|
|
376
|
+
height: var(--bs-input-icon-size);
|
|
377
|
+
color: var(--bs-input-icon-color);
|
|
378
|
+
pointer-events: none;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.bs-input__field--disabled .bs-input__select-chevron {
|
|
382
|
+
color: var(--bs-input-icon-color-disabled);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* Initials (type="initials") -- two genuinely separate bordered boxes side by side (see the class
|
|
386
|
+
doc on renderInitialsField() in bs-input.tsx for why), not one shared field the way country
|
|
387
|
+
above still is. Each box is a plain .bs-input__field, so the <select>/<input> inside either one
|
|
388
|
+
already gets normal .bs-input__control styling (flex: 1 filling ITS OWN box) with no extra
|
|
389
|
+
override needed -- only the title box's own OUTER width needs constraining, not its select. */
|
|
390
|
+
.bs-input__initials-row {
|
|
391
|
+
display: flex;
|
|
392
|
+
gap: var(--bs-input-initials-gap);
|
|
393
|
+
width: 100%;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.bs-input__field--initials-title {
|
|
397
|
+
flex: 0 0 auto;
|
|
398
|
+
width: var(--bs-input-initials-title-width);
|
|
399
|
+
/* Tighter gap and a smaller chevron than the field default -- at this box's compact fixed
|
|
400
|
+
width, the full-size icon/gap would crowd out the title text (e.g. "Mrs." truncating to
|
|
401
|
+
"M"). */
|
|
402
|
+
gap: var(--bs-spacing-50);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.bs-input__field--initials-title .bs-input__select-chevron {
|
|
406
|
+
width: 10px;
|
|
407
|
+
height: 10px;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.bs-input__field--initials-value {
|
|
411
|
+
flex: 1;
|
|
412
|
+
min-width: 0;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.bs-input__country-select {
|
|
416
|
+
width: auto;
|
|
417
|
+
}
|
|
418
|
+
|
|
345
419
|
/* Pin input (type="pin") */
|
|
346
420
|
.bs-input__field--pin {
|
|
347
421
|
border: none;
|
|
@@ -372,3 +446,7 @@
|
|
|
372
446
|
background: var(--bs-input-field-bg-disabled);
|
|
373
447
|
cursor: not-allowed;
|
|
374
448
|
}
|
|
449
|
+
|
|
450
|
+
.bs-input__field--pin.bs-input__field--error .bs-input__pin-cell {
|
|
451
|
+
border-color: var(--bs-input-field-border-error);
|
|
452
|
+
}
|
|
@@ -25,6 +25,12 @@ import { h } from "@stencil/core";
|
|
|
25
25
|
* toggle), or `dropdown` (chevron) -- those types always render their own trailing control there.
|
|
26
26
|
* For `type="date"`, the slot is used if provided, otherwise a default calendar icon is shown.
|
|
27
27
|
* @part field - The bordered field wrapper containing the icon(s) and native control(s).
|
|
28
|
+
* `type="initials"` renders this part on TWO separate elements instead of one (the title
|
|
29
|
+
* `<select>`'s own small box, and the name `<input>`'s own box) -- Figma specs these as two
|
|
30
|
+
* genuinely independent bordered containers with a gap between them, not one shared field the
|
|
31
|
+
* way every other composite type (`country` included) renders, so `::part(field)` reaches
|
|
32
|
+
* whichever of the two a given selector context matches, same "multiple elements, one shared
|
|
33
|
+
* part name" convention as `bs-attachment`'s own `star` part.
|
|
28
34
|
* @part menu - The `bs-menu` rendered below the field for `type="dropdown"` when `open` and
|
|
29
35
|
* `options` is non-empty.
|
|
30
36
|
* @part label - The `<label>` element.
|
|
@@ -277,15 +283,27 @@ export class BsInput {
|
|
|
277
283
|
renderChipControl() {
|
|
278
284
|
return (h("div", { class: "bs-input__chips" }, this.chips.map(chip => (h("span", { part: "chip", class: "bs-input__chip" }, chip, h("button", { type: "button", class: "bs-input__chip-remove", "aria-label": `Remove ${chip}`, onClick: this.onChipRemove(chip) }, "\u00D7")))), h("input", { id: "control", part: "control", class: "bs-input__control bs-input__chip-input", type: "text", value: this.chipDraft, placeholder: this.placeholder, disabled: this.disabled, "aria-required": this.required ? 'true' : undefined, onInput: this.onChipDraftInput, onKeyDown: this.onChipDraftKeydown })));
|
|
279
285
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
286
|
+
// type="initials" renders two genuinely separate bordered boxes side by side (each with its own
|
|
287
|
+
// border/radius/background, a small gap between them), not one shared field wrapper -- Figma
|
|
288
|
+
// node 10306:101047 specs this as two independent "Base Input" containers, unlike every other
|
|
289
|
+
// composite type in this file (`country` included) which shares one field box across its
|
|
290
|
+
// sub-controls. Bypasses renderField()/renderControl() entirely for this reason, the same way
|
|
291
|
+
// `pin` already does with its own renderPinField().
|
|
292
|
+
renderInitialsField() {
|
|
293
|
+
const disabledClass = this.disabled ? 'bs-input__field--disabled' : '';
|
|
294
|
+
return (h("div", { class: "bs-input__initials-row" }, h("div", { part: "field", class: `bs-input__field bs-input__field--initials-title ${this.error ? 'bs-input__field--error' : ''} ${disabledClass}` }, h("select", { part: "control", class: "bs-input__control bs-input__title-select", disabled: this.disabled, onChange: this.onTitleChange }, this.titleOptions.map(opt => (h("option", { value: opt, selected: opt === this.initialsTitle }, opt)))), this.renderSelectChevron()), h("div", { part: "field", class: `bs-input__field bs-input__field--initials-value ${this.error ? 'bs-input__field--error' : ''} ${disabledClass}` }, h("input", { id: "control", part: "control", class: "bs-input__control", type: "text", value: this.value, placeholder: this.placeholder, disabled: this.disabled, "aria-required": this.required ? 'true' : undefined, onInput: this.onInput, onChange: this.onChange }))));
|
|
295
|
+
}
|
|
296
|
+
/* Both the initials title <select> and the country <select> have their native OS arrow
|
|
297
|
+
suppressed (appearance: none in CSS) in favor of this single chevron-down, matching
|
|
298
|
+
type="dropdown"'s own chevron -- native rendering varies by OS/browser (e.g. an up+down
|
|
299
|
+
double arrow on some platforms), which this replaces with one consistent icon. */
|
|
300
|
+
renderSelectChevron() {
|
|
301
|
+
return (h("svg", { class: "bs-input__select-chevron", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" }, h("path", { d: "M4 6L8 10L12 6", stroke: "currentColor", "stroke-width": "1.3", "stroke-linecap": "round", "stroke-linejoin": "round" })));
|
|
285
302
|
}
|
|
286
303
|
renderCountryControl() {
|
|
287
304
|
return [
|
|
288
305
|
h("select", { part: "control", class: "bs-input__control bs-input__country-select", disabled: this.disabled, onChange: this.onCountryChange }, this.countryOptions.map(opt => (h("option", { value: opt.code, selected: opt.code === this.country }, opt.flagIcon ? `${opt.flagIcon} ` : '', opt.code, " ", opt.label)))),
|
|
306
|
+
this.renderSelectChevron(),
|
|
289
307
|
h("input", { id: "control", part: "control", class: "bs-input__control", type: "text", value: this.value, placeholder: this.placeholder, disabled: this.disabled, "aria-required": this.required ? 'true' : undefined, onInput: this.onInput, onChange: this.onChange }),
|
|
290
308
|
];
|
|
291
309
|
}
|
|
@@ -297,8 +315,6 @@ export class BsInput {
|
|
|
297
315
|
return this.renderTextareaControl();
|
|
298
316
|
case 'chip':
|
|
299
317
|
return this.renderChipControl();
|
|
300
|
-
case 'initials':
|
|
301
|
-
return this.renderInitialsControl();
|
|
302
318
|
case 'country':
|
|
303
319
|
return this.renderCountryControl();
|
|
304
320
|
default:
|
|
@@ -320,13 +336,15 @@ export class BsInput {
|
|
|
320
336
|
}
|
|
321
337
|
renderPinField() {
|
|
322
338
|
this.pinInputs = [];
|
|
323
|
-
|
|
339
|
+
const errorClass = this.error ? 'bs-input__field--error' : '';
|
|
340
|
+
const disabledClass = this.disabled ? 'bs-input__field--disabled' : '';
|
|
341
|
+
return (h("div", { part: "field", class: `bs-input__field bs-input__field--pin ${errorClass} ${disabledClass}` }, Array.from({ length: this.length }).map((_, i) => (h("input", { id: i === 0 ? 'control' : undefined, ref: el => (this.pinInputs[i] = el), part: "control", class: "bs-input__pin-cell", type: "text", inputMode: "numeric", maxLength: 1, value: this.value[i] ?? '', disabled: this.disabled, "aria-required": this.required ? 'true' : undefined, onInput: this.onPinInput(i), onKeyDown: this.onPinKeydown(i) })))));
|
|
324
342
|
}
|
|
325
343
|
render() {
|
|
326
|
-
return (h("div", { key: '
|
|
344
|
+
return (h("div", { key: '3647d132e96c281ba68522647ab422040c6752c2', class: `bs-input ${this.error ? 'bs-input--error' : ''}` }, this.label && (
|
|
327
345
|
// "control" is a fixed id, not a generated one -- safe because Shadow DOM scopes ids
|
|
328
346
|
// to this instance's own shadow root, so it can never collide with another bs-input.
|
|
329
|
-
h("label", { key: '
|
|
347
|
+
h("label", { key: '95eb3e3308a746797565480318b35ea2f20c36d0', part: "label", class: "bs-input__label", htmlFor: "control" }, this.label, this.required && (h("span", { key: '5c30e73a9e474ac3138aff9868e6b98d42d3771c', part: "required", class: "bs-input__required", "aria-hidden": "true" }, "*")))), this.type === 'pin' ? this.renderPinField() : this.type === 'initials' ? this.renderInitialsField() : this.renderField(), this.error ? (h("span", { id: "description-or-error", part: "error", class: "bs-input__error" }, h("svg", { part: "error-icon", class: "bs-input__error-icon", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" }, h("circle", { cx: "8", cy: "8", r: "6.5", stroke: "currentColor", "stroke-width": "1.2" }), h("path", { d: "M8 5V8.5", stroke: "currentColor", "stroke-width": "1.2", "stroke-linecap": "round" }), h("circle", { cx: "8", cy: "11", r: "0.75", fill: "currentColor" })), this.error)) : this.description ? (h("span", { id: "description-or-error", part: "description", class: "bs-input__description" }, this.description)) : null));
|
|
330
348
|
}
|
|
331
349
|
static get is() { return "bs-input"; }
|
|
332
350
|
static get encapsulation() { return "shadow"; }
|