@bluevolt-tech/lumen 1.5.1 → 2.0.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.
Files changed (47) hide show
  1. package/dist/components/bv-alert-banner/bv-alert-banner.d.ts +33 -0
  2. package/dist/components/bv-alert-banner/bv-alert-banner.js +206 -0
  3. package/dist/components/bv-badge/bv-badge.d.ts +1 -1
  4. package/dist/components/bv-badge/bv-badge.js +1 -1
  5. package/dist/components/bv-button/bv-button.d.ts +1 -1
  6. package/dist/components/bv-button/bv-button.js +7 -2
  7. package/dist/components/bv-checkbox/bv-checkbox.js +1 -1
  8. package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +7 -2
  9. package/dist/components/bv-course-grid-card/bv-course-grid-card.d.ts +0 -1
  10. package/dist/components/bv-course-grid-card/bv-course-grid-card.js +8 -12
  11. package/dist/components/bv-course-list-card/bv-course-list-card.js +7 -2
  12. package/dist/components/bv-date-range-input/bv-date-range-input.d.ts +23 -0
  13. package/dist/components/bv-date-range-input/bv-date-range-input.js +950 -0
  14. package/dist/components/bv-date-range-picker/bv-date-range-picker.d.ts +56 -0
  15. package/dist/components/bv-date-range-picker/bv-date-range-picker.js +778 -0
  16. package/dist/components/bv-empty-state/bv-empty-state.js +7 -2
  17. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +20 -5
  18. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +263 -25
  19. package/dist/components/bv-filter-panel/bv-filter-panel.js +1 -1
  20. package/dist/components/bv-icon/bv-icon.js +1 -0
  21. package/dist/components/bv-input/bv-input.d.ts +24 -0
  22. package/dist/components/bv-input/bv-input.js +148 -0
  23. package/dist/components/bv-input-dropdown/bv-input-dropdown.d.ts +46 -0
  24. package/dist/components/bv-input-dropdown/bv-input-dropdown.js +501 -0
  25. package/dist/components/bv-pagination/bv-pagination.d.ts +13 -1
  26. package/dist/components/bv-pagination/bv-pagination.js +290 -9
  27. package/dist/components/bv-portal-header/bv-portal-header.js +63 -5
  28. package/dist/components/bv-searchbox/bv-searchbox.js +1 -1
  29. package/dist/components/bv-segmented-control/bv-segmented-control.d.ts +26 -0
  30. package/dist/components/bv-segmented-control/bv-segmented-control.js +128 -0
  31. package/dist/components/bv-select/bv-select.d.ts +41 -0
  32. package/dist/components/bv-select/bv-select.js +240 -0
  33. package/dist/components/bv-split-button/bv-split-button.d.ts +37 -0
  34. package/dist/components/bv-split-button/bv-split-button.js +264 -0
  35. package/dist/components/bv-table/bv-table.d.ts +15 -0
  36. package/dist/components/bv-table/bv-table.js +260 -33
  37. package/dist/components/bv-toggle/bv-toggle.d.ts +2 -1
  38. package/dist/components/bv-toggle/bv-toggle.js +2 -2
  39. package/dist/components/bv-tooltip/bv-tooltip.d.ts +18 -0
  40. package/dist/components/bv-tooltip/bv-tooltip.js +144 -0
  41. package/dist/components/bv-user-row/bv-user-row.d.ts +1 -0
  42. package/dist/components/bv-user-row/bv-user-row.js +62 -4
  43. package/dist/storybook/stories/screens/cet-report.data.d.ts +55 -0
  44. package/dist/storybook/stories/screens/cet-report.data.js +3697 -0
  45. package/dist/themes/base.css +14 -1
  46. package/package.json +42 -1
  47. package/themes/base.css +14 -1
