@boostdev/design-system-components 1.1.1 → 1.1.2
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/dist/client.cjs +50 -50
- package/dist/client.css +456 -456
- package/dist/client.js +50 -50
- package/dist/index.cjs +50 -50
- package/dist/index.css +456 -456
- package/dist/index.js +50 -50
- package/dist/web-components/chunk-2QA62WCQ.js +48 -0
- package/dist/web-components/chunk-4BX6AWXX.js +146 -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-6T3RKUKG.js +65 -0
- package/dist/web-components/chunk-7FMR53BW.js +127 -0
- package/dist/web-components/chunk-A67LCT7C.js +134 -0
- package/dist/web-components/chunk-AGKJTMJI.js +56 -0
- package/dist/web-components/chunk-BQLZ7I4G.js +56 -0
- package/dist/web-components/chunk-CAPI25CU.js +53 -0
- package/dist/web-components/chunk-CJ5ZOO42.js +229 -0
- package/dist/web-components/chunk-CR5PGUHV.js +109 -0
- package/dist/web-components/chunk-ECW3HHWA.js +185 -0
- package/dist/web-components/chunk-HGBNDR22.js +98 -0
- package/dist/web-components/chunk-IK3PTFZ4.js +133 -0
- package/dist/web-components/chunk-IQGLIQSO.js +188 -0
- package/dist/web-components/chunk-ITHLKR7Q.js +105 -0
- package/dist/web-components/chunk-K5CE6HSB.js +169 -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-LSC4N56Q.js +168 -0
- package/dist/web-components/chunk-LY62SAVN.js +64 -0
- package/dist/web-components/chunk-O4UFI2RX.js +244 -0
- package/dist/web-components/chunk-O7I63SQX.js +124 -0
- package/dist/web-components/chunk-OHUTLSIQ.js +69 -0
- package/dist/web-components/chunk-OQTRTMAB.js +27 -0
- package/dist/web-components/chunk-OTX4COSV.js +187 -0
- package/dist/web-components/chunk-PY62FTRW.js +179 -0
- package/dist/web-components/chunk-Q4T5BJT6.js +94 -0
- package/dist/web-components/chunk-QDRH46TF.js +281 -0
- package/dist/web-components/chunk-QDST57JC.js +119 -0
- package/dist/web-components/chunk-QPOKHLMQ.js +45 -0
- package/dist/web-components/chunk-SOQQ7RVJ.js +88 -0
- package/dist/web-components/chunk-UFFCKVZE.js +149 -0
- package/dist/web-components/chunk-VM3YHGQ2.js +152 -0
- package/dist/web-components/chunk-VMMVWLXL.js +53 -0
- package/dist/web-components/chunk-VSS5ITNE.js +109 -0
- package/dist/web-components/chunk-XIENXR7H.js +118 -0
- package/dist/web-components/chunk-Y4MAXTMA.js +80 -0
- package/dist/web-components/chunk-YLVTEY23.js +165 -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 +71 -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 +169 -4
- package/src/web-components/index.ts +47 -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 +99 -0
- 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 +224 -0
- package/src/web-components/interaction/bds-drawer.spec.ts +113 -0
- package/src/web-components/interaction/bds-drawer.ts +266 -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/bds-checkbox.spec.ts +63 -0
- package/src/web-components/interaction/form/bds-checkbox.ts +168 -0
- package/src/web-components/interaction/form/bds-combobox.spec.ts +117 -0
- package/src/web-components/interaction/form/bds-combobox.ts +336 -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 +221 -0
- package/src/web-components/interaction/form/bds-radio.spec.ts +70 -0
- package/src/web-components/interaction/form/bds-radio.ts +157 -0
- package/src/web-components/interaction/form/bds-segmented-control.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-segmented-control.ts +211 -0
- package/src/web-components/interaction/form/bds-select.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-select.ts +190 -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 +166 -0
- package/src/web-components/interaction/form/bds-textarea.spec.ts +55 -0
- package/src/web-components/interaction/form/bds-textarea.ts +143 -0
- 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 +156 -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 +185 -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,142 @@
|
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
|
+
|
|
3
|
+
const SIZE_PX = { small: 40, medium: 64, large: 96 } as const;
|
|
4
|
+
const STROKE_WIDTH = 4;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `<bds-progress-circle>` — framework-agnostic circular Progress custom element.
|
|
8
|
+
*
|
|
9
|
+
* Attributes:
|
|
10
|
+
* value — current progress value (required)
|
|
11
|
+
* max — maximum value (default: 100)
|
|
12
|
+
* label — accessible label for the progress bar
|
|
13
|
+
* show-value — boolean; when set, displays the percentage in the centre
|
|
14
|
+
* size — "small" | "medium" (default) | "large"
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* <bds-progress-circle value="75" label="Loading" show-value></bds-progress-circle>
|
|
18
|
+
*/
|
|
19
|
+
export class BdsProgressCircle extends LitElement {
|
|
20
|
+
static styles = css`
|
|
21
|
+
:host {
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
justify-content: center;
|
|
25
|
+
position: relative;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.svg {
|
|
29
|
+
display: block;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.track {
|
|
33
|
+
stroke: var(--bds-color_bg--subtle);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.fill {
|
|
37
|
+
stroke: var(--progressCircle_color-active, var(--bdc-color_active));
|
|
38
|
+
transition: stroke-dashoffset var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.value {
|
|
42
|
+
position: absolute;
|
|
43
|
+
font-size: var(--bds-font_size--body--s);
|
|
44
|
+
font-weight: var(--bds-font_weight--semibold);
|
|
45
|
+
font-variant-numeric: tabular-nums;
|
|
46
|
+
color: var(--bds-color_on-bg);
|
|
47
|
+
line-height: 1;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:host([size='small']) .value { font-size: 0.5rem; }
|
|
51
|
+
:host([size='large']) .value { font-size: var(--bds-font_size--body); }
|
|
52
|
+
|
|
53
|
+
@media (prefers-reduced-motion: reduce) {
|
|
54
|
+
.fill {
|
|
55
|
+
transition: none;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
static properties = {
|
|
61
|
+
value: { type: Number },
|
|
62
|
+
max: { type: Number },
|
|
63
|
+
label: { type: String },
|
|
64
|
+
showValue: { type: Boolean, attribute: 'show-value', reflect: true },
|
|
65
|
+
size: { type: String, reflect: true },
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
declare value: number;
|
|
69
|
+
declare max: number;
|
|
70
|
+
declare label: string;
|
|
71
|
+
declare showValue: boolean;
|
|
72
|
+
declare size: 'small' | 'medium' | 'large';
|
|
73
|
+
|
|
74
|
+
constructor() {
|
|
75
|
+
super();
|
|
76
|
+
this.value = 0;
|
|
77
|
+
this.max = 100;
|
|
78
|
+
this.label = '';
|
|
79
|
+
this.showValue = false;
|
|
80
|
+
this.size = 'medium';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
render() {
|
|
84
|
+
const percentage = Math.min(100, Math.max(0, (this.value / this.max) * 100));
|
|
85
|
+
const px = SIZE_PX[this.size] ?? SIZE_PX.medium;
|
|
86
|
+
const radius = (px - STROKE_WIDTH * 2) / 2;
|
|
87
|
+
const circumference = 2 * Math.PI * radius;
|
|
88
|
+
const offset = circumference - (percentage / 100) * circumference;
|
|
89
|
+
const cx = px / 2;
|
|
90
|
+
|
|
91
|
+
return html`
|
|
92
|
+
<div
|
|
93
|
+
role="progressbar"
|
|
94
|
+
aria-label=${this.label}
|
|
95
|
+
aria-valuenow=${this.value}
|
|
96
|
+
aria-valuemin="0"
|
|
97
|
+
aria-valuemax=${this.max}
|
|
98
|
+
style="position: relative; display: inline-flex; align-items: center; justify-content: center;"
|
|
99
|
+
>
|
|
100
|
+
<svg
|
|
101
|
+
class="svg"
|
|
102
|
+
width=${px}
|
|
103
|
+
height=${px}
|
|
104
|
+
viewBox="0 0 ${px} ${px}"
|
|
105
|
+
aria-hidden="true"
|
|
106
|
+
>
|
|
107
|
+
<circle
|
|
108
|
+
class="track"
|
|
109
|
+
cx=${cx}
|
|
110
|
+
cy=${cx}
|
|
111
|
+
r=${radius}
|
|
112
|
+
stroke-width=${STROKE_WIDTH}
|
|
113
|
+
fill="none"
|
|
114
|
+
/>
|
|
115
|
+
<circle
|
|
116
|
+
class="fill"
|
|
117
|
+
cx=${cx}
|
|
118
|
+
cy=${cx}
|
|
119
|
+
r=${radius}
|
|
120
|
+
stroke-width=${STROKE_WIDTH}
|
|
121
|
+
fill="none"
|
|
122
|
+
stroke-dasharray=${circumference}
|
|
123
|
+
stroke-dashoffset=${offset}
|
|
124
|
+
stroke-linecap="round"
|
|
125
|
+
transform="rotate(-90 ${cx} ${cx})"
|
|
126
|
+
/>
|
|
127
|
+
</svg>
|
|
128
|
+
${this.showValue
|
|
129
|
+
? html`<span class="value" aria-hidden="true">${Math.round(percentage)}%</span>`
|
|
130
|
+
: nothing}
|
|
131
|
+
</div>
|
|
132
|
+
`;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
customElements.define('bds-progress-circle', BdsProgressCircle);
|
|
137
|
+
|
|
138
|
+
declare global {
|
|
139
|
+
interface HTMLElementTagNameMap {
|
|
140
|
+
'bds-progress-circle': BdsProgressCircle;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsProgress } from './bds-progress';
|
|
3
|
+
|
|
4
|
+
describe('bds-progress', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-progress')).toBe(BdsProgress);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('defaults to max=100 and size="medium"', async () => {
|
|
10
|
+
const el = await fixture('<bds-progress value="50" label="Loading"></bds-progress>') as BdsProgress;
|
|
11
|
+
expect(el.max).toBe(100);
|
|
12
|
+
expect(el.getAttribute('size')).toBe('medium');
|
|
13
|
+
cleanup(el);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('renders a progressbar track in shadow DOM', async () => {
|
|
17
|
+
const el = await fixture('<bds-progress value="50" label="Loading"></bds-progress>');
|
|
18
|
+
const track = el.shadowRoot!.querySelector('.track');
|
|
19
|
+
expect(track).not.toBeNull();
|
|
20
|
+
expect(track!.getAttribute('role')).toBe('progressbar');
|
|
21
|
+
cleanup(el);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('sets aria-label, aria-valuenow, aria-valuemax on the track', async () => {
|
|
25
|
+
const el = await fixture('<bds-progress value="60" max="200" label="Upload"></bds-progress>');
|
|
26
|
+
const track = el.shadowRoot!.querySelector('.track');
|
|
27
|
+
expect(track!.getAttribute('aria-label')).toBe('Upload');
|
|
28
|
+
expect(track!.getAttribute('aria-valuenow')).toBe('60');
|
|
29
|
+
expect(track!.getAttribute('aria-valuemax')).toBe('200');
|
|
30
|
+
cleanup(el);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('does not render the label row by default', async () => {
|
|
34
|
+
const el = await fixture('<bds-progress value="50" label="Loading"></bds-progress>');
|
|
35
|
+
expect(el.shadowRoot!.querySelector('.label-row')).toBeNull();
|
|
36
|
+
cleanup(el);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('renders label row when show-label is set', async () => {
|
|
40
|
+
const el = await fixture('<bds-progress value="50" label="Upload" show-label></bds-progress>');
|
|
41
|
+
const labelRow = el.shadowRoot!.querySelector('.label-row');
|
|
42
|
+
expect(labelRow).not.toBeNull();
|
|
43
|
+
expect(labelRow!.querySelector('.label')!.textContent).toBe('Upload');
|
|
44
|
+
cleanup(el);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('clamps percentage to 100 for value > max', async () => {
|
|
48
|
+
const el = await fixture('<bds-progress value="150" label="Done" show-label></bds-progress>');
|
|
49
|
+
const valueSpan = el.shadowRoot!.querySelector('.value');
|
|
50
|
+
expect(valueSpan!.textContent).toBe('100%');
|
|
51
|
+
cleanup(el);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('clamps percentage to 0 for negative value', async () => {
|
|
55
|
+
const el = await fixture('<bds-progress value="-10" label="Done" show-label></bds-progress>');
|
|
56
|
+
const valueSpan = el.shadowRoot!.querySelector('.value');
|
|
57
|
+
expect(valueSpan!.textContent).toBe('0%');
|
|
58
|
+
cleanup(el);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('reflects size attribute', async () => {
|
|
62
|
+
const el = await fixture('<bds-progress value="50" label="Loading" size="large"></bds-progress>') as BdsProgress;
|
|
63
|
+
expect(el.getAttribute('size')).toBe('large');
|
|
64
|
+
cleanup(el);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `<bds-progress>` — framework-agnostic Progress bar custom element.
|
|
5
|
+
*
|
|
6
|
+
* Attributes:
|
|
7
|
+
* value — current progress value (required)
|
|
8
|
+
* max — maximum value (default: 100)
|
|
9
|
+
* label — accessible label for the progress bar
|
|
10
|
+
* show-label — boolean; when set, displays the label and percentage above the bar
|
|
11
|
+
* size — "small" | "medium" (default) | "large"
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <bds-progress value="60" label="Upload progress" show-label></bds-progress>
|
|
15
|
+
*/
|
|
16
|
+
export class BdsProgress extends LitElement {
|
|
17
|
+
static styles = css`
|
|
18
|
+
:host {
|
|
19
|
+
display: block;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.container {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
gap: var(--bds-space_xxs);
|
|
26
|
+
inline-size: 100%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.label-row {
|
|
30
|
+
display: flex;
|
|
31
|
+
justify-content: space-between;
|
|
32
|
+
align-items: baseline;
|
|
33
|
+
font-size: var(--bds-font_size--body--s);
|
|
34
|
+
color: var(--bds-color_on-bg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.value {
|
|
38
|
+
font-variant-numeric: tabular-nums;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.track {
|
|
42
|
+
inline-size: 100%;
|
|
43
|
+
block-size: var(--progress_height, var(--bds-space_xs));
|
|
44
|
+
background-color: var(--bds-color_bg--subtle);
|
|
45
|
+
border-radius: 999px;
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
:host([size='small']) .track { --progress_height: var(--bds-space_xxs); }
|
|
50
|
+
:host([size='medium']) .track { --progress_height: var(--bds-space_xs); }
|
|
51
|
+
:host([size='large']) .track { --progress_height: var(--bds-space_s); }
|
|
52
|
+
|
|
53
|
+
.fill {
|
|
54
|
+
block-size: 100%;
|
|
55
|
+
background-color: var(--progress_color-active, var(--bdc-color_active));
|
|
56
|
+
border-radius: 999px;
|
|
57
|
+
transition: inline-size var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (prefers-reduced-motion: reduce) {
|
|
61
|
+
.fill {
|
|
62
|
+
transition: none;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
static properties = {
|
|
68
|
+
value: { type: Number },
|
|
69
|
+
max: { type: Number },
|
|
70
|
+
label: { type: String },
|
|
71
|
+
showLabel: { type: Boolean, attribute: 'show-label', reflect: true },
|
|
72
|
+
size: { type: String, reflect: true },
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
declare value: number;
|
|
76
|
+
declare max: number;
|
|
77
|
+
declare label: string;
|
|
78
|
+
declare showLabel: boolean;
|
|
79
|
+
declare size: 'small' | 'medium' | 'large';
|
|
80
|
+
|
|
81
|
+
constructor() {
|
|
82
|
+
super();
|
|
83
|
+
this.value = 0;
|
|
84
|
+
this.max = 100;
|
|
85
|
+
this.label = '';
|
|
86
|
+
this.showLabel = false;
|
|
87
|
+
this.size = 'medium';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private get _percentage(): number {
|
|
91
|
+
return Math.min(100, Math.max(0, (this.value / this.max) * 100));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
render() {
|
|
95
|
+
const pct = this._percentage;
|
|
96
|
+
return html`
|
|
97
|
+
<div class="container">
|
|
98
|
+
${this.showLabel
|
|
99
|
+
? html`
|
|
100
|
+
<div class="label-row">
|
|
101
|
+
<span class="label">${this.label}</span>
|
|
102
|
+
<span class="value">${Math.round(pct)}%</span>
|
|
103
|
+
</div>
|
|
104
|
+
`
|
|
105
|
+
: nothing}
|
|
106
|
+
<div
|
|
107
|
+
class="track"
|
|
108
|
+
role="progressbar"
|
|
109
|
+
aria-label=${this.label}
|
|
110
|
+
aria-valuenow=${this.value}
|
|
111
|
+
aria-valuemin="0"
|
|
112
|
+
aria-valuemax=${this.max}
|
|
113
|
+
>
|
|
114
|
+
<div class="fill" style="inline-size: ${pct}%"></div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
customElements.define('bds-progress', BdsProgress);
|
|
122
|
+
|
|
123
|
+
declare global {
|
|
124
|
+
interface HTMLElementTagNameMap {
|
|
125
|
+
'bds-progress': BdsProgress;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsRating } from './bds-rating';
|
|
3
|
+
|
|
4
|
+
describe('bds-rating', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-rating')).toBe(BdsRating);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('defaults to max=5', async () => {
|
|
10
|
+
const el = await fixture('<bds-rating value="3"></bds-rating>') as BdsRating;
|
|
11
|
+
expect(el.max).toBe(5);
|
|
12
|
+
cleanup(el);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders a container with role="img"', async () => {
|
|
16
|
+
const el = await fixture('<bds-rating value="3"></bds-rating>');
|
|
17
|
+
const container = el.shadowRoot!.querySelector('.rating');
|
|
18
|
+
expect(container!.getAttribute('role')).toBe('img');
|
|
19
|
+
cleanup(el);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('sets aria-label with value and max', async () => {
|
|
23
|
+
const el = await fixture('<bds-rating value="3"></bds-rating>');
|
|
24
|
+
const container = el.shadowRoot!.querySelector('.rating');
|
|
25
|
+
expect(container!.getAttribute('aria-label')).toBe('3 out of 5 stars');
|
|
26
|
+
cleanup(el);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('renders max number of star SVGs', async () => {
|
|
30
|
+
const el = await fixture('<bds-rating value="3"></bds-rating>');
|
|
31
|
+
const stars = el.shadowRoot!.querySelectorAll('.star');
|
|
32
|
+
expect(stars.length).toBe(5);
|
|
33
|
+
cleanup(el);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('marks the correct stars as filled', async () => {
|
|
37
|
+
const el = await fixture('<bds-rating value="3"></bds-rating>');
|
|
38
|
+
const stars = el.shadowRoot!.querySelectorAll('.star');
|
|
39
|
+
const filledStars = [...stars].filter(s => s.classList.contains('--filled'));
|
|
40
|
+
expect(filledStars.length).toBe(3);
|
|
41
|
+
cleanup(el);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('renders correct count with custom max', async () => {
|
|
45
|
+
const el = await fixture('<bds-rating value="2" max="10"></bds-rating>');
|
|
46
|
+
const stars = el.shadowRoot!.querySelectorAll('.star');
|
|
47
|
+
expect(stars.length).toBe(10);
|
|
48
|
+
const filledStars = [...stars].filter(s => s.classList.contains('--filled'));
|
|
49
|
+
expect(filledStars.length).toBe(2);
|
|
50
|
+
cleanup(el);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('stars have aria-hidden="true"', async () => {
|
|
54
|
+
const el = await fixture('<bds-rating value="3"></bds-rating>');
|
|
55
|
+
const stars = el.shadowRoot!.querySelectorAll('.star');
|
|
56
|
+
[...stars].forEach(star => {
|
|
57
|
+
expect(star.getAttribute('aria-hidden')).toBe('true');
|
|
58
|
+
});
|
|
59
|
+
cleanup(el);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('updates when value property changes', async () => {
|
|
63
|
+
const el = await fixture('<bds-rating value="1"></bds-rating>') as BdsRating;
|
|
64
|
+
el.value = 4;
|
|
65
|
+
await el.updateComplete;
|
|
66
|
+
const filledStars = [...el.shadowRoot!.querySelectorAll('.star')].filter(s => s.classList.contains('--filled'));
|
|
67
|
+
expect(filledStars.length).toBe(4);
|
|
68
|
+
cleanup(el);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { LitElement, css, html } from 'lit';
|
|
2
|
+
|
|
3
|
+
const STAR_PATH = 'M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `<bds-rating>` — framework-agnostic read-only star Rating custom element.
|
|
7
|
+
*
|
|
8
|
+
* Attributes:
|
|
9
|
+
* value — number of filled stars
|
|
10
|
+
* max — total number of stars (default: 5)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* <bds-rating value="3"></bds-rating>
|
|
14
|
+
* <bds-rating value="4" max="10"></bds-rating>
|
|
15
|
+
*/
|
|
16
|
+
export class BdsRating extends LitElement {
|
|
17
|
+
static styles = css`
|
|
18
|
+
:host {
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.rating {
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
gap: var(--bds-space_xxxs);
|
|
25
|
+
color: var(--bds-color_bg);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.star {
|
|
29
|
+
inline-size: 1.5em;
|
|
30
|
+
block-size: 1.5em;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.star.--filled {
|
|
34
|
+
color: var(--bds-color_warning);
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
static properties = {
|
|
39
|
+
value: { type: Number },
|
|
40
|
+
max: { type: Number },
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
declare value: number;
|
|
44
|
+
declare max: number;
|
|
45
|
+
|
|
46
|
+
constructor() {
|
|
47
|
+
super();
|
|
48
|
+
this.value = 0;
|
|
49
|
+
this.max = 5;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
render() {
|
|
53
|
+
return html`
|
|
54
|
+
<div
|
|
55
|
+
class="rating"
|
|
56
|
+
role="img"
|
|
57
|
+
aria-label="${this.value} out of ${this.max} stars"
|
|
58
|
+
>
|
|
59
|
+
${Array.from({ length: this.max }, (_, i) => html`
|
|
60
|
+
<svg
|
|
61
|
+
class="star ${i < this.value ? '--filled' : ''}"
|
|
62
|
+
aria-hidden="true"
|
|
63
|
+
fill="currentColor"
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
>
|
|
66
|
+
<path d=${STAR_PATH} />
|
|
67
|
+
</svg>
|
|
68
|
+
`)}
|
|
69
|
+
</div>
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
customElements.define('bds-rating', BdsRating);
|
|
75
|
+
|
|
76
|
+
declare global {
|
|
77
|
+
interface HTMLElementTagNameMap {
|
|
78
|
+
'bds-rating': BdsRating;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsSectionHeader } from './bds-section-header';
|
|
3
|
+
|
|
4
|
+
describe('bds-section-header', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-section-header')).toBe(BdsSectionHeader);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('renders an <h2> title by default', async () => {
|
|
10
|
+
const el = await fixture('<bds-section-header title="Hello"></bds-section-header>');
|
|
11
|
+
const h2 = el.shadowRoot!.querySelector('h2');
|
|
12
|
+
expect(h2).not.toBeNull();
|
|
13
|
+
expect(h2!.textContent).toBe('Hello');
|
|
14
|
+
cleanup(el);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders the title text', async () => {
|
|
18
|
+
const el = await fixture('<bds-section-header title="Welcome"></bds-section-header>');
|
|
19
|
+
expect(el.shadowRoot!.querySelector('.title')!.textContent).toBe('Welcome');
|
|
20
|
+
cleanup(el);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('does not render subtitle when not set', async () => {
|
|
24
|
+
const el = await fixture('<bds-section-header title="Hello"></bds-section-header>');
|
|
25
|
+
expect(el.shadowRoot!.querySelector('.subtitle')).toBeNull();
|
|
26
|
+
cleanup(el);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('renders subtitle when set', async () => {
|
|
30
|
+
const el = await fixture('<bds-section-header title="Hello" subtitle="Subtitle text"></bds-section-header>');
|
|
31
|
+
const subtitle = el.shadowRoot!.querySelector('.subtitle');
|
|
32
|
+
expect(subtitle).not.toBeNull();
|
|
33
|
+
expect(subtitle!.textContent).toBe('Subtitle text');
|
|
34
|
+
cleanup(el);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('uses title-as to override the title element', async () => {
|
|
38
|
+
const el = await fixture('<bds-section-header title="Hello" title-as="h1"></bds-section-header>');
|
|
39
|
+
expect(el.shadowRoot!.querySelector('h1')).not.toBeNull();
|
|
40
|
+
expect(el.shadowRoot!.querySelector('h2')).toBeNull();
|
|
41
|
+
cleanup(el);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('applies alignment class', async () => {
|
|
45
|
+
const el = await fixture('<bds-section-header title="Hello" alignment="center"></bds-section-header>');
|
|
46
|
+
const header = el.shadowRoot!.querySelector('.header');
|
|
47
|
+
expect(header!.classList.contains('--center')).toBe(true);
|
|
48
|
+
cleanup(el);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('applies size class', async () => {
|
|
52
|
+
const el = await fixture('<bds-section-header title="Hello" size="large"></bds-section-header>');
|
|
53
|
+
const header = el.shadowRoot!.querySelector('.header');
|
|
54
|
+
expect(header!.classList.contains('--large')).toBe(true);
|
|
55
|
+
cleanup(el);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
|
+
import { html as staticHtml, unsafeStatic } from 'lit/static-html.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `<bds-section-header>` — framework-agnostic Section Header custom element.
|
|
6
|
+
*
|
|
7
|
+
* Attributes:
|
|
8
|
+
* title — heading text (required)
|
|
9
|
+
* subtitle — optional subheading text
|
|
10
|
+
* alignment — "start" (default) | "center" | "end"
|
|
11
|
+
* size — "small" | "medium" (default) | "large"
|
|
12
|
+
* title-as — tag name for the title element (default: "h2")
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* <bds-section-header title="Our Products" subtitle="Browse the full range" size="large"></bds-section-header>
|
|
16
|
+
*/
|
|
17
|
+
export class BdsSectionHeader extends LitElement {
|
|
18
|
+
static styles = css`
|
|
19
|
+
:host {
|
|
20
|
+
display: block;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.header {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: var(--bds-space_m);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.title {
|
|
30
|
+
color: var(--sectionHeader-title-color, var(--bds-color_on-bg));
|
|
31
|
+
margin: 0;
|
|
32
|
+
font-family: var(--bds-font_family--body);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.subtitle {
|
|
36
|
+
color: var(--sectionHeader_subtitle-color, var(--bds-color_grey--strong));
|
|
37
|
+
margin: 0;
|
|
38
|
+
font-family: var(--bds-font_family--body);
|
|
39
|
+
font-weight: var(--bds-font_weight--medium);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.header.--start { align-items: flex-start; text-align: start; }
|
|
43
|
+
.header.--center { align-items: center; text-align: center; }
|
|
44
|
+
.header.--end { align-items: flex-end; text-align: end; }
|
|
45
|
+
|
|
46
|
+
.header.--small .title { font-size: var(--bds-font_size--heading-1); line-height: var(--bds-font_line-height--heading); font-weight: var(--bds-font_weight--bold); }
|
|
47
|
+
.header.--small .subtitle { font-size: var(--bds-font_size--body); line-height: 1.4; }
|
|
48
|
+
|
|
49
|
+
.header.--medium .title { font-size: var(--bds-font_size--display); line-height: var(--bds-font_line-height--display); font-weight: var(--bds-font_weight--bold); }
|
|
50
|
+
.header.--medium .subtitle { font-size: var(--bds-font_size--heading-3); line-height: 1.3; }
|
|
51
|
+
|
|
52
|
+
.header.--large .title { font-size: var(--bds-font_size--display); line-height: var(--bds-font_line-height--display); font-weight: var(--bds-font_weight--bold); letter-spacing: var(--bds-font_tracking--tight); }
|
|
53
|
+
.header.--large .subtitle { font-size: var(--bds-font_size--heading-2); line-height: 1.3; font-weight: var(--bds-font_weight--medium); }
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
static properties = {
|
|
57
|
+
title: { type: String },
|
|
58
|
+
subtitle: { type: String },
|
|
59
|
+
alignment: { type: String, reflect: true },
|
|
60
|
+
size: { type: String, reflect: true },
|
|
61
|
+
titleAs: { type: String, attribute: 'title-as' },
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
declare title: string;
|
|
65
|
+
declare subtitle: string;
|
|
66
|
+
declare alignment: 'start' | 'center' | 'end';
|
|
67
|
+
declare size: 'small' | 'medium' | 'large';
|
|
68
|
+
declare titleAs: string;
|
|
69
|
+
|
|
70
|
+
constructor() {
|
|
71
|
+
super();
|
|
72
|
+
this.title = '';
|
|
73
|
+
this.subtitle = '';
|
|
74
|
+
this.alignment = 'start';
|
|
75
|
+
this.size = 'medium';
|
|
76
|
+
this.titleAs = 'h2';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
render() {
|
|
80
|
+
const tag = unsafeStatic(this.titleAs || 'h2');
|
|
81
|
+
return html`
|
|
82
|
+
<div class="header --${this.alignment} --${this.size}">
|
|
83
|
+
${staticHtml`<${tag} class="title">${this.title}</${tag}>`}
|
|
84
|
+
${this.subtitle ? html`<p class="subtitle">${this.subtitle}</p>` : nothing}
|
|
85
|
+
</div>
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
customElements.define('bds-section-header', BdsSectionHeader);
|
|
91
|
+
|
|
92
|
+
declare global {
|
|
93
|
+
interface HTMLElementTagNameMap {
|
|
94
|
+
'bds-section-header': BdsSectionHeader;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsSeparator } from './bds-separator';
|
|
3
|
+
|
|
4
|
+
describe('bds-separator', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-separator')).toBe(BdsSeparator);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('defaults to orientation="horizontal"', async () => {
|
|
10
|
+
const el = await fixture('<bds-separator></bds-separator>');
|
|
11
|
+
expect(el.getAttribute('orientation')).toBe('horizontal');
|
|
12
|
+
cleanup(el);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders a separator div in shadow DOM', async () => {
|
|
16
|
+
const el = await fixture('<bds-separator></bds-separator>');
|
|
17
|
+
const sep = el.shadowRoot!.querySelector('.separator');
|
|
18
|
+
expect(sep).not.toBeNull();
|
|
19
|
+
cleanup(el);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('has role="separator"', async () => {
|
|
23
|
+
const el = await fixture('<bds-separator></bds-separator>');
|
|
24
|
+
const sep = el.shadowRoot!.querySelector('.separator');
|
|
25
|
+
expect(sep!.getAttribute('role')).toBe('separator');
|
|
26
|
+
cleanup(el);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('sets aria-orientation="horizontal" by default', async () => {
|
|
30
|
+
const el = await fixture('<bds-separator></bds-separator>');
|
|
31
|
+
const sep = el.shadowRoot!.querySelector('.separator');
|
|
32
|
+
expect(sep!.getAttribute('aria-orientation')).toBe('horizontal');
|
|
33
|
+
cleanup(el);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('sets aria-orientation="vertical" when orientation="vertical"', async () => {
|
|
37
|
+
const el = await fixture('<bds-separator orientation="vertical"></bds-separator>');
|
|
38
|
+
const sep = el.shadowRoot!.querySelector('.separator');
|
|
39
|
+
expect(sep!.getAttribute('aria-orientation')).toBe('vertical');
|
|
40
|
+
cleanup(el);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('reflects orientation property to attribute', async () => {
|
|
44
|
+
const el = await fixture('<bds-separator></bds-separator>') as BdsSeparator;
|
|
45
|
+
el.orientation = 'vertical';
|
|
46
|
+
await el.updateComplete;
|
|
47
|
+
expect(el.getAttribute('orientation')).toBe('vertical');
|
|
48
|
+
cleanup(el);
|
|
49
|
+
});
|
|
50
|
+
});
|