@boostdev/design-system-components 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +13 -10
- package/dist/client.cjs +77 -99
- package/dist/client.css +611 -580
- package/dist/client.d.cts +13 -16
- package/dist/client.d.ts +13 -16
- package/dist/client.js +87 -109
- package/dist/index.cjs +77 -99
- package/dist/index.css +611 -580
- package/dist/index.d.cts +13 -16
- package/dist/index.d.ts +13 -16
- package/dist/index.js +87 -109
- package/dist/native/index.cjs +9 -8
- package/dist/native/index.d.cts +1 -1
- package/dist/native/index.d.ts +1 -1
- package/dist/native/index.js +9 -8
- package/dist/web-components/chunk-2QA62WCQ.js +48 -0
- package/dist/web-components/chunk-3REOIRDW.js +246 -0
- package/dist/web-components/chunk-57TRNCWQ.js +93 -0
- package/dist/web-components/chunk-5IPHEONG.js +139 -0
- package/dist/web-components/chunk-5R6IFELV.js +63 -0
- package/dist/web-components/chunk-5TFWOPLH.js +49 -0
- package/dist/web-components/chunk-6I3CFC26.js +89 -0
- package/dist/web-components/chunk-6MH5UWUD.js +226 -0
- package/dist/web-components/chunk-7FMR53BW.js +127 -0
- package/dist/web-components/chunk-AGKJTMJI.js +56 -0
- package/dist/web-components/chunk-AJSXNDAP.js +151 -0
- package/dist/web-components/chunk-BQLZ7I4G.js +56 -0
- package/dist/web-components/chunk-BX3IPVOB.js +167 -0
- package/dist/web-components/chunk-CR5PGUHV.js +109 -0
- package/dist/web-components/chunk-DI46Q2EA.js +278 -0
- package/dist/web-components/chunk-DZRSJGPB.js +53 -0
- package/dist/web-components/chunk-EBJM3VD4.js +107 -0
- package/dist/web-components/chunk-ECW3HHWA.js +185 -0
- package/dist/web-components/chunk-HGBNDR22.js +98 -0
- package/dist/web-components/chunk-HHHRF2PS.js +118 -0
- package/dist/web-components/chunk-ITHLKR7Q.js +105 -0
- package/dist/web-components/chunk-JUKB3BUP.js +186 -0
- package/dist/web-components/chunk-L3XHOMN6.js +111 -0
- package/dist/{web-components.js → web-components/chunk-LGEZYFUU.js} +62 -844
- package/dist/web-components/chunk-LY62SAVN.js +64 -0
- package/dist/web-components/chunk-N6IMUOY4.js +185 -0
- package/dist/web-components/chunk-OHUTLSIQ.js +69 -0
- package/dist/web-components/chunk-OQTRTMAB.js +27 -0
- package/dist/web-components/chunk-PY62FTRW.js +179 -0
- package/dist/web-components/chunk-Q4T5BJT6.js +94 -0
- package/dist/web-components/chunk-QDST57JC.js +119 -0
- package/dist/web-components/chunk-QLZ2362S.js +279 -0
- package/dist/web-components/chunk-QPOKHLMQ.js +45 -0
- package/dist/web-components/chunk-SOQQ7RVJ.js +88 -0
- package/dist/web-components/chunk-T6AETZRP.js +131 -0
- package/dist/web-components/chunk-UFFCKVZE.js +149 -0
- package/dist/web-components/chunk-VMMVWLXL.js +53 -0
- package/dist/web-components/chunk-X3FKVHLK.js +144 -0
- package/dist/web-components/chunk-XNA6WTXG.js +133 -0
- package/dist/web-components/chunk-Y4MAXTMA.js +80 -0
- package/dist/web-components/chunk-YLVTEY23.js +165 -0
- package/dist/web-components/chunk-YRXCVKHV.js +116 -0
- package/dist/web-components/chunk-ZTC6GRP7.js +64 -0
- package/dist/web-components/globals.d.ts +2 -0
- package/dist/web-components/globals.js +1 -0
- package/dist/web-components/index.d.ts +41 -0
- package/dist/web-components/index.js +165 -0
- package/dist/web-components/interaction/bds-accordion-item.d.ts +54 -0
- package/dist/web-components/interaction/bds-accordion-item.js +7 -0
- package/dist/web-components/interaction/bds-accordion.d.ts +50 -0
- package/dist/web-components/interaction/bds-accordion.js +7 -0
- package/dist/web-components/interaction/bds-button.d.ts +100 -0
- package/dist/web-components/interaction/bds-button.js +7 -0
- package/dist/web-components/interaction/bds-collapsible.d.ts +52 -0
- package/dist/web-components/interaction/bds-collapsible.js +7 -0
- package/dist/web-components/interaction/bds-dialog.d.ts +56 -0
- package/dist/web-components/interaction/bds-dialog.js +7 -0
- package/dist/web-components/interaction/bds-drawer.d.ts +64 -0
- package/dist/web-components/interaction/bds-drawer.js +7 -0
- package/dist/web-components/interaction/bds-popover.d.ts +62 -0
- package/dist/web-components/interaction/bds-popover.js +7 -0
- package/dist/web-components/interaction/bds-skip-link.d.ts +36 -0
- package/dist/web-components/interaction/bds-skip-link.js +7 -0
- package/dist/web-components/interaction/bds-tab-panel.d.ts +26 -0
- package/dist/web-components/interaction/bds-tab-panel.js +7 -0
- package/dist/web-components/interaction/bds-tab.d.ts +45 -0
- package/dist/web-components/interaction/bds-tab.js +7 -0
- package/dist/web-components/interaction/bds-tabs.d.ts +46 -0
- package/dist/web-components/interaction/bds-tabs.js +7 -0
- package/dist/web-components/interaction/bds-toast-provider.d.ts +57 -0
- package/dist/web-components/interaction/bds-toast-provider.js +7 -0
- package/dist/web-components/interaction/bds-tooltip.d.ts +50 -0
- package/dist/web-components/interaction/bds-tooltip.js +7 -0
- package/dist/web-components/interaction/form/bds-checkbox.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-checkbox.js +7 -0
- package/dist/web-components/interaction/form/bds-combobox.d.ts +84 -0
- package/dist/web-components/interaction/form/bds-combobox.js +7 -0
- package/dist/web-components/interaction/form/bds-file-input.d.ts +62 -0
- package/dist/web-components/interaction/form/bds-file-input.js +7 -0
- package/dist/web-components/interaction/form/bds-number-input.d.ts +68 -0
- package/dist/web-components/interaction/form/bds-number-input.js +7 -0
- package/dist/web-components/interaction/form/bds-radio.d.ts +68 -0
- package/dist/web-components/interaction/form/bds-radio.js +7 -0
- package/dist/web-components/interaction/form/bds-segmented-control.d.ts +88 -0
- package/dist/web-components/interaction/form/bds-segmented-control.js +7 -0
- package/dist/web-components/interaction/form/bds-select.d.ts +79 -0
- package/dist/web-components/interaction/form/bds-select.js +7 -0
- package/dist/web-components/interaction/form/bds-slider.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-slider.js +7 -0
- package/dist/web-components/interaction/form/bds-switch.d.ts +67 -0
- package/dist/web-components/interaction/form/bds-switch.js +7 -0
- package/dist/web-components/interaction/form/bds-textarea.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-textarea.js +7 -0
- package/dist/web-components/ui/bds-alert.d.ts +66 -0
- package/dist/web-components/ui/bds-alert.js +7 -0
- package/dist/web-components/ui/bds-avatar.d.ts +50 -0
- package/dist/web-components/ui/bds-avatar.js +7 -0
- package/dist/web-components/ui/bds-badge.d.ts +35 -0
- package/dist/web-components/ui/bds-badge.js +7 -0
- package/dist/web-components/ui/bds-breadcrumb.d.ts +35 -0
- package/dist/web-components/ui/bds-breadcrumb.js +7 -0
- package/dist/web-components/ui/bds-card.d.ts +72 -0
- package/dist/web-components/ui/bds-card.js +7 -0
- package/dist/web-components/ui/bds-description-list.d.ts +42 -0
- package/dist/web-components/ui/bds-description-list.js +7 -0
- package/dist/web-components/ui/bds-icon-wrapper.d.ts +39 -0
- package/dist/web-components/ui/bds-icon-wrapper.js +7 -0
- package/dist/web-components/ui/bds-link.d.ts +59 -0
- package/dist/web-components/ui/bds-link.js +7 -0
- package/dist/web-components/ui/bds-loading.d.ts +32 -0
- package/dist/web-components/ui/bds-loading.js +7 -0
- package/dist/web-components/ui/bds-notification-banner.d.ts +61 -0
- package/dist/web-components/ui/bds-notification-banner.js +7 -0
- package/dist/web-components/ui/bds-progress-circle.d.ts +53 -0
- package/dist/web-components/ui/bds-progress-circle.js +7 -0
- package/dist/web-components/ui/bds-progress.d.ts +54 -0
- package/dist/web-components/ui/bds-progress.js +7 -0
- package/dist/web-components/ui/bds-rating.d.ts +36 -0
- package/dist/web-components/ui/bds-rating.js +7 -0
- package/dist/web-components/ui/bds-section-header.d.ts +53 -0
- package/dist/web-components/ui/bds-section-header.js +8 -0
- package/dist/web-components/ui/bds-separator.d.ts +32 -0
- package/dist/web-components/ui/bds-separator.js +7 -0
- package/dist/web-components/ui/bds-skeleton.d.ts +22 -0
- package/dist/web-components/ui/bds-skeleton.js +7 -0
- package/dist/web-components/ui/bds-typography.d.ts +44 -0
- package/dist/web-components/ui/bds-typography.js +8 -0
- package/package.json +170 -5
- package/src/components/interaction/Button/Button.module.css +12 -11
- package/src/components/interaction/Button/Button.native.tsx +10 -9
- package/src/components/interaction/Button/Button.tsx +1 -1
- package/src/components/interaction/Command/Command.module.css +3 -7
- package/src/components/interaction/Dialog/Dialog.module.css +7 -5
- package/src/components/interaction/Drawer/Drawer.module.css +49 -1
- package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +1 -3
- package/src/components/interaction/Popover/Popover.module.css +1 -3
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +1 -3
- package/src/components/interaction/form/Combobox/Combobox.module.css +2 -6
- package/src/components/interaction/form/FormInput/FormInput.module.css +1 -3
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +16 -4
- package/src/components/interaction/form/Radio/Radio.module.css +6 -16
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +70 -25
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +55 -33
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.spec.tsx +127 -56
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.stories.tsx +89 -72
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +40 -62
- package/src/components/interaction/form/SegmentedControl/index.ts +1 -1
- package/src/components/interaction/form/Select/Select.module.css +2 -4
- package/src/components/interaction/form/Switch/Switch.module.css +5 -7
- package/src/components/interaction/form/Switch/Switch.native.spec.tsx +9 -9
- package/src/components/interaction/form/Switch/Switch.native.tsx +2 -2
- package/src/components/interaction/form/Textarea/Textarea.module.css +1 -3
- package/src/components/interaction/form/atoms/InputContainer.stories.tsx +64 -0
- package/src/components/interaction/form/atoms/Label.stories.tsx +33 -0
- package/src/components/interaction/form/atoms/Message.stories.tsx +33 -0
- package/src/components/layout/Card/Card.module.css +1 -3
- package/src/components/ui/Accordion/Accordion.module.css +1 -2
- package/src/components/ui/Alert/Alert.module.css +1 -2
- package/src/components/ui/Calendar/Calendar.module.css +2 -5
- package/src/components/ui/Carousel/Carousel.module.css +1 -3
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +1 -2
- package/src/components/ui/Pagination/Pagination.module.css +1 -2
- package/src/components/ui/SkipLink/SkipLink.module.css +1 -2
- package/src/components/ui/Table/Table.module.css +1 -2
- package/src/css/bdc.css +16 -11
- package/src/index.ts +1 -1
- package/src/web-components/globals.ts +3 -3
- package/src/web-components/index.ts +47 -0
- package/src/web-components/interaction/BdsAccordion.mdx +51 -0
- package/src/web-components/interaction/BdsAccordion.stories.tsx +85 -0
- package/src/web-components/interaction/BdsCollapsible.mdx +46 -0
- package/src/web-components/interaction/BdsCollapsible.stories.tsx +87 -0
- package/src/web-components/interaction/BdsDialog.mdx +49 -0
- package/src/web-components/interaction/BdsDialog.stories.tsx +75 -0
- package/src/web-components/interaction/BdsDrawer.mdx +50 -0
- package/src/web-components/interaction/BdsDrawer.stories.tsx +66 -0
- package/src/web-components/interaction/BdsSkipLink.mdx +34 -0
- package/src/web-components/interaction/BdsSkipLink.stories.tsx +55 -0
- package/src/web-components/interaction/BdsTabs.mdx +47 -0
- package/src/web-components/interaction/BdsTabs.stories.tsx +80 -0
- package/src/web-components/interaction/BdsTooltip.mdx +38 -0
- package/src/web-components/interaction/BdsTooltip.stories.tsx +68 -0
- package/src/web-components/interaction/bds-accordion-item.spec.ts +75 -0
- package/src/web-components/interaction/bds-accordion-item.ts +181 -0
- package/src/web-components/interaction/bds-accordion.spec.ts +73 -0
- package/src/web-components/interaction/bds-accordion.ts +98 -0
- package/src/web-components/interaction/bds-button.ts +15 -13
- package/src/web-components/interaction/bds-collapsible.spec.ts +56 -0
- package/src/web-components/interaction/bds-collapsible.ts +170 -0
- package/src/web-components/interaction/bds-dialog.spec.ts +119 -0
- package/src/web-components/interaction/bds-dialog.ts +221 -0
- package/src/web-components/interaction/bds-drawer.spec.ts +113 -0
- package/src/web-components/interaction/bds-drawer.ts +315 -0
- package/src/web-components/interaction/bds-skip-link.spec.ts +42 -0
- package/src/web-components/interaction/bds-skip-link.ts +74 -0
- package/src/web-components/interaction/bds-tab-panel.spec.ts +32 -0
- package/src/web-components/interaction/bds-tab-panel.ts +38 -0
- package/src/web-components/interaction/bds-tab.spec.ts +71 -0
- package/src/web-components/interaction/bds-tab.ts +110 -0
- package/src/web-components/interaction/bds-tabs.spec.ts +120 -0
- package/src/web-components/interaction/bds-tabs.ts +152 -0
- package/src/web-components/interaction/bds-tooltip.spec.ts +49 -0
- package/src/web-components/interaction/bds-tooltip.ts +127 -0
- package/src/web-components/interaction/form/BdsCheckbox.mdx +39 -0
- package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +73 -0
- package/src/web-components/interaction/form/BdsCombobox.mdx +52 -0
- package/src/web-components/interaction/form/BdsCombobox.stories.tsx +91 -0
- package/src/web-components/interaction/form/BdsFileInput.mdx +44 -0
- package/src/web-components/interaction/form/BdsFileInput.stories.tsx +84 -0
- package/src/web-components/interaction/form/BdsNumberInput.mdx +41 -0
- package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +90 -0
- package/src/web-components/interaction/form/BdsRadio.mdx +41 -0
- package/src/web-components/interaction/form/BdsRadio.stories.tsx +90 -0
- package/src/web-components/interaction/form/BdsSegmentedControl.mdx +42 -0
- package/src/web-components/interaction/form/BdsSegmentedControl.stories.tsx +92 -0
- package/src/web-components/interaction/form/BdsSelect.mdx +38 -0
- package/src/web-components/interaction/form/BdsSelect.stories.tsx +93 -0
- package/src/web-components/interaction/form/BdsSlider.mdx +49 -0
- package/src/web-components/interaction/form/BdsSlider.stories.tsx +89 -0
- package/src/web-components/interaction/form/BdsSwitch.mdx +39 -0
- package/src/web-components/interaction/form/BdsSwitch.stories.tsx +73 -0
- package/src/web-components/interaction/form/BdsTextarea.mdx +41 -0
- package/src/web-components/interaction/form/BdsTextarea.stories.tsx +79 -0
- package/src/web-components/interaction/form/bds-checkbox.spec.ts +63 -0
- package/src/web-components/interaction/form/bds-checkbox.ts +166 -0
- package/src/web-components/interaction/form/bds-combobox.spec.ts +117 -0
- package/src/web-components/interaction/form/bds-combobox.ts +334 -0
- package/src/web-components/interaction/form/bds-file-input.spec.ts +58 -0
- package/src/web-components/interaction/form/bds-file-input.ts +209 -0
- package/src/web-components/interaction/form/bds-number-input.spec.ts +87 -0
- package/src/web-components/interaction/form/bds-number-input.ts +220 -0
- package/src/web-components/interaction/form/bds-radio.spec.ts +70 -0
- package/src/web-components/interaction/form/bds-radio.ts +151 -0
- package/src/web-components/interaction/form/bds-segmented-control.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-segmented-control.ts +282 -0
- package/src/web-components/interaction/form/bds-select.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-select.ts +188 -0
- package/src/web-components/interaction/form/bds-slider.spec.ts +41 -0
- package/src/web-components/interaction/form/bds-slider.ts +162 -0
- package/src/web-components/interaction/form/bds-switch.spec.ts +62 -0
- package/src/web-components/interaction/form/bds-switch.ts +165 -0
- package/src/web-components/interaction/form/bds-textarea.spec.ts +55 -0
- package/src/web-components/interaction/form/bds-textarea.ts +141 -0
- package/src/web-components/ui/BdsAvatar.mdx +67 -0
- package/src/web-components/ui/BdsAvatar.stories.tsx +62 -0
- package/src/web-components/ui/BdsBreadcrumb.mdx +63 -0
- package/src/web-components/ui/BdsBreadcrumb.stories.tsx +59 -0
- package/src/web-components/ui/BdsCard.mdx +83 -0
- package/src/web-components/ui/BdsCard.stories.tsx +90 -0
- package/src/web-components/ui/BdsDescriptionList.mdx +67 -0
- package/src/web-components/ui/BdsDescriptionList.stories.tsx +79 -0
- package/src/web-components/ui/BdsIconWrapper.mdx +70 -0
- package/src/web-components/ui/BdsIconWrapper.stories.tsx +76 -0
- package/src/web-components/ui/BdsLink.mdx +75 -0
- package/src/web-components/ui/BdsLink.stories.tsx +64 -0
- package/src/web-components/ui/BdsLoading.mdx +62 -0
- package/src/web-components/ui/BdsLoading.stories.tsx +37 -0
- package/src/web-components/ui/BdsNotificationBanner.mdx +90 -0
- package/src/web-components/ui/BdsNotificationBanner.stories.tsx +93 -0
- package/src/web-components/ui/BdsProgress.mdx +63 -0
- package/src/web-components/ui/BdsProgress.stories.tsx +70 -0
- package/src/web-components/ui/BdsProgressCircle.mdx +64 -0
- package/src/web-components/ui/BdsProgressCircle.stories.tsx +69 -0
- package/src/web-components/ui/BdsRating.mdx +61 -0
- package/src/web-components/ui/BdsRating.stories.tsx +39 -0
- package/src/web-components/ui/BdsSectionHeader.mdx +69 -0
- package/src/web-components/ui/BdsSectionHeader.stories.tsx +56 -0
- package/src/web-components/ui/BdsSeparator.mdx +63 -0
- package/src/web-components/ui/BdsSeparator.stories.tsx +47 -0
- package/src/web-components/ui/BdsSkeleton.mdx +67 -0
- package/src/web-components/ui/BdsSkeleton.stories.tsx +50 -0
- package/src/web-components/ui/BdsTypography.mdx +83 -0
- package/src/web-components/ui/BdsTypography.stories.tsx +51 -0
- package/src/web-components/ui/bds-alert.ts +1 -2
- package/src/web-components/ui/bds-avatar.spec.ts +75 -0
- package/src/web-components/ui/bds-avatar.ts +122 -0
- package/src/web-components/ui/bds-breadcrumb.spec.ts +55 -0
- package/src/web-components/ui/bds-breadcrumb.ts +114 -0
- package/src/web-components/ui/bds-card.spec.ts +70 -0
- package/src/web-components/ui/bds-card.ts +154 -0
- package/src/web-components/ui/bds-description-list.spec.ts +36 -0
- package/src/web-components/ui/bds-description-list.ts +79 -0
- package/src/web-components/ui/bds-icon-wrapper.spec.ts +21 -0
- package/src/web-components/ui/bds-icon-wrapper.ts +68 -0
- package/src/web-components/ui/bds-link.spec.ts +72 -0
- package/src/web-components/ui/bds-link.ts +138 -0
- package/src/web-components/ui/bds-loading.spec.ts +38 -0
- package/src/web-components/ui/bds-loading.ts +76 -0
- package/src/web-components/ui/bds-notification-banner.spec.ts +82 -0
- package/src/web-components/ui/bds-notification-banner.ts +184 -0
- package/src/web-components/ui/bds-progress-circle.spec.ts +58 -0
- package/src/web-components/ui/bds-progress-circle.ts +142 -0
- package/src/web-components/ui/bds-progress.spec.ts +66 -0
- package/src/web-components/ui/bds-progress.ts +127 -0
- package/src/web-components/ui/bds-rating.spec.ts +70 -0
- package/src/web-components/ui/bds-rating.ts +80 -0
- package/src/web-components/ui/bds-section-header.spec.ts +57 -0
- package/src/web-components/ui/bds-section-header.ts +96 -0
- package/src/web-components/ui/bds-separator.spec.ts +50 -0
- package/src/web-components/ui/bds-separator.ts +66 -0
- package/src/web-components/ui/bds-skeleton.spec.ts +22 -0
- package/src/web-components/ui/bds-skeleton.ts +55 -0
- package/src/web-components/ui/bds-typography.spec.ts +76 -0
- package/src/web-components/ui/bds-typography.ts +112 -0
- package/dist/web-components.d.ts +0 -304
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import '../index';
|
|
4
|
+
|
|
5
|
+
function BdsSkeleton({ style }: { style?: React.CSSProperties }) {
|
|
6
|
+
return React.createElement('bds-skeleton', { style });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Web Components/UI/Skeleton',
|
|
11
|
+
component: BdsSkeleton,
|
|
12
|
+
tags: ['!stable', 'experimental'],
|
|
13
|
+
parameters: { layout: 'centered' },
|
|
14
|
+
} satisfies Meta<typeof BdsSkeleton>;
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story = StoryObj<typeof meta>;
|
|
18
|
+
|
|
19
|
+
export const TextLine: Story = {
|
|
20
|
+
render: () => <BdsSkeleton style={{ width: '200px', height: '1rem' }} />,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Heading: Story = {
|
|
24
|
+
render: () => <BdsSkeleton style={{ width: '300px', height: '1.75rem' }} />,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const Avatar: Story = {
|
|
28
|
+
render: () => <BdsSkeleton style={{ width: '3rem', height: '3rem', borderRadius: '50%' }} />,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const Card: Story = {
|
|
32
|
+
render: () => <BdsSkeleton style={{ width: '280px', height: '160px' }} />,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const AllVariants: Story = {
|
|
36
|
+
render: () => (
|
|
37
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', width: '280px' }}>
|
|
38
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
39
|
+
<BdsSkeleton style={{ width: '3rem', height: '3rem', borderRadius: '50%', flexShrink: 0 }} />
|
|
40
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', flex: 1 }}>
|
|
41
|
+
<BdsSkeleton style={{ width: '100%', height: '1rem' }} />
|
|
42
|
+
<BdsSkeleton style={{ width: '60%', height: '0.75rem' }} />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<BdsSkeleton style={{ width: '100%', height: '120px' }} />
|
|
46
|
+
<BdsSkeleton style={{ width: '80%', height: '0.875rem' }} />
|
|
47
|
+
<BdsSkeleton style={{ width: '60%', height: '0.875rem' }} />
|
|
48
|
+
</div>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsTypography.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-typography>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic Typography custom element. Renders slotted content inside the appropriate semantic HTML element with the correct typographic styles.
|
|
9
|
+
|
|
10
|
+
> **Status: experimental** — API may change before stable release.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import '@boostdev/components/web-components';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Examples
|
|
19
|
+
|
|
20
|
+
### All variants
|
|
21
|
+
<Canvas of={Stories.AllVariants} />
|
|
22
|
+
|
|
23
|
+
### Heading 1
|
|
24
|
+
<Canvas of={Stories.H1} />
|
|
25
|
+
|
|
26
|
+
### Body
|
|
27
|
+
<Canvas of={Stories.Body} />
|
|
28
|
+
|
|
29
|
+
### Body small
|
|
30
|
+
<Canvas of={Stories.BodySmall} />
|
|
31
|
+
|
|
32
|
+
## Props
|
|
33
|
+
|
|
34
|
+
<ArgTypes of={Stories} />
|
|
35
|
+
|
|
36
|
+
## Attributes
|
|
37
|
+
|
|
38
|
+
| Attribute | Type | Default | Description |
|
|
39
|
+
|-----------|------|---------|-------------|
|
|
40
|
+
| `variant` | `"h1" \| "h2" \| "h3" \| "body" \| "body_s"` | `"body"` | Typographic style and semantic element |
|
|
41
|
+
| `component` | string | — | Override the rendered HTML tag (e.g. `"span"`, `"label"`) |
|
|
42
|
+
|
|
43
|
+
## Slots
|
|
44
|
+
|
|
45
|
+
| Slot | Description |
|
|
46
|
+
|------|-------------|
|
|
47
|
+
| `(default)` | Text content |
|
|
48
|
+
|
|
49
|
+
## Default tag mapping
|
|
50
|
+
|
|
51
|
+
| Variant | Rendered tag |
|
|
52
|
+
|---------|-------------|
|
|
53
|
+
| `h1` | `<h1>` |
|
|
54
|
+
| `h2` | `<h2>` |
|
|
55
|
+
| `h3` | `<h3>` |
|
|
56
|
+
| `body` | `<p>` |
|
|
57
|
+
| `body_s` | `<p>` |
|
|
58
|
+
|
|
59
|
+
## CSS Custom Properties
|
|
60
|
+
|
|
61
|
+
| Property | Description |
|
|
62
|
+
|----------|-------------|
|
|
63
|
+
| `--typography_color` | Text colour (defaults to `--bds-color_on-bg`) |
|
|
64
|
+
|
|
65
|
+
## Usage in plain HTML
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<bds-typography variant="h1">Page title</bds-typography>
|
|
69
|
+
|
|
70
|
+
<bds-typography variant="body">
|
|
71
|
+
A paragraph of body text.
|
|
72
|
+
</bds-typography>
|
|
73
|
+
|
|
74
|
+
<!-- Override tag while keeping style -->
|
|
75
|
+
<bds-typography variant="body_s" component="span">
|
|
76
|
+
Inline small text
|
|
77
|
+
</bds-typography>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Accessibility
|
|
81
|
+
|
|
82
|
+
- Uses the correct semantic HTML element by default — always prefer semantic variants over overriding `component`
|
|
83
|
+
- Use `component` only when the semantic element must differ from the visual style (e.g. a `<span>` styled as `body_s` inside a heading)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import type { TypographyVariant } from './bds-typography';
|
|
4
|
+
import '../index';
|
|
5
|
+
|
|
6
|
+
function BdsTypography({
|
|
7
|
+
variant,
|
|
8
|
+
component,
|
|
9
|
+
children,
|
|
10
|
+
}: {
|
|
11
|
+
variant?: TypographyVariant;
|
|
12
|
+
component?: string;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}) {
|
|
15
|
+
return React.createElement('bds-typography', { variant, component }, children);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const meta = {
|
|
19
|
+
title: 'Web Components/UI/Typography',
|
|
20
|
+
component: BdsTypography,
|
|
21
|
+
tags: ['!stable', 'experimental'],
|
|
22
|
+
parameters: { layout: 'padded' },
|
|
23
|
+
argTypes: {
|
|
24
|
+
variant: { control: 'select', options: ['h1', 'h2', 'h3', 'body', 'body_s'] },
|
|
25
|
+
},
|
|
26
|
+
} satisfies Meta<typeof BdsTypography>;
|
|
27
|
+
|
|
28
|
+
export default meta;
|
|
29
|
+
type Story = StoryObj<typeof meta>;
|
|
30
|
+
|
|
31
|
+
export const H1: Story = { args: { variant: 'h1', children: 'Heading level 1' } };
|
|
32
|
+
export const H2: Story = { args: { variant: 'h2', children: 'Heading level 2' } };
|
|
33
|
+
export const H3: Story = { args: { variant: 'h3', children: 'Heading level 3' } };
|
|
34
|
+
export const Body: Story = { args: { variant: 'body', children: 'Body text — the default paragraph style for reading comfort.' } };
|
|
35
|
+
export const BodySmall: Story = { args: { variant: 'body_s', children: 'Small body text — useful for captions and helper text.' } };
|
|
36
|
+
|
|
37
|
+
export const AllVariants: Story = {
|
|
38
|
+
render: () => (
|
|
39
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
40
|
+
{(['h1', 'h2', 'h3', 'body', 'body_s'] as const).map(v => (
|
|
41
|
+
<BdsTypography key={v} variant={v}>
|
|
42
|
+
{v === 'h1' && 'Heading level 1'}
|
|
43
|
+
{v === 'h2' && 'Heading level 2'}
|
|
44
|
+
{v === 'h3' && 'Heading level 3'}
|
|
45
|
+
{v === 'body' && 'Body text — comfortable reading size for paragraphs.'}
|
|
46
|
+
{v === 'body_s' && 'Small body — captions, labels, and secondary text.'}
|
|
47
|
+
</BdsTypography>
|
|
48
|
+
))}
|
|
49
|
+
</div>
|
|
50
|
+
),
|
|
51
|
+
};
|
|
@@ -110,8 +110,7 @@ export class BdsAlert extends LitElement {
|
|
|
110
110
|
transition: var(--bds-animation_transition);
|
|
111
111
|
border-radius: 50%;
|
|
112
112
|
--bdc_color: currentcolor;
|
|
113
|
-
|
|
114
|
-
outline-offset: var(--bdc-outline_offset);
|
|
113
|
+
box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color);
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
.dismiss svg {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsAvatar } from './bds-avatar';
|
|
3
|
+
|
|
4
|
+
describe('bds-avatar', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-avatar')).toBe(BdsAvatar);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('defaults to size="medium"', async () => {
|
|
10
|
+
const el = await fixture('<bds-avatar></bds-avatar>');
|
|
11
|
+
expect(el.getAttribute('size')).toBe('medium');
|
|
12
|
+
cleanup(el);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders an <img> when src is set', async () => {
|
|
16
|
+
const el = await fixture('<bds-avatar src="/photo.jpg" name="Jane Doe"></bds-avatar>');
|
|
17
|
+
const img = el.shadowRoot!.querySelector('img');
|
|
18
|
+
expect(img).not.toBeNull();
|
|
19
|
+
expect(img!.getAttribute('src')).toBe('/photo.jpg');
|
|
20
|
+
cleanup(el);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('img alt defaults to name when alt is not set', async () => {
|
|
24
|
+
const el = await fixture('<bds-avatar src="/photo.jpg" name="Jane Doe"></bds-avatar>');
|
|
25
|
+
const img = el.shadowRoot!.querySelector('img');
|
|
26
|
+
expect(img!.getAttribute('alt')).toBe('Jane Doe');
|
|
27
|
+
cleanup(el);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('img uses explicit alt when set', async () => {
|
|
31
|
+
const el = await fixture('<bds-avatar src="/photo.jpg" alt="Custom alt" name="Jane Doe"></bds-avatar>');
|
|
32
|
+
const img = el.shadowRoot!.querySelector('img');
|
|
33
|
+
expect(img!.getAttribute('alt')).toBe('Custom alt');
|
|
34
|
+
cleanup(el);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('renders fallback with initials when src is not set', async () => {
|
|
38
|
+
const el = await fixture('<bds-avatar name="Jane Doe"></bds-avatar>');
|
|
39
|
+
const fallback = el.shadowRoot!.querySelector('.fallback');
|
|
40
|
+
expect(fallback).not.toBeNull();
|
|
41
|
+
expect(fallback!.getAttribute('role')).toBe('img');
|
|
42
|
+
const initials = el.shadowRoot!.querySelector('.initials');
|
|
43
|
+
expect(initials!.textContent).toBe('JD');
|
|
44
|
+
cleanup(el);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('computes initials from first two words', async () => {
|
|
48
|
+
const el = await fixture('<bds-avatar name="Alice Bob Charlie"></bds-avatar>');
|
|
49
|
+
const initials = el.shadowRoot!.querySelector('.initials');
|
|
50
|
+
expect(initials!.textContent).toBe('AB');
|
|
51
|
+
cleanup(el);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('fallback aria-label is the name', async () => {
|
|
55
|
+
const el = await fixture('<bds-avatar name="Jane Doe"></bds-avatar>');
|
|
56
|
+
const fallback = el.shadowRoot!.querySelector('.fallback');
|
|
57
|
+
expect(fallback!.getAttribute('aria-label')).toBe('Jane Doe');
|
|
58
|
+
cleanup(el);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('fallback aria-label defaults to "User avatar" when name is not set', async () => {
|
|
62
|
+
const el = await fixture('<bds-avatar></bds-avatar>');
|
|
63
|
+
const fallback = el.shadowRoot!.querySelector('.fallback');
|
|
64
|
+
expect(fallback!.getAttribute('aria-label')).toBe('User avatar');
|
|
65
|
+
cleanup(el);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('reflects size property to attribute', async () => {
|
|
69
|
+
const el = await fixture('<bds-avatar></bds-avatar>') as BdsAvatar;
|
|
70
|
+
el.size = 'large';
|
|
71
|
+
await el.updateComplete;
|
|
72
|
+
expect(el.getAttribute('size')).toBe('large');
|
|
73
|
+
cleanup(el);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `<bds-avatar>` — framework-agnostic Avatar custom element.
|
|
5
|
+
*
|
|
6
|
+
* Shows an image when `src` is set; falls back to initials derived from `name`.
|
|
7
|
+
*
|
|
8
|
+
* Attributes:
|
|
9
|
+
* src — image URL
|
|
10
|
+
* alt — image alt text (defaults to `name` or "User avatar")
|
|
11
|
+
* name — full name; used to compute initials and as fallback aria-label
|
|
12
|
+
* size — "small" | "medium" (default) | "large"
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* <bds-avatar src="/photo.jpg" name="Jane Doe"></bds-avatar>
|
|
16
|
+
* <bds-avatar name="Jane Doe" size="large"></bds-avatar>
|
|
17
|
+
*/
|
|
18
|
+
export class BdsAvatar extends LitElement {
|
|
19
|
+
static styles = css`
|
|
20
|
+
:host {
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
inline-size: var(--avatar_size, 3em);
|
|
25
|
+
block-size: var(--avatar_size, 3em);
|
|
26
|
+
border-radius: 50%;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
flex-shrink: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:host([size='small']) { --avatar_size: 2em; }
|
|
32
|
+
:host([size='medium']) { --avatar_size: 3em; }
|
|
33
|
+
:host([size='large']) { --avatar_size: 4.5em; }
|
|
34
|
+
|
|
35
|
+
.fallback {
|
|
36
|
+
display: inline-flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
inline-size: 100%;
|
|
40
|
+
block-size: 100%;
|
|
41
|
+
background-color: var(--avatar_bg, var(--bds-color_blue));
|
|
42
|
+
color: var(--avatar_text, var(--bds-color_on-blue));
|
|
43
|
+
font-weight: var(--bds-font_weight--semibold);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.initials {
|
|
47
|
+
line-height: 1;
|
|
48
|
+
user-select: none;
|
|
49
|
+
font-size: var(--bds-font_size--body);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:host([size='small']) .initials { font-size: var(--bds-font_size--body--s); }
|
|
53
|
+
:host([size='large']) .initials { font-size: var(--bds-font_size--heading-3); }
|
|
54
|
+
|
|
55
|
+
.image {
|
|
56
|
+
inline-size: 100%;
|
|
57
|
+
block-size: 100%;
|
|
58
|
+
object-fit: cover;
|
|
59
|
+
display: block;
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
static properties = {
|
|
64
|
+
src: { type: String },
|
|
65
|
+
alt: { type: String },
|
|
66
|
+
name: { type: String },
|
|
67
|
+
size: { type: String, reflect: true },
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
declare src: string;
|
|
71
|
+
declare alt: string;
|
|
72
|
+
declare name: string;
|
|
73
|
+
declare size: 'small' | 'medium' | 'large';
|
|
74
|
+
|
|
75
|
+
constructor() {
|
|
76
|
+
super();
|
|
77
|
+
this.src = '';
|
|
78
|
+
this.alt = '';
|
|
79
|
+
this.name = '';
|
|
80
|
+
this.size = 'medium';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private get _initials(): string {
|
|
84
|
+
if (!this.name) return '';
|
|
85
|
+
return this.name
|
|
86
|
+
.split(' ')
|
|
87
|
+
.filter(Boolean)
|
|
88
|
+
.slice(0, 2)
|
|
89
|
+
.map(word => word[0].toUpperCase())
|
|
90
|
+
.join('');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
render() {
|
|
94
|
+
if (this.src) {
|
|
95
|
+
return html`<img
|
|
96
|
+
class="image"
|
|
97
|
+
src=${this.src}
|
|
98
|
+
alt=${this.alt || this.name || 'User avatar'}
|
|
99
|
+
/>`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return html`
|
|
103
|
+
<span
|
|
104
|
+
class="fallback"
|
|
105
|
+
role="img"
|
|
106
|
+
aria-label=${this.name || 'User avatar'}
|
|
107
|
+
>
|
|
108
|
+
${this._initials
|
|
109
|
+
? html`<span class="initials" aria-hidden="true">${this._initials}</span>`
|
|
110
|
+
: nothing}
|
|
111
|
+
</span>
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
customElements.define('bds-avatar', BdsAvatar);
|
|
117
|
+
|
|
118
|
+
declare global {
|
|
119
|
+
interface HTMLElementTagNameMap {
|
|
120
|
+
'bds-avatar': BdsAvatar;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsBreadcrumb } from './bds-breadcrumb';
|
|
3
|
+
|
|
4
|
+
describe('bds-breadcrumb', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-breadcrumb')).toBe(BdsBreadcrumb);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('renders a <nav> with aria-label="Breadcrumb"', async () => {
|
|
10
|
+
const el = await fixture('<bds-breadcrumb></bds-breadcrumb>');
|
|
11
|
+
const nav = el.shadowRoot!.querySelector('nav');
|
|
12
|
+
expect(nav).not.toBeNull();
|
|
13
|
+
expect(nav!.getAttribute('aria-label')).toBe('Breadcrumb');
|
|
14
|
+
cleanup(el);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders items as list items', async () => {
|
|
18
|
+
const el = await fixture('<bds-breadcrumb></bds-breadcrumb>') as BdsBreadcrumb;
|
|
19
|
+
el.items = [{ label: 'Home', href: '/' }, { label: 'Products', href: '/products' }, { label: 'Item' }];
|
|
20
|
+
await el.updateComplete;
|
|
21
|
+
const items = el.shadowRoot!.querySelectorAll('.item');
|
|
22
|
+
expect(items.length).toBe(3);
|
|
23
|
+
cleanup(el);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('renders links for non-last items', async () => {
|
|
27
|
+
const el = await fixture('<bds-breadcrumb></bds-breadcrumb>') as BdsBreadcrumb;
|
|
28
|
+
el.items = [{ label: 'Home', href: '/' }, { label: 'Current' }];
|
|
29
|
+
await el.updateComplete;
|
|
30
|
+
const link = el.shadowRoot!.querySelector('a.link');
|
|
31
|
+
expect(link).not.toBeNull();
|
|
32
|
+
expect(link!.getAttribute('href')).toBe('/');
|
|
33
|
+
cleanup(el);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('renders current page as span with aria-current="page"', async () => {
|
|
37
|
+
const el = await fixture('<bds-breadcrumb></bds-breadcrumb>') as BdsBreadcrumb;
|
|
38
|
+
el.items = [{ label: 'Home', href: '/' }, { label: 'Current' }];
|
|
39
|
+
await el.updateComplete;
|
|
40
|
+
const current = el.shadowRoot!.querySelector('.current');
|
|
41
|
+
expect(current).not.toBeNull();
|
|
42
|
+
expect(current!.getAttribute('aria-current')).toBe('page');
|
|
43
|
+
expect(current!.textContent).toBe('Current');
|
|
44
|
+
cleanup(el);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('renders separators between items', async () => {
|
|
48
|
+
const el = await fixture('<bds-breadcrumb></bds-breadcrumb>') as BdsBreadcrumb;
|
|
49
|
+
el.items = [{ label: 'Home', href: '/' }, { label: 'Products', href: '/p' }, { label: 'Item' }];
|
|
50
|
+
await el.updateComplete;
|
|
51
|
+
const separators = el.shadowRoot!.querySelectorAll('.separator');
|
|
52
|
+
expect(separators.length).toBe(2); // between each pair
|
|
53
|
+
cleanup(el);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { LitElement, css, html } from 'lit';
|
|
2
|
+
|
|
3
|
+
export interface BreadcrumbItem {
|
|
4
|
+
label: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `<bds-breadcrumb>` — framework-agnostic Breadcrumb custom element.
|
|
10
|
+
*
|
|
11
|
+
* Attributes:
|
|
12
|
+
* items — JSON string array of `{ label: string, href?: string }` objects.
|
|
13
|
+
* The last item is treated as the current page (no link).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* <bds-breadcrumb items='[{"label":"Home","href":"/"},{"label":"Products","href":"/products"},{"label":"Item"}]'></bds-breadcrumb>
|
|
17
|
+
*/
|
|
18
|
+
export class BdsBreadcrumb extends LitElement {
|
|
19
|
+
static styles = css`
|
|
20
|
+
:host {
|
|
21
|
+
display: block;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.breadcrumb {
|
|
25
|
+
font-size: var(--bds-font_size--body--s);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.list {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-wrap: wrap;
|
|
31
|
+
align-items: center;
|
|
32
|
+
gap: var(--bds-space_xxs);
|
|
33
|
+
list-style: none;
|
|
34
|
+
margin: 0;
|
|
35
|
+
padding: 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.item {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: var(--bds-space_xxs);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.link {
|
|
45
|
+
color: var(--bds-color_interactive_on-bg);
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
transition: var(--bds-animation_transition);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.link:focus-visible {
|
|
51
|
+
outline: var(--bds-outline_default);
|
|
52
|
+
outline-offset: var(--bds-outline_offset);
|
|
53
|
+
border-radius: var(--bds-border_radius--xs);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@media (hover: hover) and (pointer: fine) {
|
|
57
|
+
.link:hover {
|
|
58
|
+
text-decoration: underline;
|
|
59
|
+
text-underline-offset: 0.2em;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.separator {
|
|
64
|
+
color: var(--bds-color_on-bg--subtle);
|
|
65
|
+
user-select: none;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.current {
|
|
69
|
+
color: var(--bds-color_on-bg--subtle);
|
|
70
|
+
font-weight: var(--bds-font_weight--semibold);
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
static properties = {
|
|
75
|
+
items: { type: Array },
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
declare items: BreadcrumbItem[];
|
|
79
|
+
|
|
80
|
+
constructor() {
|
|
81
|
+
super();
|
|
82
|
+
this.items = [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
render() {
|
|
86
|
+
return html`
|
|
87
|
+
<nav class="breadcrumb" aria-label="Breadcrumb">
|
|
88
|
+
<ol class="list">
|
|
89
|
+
${this.items.map((item, index) => {
|
|
90
|
+
const isLast = index === this.items.length - 1;
|
|
91
|
+
return html`
|
|
92
|
+
<li class="item">
|
|
93
|
+
${isLast
|
|
94
|
+
? html`<span class="current" aria-current="page">${item.label}</span>`
|
|
95
|
+
: html`
|
|
96
|
+
<a class="link" href=${item.href ?? '#'}>${item.label}</a>
|
|
97
|
+
<span class="separator" aria-hidden="true">›</span>
|
|
98
|
+
`}
|
|
99
|
+
</li>
|
|
100
|
+
`;
|
|
101
|
+
})}
|
|
102
|
+
</ol>
|
|
103
|
+
</nav>
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
customElements.define('bds-breadcrumb', BdsBreadcrumb);
|
|
109
|
+
|
|
110
|
+
declare global {
|
|
111
|
+
interface HTMLElementTagNameMap {
|
|
112
|
+
'bds-breadcrumb': BdsBreadcrumb;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsCard } from './bds-card';
|
|
3
|
+
|
|
4
|
+
describe('bds-card', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-card')).toBe(BdsCard);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('defaults to variant="default", padding="medium", text-align="start"', async () => {
|
|
10
|
+
const el = await fixture('<bds-card>Content</bds-card>') as BdsCard;
|
|
11
|
+
expect(el.getAttribute('variant')).toBe('default');
|
|
12
|
+
expect(el.getAttribute('padding')).toBe('medium');
|
|
13
|
+
expect(el.getAttribute('text-align')).toBe('start');
|
|
14
|
+
cleanup(el);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders a <div> when not clickable', async () => {
|
|
18
|
+
const el = await fixture('<bds-card>Content</bds-card>');
|
|
19
|
+
expect(el.shadowRoot!.querySelector('div.card')).not.toBeNull();
|
|
20
|
+
expect(el.shadowRoot!.querySelector('button')).toBeNull();
|
|
21
|
+
cleanup(el);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('renders a <button> when clickable is set', async () => {
|
|
25
|
+
const el = await fixture('<bds-card clickable>Content</bds-card>');
|
|
26
|
+
expect(el.shadowRoot!.querySelector('button.card')).not.toBeNull();
|
|
27
|
+
expect(el.shadowRoot!.querySelector('div.card')).toBeNull();
|
|
28
|
+
cleanup(el);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('button has type="button"', async () => {
|
|
32
|
+
const el = await fixture('<bds-card clickable>Content</bds-card>');
|
|
33
|
+
const btn = el.shadowRoot!.querySelector('button');
|
|
34
|
+
expect(btn!.getAttribute('type')).toBe('button');
|
|
35
|
+
cleanup(el);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('fires bds-click event when clickable card is clicked', async () => {
|
|
39
|
+
const el = await fixture('<bds-card clickable>Content</bds-card>');
|
|
40
|
+
const btn = el.shadowRoot!.querySelector('button')!;
|
|
41
|
+
const handler = vi.fn();
|
|
42
|
+
el.addEventListener('bds-click', handler);
|
|
43
|
+
btn.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
|
|
44
|
+
expect(handler).toHaveBeenCalledOnce();
|
|
45
|
+
cleanup(el);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('applies variant, padding and text-align classes to the card element', async () => {
|
|
49
|
+
const el = await fixture('<bds-card variant="elevated" padding="large" text-align="center">Content</bds-card>');
|
|
50
|
+
const card = el.shadowRoot!.querySelector('.card')!;
|
|
51
|
+
expect(card.classList.contains('--elevated')).toBe(true);
|
|
52
|
+
expect(card.classList.contains('--padding-large')).toBe(true);
|
|
53
|
+
expect(card.classList.contains('--text-center')).toBe(true);
|
|
54
|
+
cleanup(el);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('renders slotted content', async () => {
|
|
58
|
+
const el = await fixture('<bds-card>Hello card</bds-card>');
|
|
59
|
+
expect(el.textContent?.trim()).toBe('Hello card');
|
|
60
|
+
cleanup(el);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('reflects variant property update', async () => {
|
|
64
|
+
const el = await fixture('<bds-card>Content</bds-card>') as BdsCard;
|
|
65
|
+
el.variant = 'outlined';
|
|
66
|
+
await el.updateComplete;
|
|
67
|
+
expect(el.getAttribute('variant')).toBe('outlined');
|
|
68
|
+
cleanup(el);
|
|
69
|
+
});
|
|
70
|
+
});
|