@bluevolt-tech/lumen 2.0.1 → 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.
Files changed (56) hide show
  1. package/README.md +37 -23
  2. package/dist/components/_shared/adopt-styles.d.ts +8 -0
  3. package/dist/components/_shared/date-range-validator.d.ts +61 -0
  4. package/dist/components/_shared/dropdown-controller.d.ts +31 -0
  5. package/dist/components/_shared/selectable-card.d.ts +10 -0
  6. package/dist/components/bv-alert-banner/bv-alert-banner.js +19 -17
  7. package/dist/components/bv-avatar/bv-avatar.js +19 -11
  8. package/dist/components/bv-badge/bv-badge.js +19 -11
  9. package/dist/components/bv-button/bv-button.js +18 -16
  10. package/dist/components/bv-category-pill/bv-category-pill.js +18 -16
  11. package/dist/components/bv-checkbox/bv-checkbox.js +19 -11
  12. package/dist/components/bv-chip/bv-chip.js +19 -11
  13. package/dist/components/bv-course-detail/bv-course-detail.js +20 -34
  14. package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +24 -90
  15. package/dist/components/bv-course-grid-card/bv-course-grid-card.d.ts +2 -6
  16. package/dist/components/bv-course-grid-card/bv-course-grid-card.js +98 -105
  17. package/dist/components/bv-course-list-card/bv-course-list-card.d.ts +2 -6
  18. package/dist/components/bv-course-list-card/bv-course-list-card.js +98 -105
  19. package/dist/components/bv-course-outline/bv-course-outline.js +19 -11
  20. package/dist/components/bv-date-range-input/bv-date-range-input.d.ts +4 -6
  21. package/dist/components/bv-date-range-input/bv-date-range-input.js +460 -122
  22. package/dist/components/bv-date-range-picker/bv-date-range-picker.d.ts +17 -3
  23. package/dist/components/bv-date-range-picker/bv-date-range-picker.js +339 -73
  24. package/dist/components/bv-empty-state/bv-empty-state.js +20 -28
  25. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +1 -4
  26. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +78 -53
  27. package/dist/components/bv-filter-panel/bv-filter-panel.js +20 -22
  28. package/dist/components/bv-icon/bv-icon.js +19 -11
  29. package/dist/components/bv-input/bv-input.js +18 -16
  30. package/dist/components/bv-input-dropdown/bv-input-dropdown.d.ts +1 -4
  31. package/dist/components/bv-input-dropdown/bv-input-dropdown.js +77 -78
  32. package/dist/components/bv-modal/bv-modal.js +19 -11
  33. package/dist/components/bv-page-title/bv-page-title.js +19 -6
  34. package/dist/components/bv-pagination/bv-pagination.d.ts +1 -0
  35. package/dist/components/bv-pagination/bv-pagination.js +23 -186
  36. package/dist/components/bv-portal-header/bv-portal-header.js +25 -83
  37. package/dist/components/bv-portal-layout/bv-portal-layout.js +19 -11
  38. package/dist/components/bv-progress-bar/bv-progress-bar.js +19 -11
  39. package/dist/components/bv-promo-banner/bv-promo-banner.js +19 -11
  40. package/dist/components/bv-radio/bv-radio.js +19 -11
  41. package/dist/components/bv-searchbox/bv-searchbox.js +19 -11
  42. package/dist/components/bv-segmented-control/bv-segmented-control.js +18 -16
  43. package/dist/components/bv-select/bv-select.d.ts +1 -4
  44. package/dist/components/bv-select/bv-select.js +76 -44
  45. package/dist/components/bv-split-button/bv-split-button.d.ts +1 -4
  46. package/dist/components/bv-split-button/bv-split-button.js +76 -42
  47. package/dist/components/bv-star-rating/bv-star-rating.js +19 -11
  48. package/dist/components/bv-table/bv-table.d.ts +5 -0
  49. package/dist/components/bv-table/bv-table.js +69 -19
  50. package/dist/components/bv-toggle/bv-toggle.js +19 -11
  51. package/dist/components/bv-tooltip/bv-tooltip.js +19 -17
  52. package/dist/components/bv-user-row/bv-user-row.js +22 -50
  53. package/dist/components/bv-view-switcher/bv-view-switcher.js +19 -11
  54. package/dist/themes/base.css +1 -1
  55. package/package.json +8 -1
  56. package/themes/base.css +1 -1
