@bluevolt-tech/lumen 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +286 -0
  2. package/assets/fonts/fonts.css +25 -0
  3. package/assets/icons/.gitkeep +0 -0
  4. package/assets/icons/edit.svg +3 -0
  5. package/assets/images/.gitkeep +0 -0
  6. package/assets/images/bluevolt-logo.png +0 -0
  7. package/dist/assets/fonts/fonts.css +25 -0
  8. package/dist/assets/icons/.gitkeep +0 -0
  9. package/dist/assets/icons/edit.svg +3 -0
  10. package/dist/assets/images/.gitkeep +0 -0
  11. package/dist/assets/images/bluevolt-logo.png +0 -0
  12. package/dist/components/bv-avatar/bv-avatar.d.ts +13 -0
  13. package/dist/components/bv-avatar/bv-avatar.js +81 -0
  14. package/dist/components/bv-badge/bv-badge.d.ts +11 -0
  15. package/dist/components/bv-badge/bv-badge.js +58 -0
  16. package/dist/components/bv-button/bv-button.d.ts +23 -0
  17. package/dist/components/bv-button/bv-button.js +395 -0
  18. package/dist/components/bv-category-pill/bv-category-pill.d.ts +11 -0
  19. package/dist/components/bv-category-pill/bv-category-pill.js +61 -0
  20. package/dist/components/bv-checkbox/bv-checkbox.d.ts +14 -0
  21. package/dist/components/bv-checkbox/bv-checkbox.js +89 -0
  22. package/dist/components/bv-chip/bv-chip.d.ts +11 -0
  23. package/dist/components/bv-chip/bv-chip.js +72 -0
  24. package/dist/components/bv-course-detail/bv-course-detail.d.ts +28 -0
  25. package/dist/components/bv-course-detail/bv-course-detail.js +269 -0
  26. package/dist/components/bv-course-detail-modal/bv-course-detail-modal.d.ts +35 -0
  27. package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +1455 -0
  28. package/dist/components/bv-course-grid-card/bv-course-grid-card.d.ts +12 -0
  29. package/dist/components/bv-course-grid-card/bv-course-grid-card.js +578 -0
  30. package/dist/components/bv-course-list-card/bv-course-list-card.d.ts +12 -0
  31. package/dist/components/bv-course-list-card/bv-course-list-card.js +585 -0
  32. package/dist/components/bv-course-outline/bv-course-outline.d.ts +49 -0
  33. package/dist/components/bv-course-outline/bv-course-outline.js +488 -0
  34. package/dist/components/bv-empty-state/bv-empty-state.d.ts +10 -0
  35. package/dist/components/bv-empty-state/bv-empty-state.js +69 -0
  36. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +26 -0
  37. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +164 -0
  38. package/dist/components/bv-filter-panel/bv-filter-panel.d.ts +25 -0
  39. package/dist/components/bv-filter-panel/bv-filter-panel.js +222 -0
  40. package/dist/components/bv-icon/bv-icon.d.ts +10 -0
  41. package/dist/components/bv-icon/bv-icon.js +122 -0
  42. package/dist/components/bv-icon/icons.d.ts +3 -0
  43. package/dist/components/bv-modal/bv-modal.d.ts +13 -0
  44. package/dist/components/bv-modal/bv-modal.js +104 -0
  45. package/dist/components/bv-page-title/bv-page-title.d.ts +4 -0
  46. package/dist/components/bv-page-title/bv-page-title.js +33 -0
  47. package/dist/components/bv-pagination/bv-pagination.d.ts +20 -0
  48. package/dist/components/bv-pagination/bv-pagination.js +139 -0
  49. package/dist/components/bv-portal-header/bv-portal-header.d.ts +12 -0
  50. package/dist/components/bv-portal-header/bv-portal-header.js +854 -0
  51. package/dist/components/bv-portal-layout/bv-portal-layout.d.ts +6 -0
  52. package/dist/components/bv-portal-layout/bv-portal-layout.js +39 -0
  53. package/dist/components/bv-progress-bar/bv-progress-bar.d.ts +11 -0
  54. package/dist/components/bv-progress-bar/bv-progress-bar.js +61 -0
  55. package/dist/components/bv-promo-banner/bv-promo-banner.d.ts +12 -0
  56. package/dist/components/bv-promo-banner/bv-promo-banner.js +79 -0
  57. package/dist/components/bv-radio/bv-radio.d.ts +11 -0
  58. package/dist/components/bv-radio/bv-radio.js +78 -0
  59. package/dist/components/bv-searchbox/bv-searchbox.d.ts +10 -0
  60. package/dist/components/bv-searchbox/bv-searchbox.js +68 -0
  61. package/dist/components/bv-star-rating/bv-star-rating.d.ts +11 -0
  62. package/dist/components/bv-star-rating/bv-star-rating.js +67 -0
  63. package/dist/components/bv-table/bv-table.d.ts +5 -0
  64. package/dist/components/bv-table/bv-table.js +72 -0
  65. package/dist/components/bv-toggle/bv-toggle.d.ts +11 -0
  66. package/dist/components/bv-toggle/bv-toggle.js +72 -0
  67. package/dist/components/bv-user-row/bv-user-row.d.ts +12 -0
  68. package/dist/components/bv-user-row/bv-user-row.js +574 -0
  69. package/dist/components/bv-view-switcher/bv-view-switcher.d.ts +11 -0
  70. package/dist/components/bv-view-switcher/bv-view-switcher.js +91 -0
  71. package/dist/preview/index.html +76 -0
  72. package/dist/storybook/stories/screens/course-catalog.data.d.ts +28 -0
  73. package/dist/storybook/stories/screens/course-catalog.data.js +301 -0
  74. package/dist/themes/base.css +66 -0
  75. package/dist/themes/layouts.css +35 -0
  76. package/package.json +181 -0
  77. package/themes/base.css +66 -0
  78. package/themes/layouts.css +35 -0