@@ -0,0 +1,128 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-segmented-control/bv-segmented-control.css
2
+ var bv_segmented_control_default = ":host {\n display: block;\n font-family: var(--bv-font-family-base);\n}\n\n.field-label {\n display: block;\n font-size: var(--bv-font-size-sm);\n line-height: 20px;\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-800);\n margin-bottom: 6px;\n}\n\n.field-label[hidden] {\n display: none;\n}\n\n.required-mark {\n color: var(--bv-color-danger);\n margin-left: 2px;\n}\n\n.container {\n display: flex;\n align-items: center;\n height: 44px;\n box-sizing: border-box;\n background: var(--bv-color-neutral-100);\n border: 1px solid var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-lg);\n padding: 3px;\n gap: 2px;\n}\n\n.pill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 0 var(--bv-spacing-md);\n border: none;\n border-radius: calc(var(--bv-radius-lg) - 3px);\n background: transparent;\n font-family: inherit;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-500);\n cursor: pointer;\n white-space: nowrap;\n user-select: none;\n transition:\n color var(--bv-transition-fast),\n background var(--bv-transition-fast),\n box-shadow var(--bv-transition-fast);\n}\n\n.pill:hover:not(.selected) {\n color: var(--bv-color-neutral-800);\n}\n\n.pill.selected {\n background: var(--bv-color-neutral-0);\n color: var(--bv-color-neutral-900);\n box-shadow: var(--bv-shadow-sm);\n}\n";
3
+
4
+ // components/bv-segmented-control/bv-segmented-control.ts
5
+ var _sheet = null;
6
+ function getSheet() {
7
+ if (!_sheet) {
8
+ _sheet = new CSSStyleSheet();
9
+ _sheet.replaceSync(bv_segmented_control_default);
10
+ }
11
+ return _sheet;
12
+ }
13
+ var BvSegmentedControl = class extends HTMLElement {
14
+ static observedAttributes = ["options", "value", "label", "required"];
15
+ _rendered = false;
16
+ _labelEl = null;
17
+ _containerEl = null;
18
+ _options = [];
19
+ constructor() {
20
+ super();
21
+ const shadow = this.attachShadow({ mode: "open" });
22
+ if ("adoptedStyleSheets" in ShadowRoot.prototype) {
23
+ shadow.adoptedStyleSheets = [getSheet()];
24
+ }
25
+ }
26
+ get value() {
27
+ return this.getAttribute("value") ?? "";
28
+ }
29
+ set value(v) {
30
+ this.setAttribute("value", v);
31
+ }
32
+ get required() {
33
+ return this.hasAttribute("required");
34
+ }
35
+ set required(v) {
36
+ if (v) this.setAttribute("required", "");
37
+ else this.removeAttribute("required");
38
+ }
39
+ connectedCallback() {
40
+ this._render();
41
+ }
42
+ attributeChangedCallback(name, _old, _val) {
43
+ if (!this._rendered) return;
44
+ if (name === "options") this._syncOptions();
45
+ if (name === "value") this._syncSelected();
46
+ if (name === "label" || name === "required") this._syncLabel();
47
+ }
48
+ _render() {
49
+ if (this._rendered) return;
50
+ this._rendered = true;
51
+ const shadow = this.shadowRoot;
52
+ if (!shadow.adoptedStyleSheets.length) {
53
+ const s = document.createElement("style");
54
+ s.textContent = bv_segmented_control_default;
55
+ shadow.appendChild(s);
56
+ }
57
+ const labelEl = document.createElement("span");
58
+ labelEl.className = "field-label";
59
+ this._labelEl = labelEl;
60
+ const container = document.createElement("div");
61
+ container.className = "container";
62
+ container.setAttribute("role", "group");
63
+ this._containerEl = container;
64
+ shadow.append(labelEl, container);
65
+ this._syncLabel();
66
+ this._syncOptions();
67
+ }
68
+ _syncLabel() {
69
+ if (!this._labelEl || !this._containerEl) return;
70
+ const text = this.getAttribute("label") ?? "";
71
+ this._labelEl.textContent = text;
72
+ if (this.hasAttribute("required")) {
73
+ const mark = document.createElement("span");
74
+ mark.className = "required-mark";
75
+ mark.setAttribute("aria-hidden", "true");
76
+ mark.textContent = "*";
77
+ this._labelEl.appendChild(mark);
78
+ }
79
+ this._labelEl.hidden = !text;
80
+ if (text) this._containerEl.setAttribute("aria-label", text);
81
+ else this._containerEl.removeAttribute("aria-label");
82
+ }
83
+ _syncOptions() {
84
+ if (!this._containerEl) return;
85
+ try {
86
+ this._options = JSON.parse(this.getAttribute("options") ?? "[]");
87
+ } catch {
88
+ this._options = [];
89
+ }
90
+ this._containerEl.innerHTML = "";
91
+ for (const opt of this._options) {
92
+ const btn = document.createElement("button");
93
+ btn.type = "button";
94
+ btn.className = "pill";
95
+ btn.dataset["value"] = opt.value;
96
+ btn.textContent = opt.label;
97
+ btn.setAttribute("aria-pressed", "false");
98
+ btn.addEventListener("click", () => {
99
+ if (this.value === opt.value) return;
100
+ this.value = opt.value;
101
+ this.dispatchEvent(
102
+ new CustomEvent("bv-change", {
103
+ bubbles: true,
104
+ composed: true,
105
+ detail: { value: opt.value, label: opt.label }
106
+ })
107
+ );
108
+ });
109
+ this._containerEl.appendChild(btn);
110
+ }
111
+ this._syncSelected();
112
+ }
113
+ _syncSelected() {
114
+ if (!this._containerEl) return;
115
+ const current = this.value;
116
+ for (const btn of this._containerEl.querySelectorAll(".pill")) {
117
+ const isSelected = btn.dataset["value"] === current;
118
+ btn.classList.toggle("selected", isSelected);
119
+ btn.setAttribute("aria-pressed", isSelected ? "true" : "false");
120
+ }
121
+ }
122
+ };
123
+ if (!customElements.get("bv-segmented-control")) {
124
+ customElements.define("bv-segmented-control", BvSegmentedControl);
125
+ }
126
+ export {
127
+ BvSegmentedControl
128
+ };
@@ -0,0 +1,41 @@
1
+ export interface SelectOption {
2
+ label: string;
3
+ value: string;
4
+ }
5
+ export interface SelectChangeDetail {
6
+ value: string;
7
+ label: string;
8
+ }
9
+ export declare class BvSelect extends HTMLElement {
10
+ static readonly observedAttributes: readonly ["label", "options", "value", "placeholder", "error", "required", "disabled"];
11
+ private _rendered;
12
+ private _labelEl;
13
+ private _triggerEl;
14
+ private _triggerLabelEl;
15
+ private _panelEl;
16
+ private _errorEl;
17
+ private _options;
18
+ private _value;
19
+ private _offClick;
20
+ constructor();
21
+ get value(): string;
22
+ set value(v: string);
23
+ get disabled(): boolean;
24
+ set disabled(v: boolean);
25
+ get required(): boolean;
26
+ set required(v: boolean);
27
+ connectedCallback(): void;
28
+ disconnectedCallback(): void;
29
+ attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
30
+ private _render;
31
+ private _toggle;
32
+ private _open;
33
+ private _close;
34
+ private _syncLabel;
35
+ private _syncTriggerLabel;
36
+ private _renderOptions;
37
+ private _syncSelected;
38
+ private _syncError;
39
+ private _syncDisabled;
40
+ private _select;
41
+ }
@@ -0,0 +1,240 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-select/bv-select.css
2
+ var bv_select_default = ":host {\n display: block;\n position: relative;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Label \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.field-label {\n display: block;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-800);\n margin-bottom: 6px;\n}\n\n.required-mark {\n color: var(--bv-color-danger);\n margin-left: 2px;\n}\n\n/* \u2500\u2500 Trigger \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 44px;\n padding: 0 var(--bv-spacing-md);\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-lg);\n cursor: pointer;\n font-family: inherit;\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-800);\n text-align: left;\n transition:\n border-color var(--bv-transition-fast),\n box-shadow var(--bv-transition-fast);\n}\n\n.trigger:focus-visible {\n outline: none;\n border-color: var(--bv-color-primary);\n box-shadow:\n 0 0 0 3px var(--bv-color-primary-light),\n 0 1px 2px 0 rgba(16, 24, 40, 0.05);\n}\n\n:host([open]) .trigger {\n border-color: var(--bv-color-primary);\n box-shadow:\n 0 0 0 3px var(--bv-color-primary-light),\n 0 1px 2px 0 rgba(16, 24, 40, 0.05);\n}\n\n:host([error]:not([error=''])) .trigger {\n border-color: var(--bv-color-danger);\n}\n\n.trigger:disabled {\n background: var(--bv-color-neutral-100);\n color: var(--bv-color-neutral-400);\n cursor: not-allowed;\n}\n\n.trigger-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.trigger-label.is-placeholder {\n color: var(--bv-color-neutral-400);\n}\n\n.trigger-chevron {\n display: flex;\n color: var(--bv-color-neutral-500);\n flex-shrink: 0;\n margin-left: var(--bv-spacing-sm);\n transition: transform var(--bv-transition-fast);\n}\n\n:host([open]) .trigger-chevron {\n transform: rotate(180deg);\n}\n\n/* \u2500\u2500 Dropdown panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.panel {\n display: none;\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-lg);\n box-shadow: var(--bv-shadow-md);\n z-index: 200;\n overflow: hidden;\n padding: var(--bv-spacing-xs) 0;\n}\n\n:host([open]) .panel {\n display: block;\n}\n\n/* \u2500\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--bv-spacing-sm);\n padding: 10px var(--bv-spacing-md);\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-700);\n cursor: pointer;\n transition: background var(--bv-transition-fast);\n}\n\n.option:hover {\n background: var(--bv-color-secondary);\n}\n\n.option[aria-selected='true'] {\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n background: var(--bv-color-secondary-light);\n}\n\n.option-text {\n flex: 1;\n}\n\n.option-check {\n display: none;\n color: var(--bv-color-primary);\n flex-shrink: 0;\n}\n\n.option[aria-selected='true'] .option-check {\n display: flex;\n}\n\n/* \u2500\u2500 Error message \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.field-error {\n display: block;\n font-size: var(--bv-font-size-xs);\n color: var(--bv-color-danger);\n margin-top: var(--bv-spacing-xs);\n}\n";
3
+
4
+ // components/bv-select/bv-select.ts
5
+ var CHEVRON_DOWN = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>`;
6
+ var CHECK = `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>`;
7
+ var _sheet = null;
8
+ function getSheet() {
9
+ if (!_sheet) {
10
+ _sheet = new CSSStyleSheet();
11
+ _sheet.replaceSync(bv_select_default);
12
+ }
13
+ return _sheet;
14
+ }
15
+ var BvSelect = class extends HTMLElement {
16
+ static observedAttributes = [
17
+ "label",
18
+ "options",
19
+ "value",
20
+ "placeholder",
21
+ "error",
22
+ "required",
23
+ "disabled"
24
+ ];
25
+ _rendered = false;
26
+ _labelEl = null;
27
+ _triggerEl = null;
28
+ _triggerLabelEl = null;
29
+ _panelEl = null;
30
+ _errorEl = null;
31
+ _options = [];
32
+ _value = "";
33
+ _offClick = null;
34
+ constructor() {
35
+ super();
36
+ const shadow = this.attachShadow({ mode: "open" });
37
+ if ("adoptedStyleSheets" in ShadowRoot.prototype) {
38
+ shadow.adoptedStyleSheets = [getSheet()];
39
+ }
40
+ }
41
+ get value() {
42
+ return this._value;
43
+ }
44
+ set value(v) {
45
+ this.setAttribute("value", v);
46
+ }
47
+ get disabled() {
48
+ return this.hasAttribute("disabled");
49
+ }
50
+ set disabled(v) {
51
+ if (v) this.setAttribute("disabled", "");
52
+ else this.removeAttribute("disabled");
53
+ }
54
+ get required() {
55
+ return this.hasAttribute("required");
56
+ }
57
+ set required(v) {
58
+ if (v) this.setAttribute("required", "");
59
+ else this.removeAttribute("required");
60
+ }
61
+ connectedCallback() {
62
+ this._render();
63
+ }
64
+ disconnectedCallback() {
65
+ if (this._offClick) document.removeEventListener("click", this._offClick);
66
+ }
67
+ attributeChangedCallback(name, _old, val) {
68
+ if (name === "options") {
69
+ try {
70
+ this._options = JSON.parse(val ?? "[]");
71
+ } catch {
72
+ this._options = [];
73
+ }
74
+ if (this._rendered) this._renderOptions();
75
+ }
76
+ if (name === "value") {
77
+ this._value = val ?? "";
78
+ if (this._rendered) {
79
+ this._syncTriggerLabel();
80
+ this._syncSelected();
81
+ }
82
+ }
83
+ if (!this._rendered) return;
84
+ if (name === "label" || name === "required") this._syncLabel();
85
+ if (name === "error") this._syncError();
86
+ if (name === "disabled") this._syncDisabled();
87
+ if (name === "placeholder") this._syncTriggerLabel();
88
+ }
89
+ _render() {
90
+ if (this._rendered) return;
91
+ this._rendered = true;
92
+ try {
93
+ this._options = JSON.parse(this.getAttribute("options") ?? "[]");
94
+ } catch {
95
+ this._options = [];
96
+ }
97
+ this._value = this.getAttribute("value") ?? "";
98
+ const shadow = this.shadowRoot;
99
+ if (!shadow.adoptedStyleSheets.length) {
100
+ const s = document.createElement("style");
101
+ s.textContent = bv_select_default;
102
+ shadow.appendChild(s);
103
+ }
104
+ const label = document.createElement("label");
105
+ label.className = "field-label";
106
+ this._labelEl = label;
107
+ const trigger = document.createElement("button");
108
+ trigger.type = "button";
109
+ trigger.className = "trigger";
110
+ trigger.setAttribute("aria-haspopup", "listbox");
111
+ trigger.setAttribute("aria-expanded", "false");
112
+ trigger.setAttribute("part", "trigger");
113
+ this._triggerEl = trigger;
114
+ const triggerLabel = document.createElement("span");
115
+ triggerLabel.className = "trigger-label";
116
+ this._triggerLabelEl = triggerLabel;
117
+ const chevron = document.createElement("span");
118
+ chevron.className = "trigger-chevron";
119
+ chevron.innerHTML = CHEVRON_DOWN;
120
+ trigger.append(triggerLabel, chevron);
121
+ trigger.addEventListener("click", (e) => {
122
+ e.stopPropagation();
123
+ if (!this.hasAttribute("disabled")) this._toggle();
124
+ });
125
+ const panel = document.createElement("div");
126
+ panel.className = "panel";
127
+ panel.setAttribute("role", "listbox");
128
+ this._panelEl = panel;
129
+ const errorEl = document.createElement("span");
130
+ errorEl.className = "field-error";
131
+ errorEl.setAttribute("aria-live", "polite");
132
+ this._errorEl = errorEl;
133
+ shadow.append(label, trigger, panel, errorEl);
134
+ this._syncLabel();
135
+ this._syncTriggerLabel();
136
+ this._renderOptions();
137
+ this._syncError();
138
+ this._syncDisabled();
139
+ this._offClick = (e) => {
140
+ if (!this.contains(e.target) && !shadow.contains(e.target)) {
141
+ this._close();
142
+ }
143
+ };
144
+ document.addEventListener("click", this._offClick);
145
+ this.addEventListener("keydown", (e) => {
146
+ if (e.key === "Escape") this._close();
147
+ });
148
+ }
149
+ _toggle() {
150
+ if (this.hasAttribute("open")) this._close();
151
+ else this._open();
152
+ }
153
+ _open() {
154
+ var _a;
155
+ this.setAttribute("open", "");
156
+ (_a = this._triggerEl) == null ? void 0 : _a.setAttribute("aria-expanded", "true");
157
+ }
158
+ _close() {
159
+ var _a;
160
+ this.removeAttribute("open");
161
+ (_a = this._triggerEl) == null ? void 0 : _a.setAttribute("aria-expanded", "false");
162
+ }
163
+ _syncLabel() {
164
+ if (!this._labelEl) return;
165
+ const labelText = this.getAttribute("label") ?? "";
166
+ this._labelEl.textContent = labelText;
167
+ if (this.hasAttribute("required")) {
168
+ const mark = document.createElement("span");
169
+ mark.className = "required-mark";
170
+ mark.setAttribute("aria-hidden", "true");
171
+ mark.textContent = "*";
172
+ this._labelEl.appendChild(mark);
173
+ }
174
+ this._labelEl.hidden = !labelText;
175
+ }
176
+ _syncTriggerLabel() {
177
+ if (!this._triggerLabelEl) return;
178
+ const match = this._options.find((o) => o.value === this._value);
179
+ const placeholder = this.getAttribute("placeholder") ?? "Select";
180
+ this._triggerLabelEl.textContent = (match == null ? void 0 : match.label) ?? placeholder;
181
+ this._triggerLabelEl.classList.toggle("is-placeholder", !match);
182
+ }
183
+ _renderOptions() {
184
+ if (!this._panelEl) return;
185
+ this._panelEl.innerHTML = "";
186
+ for (const opt of this._options) {
187
+ const item = document.createElement("div");
188
+ item.className = "option";
189
+ item.setAttribute("role", "option");
190
+ item.setAttribute("aria-selected", opt.value === this._value ? "true" : "false");
191
+ const text = document.createElement("span");
192
+ text.className = "option-text";
193
+ text.textContent = opt.label;
194
+ const check = document.createElement("span");
195
+ check.className = "option-check";
196
+ check.innerHTML = CHECK;
197
+ item.append(text, check);
198
+ item.addEventListener("click", () => this._select(opt));
199
+ this._panelEl.appendChild(item);
200
+ }
201
+ }
202
+ _syncSelected() {
203
+ var _a;
204
+ (_a = this._panelEl) == null ? void 0 : _a.querySelectorAll(".option").forEach((el, i) => {
205
+ const opt = this._options[i];
206
+ el.setAttribute("aria-selected", (opt == null ? void 0 : opt.value) === this._value ? "true" : "false");
207
+ });
208
+ this._syncTriggerLabel();
209
+ }
210
+ _syncError() {
211
+ if (!this._errorEl) return;
212
+ const msg = this.getAttribute("error") ?? "";
213
+ this._errorEl.textContent = msg;
214
+ this._errorEl.hidden = !msg;
215
+ }
216
+ _syncDisabled() {
217
+ if (!this._triggerEl) return;
218
+ this._triggerEl.disabled = this.hasAttribute("disabled");
219
+ }
220
+ _select(opt) {
221
+ this._value = opt.value;
222
+ this.setAttribute("value", opt.value);
223
+ this._syncTriggerLabel();
224
+ this._syncSelected();
225
+ this._close();
226
+ this.dispatchEvent(
227
+ new CustomEvent("bv-change", {
228
+ bubbles: true,
229
+ composed: true,
230
+ detail: { value: opt.value, label: opt.label }
231
+ })
232
+ );
233
+ }
234
+ };
235
+ if (!customElements.get("bv-select")) {
236
+ customElements.define("bv-select", BvSelect);
237
+ }
238
+ export {
239
+ BvSelect
240
+ };
@@ -0,0 +1,37 @@
1
+ export type SplitButtonVariant = 'primary' | 'secondary' | 'outline' | 'outline-secondary';
2
+ export interface SplitButtonOption {
3
+ value: string;
4
+ label: string;
5
+ description?: string;
6
+ icon?: string;
7
+ }
8
+ export interface SplitButtonSelectDetail {
9
+ value: string;
10
+ }
11
+ export declare class BvSplitButton extends HTMLElement {
12
+ static readonly observedAttributes: readonly ["label", "variant", "disabled", "options", "open"];
13
+ private _rendered;
14
+ private _mainBtn;
15
+ private _toggleBtn;
16
+ private _labelEl;
17
+ private _panelEl;
18
+ private _offClick;
19
+ constructor();
20
+ get label(): string;
21
+ set label(v: string);
22
+ get variant(): SplitButtonVariant;
23
+ set variant(v: SplitButtonVariant);
24
+ get disabled(): boolean;
25
+ set disabled(v: boolean);
26
+ get options(): SplitButtonOption[];
27
+ set options(v: SplitButtonOption[]);
28
+ connectedCallback(): void;
29
+ disconnectedCallback(): void;
30
+ attributeChangedCallback(name: string, _old: string | null, _val: string | null): void;
31
+ private _render;
32
+ private _toggle;
33
+ private _open;
34
+ private _close;
35
+ private _syncDisabled;
36
+ private _syncPanel;
37
+ }