@@ -1,6 +1,73 @@
1
1
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-input-dropdown/bv-input-dropdown.css
2
2
  var bv_input_dropdown_default = ":host {\n display: block;\n position: relative;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Field 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 */\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.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 box-sizing: border-box;\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([disabled]) .trigger {\n background: var(--bv-color-neutral-100);\n color: var(--bv-color-neutral-400);\n cursor: not-allowed;\n}\n\n:host([error]:not([error=''])) .trigger {\n border-color: var(--bv-color-danger);\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 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\u2500\u2500\u2500\u2500 */\n\n.panel {\n display: none;\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 100%;\n width: max-content;\n max-width: 600px;\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}\n\n:host([toggle-label]) .panel {\n min-width: 260px;\n}\n\n:host([open]) .panel {\n display: block;\n}\n\n/* \u2500\u2500 Panel header (search + toolbar) \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-header {\n border-bottom: 1px solid var(--bv-color-neutral-200);\n padding: var(--bv-spacing-sm);\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-xs);\n}\n\n.panel-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--bv-spacing-xs) 0;\n}\n\n/* \u2500\u2500 Panel content (scrollable slot area) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.panel-content {\n overflow-y: auto;\n max-height: var(--bv-input-dropdown-content-height, 280px);\n padding: var(--bv-spacing-xs) 0;\n}\n\n/* Stack all slotted content vertically */\n::slotted(*) {\n display: block;\n}\n\n/* Row padding \u2014 left aligns with the panel-header padding */\n::slotted(bv-checkbox) {\n padding: 6px var(--bv-spacing-sm);\n box-sizing: border-box;\n white-space: nowrap;\n max-width: 100%;\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\n.field-error:empty {\n display: none;\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
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-searchbox/bv-searchbox.css
5
72
  var bv_searchbox_default = ":host {\n display: block;\n width: 100%;\n position: relative;\n font-family: var(--bv-font-family-base);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--bv-color-neutral-400);\n display: flex;\n pointer-events: none;\n}\n\n.search-input {\n width: 100%;\n box-sizing: border-box;\n height: 40px;\n padding: 0 12px 0 38px;\n font-size: var(--bv-font-size-sm);\n font-family: inherit;\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-lg);\n outline: none;\n color: var(--bv-color-neutral-800);\n background: var(--bv-color-neutral-0);\n transition: border-color var(--bv-transition-fast);\n}\n\n:host([size='sm']) .search-input {\n height: 36px;\n}\n:host([size='lg']) .search-input {\n height: 46px;\n}\n\n.search-input::placeholder {\n color: var(--bv-color-neutral-400);\n}\n\n.search-input:focus {\n border-color: #6fb0d8;\n box-shadow:\n 0px 0px 0px 4px #dbe8ff,\n 0px 1px 2px 0px rgba(16, 24, 40, 0.05);\n}\n";
6
73
 