@@ -0,0 +1,6 @@
1
+ export declare class BvPortalLayout extends HTMLElement {
2
+ private _rendered;
3
+ constructor();
4
+ connectedCallback(): void;
5
+ private _render;
6
+ }
@@ -0,0 +1,39 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-portal-layout/bv-portal-layout.css
2
+ var bv_portal_layout_default = ":host {\n display: block;\n min-height: 100vh;\n box-sizing: border-box;\n\n background: var(--bv-layout-bg, #f9fafb);\n padding: var(--bv-layout-gutter, 20px);\n\n /* Publish layout context tokens so all descendants inherit them */\n --bv-layout-gutter: 20px;\n --bv-layout-bg: #f9fafb;\n --bv-layout-radius: 0px;\n --bv-content-radius: 0px;\n}\n\n.layout {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n";
3
+
4
+ // components/bv-portal-layout/bv-portal-layout.ts
5
+ var BvPortalLayout = class extends HTMLElement {
6
+ _rendered = false;
7
+ constructor() {
8
+ super();
9
+ this.attachShadow({ mode: "open" });
10
+ if ("replaceSync" in CSSStyleSheet.prototype) {
11
+ const sheet = new CSSStyleSheet();
12
+ sheet.replaceSync(bv_portal_layout_default);
13
+ this.shadowRoot.adoptedStyleSheets = [sheet];
14
+ }
15
+ }
16
+ connectedCallback() {
17
+ this._render();
18
+ }
19
+ _render() {
20
+ if (this._rendered) return;
21
+ this._rendered = true;
22
+ const shadow = this.shadowRoot;
23
+ if (!shadow.adoptedStyleSheets.length) {
24
+ const s = document.createElement("style");
25
+ s.textContent = bv_portal_layout_default;
26
+ shadow.appendChild(s);
27
+ }
28
+ const layout = document.createElement("div");
29
+ layout.className = "layout";
30
+ layout.appendChild(document.createElement("slot"));
31
+ shadow.appendChild(layout);
32
+ }
33
+ };
34
+ if (!customElements.get("bv-portal-layout")) {
35
+ customElements.define("bv-portal-layout", BvPortalLayout);
36
+ }
37
+ export {
38
+ BvPortalLayout
39
+ };
@@ -0,0 +1,11 @@
1
+ export declare class BvProgressBar extends HTMLElement {
2
+ static readonly observedAttributes: string[];
3
+ private _fill;
4
+ private _rendered;
5
+ constructor();
6
+ connectedCallback(): void;
7
+ attributeChangedCallback(name: string): void;
8
+ private get _percent();
9
+ private _render;
10
+ private _syncFill;
11
+ }
@@ -0,0 +1,61 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-progress-bar/bv-progress-bar.css
2
+ var bv_progress_bar_default = ":host {\n --bv-progress-track: var(--bv-color-neutral-200);\n --bv-progress-fill: var(--bv-color-primary);\n --bv-progress-height: 8px;\n display: block;\n width: 100%;\n}\n\n:host([variant='success']) {\n --bv-progress-fill: var(--bv-color-success);\n}\n:host([variant='warning']) {\n --bv-progress-fill: var(--bv-color-warning);\n}\n:host([variant='danger']) {\n --bv-progress-fill: var(--bv-color-danger);\n}\n\n:host([size='sm']) {\n --bv-progress-height: 4px;\n}\n:host([size='lg']) {\n --bv-progress-height: 12px;\n}\n\n.track {\n width: 100%;\n height: var(--bv-progress-height);\n background: var(--bv-progress-track);\n border-radius: var(--bv-radius-full);\n overflow: hidden;\n}\n\n.fill {\n height: 100%;\n background: var(--bv-progress-fill);\n border-radius: var(--bv-radius-full);\n transition: width var(--bv-transition-normal);\n min-width: 0;\n max-width: 100%;\n}\n";
3
+
4
+ // components/bv-progress-bar/bv-progress-bar.ts
5
+ var BvProgressBar = class extends HTMLElement {
6
+ static observedAttributes = ["value", "max", "variant", "size"];
7
+ _fill = null;
8
+ _rendered = false;
9
+ constructor() {
10
+ super();
11
+ this.attachShadow({ mode: "open" });
12
+ if ("replaceSync" in CSSStyleSheet.prototype) {
13
+ const sheet = new CSSStyleSheet();
14
+ sheet.replaceSync(bv_progress_bar_default);
15
+ this.shadowRoot.adoptedStyleSheets = [sheet];
16
+ }
17
+ }
18
+ connectedCallback() {
19
+ this._render();
20
+ }
21
+ attributeChangedCallback(name) {
22
+ if (this._rendered && (name === "value" || name === "max")) this._syncFill();
23
+ }
24
+ get _percent() {
25
+ const value = parseFloat(this.getAttribute("value") ?? "0");
26
+ const max = parseFloat(this.getAttribute("max") ?? "100");
27
+ return Math.min(100, Math.max(0, value / max * 100));
28
+ }
29
+ _render() {
30
+ if (this._rendered) return;
31
+ this._rendered = true;
32
+ const shadow = this.shadowRoot;
33
+ if (!shadow.adoptedStyleSheets.length) {
34
+ const s = document.createElement("style");
35
+ s.textContent = bv_progress_bar_default;
36
+ shadow.appendChild(s);
37
+ }
38
+ this.setAttribute("role", "progressbar");
39
+ const track = document.createElement("div");
40
+ track.className = "track";
41
+ this._fill = document.createElement("div");
42
+ this._fill.className = "fill";
43
+ this._syncFill();
44
+ track.appendChild(this._fill);
45
+ shadow.appendChild(track);
46
+ }
47
+ _syncFill() {
48
+ if (!this._fill) return;
49
+ const pct = this._percent;
50
+ this._fill.style.width = `${pct}%`;
51
+ this.setAttribute("aria-valuenow", String(pct));
52
+ this.setAttribute("aria-valuemin", "0");
53
+ this.setAttribute("aria-valuemax", "100");
54
+ }
55
+ };
56
+ if (!customElements.get("bv-progress-bar")) {
57
+ customElements.define("bv-progress-bar", BvProgressBar);
58
+ }
59
+ export {
60
+ BvProgressBar
61
+ };
@@ -0,0 +1,12 @@
1
+ export declare class BvPromoBanner extends HTMLElement {
2
+ static readonly observedAttributes: string[];
3
+ private _rendered;
4
+ private _messageEl;
5
+ private _badgeLabelEl;
6
+ private _badgeLogoEl;
7
+ private _anchor;
8
+ constructor();
9
+ connectedCallback(): void;
10
+ attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
11
+ private _render;
12
+ }
@@ -0,0 +1,79 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-promo-banner/bv-promo-banner.css
2
+ var bv_promo_banner_default = ":host {\n display: inline-block;\n}\n\n.banner {\n display: flex;\n align-items: center;\n gap: var(--bv-spacing-sm);\n padding: 5px var(--bv-spacing-sm) 5px 5px;\n background: var(--bv-color-primary-light);\n border-radius: var(--bv-radius-xl);\n cursor: pointer;\n text-decoration: none;\n transition: opacity var(--bv-transition-fast);\n}\n\n.banner:hover {\n opacity: 0.88;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n gap: var(--bv-spacing-xs);\n padding: 2px var(--bv-spacing-sm);\n background: var(--bv-color-neutral-0);\n border-radius: var(--bv-radius-full);\n flex-shrink: 0;\n}\n\n.badge-label {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-primary-dark);\n white-space: nowrap;\n}\n\n.badge-logo {\n height: 12px;\n width: auto;\n display: block;\n}\n\n.message {\n flex: none;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chevron {\n flex-shrink: 0;\n width: 16px;\n height: 16px;\n color: var(--bv-color-primary);\n display: flex;\n align-items: center;\n}\n";
3
+
4
+ // components/bv-promo-banner/bv-promo-banner.ts
5
+ var CHEVRON = `<svg class="chevron" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
6
+ <path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
7
+ </svg>`;
8
+ var BvPromoBanner = class extends HTMLElement {
9
+ static observedAttributes = ["message", "badge-label", "badge-logo", "href"];
10
+ _rendered = false;
11
+ _messageEl = null;
12
+ _badgeLabelEl = null;
13
+ _badgeLogoEl = null;
14
+ _anchor = null;
15
+ constructor() {
16
+ super();
17
+ this.attachShadow({ mode: "open" });
18
+ if ("replaceSync" in CSSStyleSheet.prototype) {
19
+ const sheet = new CSSStyleSheet();
20
+ sheet.replaceSync(bv_promo_banner_default);
21
+ this.shadowRoot.adoptedStyleSheets = [sheet];
22
+ }
23
+ }
24
+ connectedCallback() {
25
+ this._render();
26
+ }
27
+ attributeChangedCallback(name, _old, val) {
28
+ if (!this._rendered) return;
29
+ if (name === "message" && this._messageEl) this._messageEl.textContent = val ?? "";
30
+ if (name === "badge-label" && this._badgeLabelEl) this._badgeLabelEl.textContent = val ?? "";
31
+ if (name === "badge-logo" && this._badgeLogoEl) {
32
+ this._badgeLogoEl.src = val ?? "";
33
+ this._badgeLogoEl.hidden = !val;
34
+ }
35
+ if (name === "href" && this._anchor) this._anchor.href = val ?? "";
36
+ }
37
+ _render() {
38
+ if (this._rendered) return;
39
+ this._rendered = true;
40
+ const shadow = this.shadowRoot;
41
+ if (!shadow.adoptedStyleSheets.length) {
42
+ const s = document.createElement("style");
43
+ s.textContent = bv_promo_banner_default;
44
+ shadow.appendChild(s);
45
+ }
46
+ const anchor = document.createElement("a");
47
+ anchor.className = "banner";
48
+ anchor.href = this.getAttribute("href") ?? "";
49
+ anchor.rel = "noopener noreferrer";
50
+ this._anchor = anchor;
51
+ const badge = document.createElement("span");
52
+ badge.className = "badge";
53
+ const badgeLabel = document.createElement("span");
54
+ badgeLabel.className = "badge-label";
55
+ badgeLabel.textContent = this.getAttribute("badge-label") ?? "";
56
+ this._badgeLabelEl = badgeLabel;
57
+ const badgeLogo = document.createElement("img");
58
+ badgeLogo.className = "badge-logo";
59
+ badgeLogo.alt = "";
60
+ badgeLogo.src = this.getAttribute("badge-logo") ?? "";
61
+ badgeLogo.hidden = !this.getAttribute("badge-logo");
62
+ this._badgeLogoEl = badgeLogo;
63
+ badge.append(badgeLabel, badgeLogo);
64
+ const message = document.createElement("span");
65
+ message.className = "message";
66
+ message.textContent = this.getAttribute("message") ?? "";
67
+ this._messageEl = message;
68
+ const chevron = document.createElement("span");
69
+ chevron.innerHTML = CHEVRON;
70
+ anchor.append(badge, message, chevron);
71
+ shadow.appendChild(anchor);
72
+ }
73
+ };
74
+ if (!customElements.get("bv-promo-banner")) {
75
+ customElements.define("bv-promo-banner", BvPromoBanner);
76
+ }
77
+ export {
78
+ BvPromoBanner
79
+ };
@@ -0,0 +1,11 @@
1
+ export declare class BvRadio extends HTMLElement {
2
+ static readonly observedAttributes: string[];
3
+ private _rendered;
4
+ private _labelEl;
5
+ constructor();
6
+ connectedCallback(): void;
7
+ attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
8
+ get checked(): boolean;
9
+ set checked(v: boolean);
10
+ private _render;
11
+ }
@@ -0,0 +1,78 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-radio/bv-radio.css
2
+ var bv_radio_default = ":host {\n --bv-radio-size: 16px;\n --bv-radio-border: var(--bv-color-neutral-300);\n --bv-radio-checked-color: var(--bv-color-primary);\n display: inline-flex;\n font-family: var(--bv-font-family-base);\n}\n\n.wrap {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n user-select: none;\n}\n\n:host([disabled]) .wrap {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.circle {\n width: var(--bv-radio-size);\n height: var(--bv-radio-size);\n border-radius: 50%;\n border: 1.5px solid var(--bv-radio-border);\n background: var(--bv-color-neutral-0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: border-color var(--bv-transition-fast);\n}\n\n:host([checked]) .circle {\n border-color: var(--bv-radio-checked-color);\n}\n\n.dot {\n width: calc(var(--bv-radio-size) * 0.5);\n height: calc(var(--bv-radio-size) * 0.5);\n border-radius: 50%;\n background: var(--bv-radio-checked-color);\n display: none;\n}\n\n:host([checked]) .dot {\n display: block;\n}\n\n.label {\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-800);\n line-height: 20px;\n}\n";
3
+
4
+ // components/bv-radio/bv-radio.ts
5
+ var BvRadio = class extends HTMLElement {
6
+ static observedAttributes = ["checked", "disabled", "label", "name", "value"];
7
+ _rendered = false;
8
+ _labelEl = null;
9
+ constructor() {
10
+ super();
11
+ this.attachShadow({ mode: "open" });
12
+ if ("replaceSync" in CSSStyleSheet.prototype) {
13
+ const sheet = new CSSStyleSheet();
14
+ sheet.replaceSync(bv_radio_default);
15
+ this.shadowRoot.adoptedStyleSheets = [sheet];
16
+ }
17
+ }
18
+ connectedCallback() {
19
+ this._render();
20
+ }
21
+ attributeChangedCallback(name, _old, val) {
22
+ if (!this._rendered) return;
23
+ if (name === "label" && this._labelEl) this._labelEl.textContent = val ?? "";
24
+ }
25
+ get checked() {
26
+ return this.hasAttribute("checked");
27
+ }
28
+ set checked(v) {
29
+ if (v) this.setAttribute("checked", "");
30
+ else this.removeAttribute("checked");
31
+ }
32
+ _render() {
33
+ if (this._rendered) return;
34
+ this._rendered = true;
35
+ const shadow = this.shadowRoot;
36
+ if (!shadow.adoptedStyleSheets.length) {
37
+ const s = document.createElement("style");
38
+ s.textContent = bv_radio_default;
39
+ shadow.appendChild(s);
40
+ }
41
+ const wrap = document.createElement("label");
42
+ wrap.className = "wrap";
43
+ const circle = document.createElement("span");
44
+ circle.className = "circle";
45
+ const dot = document.createElement("span");
46
+ dot.className = "dot";
47
+ circle.appendChild(dot);
48
+ this._labelEl = document.createElement("span");
49
+ this._labelEl.className = "label";
50
+ this._labelEl.textContent = this.getAttribute("label") ?? "";
51
+ const slot = document.createElement("slot");
52
+ wrap.append(circle, this._labelEl, slot);
53
+ shadow.appendChild(wrap);
54
+ wrap.addEventListener("click", () => {
55
+ if (this.hasAttribute("disabled") || this.checked) return;
56
+ const name = this.getAttribute("name");
57
+ if (name) {
58
+ document.querySelectorAll(`bv-radio[name="${name}"]`).forEach((r) => {
59
+ if (r !== this) r.checked = false;
60
+ });
61
+ }
62
+ this.checked = true;
63
+ this.dispatchEvent(
64
+ new CustomEvent("bv-change", {
65
+ bubbles: true,
66
+ composed: true,
67
+ detail: { value: this.getAttribute("value"), checked: true }
68
+ })
69
+ );
70
+ });
71
+ }
72
+ };
73
+ if (!customElements.get("bv-radio")) {
74
+ customElements.define("bv-radio", BvRadio);
75
+ }
76
+ export {
77
+ BvRadio
78
+ };
@@ -0,0 +1,10 @@
1
+ export declare class BvSearchbox extends HTMLElement {
2
+ static readonly observedAttributes: string[];
3
+ private _rendered;
4
+ private _input;
5
+ constructor();
6
+ connectedCallback(): void;
7
+ attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
8
+ get value(): string;
9
+ private _render;
10
+ }
@@ -0,0 +1,68 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-searchbox/bv-searchbox.css
2
+ 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.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";
3
+
4
+ // components/bv-searchbox/bv-searchbox.ts
5
+ var SEARCH_ICON = `<svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
6
+ <path d="M17.5 17.5L13.875 13.875M15.8333 9.16667C15.8333 12.8486 12.8486 15.8333 9.16667 15.8333C5.48477 15.8333 2.5 12.8486 2.5 9.16667C2.5 5.48477 5.48477 2.5 9.16667 2.5C12.8486 2.5 15.8333 5.48477 15.8333 9.16667Z"
7
+ stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
8
+ </svg>`;
9
+ var BvSearchbox = class extends HTMLElement {
10
+ static observedAttributes = ["placeholder", "value", "size"];
11
+ _rendered = false;
12
+ _input = null;
13
+ constructor() {
14
+ super();
15
+ this.attachShadow({ mode: "open" });
16
+ if ("replaceSync" in CSSStyleSheet.prototype) {
17
+ const sheet = new CSSStyleSheet();
18
+ sheet.replaceSync(bv_searchbox_default);
19
+ this.shadowRoot.adoptedStyleSheets = [sheet];
20
+ }
21
+ }
22
+ connectedCallback() {
23
+ this._render();
24
+ }
25
+ attributeChangedCallback(name, _old, val) {
26
+ if (!this._rendered || !this._input) return;
27
+ if (name === "placeholder") this._input.placeholder = val ?? "";
28
+ if (name === "value") this._input.value = val ?? "";
29
+ }
30
+ get value() {
31
+ var _a;
32
+ return ((_a = this._input) == null ? void 0 : _a.value) ?? "";
33
+ }
34
+ _render() {
35
+ if (this._rendered) return;
36
+ this._rendered = true;
37
+ const shadow = this.shadowRoot;
38
+ if (!shadow.adoptedStyleSheets.length) {
39
+ const s = document.createElement("style");
40
+ s.textContent = bv_searchbox_default;
41
+ shadow.appendChild(s);
42
+ }
43
+ const icon = document.createElement("span");
44
+ icon.className = "search-icon";
45
+ icon.innerHTML = SEARCH_ICON;
46
+ this._input = document.createElement("input");
47
+ this._input.type = "search";
48
+ this._input.className = "search-input";
49
+ this._input.placeholder = this.getAttribute("placeholder") ?? "Search\u2026";
50
+ this._input.value = this.getAttribute("value") ?? "";
51
+ this._input.addEventListener("input", () => {
52
+ this.dispatchEvent(
53
+ new CustomEvent("bv-search", {
54
+ bubbles: true,
55
+ composed: true,
56
+ detail: { value: this._input.value }
57
+ })
58
+ );
59
+ });
60
+ shadow.append(icon, this._input);
61
+ }
62
+ };
63
+ if (!customElements.get("bv-searchbox")) {
64
+ customElements.define("bv-searchbox", BvSearchbox);
65
+ }
66
+ export {
67
+ BvSearchbox
68
+ };
@@ -0,0 +1,11 @@
1
+ export declare class BvStarRating extends HTMLElement {
2
+ static readonly observedAttributes: string[];
3
+ private _rendered;
4
+ constructor();
5
+ connectedCallback(): void;
6
+ attributeChangedCallback(): void;
7
+ private get _value();
8
+ private get _max();
9
+ private _render;
10
+ private _buildStars;
11
+ }
@@ -0,0 +1,67 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-star-rating/bv-star-rating.css
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
+
4
+ // components/bv-star-rating/bv-star-rating.ts
5
+ 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
+ var BvStarRating = class extends HTMLElement {
7
+ static observedAttributes = ["value", "max", "size"];
8
+ _rendered = false;
9
+ constructor() {
10
+ 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
+ }
17
+ }
18
+ connectedCallback() {
19
+ this._render();
20
+ }
21
+ attributeChangedCallback() {
22
+ if (this._rendered) this._buildStars();
23
+ }
24
+ get _value() {
25
+ return parseFloat(this.getAttribute("value") ?? "0");
26
+ }
27
+ get _max() {
28
+ return parseInt(this.getAttribute("max") ?? "5", 10);
29
+ }
30
+ _render() {
31
+ if (this._rendered) return;
32
+ this._rendered = true;
33
+ 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
+ const wrap = document.createElement("div");
40
+ wrap.className = "stars";
41
+ wrap.setAttribute("role", "img");
42
+ wrap.setAttribute("aria-label", `${this._value} out of ${this._max} stars`);
43
+ shadow.appendChild(wrap);
44
+ this._buildStars();
45
+ }
46
+ _buildStars() {
47
+ const wrap = this.shadowRoot.querySelector(".stars");
48
+ wrap.innerHTML = "";
49
+ wrap.setAttribute("aria-label", `${this._value} out of ${this._max} stars`);
50
+ for (let i = 1; i <= this._max; i++) {
51
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
52
+ svg.setAttribute("viewBox", "0 0 20 20");
53
+ svg.setAttribute("fill", "currentColor");
54
+ svg.setAttribute("class", `star${i <= this._value ? " filled" : ""}`);
55
+ const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
56
+ path.setAttribute("d", STAR_PATH);
57
+ svg.appendChild(path);
58
+ wrap.appendChild(svg);
59
+ }
60
+ }
61
+ };
62
+ if (!customElements.get("bv-star-rating")) {
63
+ customElements.define("bv-star-rating", BvStarRating);
64
+ }
65
+ export {
66
+ BvStarRating
67
+ };
@@ -0,0 +1,5 @@
1
+ export declare class BvTable extends HTMLElement {
2
+ static readonly observedAttributes: string[];
3
+ connectedCallback(): void;
4
+ private _enhanceHeaders;
5
+ }
@@ -0,0 +1,72 @@
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 overflow-x: auto;\n border: 1px solid var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-lg);\n font-family: var(--bv-font-family-base);\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-500);\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}\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 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 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";
3
+
4
+ // components/bv-table/bv-table.ts
5
+ var SORT_NONE = `<svg class="bv-sort-icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
6
+ <path d="M8 3v10M5 6l3-3 3 3M5 10l3 3 3-3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
7
+ </svg>`;
8
+ var SORT_ASC = `<svg class="bv-sort-icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
9
+ <path d="M8 13V3M5 6l3-3 3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
10
+ </svg>`;
11
+ var SORT_DESC = `<svg class="bv-sort-icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
12
+ <path d="M8 3v10M5 10l3 3 3-3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
13
+ </svg>`;
14
+ function injectTableStyles() {
15
+ if (document.getElementById("bv-table-styles")) return;
16
+ const style = document.createElement("style");
17
+ style.id = "bv-table-styles";
18
+ style.textContent = bv_table_default;
19
+ document.head.appendChild(style);
20
+ }
21
+ var BvTable = class extends HTMLElement {
22
+ static observedAttributes = ["striped", "bordered"];
23
+ connectedCallback() {
24
+ injectTableStyles();
25
+ this._enhanceHeaders();
26
+ }
27
+ _enhanceHeaders() {
28
+ this.querySelectorAll("thead th[data-sortable]").forEach((th) => {
29
+ var _a;
30
+ const label = ((_a = th.textContent) == null ? void 0 : _a.trim()) ?? "";
31
+ const sortDir = th.getAttribute("data-sort") ?? "none";
32
+ const icon = sortDir === "asc" ? SORT_ASC : sortDir === "desc" ? SORT_DESC : SORT_NONE;
33
+ th.innerHTML = `<span class="bv-th-content">${label}${icon}</span>`;
34
+ th.addEventListener("click", () => {
35
+ var _a2, _b, _c, _d;
36
+ const current = th.getAttribute("data-sort") ?? "none";
37
+ const next = current === "none" ? "asc" : current === "asc" ? "desc" : "none";
38
+ this.querySelectorAll("thead th[data-sortable]").forEach((other) => {
39
+ var _a3, _b2;
40
+ if (other !== th) {
41
+ other.removeAttribute("data-sort");
42
+ const otherLabel = ((_b2 = (_a3 = other.querySelector(".bv-th-content")) == null ? void 0 : _a3.firstChild) == null ? void 0 : _b2.textContent) ?? "";
43
+ other.innerHTML = `<span class="bv-th-content">${otherLabel}${SORT_NONE}</span>`;
44
+ }
45
+ });
46
+ if (next === "none") {
47
+ th.removeAttribute("data-sort");
48
+ const l = ((_b = (_a2 = th.querySelector(".bv-th-content")) == null ? void 0 : _a2.firstChild) == null ? void 0 : _b.textContent) ?? label;
49
+ th.innerHTML = `<span class="bv-th-content">${l}${SORT_NONE}</span>`;
50
+ } else {
51
+ th.setAttribute("data-sort", next);
52
+ const newIcon = next === "asc" ? SORT_ASC : SORT_DESC;
53
+ const l = ((_d = (_c = th.querySelector(".bv-th-content")) == null ? void 0 : _c.firstChild) == null ? void 0 : _d.textContent) ?? label;
54
+ th.innerHTML = `<span class="bv-th-content">${l}${newIcon}</span>`;
55
+ }
56
+ this.dispatchEvent(
57
+ new CustomEvent("bv-sort", {
58
+ bubbles: true,
59
+ composed: true,
60
+ detail: { column: th.getAttribute("data-column"), direction: next }
61
+ })
62
+ );
63
+ });
64
+ });
65
+ }
66
+ };
67
+ if (!customElements.get("bv-table")) {
68
+ customElements.define("bv-table", BvTable);
69
+ }
70
+ export {
71
+ BvTable
72
+ };
@@ -0,0 +1,11 @@
1
+ export declare class BvToggle extends HTMLElement {
2
+ static readonly observedAttributes: string[];
3
+ private _rendered;
4
+ private _labelEl;
5
+ constructor();
6
+ connectedCallback(): void;
7
+ attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
8
+ get checked(): boolean;
9
+ set checked(v: boolean);
10
+ private _render;
11
+ }
@@ -0,0 +1,72 @@
1
+ // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-toggle/bv-toggle.css
2
+ var bv_toggle_default = ":host {\n --bv-toggle-width: 44px;\n --bv-toggle-height: 24px;\n --bv-toggle-track-off: var(--bv-color-neutral-300);\n --bv-toggle-track-on: var(--bv-color-primary);\n --bv-toggle-thumb: var(--bv-color-neutral-0);\n display: inline-flex;\n font-family: var(--bv-font-family-base);\n}\n\n.wrap {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n user-select: none;\n}\n\n:host([disabled]) .wrap {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.track {\n position: relative;\n width: var(--bv-toggle-width);\n height: var(--bv-toggle-height);\n border-radius: var(--bv-radius-full);\n background: var(--bv-toggle-track-off);\n transition: background var(--bv-transition-fast);\n flex-shrink: 0;\n}\n\n:host([checked]) .track {\n background: var(--bv-toggle-track-on);\n}\n\n.thumb {\n position: absolute;\n top: 3px;\n left: 3px;\n width: calc(var(--bv-toggle-height) - 6px);\n height: calc(var(--bv-toggle-height) - 6px);\n border-radius: 50%;\n background: var(--bv-toggle-thumb);\n box-shadow: var(--bv-shadow-sm);\n transition: transform var(--bv-transition-fast);\n}\n\n:host([checked]) .thumb {\n transform: translateX(calc(var(--bv-toggle-width) - var(--bv-toggle-height)));\n}\n\n.label {\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-800);\n line-height: 20px;\n}\n";
3
+
4
+ // components/bv-toggle/bv-toggle.ts
5
+ var BvToggle = class extends HTMLElement {
6
+ static observedAttributes = ["checked", "disabled", "label"];
7
+ _rendered = false;
8
+ _labelEl = null;
9
+ constructor() {
10
+ super();
11
+ this.attachShadow({ mode: "open" });
12
+ if ("replaceSync" in CSSStyleSheet.prototype) {
13
+ const sheet = new CSSStyleSheet();
14
+ sheet.replaceSync(bv_toggle_default);
15
+ this.shadowRoot.adoptedStyleSheets = [sheet];
16
+ }
17
+ }
18
+ connectedCallback() {
19
+ this._render();
20
+ }
21
+ attributeChangedCallback(name, _old, val) {
22
+ if (!this._rendered) return;
23
+ if (name === "label" && this._labelEl) this._labelEl.textContent = val ?? "";
24
+ }
25
+ get checked() {
26
+ return this.hasAttribute("checked");
27
+ }
28
+ set checked(v) {
29
+ if (v) this.setAttribute("checked", "");
30
+ else this.removeAttribute("checked");
31
+ }
32
+ _render() {
33
+ if (this._rendered) return;
34
+ this._rendered = true;
35
+ const shadow = this.shadowRoot;
36
+ if (!shadow.adoptedStyleSheets.length) {
37
+ const s = document.createElement("style");
38
+ s.textContent = bv_toggle_default;
39
+ shadow.appendChild(s);
40
+ }
41
+ const wrap = document.createElement("label");
42
+ wrap.className = "wrap";
43
+ const track = document.createElement("span");
44
+ track.className = "track";
45
+ const thumb = document.createElement("span");
46
+ thumb.className = "thumb";
47
+ track.appendChild(thumb);
48
+ this._labelEl = document.createElement("span");
49
+ this._labelEl.className = "label";
50
+ this._labelEl.textContent = this.getAttribute("label") ?? "";
51
+ const slot = document.createElement("slot");
52
+ wrap.append(track, this._labelEl, slot);
53
+ shadow.appendChild(wrap);
54
+ wrap.addEventListener("click", () => {
55
+ if (this.hasAttribute("disabled")) return;
56
+ this.checked = !this.checked;
57
+ this.dispatchEvent(
58
+ new CustomEvent("bv-change", {
59
+ bubbles: true,
60
+ composed: true,
61
+ detail: { checked: this.checked }
62
+ })
63
+ );
64
+ });
65
+ }
66
+ };
67
+ if (!customElements.get("bv-toggle")) {
68
+ customElements.define("bv-toggle", BvToggle);
69
+ }
70
+ export {
71
+ BvToggle
72
+ };
@@ -0,0 +1,12 @@
1
+ import '../bv-avatar/bv-avatar.ts';
2
+ import '../bv-button/bv-button.ts';
3
+ export declare class BvUserRow extends HTMLElement {
4
+ static readonly observedAttributes: string[];
5
+ private _rendered;
6
+ private _els;
7
+ constructor();
8
+ connectedCallback(): void;
9
+ attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
10
+ private _greeting;
11
+ private _render;
12
+ }