@bluevolt-tech/lumen 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -23
- package/dist/components/_shared/adopt-styles.d.ts +8 -0
- package/dist/components/_shared/date-range-validator.d.ts +61 -0
- package/dist/components/_shared/dropdown-controller.d.ts +31 -0
- package/dist/components/_shared/selectable-card.d.ts +10 -0
- package/dist/components/bv-alert-banner/bv-alert-banner.js +19 -17
- package/dist/components/bv-avatar/bv-avatar.js +19 -11
- package/dist/components/bv-badge/bv-badge.js +19 -11
- package/dist/components/bv-button/bv-button.js +18 -16
- package/dist/components/bv-category-pill/bv-category-pill.js +18 -16
- package/dist/components/bv-checkbox/bv-checkbox.js +19 -11
- package/dist/components/bv-chip/bv-chip.js +19 -11
- package/dist/components/bv-course-detail/bv-course-detail.js +20 -34
- package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +24 -90
- package/dist/components/bv-course-grid-card/bv-course-grid-card.d.ts +2 -2
- package/dist/components/bv-course-grid-card/bv-course-grid-card.js +105 -55
- package/dist/components/bv-course-list-card/bv-course-list-card.d.ts +2 -2
- package/dist/components/bv-course-list-card/bv-course-list-card.js +105 -55
- package/dist/components/bv-course-outline/bv-course-outline.js +19 -11
- package/dist/components/bv-date-range-input/bv-date-range-input.d.ts +4 -6
- package/dist/components/bv-date-range-input/bv-date-range-input.js +460 -122
- package/dist/components/bv-date-range-picker/bv-date-range-picker.d.ts +17 -3
- package/dist/components/bv-date-range-picker/bv-date-range-picker.js +339 -73
- package/dist/components/bv-empty-state/bv-empty-state.js +20 -28
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +1 -4
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +78 -53
- package/dist/components/bv-filter-panel/bv-filter-panel.js +20 -22
- package/dist/components/bv-icon/bv-icon.js +19 -11
- package/dist/components/bv-input/bv-input.js +18 -16
- package/dist/components/bv-input-dropdown/bv-input-dropdown.d.ts +1 -4
- package/dist/components/bv-input-dropdown/bv-input-dropdown.js +77 -78
- package/dist/components/bv-modal/bv-modal.js +19 -11
- package/dist/components/bv-page-title/bv-page-title.js +19 -6
- package/dist/components/bv-pagination/bv-pagination.d.ts +1 -0
- package/dist/components/bv-pagination/bv-pagination.js +23 -186
- package/dist/components/bv-portal-header/bv-portal-header.js +25 -83
- package/dist/components/bv-portal-layout/bv-portal-layout.js +19 -11
- package/dist/components/bv-progress-bar/bv-progress-bar.js +19 -11
- package/dist/components/bv-promo-banner/bv-promo-banner.js +19 -11
- package/dist/components/bv-radio/bv-radio.js +19 -11
- package/dist/components/bv-searchbox/bv-searchbox.js +19 -11
- package/dist/components/bv-segmented-control/bv-segmented-control.js +18 -16
- package/dist/components/bv-select/bv-select.d.ts +1 -4
- package/dist/components/bv-select/bv-select.js +76 -44
- package/dist/components/bv-split-button/bv-split-button.d.ts +1 -4
- package/dist/components/bv-split-button/bv-split-button.js +76 -42
- package/dist/components/bv-star-rating/bv-star-rating.js +19 -11
- package/dist/components/bv-table/bv-table.d.ts +5 -0
- package/dist/components/bv-table/bv-table.js +69 -19
- package/dist/components/bv-toggle/bv-toggle.js +19 -11
- package/dist/components/bv-tooltip/bv-tooltip.js +19 -17
- package/dist/components/bv-user-row/bv-user-row.js +22 -50
- package/dist/components/bv-view-switcher/bv-view-switcher.js +19 -11
- package/dist/themes/base.css +2 -1
- package/package.json +8 -1
- package/themes/base.css +2 -1
|
@@ -1,17 +1,76 @@
|
|
|
1
1
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-select/bv-select.css
|
|
2
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
3
|
|
|
4
|
+
// components/_shared/adopt-styles.ts
|
|
5
|
+
var _sheetCache = /* @__PURE__ */ new Map();
|
|
6
|
+
function adoptStyles(shadow, css) {
|
|
7
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype && typeof CSSStyleSheet !== "undefined" && "replaceSync" in CSSStyleSheet.prototype) {
|
|
8
|
+
let sheet = _sheetCache.get(css);
|
|
9
|
+
if (!sheet) {
|
|
10
|
+
sheet = new CSSStyleSheet();
|
|
11
|
+
sheet.replaceSync(css);
|
|
12
|
+
_sheetCache.set(css, sheet);
|
|
13
|
+
}
|
|
14
|
+
shadow.adoptedStyleSheets = [sheet];
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const style = document.createElement("style");
|
|
18
|
+
style.textContent = css;
|
|
19
|
+
shadow.appendChild(style);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// components/_shared/dropdown-controller.ts
|
|
23
|
+
function bindDropdownController(host, options = {}) {
|
|
24
|
+
const shadow = host.shadowRoot;
|
|
25
|
+
if (!shadow) {
|
|
26
|
+
throw new Error("bindDropdownController requires the host to have an open shadow root.");
|
|
27
|
+
}
|
|
28
|
+
const syncExpanded = () => {
|
|
29
|
+
var _a;
|
|
30
|
+
(_a = options.trigger) == null ? void 0 : _a.setAttribute("aria-expanded", host.hasAttribute("open") ? "true" : "false");
|
|
31
|
+
};
|
|
32
|
+
const open = () => {
|
|
33
|
+
var _a;
|
|
34
|
+
if (host.hasAttribute("open")) return;
|
|
35
|
+
(_a = options.onBeforeOpen) == null ? void 0 : _a.call(options);
|
|
36
|
+
host.setAttribute("open", "");
|
|
37
|
+
syncExpanded();
|
|
38
|
+
host.dispatchEvent(new CustomEvent("bv-open", { bubbles: true, composed: true }));
|
|
39
|
+
};
|
|
40
|
+
const close = () => {
|
|
41
|
+
if (!host.hasAttribute("open")) return;
|
|
42
|
+
host.removeAttribute("open");
|
|
43
|
+
syncExpanded();
|
|
44
|
+
};
|
|
45
|
+
const toggle = () => {
|
|
46
|
+
if (host.hasAttribute("open")) close();
|
|
47
|
+
else open();
|
|
48
|
+
};
|
|
49
|
+
const offClick = (e) => {
|
|
50
|
+
if (!host.hasAttribute("open")) return;
|
|
51
|
+
const target = e.target;
|
|
52
|
+
if (host.contains(target) || shadow.contains(target)) return;
|
|
53
|
+
close();
|
|
54
|
+
};
|
|
55
|
+
document.addEventListener("click", offClick);
|
|
56
|
+
const onKeyDown = (e) => {
|
|
57
|
+
if (e.key === "Escape") close();
|
|
58
|
+
};
|
|
59
|
+
host.addEventListener("keydown", onKeyDown);
|
|
60
|
+
const observer = new MutationObserver(syncExpanded);
|
|
61
|
+
observer.observe(host, { attributes: true, attributeFilter: ["open"] });
|
|
62
|
+
const cleanup = () => {
|
|
63
|
+
observer.disconnect();
|
|
64
|
+
document.removeEventListener("click", offClick);
|
|
65
|
+
host.removeEventListener("keydown", onKeyDown);
|
|
66
|
+
};
|
|
67
|
+
syncExpanded();
|
|
68
|
+
return { open, close, toggle, cleanup };
|
|
69
|
+
}
|
|
70
|
+
|
|
4
71
|
// components/bv-select/bv-select.ts
|
|
5
72
|
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
73
|
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
74
|
var BvSelect = class extends HTMLElement {
|
|
16
75
|
static observedAttributes = [
|
|
17
76
|
"label",
|
|
@@ -30,13 +89,10 @@ var BvSelect = class extends HTMLElement {
|
|
|
30
89
|
_errorEl = null;
|
|
31
90
|
_options = [];
|
|
32
91
|
_value = "";
|
|
33
|
-
|
|
92
|
+
_dropdown = null;
|
|
34
93
|
constructor() {
|
|
35
94
|
super();
|
|
36
|
-
|
|
37
|
-
if ("adoptedStyleSheets" in ShadowRoot.prototype) {
|
|
38
|
-
shadow.adoptedStyleSheets = [getSheet()];
|
|
39
|
-
}
|
|
95
|
+
adoptStyles(this.attachShadow({ mode: "open" }), bv_select_default);
|
|
40
96
|
}
|
|
41
97
|
get value() {
|
|
42
98
|
return this._value;
|
|
@@ -62,7 +118,8 @@ var BvSelect = class extends HTMLElement {
|
|
|
62
118
|
this._render();
|
|
63
119
|
}
|
|
64
120
|
disconnectedCallback() {
|
|
65
|
-
|
|
121
|
+
var _a;
|
|
122
|
+
(_a = this._dropdown) == null ? void 0 : _a.cleanup();
|
|
66
123
|
}
|
|
67
124
|
attributeChangedCallback(name, _old, val) {
|
|
68
125
|
if (name === "options") {
|
|
@@ -96,11 +153,6 @@ var BvSelect = class extends HTMLElement {
|
|
|
96
153
|
}
|
|
97
154
|
this._value = this.getAttribute("value") ?? "";
|
|
98
155
|
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
156
|
const label = document.createElement("label");
|
|
105
157
|
label.className = "field-label";
|
|
106
158
|
this._labelEl = label;
|
|
@@ -119,8 +171,9 @@ var BvSelect = class extends HTMLElement {
|
|
|
119
171
|
chevron.innerHTML = CHEVRON_DOWN;
|
|
120
172
|
trigger.append(triggerLabel, chevron);
|
|
121
173
|
trigger.addEventListener("click", (e) => {
|
|
174
|
+
var _a;
|
|
122
175
|
e.stopPropagation();
|
|
123
|
-
if (!this.hasAttribute("disabled")) this.
|
|
176
|
+
if (!this.hasAttribute("disabled")) (_a = this._dropdown) == null ? void 0 : _a.toggle();
|
|
124
177
|
});
|
|
125
178
|
const panel = document.createElement("div");
|
|
126
179
|
panel.className = "panel";
|
|
@@ -136,29 +189,7 @@ var BvSelect = class extends HTMLElement {
|
|
|
136
189
|
this._renderOptions();
|
|
137
190
|
this._syncError();
|
|
138
191
|
this._syncDisabled();
|
|
139
|
-
this.
|
|
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");
|
|
192
|
+
this._dropdown = bindDropdownController(this, { trigger });
|
|
162
193
|
}
|
|
163
194
|
_syncLabel() {
|
|
164
195
|
if (!this._labelEl) return;
|
|
@@ -218,11 +249,12 @@ var BvSelect = class extends HTMLElement {
|
|
|
218
249
|
this._triggerEl.disabled = this.hasAttribute("disabled");
|
|
219
250
|
}
|
|
220
251
|
_select(opt) {
|
|
252
|
+
var _a;
|
|
221
253
|
this._value = opt.value;
|
|
222
254
|
this.setAttribute("value", opt.value);
|
|
223
255
|
this._syncTriggerLabel();
|
|
224
256
|
this._syncSelected();
|
|
225
|
-
this.
|
|
257
|
+
(_a = this._dropdown) == null ? void 0 : _a.close();
|
|
226
258
|
this.dispatchEvent(
|
|
227
259
|
new CustomEvent("bv-change", {
|
|
228
260
|
bubbles: true,
|
|
@@ -15,7 +15,7 @@ export declare class BvSplitButton extends HTMLElement {
|
|
|
15
15
|
private _toggleBtn;
|
|
16
16
|
private _labelEl;
|
|
17
17
|
private _panelEl;
|
|
18
|
-
private
|
|
18
|
+
private _dropdown;
|
|
19
19
|
constructor();
|
|
20
20
|
get label(): string;
|
|
21
21
|
set label(v: string);
|
|
@@ -29,9 +29,6 @@ export declare class BvSplitButton extends HTMLElement {
|
|
|
29
29
|
disconnectedCallback(): void;
|
|
30
30
|
attributeChangedCallback(name: string, _old: string | null, _val: string | null): void;
|
|
31
31
|
private _render;
|
|
32
|
-
private _toggle;
|
|
33
|
-
private _open;
|
|
34
|
-
private _close;
|
|
35
32
|
private _syncDisabled;
|
|
36
33
|
private _syncPanel;
|
|
37
34
|
}
|
|
@@ -1,6 +1,73 @@
|
|
|
1
1
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-split-button/bv-split-button.css
|
|
2
2
|
var bv_split_button_default = ":host {\n --bv-button-bg: var(--bv-color-primary);\n --bv-button-bg-hover: color-mix(in srgb, var(--bv-color-primary) 82%, black);\n --bv-button-color: var(--bv-color-neutral-0);\n --bv-button-border-color: var(--bv-color-primary);\n\n display: inline-flex;\n position: relative;\n font-family: var(--bv-font-family-base);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n/* \u2500\u2500 Variants \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:host([variant='secondary']) {\n --bv-button-bg: var(--bv-color-secondary);\n --bv-button-bg-hover: color-mix(in srgb, var(--bv-color-secondary) 82%, black);\n --bv-button-color: var(--bv-color-neutral-0);\n --bv-button-border-color: var(--bv-color-secondary);\n}\n\n:host([variant='outline']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-neutral-100);\n --bv-button-color: var(--bv-color-primary);\n --bv-button-border-color: var(--bv-color-primary);\n}\n\n:host([variant='outline-secondary']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-neutral-100);\n --bv-button-color: var(--bv-color-neutral-700);\n --bv-button-border-color: var(--bv-color-neutral-300);\n}\n\n/* \u2500\u2500 Wrap \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.wrap {\n display: flex;\n align-items: stretch;\n width: 100%;\n}\n\n/* \u2500\u2500 Main button \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.main-btn {\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0 var(--bv-spacing-md);\n min-height: 44px;\n background: var(--bv-button-bg);\n color: var(--bv-button-color);\n border: none;\n border-radius: var(--bv-radius-lg) 0 0 var(--bv-radius-lg);\n font-family: inherit;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n cursor: pointer;\n white-space: nowrap;\n transition: background var(--bv-transition-fast);\n}\n\n.main-btn:hover:not(:disabled) {\n background: var(--bv-button-bg-hover);\n}\n\n/* \u2500\u2500 Divider \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.divider {\n width: 1px;\n background: var(--bv-button-color);\n opacity: 0.25;\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Toggle button \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.toggle-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n flex-shrink: 0;\n background: var(--bv-button-bg);\n color: var(--bv-button-color);\n border: none;\n border-radius: 0 var(--bv-radius-lg) var(--bv-radius-lg) 0;\n cursor: pointer;\n transition: background var(--bv-transition-fast);\n}\n\n.toggle-btn:hover:not(:disabled) {\n background: var(--bv-button-bg-hover);\n}\n\n.main-btn:disabled,\n.toggle-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* \u2500\u2500 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\u2500\u2500\u2500\u2500\u2500 */\n\n.panel {\n display: none;\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 220px;\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 padding: var(--bv-spacing-xs) 0;\n}\n\n:host([open]) .panel {\n display: block;\n}\n\n/* \u2500\u2500 Option \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 gap: var(--bv-spacing-sm);\n width: 100%;\n padding: var(--bv-spacing-sm) var(--bv-spacing-md);\n background: transparent;\n border: none;\n text-align: left;\n cursor: pointer;\n font-family: inherit;\n transition: background var(--bv-transition-fast);\n}\n\n.option:hover {\n background: var(--bv-color-neutral-100);\n}\n\n.option-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--bv-color-neutral-600);\n flex-shrink: 0;\n}\n\n.option-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.option-label {\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-700);\n line-height: 1.4;\n}\n\n.option-desc {\n font-size: var(--bv-font-size-xs);\n color: var(--bv-color-neutral-500);\n line-height: 1.4;\n}\n";
|
|
3
3
|
|
|
4
|
+
// components/_shared/adopt-styles.ts
|
|
5
|
+
var _sheetCache = /* @__PURE__ */ new Map();
|
|
6
|
+
function adoptStyles(shadow, css) {
|
|
7
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype && typeof CSSStyleSheet !== "undefined" && "replaceSync" in CSSStyleSheet.prototype) {
|
|
8
|
+
let sheet = _sheetCache.get(css);
|
|
9
|
+
if (!sheet) {
|
|
10
|
+
sheet = new CSSStyleSheet();
|
|
11
|
+
sheet.replaceSync(css);
|
|
12
|
+
_sheetCache.set(css, sheet);
|
|
13
|
+
}
|
|
14
|
+
shadow.adoptedStyleSheets = [sheet];
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const style = document.createElement("style");
|
|
18
|
+
style.textContent = css;
|
|
19
|
+
shadow.appendChild(style);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// components/_shared/dropdown-controller.ts
|
|
23
|
+
function bindDropdownController(host, options = {}) {
|
|
24
|
+
const shadow = host.shadowRoot;
|
|
25
|
+
if (!shadow) {
|
|
26
|
+
throw new Error("bindDropdownController requires the host to have an open shadow root.");
|
|
27
|
+
}
|
|
28
|
+
const syncExpanded = () => {
|
|
29
|
+
var _a;
|
|
30
|
+
(_a = options.trigger) == null ? void 0 : _a.setAttribute("aria-expanded", host.hasAttribute("open") ? "true" : "false");
|
|
31
|
+
};
|
|
32
|
+
const open = () => {
|
|
33
|
+
var _a;
|
|
34
|
+
if (host.hasAttribute("open")) return;
|
|
35
|
+
(_a = options.onBeforeOpen) == null ? void 0 : _a.call(options);
|
|
36
|
+
host.setAttribute("open", "");
|
|
37
|
+
syncExpanded();
|
|
38
|
+
host.dispatchEvent(new CustomEvent("bv-open", { bubbles: true, composed: true }));
|
|
39
|
+
};
|
|
40
|
+
const close = () => {
|
|
41
|
+
if (!host.hasAttribute("open")) return;
|
|
42
|
+
host.removeAttribute("open");
|
|
43
|
+
syncExpanded();
|
|
44
|
+
};
|
|
45
|
+
const toggle = () => {
|
|
46
|
+
if (host.hasAttribute("open")) close();
|
|
47
|
+
else open();
|
|
48
|
+
};
|
|
49
|
+
const offClick = (e) => {
|
|
50
|
+
if (!host.hasAttribute("open")) return;
|
|
51
|
+
const target = e.target;
|
|
52
|
+
if (host.contains(target) || shadow.contains(target)) return;
|
|
53
|
+
close();
|
|
54
|
+
};
|
|
55
|
+
document.addEventListener("click", offClick);
|
|
56
|
+
const onKeyDown = (e) => {
|
|
57
|
+
if (e.key === "Escape") close();
|
|
58
|
+
};
|
|
59
|
+
host.addEventListener("keydown", onKeyDown);
|
|
60
|
+
const observer = new MutationObserver(syncExpanded);
|
|
61
|
+
observer.observe(host, { attributes: true, attributeFilter: ["open"] });
|
|
62
|
+
const cleanup = () => {
|
|
63
|
+
observer.disconnect();
|
|
64
|
+
document.removeEventListener("click", offClick);
|
|
65
|
+
host.removeEventListener("keydown", onKeyDown);
|
|
66
|
+
};
|
|
67
|
+
syncExpanded();
|
|
68
|
+
return { open, close, toggle, cleanup };
|
|
69
|
+
}
|
|
70
|
+
|
|
4
71
|
// components/bv-icon/icons.ts
|
|
5
72
|
var icons = {
|
|
6
73
|
// Navigation
|
|
@@ -76,14 +143,6 @@ var rawIcons = {
|
|
|
76
143
|
|
|
77
144
|
// components/bv-split-button/bv-split-button.ts
|
|
78
145
|
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"><polyline points="6 9 12 15 18 9"/></svg>`;
|
|
79
|
-
var _sheet = null;
|
|
80
|
-
function getSheet() {
|
|
81
|
-
if (!_sheet) {
|
|
82
|
-
_sheet = new CSSStyleSheet();
|
|
83
|
-
_sheet.replaceSync(bv_split_button_default);
|
|
84
|
-
}
|
|
85
|
-
return _sheet;
|
|
86
|
-
}
|
|
87
146
|
var BvSplitButton = class extends HTMLElement {
|
|
88
147
|
static observedAttributes = ["label", "variant", "disabled", "options", "open"];
|
|
89
148
|
_rendered = false;
|
|
@@ -91,13 +150,10 @@ var BvSplitButton = class extends HTMLElement {
|
|
|
91
150
|
_toggleBtn = null;
|
|
92
151
|
_labelEl = null;
|
|
93
152
|
_panelEl = null;
|
|
94
|
-
|
|
153
|
+
_dropdown = null;
|
|
95
154
|
constructor() {
|
|
96
155
|
super();
|
|
97
|
-
|
|
98
|
-
if ("adoptedStyleSheets" in ShadowRoot.prototype) {
|
|
99
|
-
shadow.adoptedStyleSheets = [getSheet()];
|
|
100
|
-
}
|
|
156
|
+
adoptStyles(this.attachShadow({ mode: "open" }), bv_split_button_default);
|
|
101
157
|
}
|
|
102
158
|
get label() {
|
|
103
159
|
return this.getAttribute("label") ?? "";
|
|
@@ -132,7 +188,8 @@ var BvSplitButton = class extends HTMLElement {
|
|
|
132
188
|
this._render();
|
|
133
189
|
}
|
|
134
190
|
disconnectedCallback() {
|
|
135
|
-
|
|
191
|
+
var _a;
|
|
192
|
+
(_a = this._dropdown) == null ? void 0 : _a.cleanup();
|
|
136
193
|
}
|
|
137
194
|
attributeChangedCallback(name, _old, _val) {
|
|
138
195
|
if (!this._rendered) return;
|
|
@@ -144,11 +201,6 @@ var BvSplitButton = class extends HTMLElement {
|
|
|
144
201
|
if (this._rendered) return;
|
|
145
202
|
this._rendered = true;
|
|
146
203
|
const shadow = this.shadowRoot;
|
|
147
|
-
if (!shadow.adoptedStyleSheets.length) {
|
|
148
|
-
const s = document.createElement("style");
|
|
149
|
-
s.textContent = bv_split_button_default;
|
|
150
|
-
shadow.appendChild(s);
|
|
151
|
-
}
|
|
152
204
|
const wrap = document.createElement("div");
|
|
153
205
|
wrap.className = "wrap";
|
|
154
206
|
const mainBtn = document.createElement("button");
|
|
@@ -176,8 +228,9 @@ var BvSplitButton = class extends HTMLElement {
|
|
|
176
228
|
toggleBtn.setAttribute("aria-label", "More options");
|
|
177
229
|
toggleBtn.innerHTML = CHEVRON_DOWN;
|
|
178
230
|
toggleBtn.addEventListener("click", (e) => {
|
|
231
|
+
var _a;
|
|
179
232
|
e.stopPropagation();
|
|
180
|
-
if (!this.disabled) this.
|
|
233
|
+
if (!this.disabled) (_a = this._dropdown) == null ? void 0 : _a.toggle();
|
|
181
234
|
});
|
|
182
235
|
this._toggleBtn = toggleBtn;
|
|
183
236
|
wrap.append(mainBtn, divider, toggleBtn);
|
|
@@ -188,27 +241,7 @@ var BvSplitButton = class extends HTMLElement {
|
|
|
188
241
|
shadow.append(wrap, panel);
|
|
189
242
|
this._syncDisabled();
|
|
190
243
|
this._syncPanel();
|
|
191
|
-
this.
|
|
192
|
-
if (!this.contains(e.target) && !shadow.contains(e.target)) {
|
|
193
|
-
this._close();
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
document.addEventListener("click", this._offClick);
|
|
197
|
-
}
|
|
198
|
-
_toggle() {
|
|
199
|
-
if (this.hasAttribute("open")) this._close();
|
|
200
|
-
else this._open();
|
|
201
|
-
}
|
|
202
|
-
_open() {
|
|
203
|
-
var _a;
|
|
204
|
-
this.setAttribute("open", "");
|
|
205
|
-
(_a = this._toggleBtn) == null ? void 0 : _a.setAttribute("aria-expanded", "true");
|
|
206
|
-
this.dispatchEvent(new CustomEvent("bv-open", { bubbles: true, composed: true }));
|
|
207
|
-
}
|
|
208
|
-
_close() {
|
|
209
|
-
var _a;
|
|
210
|
-
this.removeAttribute("open");
|
|
211
|
-
(_a = this._toggleBtn) == null ? void 0 : _a.setAttribute("aria-expanded", "false");
|
|
244
|
+
this._dropdown = bindDropdownController(this, { trigger: toggleBtn });
|
|
212
245
|
}
|
|
213
246
|
_syncDisabled() {
|
|
214
247
|
const d = this.disabled;
|
|
@@ -243,7 +276,8 @@ var BvSplitButton = class extends HTMLElement {
|
|
|
243
276
|
}
|
|
244
277
|
btn.appendChild(content);
|
|
245
278
|
btn.addEventListener("click", () => {
|
|
246
|
-
|
|
279
|
+
var _a;
|
|
280
|
+
(_a = this._dropdown) == null ? void 0 : _a.close();
|
|
247
281
|
this.dispatchEvent(
|
|
248
282
|
new CustomEvent("bv-option-select", {
|
|
249
283
|
bubbles: true,
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-star-rating/bv-star-rating.css
|
|
2
2
|
var bv_star_rating_default = ":host {\n --bv-star-color: #f59e0b;\n --bv-star-empty-color: var(--bv-color-neutral-200);\n --bv-star-size: 20px;\n display: inline-flex;\n}\n\n:host([size='sm']) {\n --bv-star-size: 14px;\n}\n:host([size='lg']) {\n --bv-star-size: 28px;\n}\n\n.stars {\n display: inline-flex;\n gap: 2px;\n align-items: center;\n}\n\n.star {\n width: var(--bv-star-size);\n height: var(--bv-star-size);\n color: var(--bv-star-empty-color);\n flex-shrink: 0;\n transition: color var(--bv-transition-fast);\n}\n\n.star.filled {\n color: var(--bv-star-color);\n}\n";
|
|
3
3
|
|
|
4
|
+
// components/_shared/adopt-styles.ts
|
|
5
|
+
var _sheetCache = /* @__PURE__ */ new Map();
|
|
6
|
+
function adoptStyles(shadow, css) {
|
|
7
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype && typeof CSSStyleSheet !== "undefined" && "replaceSync" in CSSStyleSheet.prototype) {
|
|
8
|
+
let sheet = _sheetCache.get(css);
|
|
9
|
+
if (!sheet) {
|
|
10
|
+
sheet = new CSSStyleSheet();
|
|
11
|
+
sheet.replaceSync(css);
|
|
12
|
+
_sheetCache.set(css, sheet);
|
|
13
|
+
}
|
|
14
|
+
shadow.adoptedStyleSheets = [sheet];
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const style = document.createElement("style");
|
|
18
|
+
style.textContent = css;
|
|
19
|
+
shadow.appendChild(style);
|
|
20
|
+
}
|
|
21
|
+
|
|
4
22
|
// components/bv-star-rating/bv-star-rating.ts
|
|
5
23
|
var STAR_PATH = "M10 1.5L12.39 6.26L17.72 7.07L13.86 10.83L14.78 16.14L10 13.63L5.22 16.14L6.14 10.83L2.28 7.07L7.61 6.26L10 1.5Z";
|
|
6
24
|
var BvStarRating = class extends HTMLElement {
|
|
@@ -8,12 +26,7 @@ var BvStarRating = class extends HTMLElement {
|
|
|
8
26
|
_rendered = false;
|
|
9
27
|
constructor() {
|
|
10
28
|
super();
|
|
11
|
-
this.attachShadow({ mode: "open" });
|
|
12
|
-
if ("replaceSync" in CSSStyleSheet.prototype) {
|
|
13
|
-
const sheet = new CSSStyleSheet();
|
|
14
|
-
sheet.replaceSync(bv_star_rating_default);
|
|
15
|
-
this.shadowRoot.adoptedStyleSheets = [sheet];
|
|
16
|
-
}
|
|
29
|
+
adoptStyles(this.attachShadow({ mode: "open" }), bv_star_rating_default);
|
|
17
30
|
}
|
|
18
31
|
connectedCallback() {
|
|
19
32
|
this._render();
|
|
@@ -31,11 +44,6 @@ var BvStarRating = class extends HTMLElement {
|
|
|
31
44
|
if (this._rendered) return;
|
|
32
45
|
this._rendered = true;
|
|
33
46
|
const shadow = this.shadowRoot;
|
|
34
|
-
if (!shadow.adoptedStyleSheets.length) {
|
|
35
|
-
const s = document.createElement("style");
|
|
36
|
-
s.textContent = bv_star_rating_default;
|
|
37
|
-
shadow.appendChild(s);
|
|
38
|
-
}
|
|
39
47
|
const wrap = document.createElement("div");
|
|
40
48
|
wrap.className = "stars";
|
|
41
49
|
wrap.setAttribute("role", "img");
|
|
@@ -7,8 +7,13 @@ export declare class BvTable extends HTMLElement {
|
|
|
7
7
|
private _boundMouseDown;
|
|
8
8
|
private _boundMouseMove;
|
|
9
9
|
private _boundMouseUp;
|
|
10
|
+
get loading(): boolean;
|
|
11
|
+
set loading(v: boolean);
|
|
10
12
|
connectedCallback(): void;
|
|
11
13
|
disconnectedCallback(): void;
|
|
14
|
+
attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
|
|
15
|
+
private _renderSkeleton;
|
|
16
|
+
private _removeSkeleton;
|
|
12
17
|
private _setupDrag;
|
|
13
18
|
private _teardownDrag;
|
|
14
19
|
private _enhanceBodyCells;
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-table/bv-table.css
|
|
2
|
-
var bv_table_default = "bv-table {\n display: block;\n width: 100%;\n box-sizing: border-box;\n overflow-x: auto;\n border: 1px solid var(--bv-color-neutral-200);\n font-family: var(--bv-font-family-base);\n cursor: grab;\n}\n\n/* During drag: override cursor for the entire table and all children */\nbv-table[data-dragging],\nbv-table[data-dragging] * {\n cursor: grabbing !important;\n user-select: none !important;\n}\n\nbv-table tbody td {\n cursor: grab;\n}\n\n/* Only the rendered glyphs are text-selectable \u2014 see _enhanceBodyCells in bv-table.ts */\nbv-table tbody td .bv-cell-text {\n cursor: text;\n}\n\nbv-table table {\n width: 100%;\n border-collapse: collapse;\n min-width: 0;\n}\n\n/* \u2500\u2500 Header \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\u2500\u2500\u2500\u2500\u2500*/\n\nbv-table thead tr {\n background: var(--bv-color-neutral-100);\n}\n\nbv-table thead th {\n padding: 12px 16px;\n text-align: left;\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-800);\n border-bottom: 1px solid var(--bv-color-neutral-200);\n white-space: nowrap;\n user-select: none;\n vertical-align: middle;\n}\n\nbv-table thead th[data-sortable] {\n cursor: pointer;\n}\n\nbv-table thead th[data-sortable]:hover {\n color: var(--bv-color-neutral-700);\n}\n\nbv-table thead th[data-sort='asc'] .bv-sort-icon,\nbv-table thead th[data-sort='desc'] .bv-sort-icon {\n color: var(--bv-color-primary);\n}\n\n.bv-th-content {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.bv-sort-icon {\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Body \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\n\nbv-table tbody td {\n padding: 12px 16px;\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-700);\n border-bottom: 1px solid var(--bv-color-neutral-100);\n vertical-align: middle;\n white-space: nowrap;\n}\n\nbv-table tbody tr:last-child td {\n border-bottom: none;\n}\n\nbv-table tbody tr:hover td {\n background: var(--bv-color-neutral-100);\n}\n\n/* \u2500\u2500 Column alignment \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\nbv-table thead th[data-align='right'],\nbv-table tbody td[data-align='right'] {\n text-align: right;\n}\n\nbv-table thead th[data-align='center'],\nbv-table tbody td[data-align='center'] {\n text-align: center;\n}\n\n/* \u2500\u2500 Cell modifier classes \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/* Muted: em dash or empty placeholder */\nbv-table td.bv-cell-muted {\n color: var(--bv-color-neutral-400);\n}\n\n/* Hidden: redacted identity for external users */\nbv-table td.bv-cell-hidden {\n color: var(--bv-color-neutral-400);\n font-style: italic;\n}\n\n/* Colored text for numeric highlight states */\nbv-table td.bv-cell-success {\n color: var(--bv-color-success);\n font-weight: var(--bv-font-weight-medium);\n}\n\nbv-table td.bv-cell-warning {\n color: var(--bv-color-warning);\n font-weight: var(--bv-font-weight-medium);\n}\n\nbv-table td.bv-cell-danger {\n color: var(--bv-color-danger);\n font-weight: var(--bv-font-weight-medium);\n}\n\nbv-table td.bv-cell-info {\n color: var(--bv-color-primary);\n font-weight: var(--bv-font-weight-medium);\n}\n\n/* \u2500\u2500 Modifiers \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\u2500\u2500*/\n\nbv-table[striped] tbody tr:nth-child(even) td {\n background: var(--bv-color-neutral-100);\n}\n\nbv-table[bordered] thead th,\nbv-table[bordered] tbody td {\n border-right: 1px solid var(--bv-color-neutral-100);\n}\n\nbv-table[bordered] thead th:last-child,\nbv-table[bordered] tbody td:last-child {\n border-right: none;\n}\n\n/* \u2500\u2500 Column divider \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\nbv-table thead th[data-divider],\nbv-table tbody td[data-divider] {\n border-left: 1px solid var(--bv-color-neutral-200);\n}\n\n/* \u2500\u2500 Checkbox column \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\nbv-table thead th.bv-col-check,\nbv-table tbody td.bv-col-check {\n width: 48px;\n padding: 12px 16px;\n}\n";
|
|
2
|
+
var bv_table_default = "bv-table {\n display: block;\n width: 100%;\n box-sizing: border-box;\n overflow-x: auto;\n border: 1px solid var(--bv-color-neutral-200);\n font-family: var(--bv-font-family-base);\n cursor: grab;\n}\n\n/* During drag: override cursor for the entire table and all children */\nbv-table[data-dragging],\nbv-table[data-dragging] * {\n cursor: grabbing !important;\n user-select: none !important;\n}\n\nbv-table tbody td {\n cursor: grab;\n}\n\n/* Only the rendered glyphs are text-selectable \u2014 see _enhanceBodyCells in bv-table.ts */\nbv-table tbody td .bv-cell-text {\n cursor: text;\n}\n\nbv-table table {\n width: 100%;\n border-collapse: collapse;\n min-width: 0;\n}\n\n/* \u2500\u2500 Header \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\u2500\u2500\u2500\u2500\u2500*/\n\nbv-table thead tr {\n background: var(--bv-color-neutral-100);\n}\n\nbv-table thead th {\n padding: 12px 16px;\n text-align: left;\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-800);\n border-bottom: 1px solid var(--bv-color-neutral-200);\n white-space: nowrap;\n user-select: none;\n vertical-align: middle;\n}\n\nbv-table thead th[data-sortable] {\n cursor: pointer;\n}\n\nbv-table thead th[data-sortable]:hover {\n color: var(--bv-color-neutral-700);\n}\n\nbv-table thead th[data-sort='asc'] .bv-sort-icon,\nbv-table thead th[data-sort='desc'] .bv-sort-icon {\n color: var(--bv-color-primary);\n}\n\n.bv-th-content {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.bv-sort-icon {\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Body \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\n\nbv-table tbody td {\n padding: 12px 16px;\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-700);\n border-bottom: 1px solid var(--bv-color-neutral-100);\n vertical-align: middle;\n white-space: nowrap;\n}\n\nbv-table tbody tr:last-child td {\n border-bottom: none;\n}\n\nbv-table tbody tr:hover td {\n background: var(--bv-color-neutral-100);\n}\n\n/* \u2500\u2500 Column alignment \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\nbv-table thead th[data-align='right'],\nbv-table tbody td[data-align='right'] {\n text-align: right;\n}\n\nbv-table thead th[data-align='center'],\nbv-table tbody td[data-align='center'] {\n text-align: center;\n}\n\n/* \u2500\u2500 Cell modifier classes \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/* Muted: em dash or empty placeholder */\nbv-table td.bv-cell-muted {\n color: var(--bv-color-neutral-400);\n}\n\n/* Hidden: redacted identity for external users */\nbv-table td.bv-cell-hidden {\n color: var(--bv-color-neutral-400);\n font-style: italic;\n}\n\n/* Colored text for numeric highlight states */\nbv-table td.bv-cell-success {\n color: var(--bv-color-success);\n font-weight: var(--bv-font-weight-medium);\n}\n\nbv-table td.bv-cell-warning {\n color: var(--bv-color-warning);\n font-weight: var(--bv-font-weight-medium);\n}\n\nbv-table td.bv-cell-danger {\n color: var(--bv-color-danger);\n font-weight: var(--bv-font-weight-medium);\n}\n\nbv-table td.bv-cell-info {\n color: var(--bv-color-primary);\n font-weight: var(--bv-font-weight-medium);\n}\n\n/* \u2500\u2500 Modifiers \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\u2500\u2500*/\n\nbv-table[striped] tbody tr:nth-child(even) td {\n background: var(--bv-color-neutral-100);\n}\n\nbv-table[bordered] thead th,\nbv-table[bordered] tbody td {\n border-right: 1px solid var(--bv-color-neutral-100);\n}\n\nbv-table[bordered] thead th:last-child,\nbv-table[bordered] tbody td:last-child {\n border-right: none;\n}\n\n/* \u2500\u2500 Column divider \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\nbv-table thead th[data-divider],\nbv-table tbody td[data-divider] {\n border-left: 1px solid var(--bv-color-neutral-200);\n}\n\n/* \u2500\u2500 Checkbox column \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\nbv-table thead th.bv-col-check,\nbv-table tbody td.bv-col-check {\n width: 48px;\n padding: 12px 16px;\n}\n\n/* \u2500\u2500 BTN-10191 \xB7 loading skeleton \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/* Hide the real table while the skeleton is showing. Consumers keep\n their <thead>/<tbody> markup in place so no re-hydration is needed\n when data lands \u2014 only display switches. */\nbv-table[loading] > table {\n display: none;\n}\n\n.bv-table-skeleton {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-md-minus);\n padding: var(--bv-spacing-md);\n}\n\n.bv-table-skeleton-row {\n display: flex;\n gap: var(--bv-spacing-lg);\n}\n\n.bv-table-skeleton-bar {\n flex: 1;\n height: 14px;\n border-radius: var(--bv-radius-sm);\n background: var(--bv-color-neutral-200);\n animation: bv-table-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n/* Slight offset per row so the shimmer isn't in lockstep \u2014 reads more\n like real content loading than a pulsing wall. */\n.bv-table-skeleton-row:nth-child(even) .bv-table-skeleton-bar {\n animation-delay: 0.2s;\n}\n\n@keyframes bv-table-skeleton-shimmer {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n";
|
|
3
3
|
|
|
4
4
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-tooltip/bv-tooltip.css
|
|
5
5
|
var bv_tooltip_default = ":host {\n display: inline-flex;\n align-items: center;\n position: relative;\n font-family: var(--bv-font-family-base);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.wrap {\n display: inline-flex;\n align-items: center;\n position: relative;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n cursor: help;\n color: var(--bv-color-neutral-400);\n outline: none;\n border: none;\n background: none;\n padding: 0;\n line-height: 0;\n}\n\n.trigger:hover,\n.trigger:focus {\n color: var(--bv-color-neutral-600);\n}\n\n.trigger svg {\n display: block;\n width: 14px;\n height: 14px;\n}\n\n/* \u2500\u2500 Popup \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.popup {\n /* Shown/positioned entirely via JS \u2014 display starts as none */\n display: none;\n position: absolute;\n z-index: 500;\n min-width: 200px;\n max-width: 300px;\n background: var(--bv-color-neutral-900);\n color: var(--bv-color-neutral-0);\n border-radius: var(--bv-radius-md);\n padding: 10px 12px;\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-regular);\n line-height: 1.6;\n box-shadow: var(--bv-shadow-lg);\n pointer-events: none;\n white-space: normal;\n}\n\n/* \u2500\u2500 Content \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.text-content {\n display: none;\n}\n\n:host([text]) .text-content {\n display: block;\n}\n\n:host([text]) slot {\n display: none;\n}\n\n::slotted(p) {\n margin: 0 0 4px;\n}\n\n::slotted(p:last-child) {\n margin-bottom: 0;\n}\n";
|
|
6
6
|
|
|
7
|
-
// components/
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
// components/_shared/adopt-styles.ts
|
|
8
|
+
var _sheetCache = /* @__PURE__ */ new Map();
|
|
9
|
+
function adoptStyles(shadow, css) {
|
|
10
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype && typeof CSSStyleSheet !== "undefined" && "replaceSync" in CSSStyleSheet.prototype) {
|
|
11
|
+
let sheet = _sheetCache.get(css);
|
|
12
|
+
if (!sheet) {
|
|
13
|
+
sheet = new CSSStyleSheet();
|
|
14
|
+
sheet.replaceSync(css);
|
|
15
|
+
_sheetCache.set(css, sheet);
|
|
16
|
+
}
|
|
17
|
+
shadow.adoptedStyleSheets = [sheet];
|
|
18
|
+
return;
|
|
14
19
|
}
|
|
15
|
-
|
|
20
|
+
const style = document.createElement("style");
|
|
21
|
+
style.textContent = css;
|
|
22
|
+
shadow.appendChild(style);
|
|
16
23
|
}
|
|
24
|
+
|
|
25
|
+
// components/bv-tooltip/bv-tooltip.ts
|
|
26
|
+
var QUESTION_MARK_SVG = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>`;
|
|
17
27
|
var _uid = 0;
|
|
18
28
|
var BvTooltip = class extends HTMLElement {
|
|
19
29
|
static observedAttributes = ["text", "position"];
|
|
@@ -23,10 +33,7 @@ var BvTooltip = class extends HTMLElement {
|
|
|
23
33
|
_popupEl = null;
|
|
24
34
|
constructor() {
|
|
25
35
|
super();
|
|
26
|
-
|
|
27
|
-
if ("adoptedStyleSheets" in ShadowRoot.prototype) {
|
|
28
|
-
shadow.adoptedStyleSheets = [getSheet()];
|
|
29
|
-
}
|
|
36
|
+
adoptStyles(this.attachShadow({ mode: "open" }), bv_tooltip_default);
|
|
30
37
|
}
|
|
31
38
|
get text() {
|
|
32
39
|
return this.getAttribute("text") ?? "";
|
|
@@ -53,11 +60,6 @@ var BvTooltip = class extends HTMLElement {
|
|
|
53
60
|
if (this._rendered) return;
|
|
54
61
|
this._rendered = true;
|
|
55
62
|
const shadow = this.shadowRoot;
|
|
56
|
-
if (!shadow.adoptedStyleSheets.length) {
|
|
57
|
-
const s = document.createElement("style");
|
|
58
|
-
s.textContent = bv_tooltip_default;
|
|
59
|
-
shadow.appendChild(s);
|
|
60
|
-
}
|
|
61
63
|
const wrap = document.createElement("span");
|
|
62
64
|
wrap.className = "wrap";
|
|
63
65
|
const popupId = `bv-tooltip-popup-${++_uid}`;
|
|
@@ -164,22 +166,70 @@ function injectTableStyles() {
|
|
|
164
166
|
document.head.appendChild(style);
|
|
165
167
|
}
|
|
166
168
|
var BvTable = class extends HTMLElement {
|
|
167
|
-
static observedAttributes = ["striped", "bordered"];
|
|
169
|
+
static observedAttributes = ["striped", "bordered", "loading", "loading-rows"];
|
|
168
170
|
_isDragging = false;
|
|
169
171
|
_dragStartX = 0;
|
|
170
172
|
_dragScrollLeft = 0;
|
|
171
173
|
_boundMouseDown = (e) => this._onMouseDown(e);
|
|
172
174
|
_boundMouseMove = (e) => this._onMouseMove(e);
|
|
173
175
|
_boundMouseUp = () => this._onMouseUp();
|
|
176
|
+
get loading() {
|
|
177
|
+
return this.hasAttribute("loading");
|
|
178
|
+
}
|
|
179
|
+
set loading(v) {
|
|
180
|
+
if (v) this.setAttribute("loading", "");
|
|
181
|
+
else this.removeAttribute("loading");
|
|
182
|
+
}
|
|
174
183
|
connectedCallback() {
|
|
175
184
|
injectTableStyles();
|
|
176
185
|
this._enhanceHeaders();
|
|
177
186
|
this._enhanceBodyCells();
|
|
178
187
|
this._setupDrag();
|
|
188
|
+
if (this.hasAttribute("loading")) this._renderSkeleton();
|
|
179
189
|
}
|
|
180
190
|
disconnectedCallback() {
|
|
181
191
|
this._teardownDrag();
|
|
182
192
|
}
|
|
193
|
+
attributeChangedCallback(name, _old, val) {
|
|
194
|
+
if (!this.isConnected) return;
|
|
195
|
+
if (name === "loading") {
|
|
196
|
+
if (val === null) this._removeSkeleton();
|
|
197
|
+
else this._renderSkeleton();
|
|
198
|
+
}
|
|
199
|
+
if (name === "loading-rows" && this.hasAttribute("loading")) {
|
|
200
|
+
this._removeSkeleton();
|
|
201
|
+
this._renderSkeleton();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Renders skeleton rows as a light-DOM sibling to the user's <table>.
|
|
205
|
+
// The `loading` attribute on the host + CSS in bv-table.css handles the
|
|
206
|
+
// "hide the real table" side of the swap.
|
|
207
|
+
_renderSkeleton() {
|
|
208
|
+
if (this.querySelector(":scope > .bv-table-skeleton")) return;
|
|
209
|
+
const rowsAttr = this.getAttribute("loading-rows");
|
|
210
|
+
const rows = Math.max(1, Number(rowsAttr) || 10);
|
|
211
|
+
const columns = Math.max(1, this.querySelectorAll("thead th").length || 4);
|
|
212
|
+
const skeleton = document.createElement("div");
|
|
213
|
+
skeleton.className = "bv-table-skeleton";
|
|
214
|
+
skeleton.setAttribute("role", "status");
|
|
215
|
+
skeleton.setAttribute("aria-live", "polite");
|
|
216
|
+
skeleton.setAttribute("aria-label", this.getAttribute("loading-label") ?? "Loading");
|
|
217
|
+
for (let r = 0; r < rows; r++) {
|
|
218
|
+
const row = document.createElement("div");
|
|
219
|
+
row.className = "bv-table-skeleton-row";
|
|
220
|
+
for (let c = 0; c < columns; c++) {
|
|
221
|
+
const bar = document.createElement("div");
|
|
222
|
+
bar.className = "bv-table-skeleton-bar";
|
|
223
|
+
row.appendChild(bar);
|
|
224
|
+
}
|
|
225
|
+
skeleton.appendChild(row);
|
|
226
|
+
}
|
|
227
|
+
this.appendChild(skeleton);
|
|
228
|
+
}
|
|
229
|
+
_removeSkeleton() {
|
|
230
|
+
var _a;
|
|
231
|
+
(_a = this.querySelector(":scope > .bv-table-skeleton")) == null ? void 0 : _a.remove();
|
|
232
|
+
}
|
|
183
233
|
_setupDrag() {
|
|
184
234
|
this.addEventListener("mousedown", this._boundMouseDown);
|
|
185
235
|
window.addEventListener("mousemove", this._boundMouseMove);
|