@@ -15,12 +82,7 @@ var BvSearchbox = class extends HTMLElement {
15
82
  _input = null;
16
83
  constructor() {
17
84
  super();
18
- this.attachShadow({ mode: "open" });
19
- if ("replaceSync" in CSSStyleSheet.prototype) {
20
- const sheet = new CSSStyleSheet();
21
- sheet.replaceSync(bv_searchbox_default);
22
- this.shadowRoot.adoptedStyleSheets = [sheet];
23
- }
85
+ adoptStyles(this.attachShadow({ mode: "open" }), bv_searchbox_default);
24
86
  }
25
87
  connectedCallback() {
26
88
  this._render();
@@ -38,11 +100,6 @@ var BvSearchbox = class extends HTMLElement {
38
100
  if (this._rendered) return;
39
101
  this._rendered = true;
40
102
  const shadow = this.shadowRoot;
41
- if (!shadow.adoptedStyleSheets.length) {
42
- const s = document.createElement("style");
43
- s.textContent = bv_searchbox_default;
44
- shadow.appendChild(s);
45
- }
46
103
  const icon = document.createElement("span");
47
104
  icon.className = "search-icon";
48
105
  icon.innerHTML = SEARCH_ICON;
@@ -84,12 +141,7 @@ var BvCheckbox = class extends HTMLElement {
84
141
  _labelEl = null;
85
142
  constructor() {
86
143
  super();
87
- this.attachShadow({ mode: "open" });
88
- if ("replaceSync" in CSSStyleSheet.prototype) {
89
- const sheet = new CSSStyleSheet();
90
- sheet.replaceSync(bv_checkbox_default);
91
- this.shadowRoot.adoptedStyleSheets = [sheet];
92
- }
144
+ adoptStyles(this.attachShadow({ mode: "open" }), bv_checkbox_default);
93
145
  }
94
146
  connectedCallback() {
95
147
  this._render();
@@ -113,11 +165,6 @@ var BvCheckbox = class extends HTMLElement {
113
165
  if (this._rendered) return;
114
166
  this._rendered = true;
115
167
  const shadow = this.shadowRoot;
116
- if (!shadow.adoptedStyleSheets.length) {
117
- const s = document.createElement("style");
118
- s.textContent = bv_checkbox_default;
119
- shadow.appendChild(s);
120
- }
121
168
  const wrap = document.createElement("label");
122
169
  wrap.className = "wrap";
123
170
  const box = document.createElement("span");
@@ -164,12 +211,7 @@ var BvToggle = class extends HTMLElement {
164
211
  _labelEl = null;
165
212
  constructor() {
166
213
  super();
167
- this.attachShadow({ mode: "open" });
168
- if ("replaceSync" in CSSStyleSheet.prototype) {
169
- const sheet = new CSSStyleSheet();
170
- sheet.replaceSync(bv_toggle_default);
171
- this.shadowRoot.adoptedStyleSheets = [sheet];
172
- }
214
+ adoptStyles(this.attachShadow({ mode: "open" }), bv_toggle_default);
173
215
  }
174
216
  connectedCallback() {
175
217
  this._render();
@@ -189,11 +231,6 @@ var BvToggle = class extends HTMLElement {
189
231
  if (this._rendered) return;
190
232
  this._rendered = true;
191
233
  const shadow = this.shadowRoot;
192
- if (!shadow.adoptedStyleSheets.length) {
193
- const s = document.createElement("style");
194
- s.textContent = bv_toggle_default;
195
- shadow.appendChild(s);
196
- }
197
234
  const wrap = document.createElement("label");
198
235
  wrap.className = "wrap";
199
236
  const track = document.createElement("span");
@@ -226,14 +263,6 @@ if (!customElements.get("bv-toggle")) {
226
263
 
227
264
  // components/bv-input-dropdown/bv-input-dropdown.ts
228
265
  var CHEVRON_ICON = `<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>`;
229
- var _sheet = null;
230
- function getSheet() {
231
- if (!_sheet) {
232
- _sheet = new CSSStyleSheet();
233
- _sheet.replaceSync(bv_input_dropdown_default);
234
- }
235
- return _sheet;
236
- }
237
266
  var BvInputDropdown = class extends HTMLElement {
238
267
  static observedAttributes = [
239
268
  "label",
@@ -258,13 +287,10 @@ var BvInputDropdown = class extends HTMLElement {
258
287
  _selectAllEl = null;
259
288
  _toggleEl = null;
260
289
  _errorEl = null;
261
- _offClick = null;
290
+ _dropdown = null;
262
291
  constructor() {
263
292
  super();
264
- const shadow = this.attachShadow({ mode: "open" });
265
- if ("adoptedStyleSheets" in ShadowRoot.prototype) {
266
- shadow.adoptedStyleSheets = [getSheet()];
267
- }
293
+ adoptStyles(this.attachShadow({ mode: "open" }), bv_input_dropdown_default);
268
294
  }
269
295
  get value() {
270
296
  return this.getAttribute("value") ?? "";
@@ -290,7 +316,8 @@ var BvInputDropdown = class extends HTMLElement {
290
316
  this._render();
291
317
  }
292
318
  disconnectedCallback() {
293
- if (this._offClick) document.removeEventListener("click", this._offClick);
319
+ var _a;
320
+ (_a = this._dropdown) == null ? void 0 : _a.cleanup();
294
321
  }
295
322
  attributeChangedCallback(name, _old, _val) {
296
323
  if (!this._rendered) return;
@@ -300,20 +327,11 @@ var BvInputDropdown = class extends HTMLElement {
300
327
  if (name === "search") this._syncSearch();
301
328
  if (name === "select-all" || name === "select-all-state" || name === "toggle-label" || name === "toggle-checked")
302
329
  this._syncToolbar();
303
- if (name === "open") {
304
- const trigger = this.shadowRoot.querySelector(".trigger");
305
- if (trigger) trigger.setAttribute("aria-expanded", _val !== null ? "true" : "false");
306
- }
307
330
  }
308
331
  _render() {
309
332
  if (this._rendered) return;
310
333
  this._rendered = true;
311
334
  const shadow = this.shadowRoot;
312
- if (!shadow.adoptedStyleSheets.length) {
313
- const s = document.createElement("style");
314
- s.textContent = bv_input_dropdown_default;
315
- shadow.appendChild(s);
316
- }
317
335
  const label = document.createElement("label");
318
336
  label.className = "field-label";
319
337
  this._labelEl = label;
@@ -324,8 +342,9 @@ var BvInputDropdown = class extends HTMLElement {
324
342
  trigger.setAttribute("aria-expanded", "false");
325
343
  trigger.setAttribute("part", "trigger");
326
344
  trigger.addEventListener("click", (e) => {
345
+ var _a;
327
346
  e.stopPropagation();
328
- if (!this.disabled) this._toggle();
347
+ if (!this.disabled) (_a = this._dropdown) == null ? void 0 : _a.toggle();
329
348
  });
330
349
  const triggerLabel = document.createElement("span");
331
350
  triggerLabel.className = "trigger-label";
@@ -398,27 +417,7 @@ var BvInputDropdown = class extends HTMLElement {
398
417
  this._syncError();
399
418
  this._syncSearch();
400
419
  this._syncToolbar();
401
- this._offClick = (e) => {
402
- if (!this.contains(e.target) && !shadow.contains(e.target)) {
403
- this._close();
404
- }
405
- };
406
- document.addEventListener("click", this._offClick);
407
- }
408
- _toggle() {
409
- if (this.hasAttribute("open")) this._close();
410
- else this._open();
411
- }
412
- _open() {
413
- var _a;
414
- this.setAttribute("open", "");
415
- (_a = this.shadowRoot.querySelector(".trigger")) == null ? void 0 : _a.setAttribute("aria-expanded", "true");
416
- this.dispatchEvent(new CustomEvent("bv-open", { bubbles: true, composed: true }));
417
- }
418
- _close() {
419
- var _a;
420
- this.removeAttribute("open");
421
- (_a = this.shadowRoot.querySelector(".trigger")) == null ? void 0 : _a.setAttribute("aria-expanded", "false");
420
+ this._dropdown = bindDropdownController(this, { trigger });
422
421
  }
423
422
  _syncLabel() {
424
423
  if (!this._labelEl) return;
@@ -1,6 +1,24 @@
1
1
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-modal/bv-modal.css
2
2
  var bv_modal_default = '/* \u2500\u2500 Public theming API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 Apps can override per-instance:\n\n HTML: <bv-modal style="--bv-modal-width: 600px;">\n Angular: <bv-modal [style.--bv-modal-bg]="bgColor">\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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:host {\n --bv-modal-width: 800px;\n --bv-modal-bg: var(--bv-color-neutral-0);\n --bv-modal-radius: var(--bv-radius-xl);\n --bv-modal-title-color: #101828;\n --bv-modal-backdrop: rgba(16, 24, 40, 0.6);\n --bv-modal-body-max-height: none;\n}\n\ndialog {\n padding: 0;\n border: none;\n border-radius: var(--bv-modal-radius);\n background: transparent;\n width: var(--bv-modal-width);\n max-width: min(var(--bv-modal-width), calc(100vw - 32px));\n outline: none;\n}\n\ndialog::backdrop {\n background: var(--bv-modal-backdrop);\n}\n\n.panel {\n display: flex;\n width: 100%;\n padding: 20px 16px;\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n gap: 20px;\n border-radius: var(--bv-modal-radius);\n background: var(--bv-modal-bg);\n box-sizing: border-box;\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\n.header {\n display: flex;\n width: 100%;\n align-items: center;\n justify-content: space-between;\n}\n\n.title {\n margin: 0;\n color: var(--bv-modal-title-color);\n font-family: var(--bv-font-family-base);\n font-size: 24px;\n font-style: normal;\n font-weight: var(--bv-font-weight-medium);\n line-height: 32px;\n}\n\n.close-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: none;\n border: none;\n border-radius: var(--bv-radius-md);\n cursor: pointer;\n color: var(--bv-color-neutral-500);\n font-size: 18px;\n line-height: 1;\n flex-shrink: 0;\n transition:\n color var(--bv-transition-fast),\n background var(--bv-transition-fast);\n}\n\n.close-btn:hover {\n color: var(--bv-color-neutral-800);\n background: var(--bv-color-neutral-100);\n}\n\n/* \u2500\u2500 Separator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.separator {\n width: 100%;\n border: none;\n border-top: 1px solid var(--bv-color-neutral-200);\n margin: 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\n.body {\n width: 100%;\n max-height: var(--bv-modal-body-max-height);\n overflow-y: auto;\n color: var(--bv-color-neutral-600);\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n line-height: 20px;\n}\n\n/* \u2500\u2500 Footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.footer {\n width: 100%;\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-modal/bv-modal.ts
5
23
  var BvModal = class extends HTMLElement {
6
24
  static observedAttributes = ["title", "open"];
@@ -9,12 +27,7 @@ var BvModal = class extends HTMLElement {
9
27
  _rendered = false;
10
28
  constructor() {
11
29
  super();
12
- this.attachShadow({ mode: "open" });
13
- if (typeof CSSStyleSheet !== "undefined" && "replaceSync" in CSSStyleSheet.prototype) {
14
- const sheet = new CSSStyleSheet();
15
- sheet.replaceSync(bv_modal_default);
16
- this.shadowRoot.adoptedStyleSheets = [sheet];
17
- }
30
+ adoptStyles(this.attachShadow({ mode: "open" }), bv_modal_default);
18
31
  }
19
32
  connectedCallback() {
20
33
  this._render();
@@ -48,11 +61,6 @@ var BvModal = class extends HTMLElement {
48
61
  if (this._rendered) return;
49
62
  this._rendered = true;
50
63
  const shadow = this.shadowRoot;
51
- if (!shadow.adoptedStyleSheets.length) {
52
- const style = document.createElement("style");
53
- style.textContent = bv_modal_default;
54
- shadow.appendChild(style);
55
- }
56
64
  const dialog = document.createElement("dialog");
57
65
  this._dialog = dialog;
58
66
  dialog.addEventListener("click", (e) => {
@@ -1,16 +1,29 @@
1
1
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-page-title/bv-page-title.css
2
2
  var bv_page_title_default = ":host {\n display: block;\n}\n\nh1 {\n margin: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-2xl);\n font-weight: var(--bv-font-weight-medium);\n line-height: 1.2;\n color: var(--bv-color-neutral-900);\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-page-title/bv-page-title.ts
5
23
  var BvPageTitle = class extends HTMLElement {
6
24
  constructor() {
7
25
  super();
8
- this.attachShadow({ mode: "open" });
9
- if ("replaceSync" in CSSStyleSheet.prototype) {
10
- const sheet = new CSSStyleSheet();
11
- sheet.replaceSync(bv_page_title_default);
12
- this.shadowRoot.adoptedStyleSheets = [sheet];
13
- }
26
+ adoptStyles(this.attachShadow({ mode: "open" }), bv_page_title_default);
14
27
  }
15
28
  connectedCallback() {
16
29
  if (this.shadowRoot.childElementCount > (this.shadowRoot.adoptedStyleSheets.length ? 0 : 1))
@@ -1,6 +1,7 @@
1
1
  export declare class BvPagination extends HTMLElement {
2
2
  static readonly observedAttributes: readonly ["page", "total-pages", "total", "page-size", "siblings", "show-results", "show-page-size", "page-size-options", "compact"];
3
3
  private _rendered;
4
+ private _metaEl;
4
5
  private _pagesEl;
5
6
  private _prevBtn;
6
7
  private _nextBtn;
@@ -1,180 +1,23 @@
1
1
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-pagination/bv-pagination.css
2
- var bv_pagination_default = `:host {
3
- display: block;
4
- }
5
-
6
- .wrap {
7
- display: flex;
8
- align-items: center;
9
- justify-content: space-between;
10
- gap: var(--bv-spacing-xl);
11
- width: 100%;
12
- font-family: var(--bv-font-family-base);
13
- }
14
-
15
- /* \u2500\u2500 Meta section (results count + page-size) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
2
+ var bv_pagination_default = ":host {\n display: block;\n}\n\n/*\n * Any element inside the shadow tree that carries author-declared display\n * still respects the `hidden` attribute. Without this, `[hidden] { display: none }`\n * (UA rule) loses to author `display: <value>` and the element stays visible.\n */\n[hidden] {\n display: none !important;\n}\n\n.wrap {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--bv-spacing-xl);\n width: 100%;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Meta section (results count + page-size) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.meta {\n display: flex;\n align-items: center;\n gap: var(--bv-spacing-sm);\n}\n\n.results-count {\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-700);\n white-space: nowrap;\n margin-right: var(--bv-spacing-sm);\n}\n\n.page-size-wrap {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.page-size-select {\n height: 36px;\n box-sizing: border-box;\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-lg);\n background-color: var(--bv-color-neutral-0);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M5 7.5l5 5 5-5' stroke='%23667085' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 8px center;\n appearance: none;\n -webkit-appearance: none;\n font-family: inherit;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-700);\n padding: 0 28px 0 var(--bv-spacing-sm);\n cursor: pointer;\n box-shadow: var(--bv-shadow-sm);\n outline: none;\n}\n\n.page-size-select:focus {\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.per-page-label {\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-500);\n white-space: nowrap;\n}\n\n/* \u2500\u2500 Nav section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.nav {\n display: flex;\n align-items: center;\n gap: var(--bv-spacing-xs);\n}\n\n/*\n * When .meta collapses (opt-out consumers: no show-results, no show-page-size),\n * .wrap's `space-between` has only one visible child and packs .nav to the\n * left. Give .nav the full width and use auto-margins to reproduce the\n * pre-v2.0.0 3-column layout: Prev on far left, pages in the middle,\n * (range + Next) grouped on the far right.\n */\n.meta[hidden] ~ .nav {\n flex: 1;\n}\n/*\n * Non-compact: two auto-margins split the extra space into equal gaps so the\n * layout reads `[Prev]___[pages]___[range][Next]`. Prev sits on the far left,\n * pages centered in the middle, range + Next grouped on the far right.\n */\n.meta[hidden] ~ .nav .pages {\n margin-left: auto;\n}\n.meta[hidden] ~ .nav .range-label {\n margin-left: auto;\n}\n/* Compact: page label centers between Prev and Next. */\n.meta[hidden] ~ .nav .page-label {\n margin-left: auto;\n margin-right: auto;\n}\n\n/* \u2500\u2500 Shared button base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid transparent;\n border-radius: var(--bv-radius-lg);\n background: transparent;\n font-family: inherit;\n font-size: var(--bv-font-size-sm);\n cursor: pointer;\n transition:\n background var(--bv-transition-fast),\n color var(--bv-transition-fast);\n}\n\n/* Prev / Next buttons */\n.nav-btn {\n gap: var(--bv-spacing-xs);\n height: 36px;\n padding: 0 var(--bv-spacing-sm);\n border-color: var(--bv-color-neutral-300);\n background: var(--bv-color-neutral-0);\n color: var(--bv-color-neutral-700);\n font-weight: var(--bv-font-weight-semibold);\n box-shadow: var(--bv-shadow-sm);\n white-space: nowrap;\n}\n\n.nav-btn:hover:not(:disabled) {\n background: var(--bv-color-neutral-100);\n}\n\n.nav-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.nav-icon {\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n}\n\n/* Compact page label \u2014 plain text between Prev / Next */\n.page-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 white-space: nowrap;\n padding: 0 var(--bv-spacing-md);\n}\n\n/* \u2500\u2500 Page number buttons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.pages {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.page-btn {\n width: 40px;\n height: 40px;\n color: var(--bv-color-neutral-600);\n font-weight: var(--bv-font-weight-medium);\n}\n\n.page-btn:hover:not(.active) {\n background: var(--bv-color-neutral-100);\n}\n\n.page-btn.active {\n background: var(--bv-color-neutral-100);\n color: var(--bv-color-neutral-900);\n cursor: default;\n}\n\n.ellipsis {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-400);\n}\n\n/* \u2500\u2500 Range 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 */\n\n.range-label {\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-600);\n white-space: nowrap;\n margin-left: var(--bv-spacing-xs);\n}\n";
16
3
 
17
- .meta {
18
- display: flex;
19
- align-items: center;
20
- gap: var(--bv-spacing-sm);
21
- }
22
-
23
- .results-count {
24
- font-size: var(--bv-font-size-sm);
25
- font-weight: var(--bv-font-weight-semibold);
26
- color: var(--bv-color-neutral-700);
27
- white-space: nowrap;
28
- margin-right: var(--bv-spacing-sm);
29
- }
30
-
31
- .page-size-wrap {
32
- display: inline-flex;
33
- align-items: center;
34
- gap: 6px;
35
- }
36
-
37
- .page-size-select {
38
- height: 36px;
39
- box-sizing: border-box;
40
- border: 1px solid var(--bv-color-neutral-300);
41
- border-radius: var(--bv-radius-lg);
42
- background-color: var(--bv-color-neutral-0);
43
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M5 7.5l5 5 5-5' stroke='%23667085' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
44
- background-repeat: no-repeat;
45
- background-position: right 8px center;
46
- appearance: none;
47
- -webkit-appearance: none;
48
- font-family: inherit;
49
- font-size: var(--bv-font-size-sm);
50
- font-weight: var(--bv-font-weight-semibold);
51
- color: var(--bv-color-neutral-700);
52
- padding: 0 28px 0 var(--bv-spacing-sm);
53
- cursor: pointer;
54
- box-shadow: var(--bv-shadow-sm);
55
- outline: none;
56
- }
57
-
58
- .page-size-select:focus {
59
- border-color: var(--bv-color-primary);
60
- box-shadow:
61
- 0 0 0 3px var(--bv-color-primary-light),
62
- 0 1px 2px 0 rgba(16, 24, 40, 0.05);
63
- }
64
-
65
- .per-page-label {
66
- font-size: var(--bv-font-size-sm);
67
- color: var(--bv-color-neutral-500);
68
- white-space: nowrap;
69
- }
70
-
71
- /* \u2500\u2500 Nav section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
72
-
73
- .nav {
74
- display: flex;
75
- align-items: center;
76
- gap: var(--bv-spacing-xs);
77
- }
78
-
79
- /* \u2500\u2500 Shared button base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
80
-
81
- .btn {
82
- display: inline-flex;
83
- align-items: center;
84
- justify-content: center;
85
- border: 1px solid transparent;
86
- border-radius: var(--bv-radius-lg);
87
- background: transparent;
88
- font-family: inherit;
89
- font-size: var(--bv-font-size-sm);
90
- cursor: pointer;
91
- transition:
92
- background var(--bv-transition-fast),
93
- color var(--bv-transition-fast);
94
- }
95
-
96
- /* Prev / Next buttons */
97
- .nav-btn {
98
- gap: var(--bv-spacing-xs);
99
- height: 36px;
100
- padding: 0 var(--bv-spacing-sm);
101
- border-color: var(--bv-color-neutral-300);
102
- background: var(--bv-color-neutral-0);
103
- color: var(--bv-color-neutral-700);
104
- font-weight: var(--bv-font-weight-semibold);
105
- box-shadow: var(--bv-shadow-sm);
106
- white-space: nowrap;
107
- }
108
-
109
- .nav-btn:hover:not(:disabled) {
110
- background: var(--bv-color-neutral-100);
111
- }
112
-
113
- .nav-btn:disabled {
114
- opacity: 0.5;
115
- cursor: not-allowed;
116
- }
117
-
118
- .nav-icon {
119
- width: 20px;
120
- height: 20px;
121
- flex-shrink: 0;
122
- }
123
-
124
- /* Compact page label \u2014 plain text between Prev / Next */
125
- .page-label {
126
- font-size: var(--bv-font-size-sm);
127
- font-weight: var(--bv-font-weight-semibold);
128
- color: var(--bv-color-neutral-700);
129
- white-space: nowrap;
130
- padding: 0 var(--bv-spacing-md);
131
- }
132
-
133
- /* \u2500\u2500 Page number buttons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
134
-
135
- .pages {
136
- display: flex;
137
- align-items: center;
138
- gap: 2px;
139
- }
140
-
141
- .page-btn {
142
- width: 40px;
143
- height: 40px;
144
- color: var(--bv-color-neutral-600);
145
- font-weight: var(--bv-font-weight-medium);
146
- }
147
-
148
- .page-btn:hover:not(.active) {
149
- background: var(--bv-color-neutral-100);
150
- }
151
-
152
- .page-btn.active {
153
- background: var(--bv-color-neutral-100);
154
- color: var(--bv-color-neutral-900);
155
- cursor: default;
156
- }
157
-
158
- .ellipsis {
159
- display: inline-flex;
160
- align-items: center;
161
- justify-content: center;
162
- width: 40px;
163
- height: 40px;
164
- font-size: var(--bv-font-size-sm);
165
- color: var(--bv-color-neutral-400);
166
- }
167
-
168
- /* \u2500\u2500 Range 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 */
169
-
170
- .range-label {
171
- font-size: var(--bv-font-size-sm);
172
- font-weight: var(--bv-font-weight-medium);
173
- color: var(--bv-color-neutral-600);
174
- white-space: nowrap;
175
- margin-left: var(--bv-spacing-xs);
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);
176
20
  }
177
- `;
178
21
 
179
22
  // components/bv-pagination/bv-pagination.ts
180
23
  var PREV_ICON = `<svg class="nav-icon" viewBox="0 0 20 20" fill="none"><path d="M12.5 15l-5-5 5-5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
@@ -192,6 +35,7 @@ var BvPagination = class extends HTMLElement {
192
35
  "compact"
193
36
  ];
194
37
  _rendered = false;
38
+ _metaEl = null;
195
39
  _pagesEl = null;
196
40
  _prevBtn = null;
197
41
  _nextBtn = null;
@@ -202,12 +46,7 @@ var BvPagination = class extends HTMLElement {
202
46
  _pageLabelEl = null;
203
47
  constructor() {
204
48
  super();
205
- this.attachShadow({ mode: "open" });
206
- if ("replaceSync" in CSSStyleSheet.prototype) {
207
- const sheet = new CSSStyleSheet();
208
- sheet.replaceSync(bv_pagination_default);
209
- this.shadowRoot.adoptedStyleSheets = [sheet];
210
- }
49
+ adoptStyles(this.attachShadow({ mode: "open" }), bv_pagination_default);
211
50
  }
212
51
  connectedCallback() {
213
52
  this._render();
@@ -271,15 +110,11 @@ var BvPagination = class extends HTMLElement {
271
110
  if (this._rendered) return;
272
111
  this._rendered = true;
273
112
  const shadow = this.shadowRoot;
274
- if (!shadow.adoptedStyleSheets.length) {
275
- const s = document.createElement("style");
276
- s.textContent = bv_pagination_default;
277
- shadow.appendChild(s);
278
- }
279
113
  const wrap = document.createElement("div");
280
114
  wrap.className = "wrap";
281
115
  const metaEl = document.createElement("div");
282
116
  metaEl.className = "meta";
117
+ this._metaEl = metaEl;
283
118
  const resultsEl = document.createElement("span");
284
119
  resultsEl.className = "results-count";
285
120
  this._resultsEl = resultsEl;
@@ -291,7 +126,6 @@ var BvPagination = class extends HTMLElement {
291
126
  this._pageSizeSelectEl = pageSizeSelect;
292
127
  pageSizeSelect.addEventListener("change", () => {
293
128
  const newSize = parseInt(pageSizeSelect.value, 10);
294
- this.setAttribute("page-size", String(newSize));
295
129
  this.dispatchEvent(
296
130
  new CustomEvent("bv-page-size-change", {
297
131
  bubbles: true,
@@ -367,6 +201,9 @@ var BvPagination = class extends HTMLElement {
367
201
  if (this._pageSizeSelectEl) {
368
202
  this._syncPageSizeOptions(pageSize);
369
203
  }
204
+ if (this._metaEl) {
205
+ this._metaEl.hidden = !this.showResults && !this.showPageSize;
206
+ }
370
207
  if (!this._pagesEl || compact) return;
371
208
  this._pagesEl.innerHTML = "";
372
209
  const pages = this._pageRange(page, totalPages, siblings);