@bluevolt-tech/lumen 1.5.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/bv-alert-banner/bv-alert-banner.d.ts +33 -0
- package/dist/components/bv-alert-banner/bv-alert-banner.js +206 -0
- package/dist/components/bv-badge/bv-badge.d.ts +1 -1
- package/dist/components/bv-badge/bv-badge.js +1 -1
- package/dist/components/bv-button/bv-button.d.ts +1 -1
- package/dist/components/bv-button/bv-button.js +1 -1
- package/dist/components/bv-checkbox/bv-checkbox.js +1 -1
- package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +1 -1
- package/dist/components/bv-course-grid-card/bv-course-grid-card.js +1 -1
- package/dist/components/bv-course-list-card/bv-course-list-card.js +1 -1
- package/dist/components/bv-date-range-input/bv-date-range-input.d.ts +23 -0
- package/dist/components/bv-date-range-input/bv-date-range-input.js +950 -0
- package/dist/components/bv-date-range-picker/bv-date-range-picker.d.ts +56 -0
- package/dist/components/bv-date-range-picker/bv-date-range-picker.js +778 -0
- package/dist/components/bv-empty-state/bv-empty-state.js +1 -1
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +20 -5
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +263 -25
- package/dist/components/bv-filter-panel/bv-filter-panel.js +1 -1
- package/dist/components/bv-input/bv-input.d.ts +24 -0
- package/dist/components/bv-input/bv-input.js +148 -0
- package/dist/components/bv-input-dropdown/bv-input-dropdown.d.ts +46 -0
- package/dist/components/bv-input-dropdown/bv-input-dropdown.js +501 -0
- package/dist/components/bv-pagination/bv-pagination.d.ts +13 -1
- package/dist/components/bv-pagination/bv-pagination.js +290 -9
- package/dist/components/bv-portal-header/bv-portal-header.js +2 -2
- package/dist/components/bv-searchbox/bv-searchbox.js +1 -1
- package/dist/components/bv-segmented-control/bv-segmented-control.d.ts +26 -0
- package/dist/components/bv-segmented-control/bv-segmented-control.js +128 -0
- package/dist/components/bv-select/bv-select.d.ts +41 -0
- package/dist/components/bv-select/bv-select.js +240 -0
- package/dist/components/bv-split-button/bv-split-button.d.ts +37 -0
- package/dist/components/bv-split-button/bv-split-button.js +264 -0
- package/dist/components/bv-table/bv-table.d.ts +15 -0
- package/dist/components/bv-table/bv-table.js +260 -33
- package/dist/components/bv-toggle/bv-toggle.d.ts +2 -1
- package/dist/components/bv-toggle/bv-toggle.js +2 -2
- package/dist/components/bv-tooltip/bv-tooltip.d.ts +18 -0
- package/dist/components/bv-tooltip/bv-tooltip.js +144 -0
- package/dist/components/bv-user-row/bv-user-row.js +1 -1
- package/dist/storybook/stories/screens/cet-report.data.d.ts +55 -0
- package/dist/storybook/stories/screens/cet-report.data.js +3697 -0
- package/dist/themes/base.css +14 -1
- package/package.json +42 -1
- package/themes/base.css +14 -1
|
@@ -1,5 +1,147 @@
|
|
|
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 overflow-x: auto;\n border: 1px solid var(--bv-color-neutral-200);\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";
|
|
3
|
+
|
|
4
|
+
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-tooltip/bv-tooltip.css
|
|
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
|
+
|
|
7
|
+
// components/bv-tooltip/bv-tooltip.ts
|
|
8
|
+
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>`;
|
|
9
|
+
var _sheet = null;
|
|
10
|
+
function getSheet() {
|
|
11
|
+
if (!_sheet) {
|
|
12
|
+
_sheet = new CSSStyleSheet();
|
|
13
|
+
_sheet.replaceSync(bv_tooltip_default);
|
|
14
|
+
}
|
|
15
|
+
return _sheet;
|
|
16
|
+
}
|
|
17
|
+
var _uid = 0;
|
|
18
|
+
var BvTooltip = class extends HTMLElement {
|
|
19
|
+
static observedAttributes = ["text", "position"];
|
|
20
|
+
_rendered = false;
|
|
21
|
+
_textEl = null;
|
|
22
|
+
_triggerEl = null;
|
|
23
|
+
_popupEl = null;
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
27
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype) {
|
|
28
|
+
shadow.adoptedStyleSheets = [getSheet()];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
get text() {
|
|
32
|
+
return this.getAttribute("text") ?? "";
|
|
33
|
+
}
|
|
34
|
+
set text(v) {
|
|
35
|
+
this.setAttribute("text", v);
|
|
36
|
+
}
|
|
37
|
+
get position() {
|
|
38
|
+
return this.getAttribute("position") ?? "top";
|
|
39
|
+
}
|
|
40
|
+
set position(v) {
|
|
41
|
+
this.setAttribute("position", v);
|
|
42
|
+
}
|
|
43
|
+
connectedCallback() {
|
|
44
|
+
this._render();
|
|
45
|
+
}
|
|
46
|
+
attributeChangedCallback(name, _old, _val) {
|
|
47
|
+
if (!this._rendered) return;
|
|
48
|
+
if (name === "text" && this._textEl) {
|
|
49
|
+
this._textEl.textContent = this.text;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
_render() {
|
|
53
|
+
if (this._rendered) return;
|
|
54
|
+
this._rendered = true;
|
|
55
|
+
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
|
+
const wrap = document.createElement("span");
|
|
62
|
+
wrap.className = "wrap";
|
|
63
|
+
const popupId = `bv-tooltip-popup-${++_uid}`;
|
|
64
|
+
const trigger = document.createElement("span");
|
|
65
|
+
trigger.className = "trigger";
|
|
66
|
+
trigger.setAttribute("tabindex", "0");
|
|
67
|
+
trigger.setAttribute("role", "button");
|
|
68
|
+
trigger.setAttribute("aria-label", "More information");
|
|
69
|
+
trigger.setAttribute("aria-describedby", popupId);
|
|
70
|
+
trigger.innerHTML = QUESTION_MARK_SVG;
|
|
71
|
+
this._triggerEl = trigger;
|
|
72
|
+
const popup = document.createElement("span");
|
|
73
|
+
popup.id = popupId;
|
|
74
|
+
popup.className = "popup";
|
|
75
|
+
popup.setAttribute("role", "tooltip");
|
|
76
|
+
this._popupEl = popup;
|
|
77
|
+
const textEl = document.createElement("span");
|
|
78
|
+
textEl.className = "text-content";
|
|
79
|
+
textEl.textContent = this.text;
|
|
80
|
+
this._textEl = textEl;
|
|
81
|
+
const slot = document.createElement("slot");
|
|
82
|
+
popup.append(textEl, slot);
|
|
83
|
+
wrap.append(trigger, popup);
|
|
84
|
+
shadow.appendChild(wrap);
|
|
85
|
+
trigger.addEventListener("mouseenter", () => this._show());
|
|
86
|
+
trigger.addEventListener("mouseleave", () => this._hide());
|
|
87
|
+
trigger.addEventListener("focus", () => this._show());
|
|
88
|
+
trigger.addEventListener("blur", () => this._hide());
|
|
89
|
+
}
|
|
90
|
+
_show() {
|
|
91
|
+
const popup = this._popupEl;
|
|
92
|
+
const trigger = this._triggerEl;
|
|
93
|
+
if (!popup || !trigger) return;
|
|
94
|
+
popup.style.top = "0";
|
|
95
|
+
popup.style.bottom = "auto";
|
|
96
|
+
popup.style.left = "0";
|
|
97
|
+
popup.style.right = "auto";
|
|
98
|
+
popup.style.transform = "none";
|
|
99
|
+
popup.style.display = "block";
|
|
100
|
+
popup.style.visibility = "hidden";
|
|
101
|
+
const tRect = trigger.getBoundingClientRect();
|
|
102
|
+
const pRect = popup.getBoundingClientRect();
|
|
103
|
+
const vw = window.innerWidth;
|
|
104
|
+
const vh = window.innerHeight;
|
|
105
|
+
const gap = 8;
|
|
106
|
+
const spaceAbove = tRect.top - gap;
|
|
107
|
+
const spaceBelow = vh - tRect.bottom - gap;
|
|
108
|
+
const preferBottom = this.position === "bottom";
|
|
109
|
+
const goBelow = preferBottom ? spaceBelow >= pRect.height || spaceBelow >= spaceAbove : spaceAbove < pRect.height;
|
|
110
|
+
if (goBelow) {
|
|
111
|
+
popup.style.top = "calc(100% + 8px)";
|
|
112
|
+
popup.style.bottom = "auto";
|
|
113
|
+
} else {
|
|
114
|
+
popup.style.bottom = "calc(100% + 8px)";
|
|
115
|
+
popup.style.top = "auto";
|
|
116
|
+
}
|
|
117
|
+
const rawLeft = tRect.left;
|
|
118
|
+
const rawRight = tRect.left + pRect.width;
|
|
119
|
+
let transformX = 0;
|
|
120
|
+
if (rawRight > vw - gap) {
|
|
121
|
+
transformX = vw - gap - rawRight;
|
|
122
|
+
}
|
|
123
|
+
if (rawLeft + transformX < gap) {
|
|
124
|
+
transformX = gap - rawLeft;
|
|
125
|
+
}
|
|
126
|
+
popup.style.left = "0";
|
|
127
|
+
popup.style.transform = transformX !== 0 ? `translateX(${transformX}px)` : "none";
|
|
128
|
+
popup.style.visibility = "";
|
|
129
|
+
}
|
|
130
|
+
_hide() {
|
|
131
|
+
const popup = this._popupEl;
|
|
132
|
+
if (!popup) return;
|
|
133
|
+
popup.style.display = "";
|
|
134
|
+
popup.style.top = "";
|
|
135
|
+
popup.style.bottom = "";
|
|
136
|
+
popup.style.left = "";
|
|
137
|
+
popup.style.right = "";
|
|
138
|
+
popup.style.transform = "";
|
|
139
|
+
popup.style.visibility = "";
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
if (!customElements.get("bv-tooltip")) {
|
|
143
|
+
customElements.define("bv-tooltip", BvTooltip);
|
|
144
|
+
}
|
|
3
145
|
|
|
4
146
|
// components/bv-table/bv-table.ts
|
|
5
147
|
var SORT_NONE = `<svg class="bv-sort-icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -11,6 +153,9 @@ var SORT_ASC = `<svg class="bv-sort-icon" viewBox="0 0 16 16" fill="none" xmlns=
|
|
|
11
153
|
var SORT_DESC = `<svg class="bv-sort-icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
12
154
|
<path d="M8 3v10M5 10l3 3 3-3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
13
155
|
</svg>`;
|
|
156
|
+
function escapeAttr(s) {
|
|
157
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
158
|
+
}
|
|
14
159
|
function injectTableStyles() {
|
|
15
160
|
if (document.getElementById("bv-table-styles")) return;
|
|
16
161
|
const style = document.createElement("style");
|
|
@@ -20,47 +165,129 @@ function injectTableStyles() {
|
|
|
20
165
|
}
|
|
21
166
|
var BvTable = class extends HTMLElement {
|
|
22
167
|
static observedAttributes = ["striped", "bordered"];
|
|
168
|
+
_isDragging = false;
|
|
169
|
+
_dragStartX = 0;
|
|
170
|
+
_dragScrollLeft = 0;
|
|
171
|
+
_boundMouseDown = (e) => this._onMouseDown(e);
|
|
172
|
+
_boundMouseMove = (e) => this._onMouseMove(e);
|
|
173
|
+
_boundMouseUp = () => this._onMouseUp();
|
|
23
174
|
connectedCallback() {
|
|
24
175
|
injectTableStyles();
|
|
25
176
|
this._enhanceHeaders();
|
|
177
|
+
this._enhanceBodyCells();
|
|
178
|
+
this._setupDrag();
|
|
179
|
+
}
|
|
180
|
+
disconnectedCallback() {
|
|
181
|
+
this._teardownDrag();
|
|
182
|
+
}
|
|
183
|
+
_setupDrag() {
|
|
184
|
+
this.addEventListener("mousedown", this._boundMouseDown);
|
|
185
|
+
window.addEventListener("mousemove", this._boundMouseMove);
|
|
186
|
+
window.addEventListener("mouseup", this._boundMouseUp);
|
|
187
|
+
}
|
|
188
|
+
_teardownDrag() {
|
|
189
|
+
this.removeEventListener("mousedown", this._boundMouseDown);
|
|
190
|
+
window.removeEventListener("mousemove", this._boundMouseMove);
|
|
191
|
+
window.removeEventListener("mouseup", this._boundMouseUp);
|
|
192
|
+
}
|
|
193
|
+
// Wraps each plain-text body cell's content in an inline span. Unlike the
|
|
194
|
+
// <td> itself, an inline span only occupies the rendered width of its text —
|
|
195
|
+
// so hovering the cell's padding (short values, blank space) stays grab-able,
|
|
196
|
+
// and only the glyphs themselves resolve to a text-selectable target.
|
|
197
|
+
_enhanceBodyCells() {
|
|
198
|
+
this.querySelectorAll("tbody td").forEach((td) => {
|
|
199
|
+
if (td.children.length > 0) return;
|
|
200
|
+
const text = td.textContent;
|
|
201
|
+
if (!text || !text.trim()) return;
|
|
202
|
+
const span = document.createElement("span");
|
|
203
|
+
span.className = "bv-cell-text";
|
|
204
|
+
span.textContent = text;
|
|
205
|
+
td.replaceChildren(span);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
_onMouseDown(e) {
|
|
209
|
+
if (e.button !== 0) return;
|
|
210
|
+
if (this._isOverText(e.target)) return;
|
|
211
|
+
this._isDragging = true;
|
|
212
|
+
this._dragStartX = e.pageX;
|
|
213
|
+
this._dragScrollLeft = this.scrollLeft;
|
|
214
|
+
this.setAttribute("data-dragging", "");
|
|
215
|
+
e.preventDefault();
|
|
216
|
+
}
|
|
217
|
+
_onMouseMove(e) {
|
|
218
|
+
if (!this._isDragging) return;
|
|
219
|
+
this.scrollLeft = this._dragScrollLeft - (e.pageX - this._dragStartX);
|
|
220
|
+
}
|
|
221
|
+
_onMouseUp() {
|
|
222
|
+
if (!this._isDragging) return;
|
|
223
|
+
this._isDragging = false;
|
|
224
|
+
this.removeAttribute("data-dragging");
|
|
225
|
+
}
|
|
226
|
+
// Returns true when the mousedown target is rendered text the user may want
|
|
227
|
+
// to select: either a body cell's .bv-cell-text span (see _enhanceBodyCells)
|
|
228
|
+
// or a header cell with a direct text-node child (headers are left unwrapped).
|
|
229
|
+
_isOverText(target) {
|
|
230
|
+
var _a;
|
|
231
|
+
if (!(target instanceof Element)) return false;
|
|
232
|
+
if (target.closest(".bv-cell-text")) return true;
|
|
233
|
+
for (const node of target.childNodes) {
|
|
234
|
+
if (node.nodeType === Node.TEXT_NODE && ((_a = node.textContent) == null ? void 0 : _a.trim())) return true;
|
|
235
|
+
}
|
|
236
|
+
return false;
|
|
26
237
|
}
|
|
27
238
|
_enhanceHeaders() {
|
|
28
|
-
this.querySelectorAll("thead th
|
|
239
|
+
this.querySelectorAll("thead th").forEach((th) => {
|
|
29
240
|
var _a;
|
|
241
|
+
const hasSortable = th.hasAttribute("data-sortable");
|
|
242
|
+
const hasTooltip = th.hasAttribute("data-tooltip");
|
|
243
|
+
if (!hasSortable && !hasTooltip) return;
|
|
30
244
|
const label = ((_a = th.textContent) == null ? void 0 : _a.trim()) ?? "";
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
245
|
+
let inner = label;
|
|
246
|
+
if (hasTooltip) {
|
|
247
|
+
const tip = escapeAttr(th.getAttribute("data-tooltip") ?? "");
|
|
248
|
+
inner += `<bv-tooltip text="${tip}" position="bottom"></bv-tooltip>`;
|
|
249
|
+
}
|
|
250
|
+
if (hasSortable) {
|
|
251
|
+
const sortDir = th.getAttribute("data-sort") ?? "none";
|
|
252
|
+
const icon = sortDir === "asc" ? SORT_ASC : sortDir === "desc" ? SORT_DESC : SORT_NONE;
|
|
253
|
+
inner = `<span class="bv-th-content">${inner}${icon}</span>`;
|
|
254
|
+
} else {
|
|
255
|
+
inner = `<span class="bv-th-content">${inner}</span>`;
|
|
256
|
+
}
|
|
257
|
+
th.innerHTML = inner;
|
|
258
|
+
if (hasSortable) {
|
|
259
|
+
th.addEventListener("click", () => {
|
|
260
|
+
var _a2, _b;
|
|
261
|
+
const current = th.getAttribute("data-sort") ?? "none";
|
|
262
|
+
const next = current === "none" ? "asc" : current === "asc" ? "desc" : "none";
|
|
263
|
+
this.querySelectorAll("thead th[data-sortable]").forEach((other) => {
|
|
264
|
+
var _a3, _b2;
|
|
265
|
+
if (other !== th) {
|
|
266
|
+
other.removeAttribute("data-sort");
|
|
267
|
+
const otherLabel = ((_b2 = (_a3 = other.querySelector(".bv-th-content")) == null ? void 0 : _a3.childNodes[0]) == null ? void 0 : _b2.textContent) ?? "";
|
|
268
|
+
const otherTooltip = other.hasAttribute("data-tooltip") ? `<bv-tooltip text="${escapeAttr(other.getAttribute("data-tooltip") ?? "")}" position="bottom"></bv-tooltip>` : "";
|
|
269
|
+
other.innerHTML = `<span class="bv-th-content">${otherLabel}${otherTooltip}${SORT_NONE}</span>`;
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
const currentLabel = ((_b = (_a2 = th.querySelector(".bv-th-content")) == null ? void 0 : _a2.childNodes[0]) == null ? void 0 : _b.textContent) ?? label;
|
|
273
|
+
const currentTooltip = hasTooltip ? `<bv-tooltip text="${escapeAttr(th.getAttribute("data-tooltip") ?? "")}" position="bottom"></bv-tooltip>` : "";
|
|
274
|
+
if (next === "none") {
|
|
275
|
+
th.removeAttribute("data-sort");
|
|
276
|
+
th.innerHTML = `<span class="bv-th-content">${currentLabel}${currentTooltip}${SORT_NONE}</span>`;
|
|
277
|
+
} else {
|
|
278
|
+
th.setAttribute("data-sort", next);
|
|
279
|
+
const newIcon = next === "asc" ? SORT_ASC : SORT_DESC;
|
|
280
|
+
th.innerHTML = `<span class="bv-th-content">${currentLabel}${currentTooltip}${newIcon}</span>`;
|
|
44
281
|
}
|
|
282
|
+
this.dispatchEvent(
|
|
283
|
+
new CustomEvent("bv-sort", {
|
|
284
|
+
bubbles: true,
|
|
285
|
+
composed: true,
|
|
286
|
+
detail: { column: th.getAttribute("data-column"), direction: next }
|
|
287
|
+
})
|
|
288
|
+
);
|
|
45
289
|
});
|
|
46
|
-
|
|
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
|
-
});
|
|
290
|
+
}
|
|
64
291
|
});
|
|
65
292
|
}
|
|
66
293
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
export type ToggleSize = 'sm' | 'md';
|
|
1
2
|
export declare class BvToggle extends HTMLElement {
|
|
2
|
-
static readonly observedAttributes:
|
|
3
|
+
static readonly observedAttributes: readonly ["checked", "disabled", "label", "size"];
|
|
3
4
|
private _rendered;
|
|
4
5
|
private _labelEl;
|
|
5
6
|
constructor();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
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";
|
|
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:host([hidden]) {\n display: none;\n}\n\n:host([size='sm']) {\n --bv-toggle-width: 32px;\n --bv-toggle-height: 18px;\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\n:host([size='sm']) .label {\n font-size: var(--bv-font-size-xs);\n line-height: 18px;\n}\n";
|
|
3
3
|
|
|
4
4
|
// components/bv-toggle/bv-toggle.ts
|
|
5
5
|
var BvToggle = class extends HTMLElement {
|
|
6
|
-
static observedAttributes = ["checked", "disabled", "label"];
|
|
6
|
+
static observedAttributes = ["checked", "disabled", "label", "size"];
|
|
7
7
|
_rendered = false;
|
|
8
8
|
_labelEl = null;
|
|
9
9
|
constructor() {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type TooltipPosition = 'top' | 'bottom';
|
|
2
|
+
export declare class BvTooltip extends HTMLElement {
|
|
3
|
+
static readonly observedAttributes: readonly ["text", "position"];
|
|
4
|
+
private _rendered;
|
|
5
|
+
private _textEl;
|
|
6
|
+
private _triggerEl;
|
|
7
|
+
private _popupEl;
|
|
8
|
+
constructor();
|
|
9
|
+
get text(): string;
|
|
10
|
+
set text(v: string);
|
|
11
|
+
get position(): TooltipPosition;
|
|
12
|
+
set position(v: TooltipPosition);
|
|
13
|
+
connectedCallback(): void;
|
|
14
|
+
attributeChangedCallback(name: string, _old: string | null, _val: string | null): void;
|
|
15
|
+
private _render;
|
|
16
|
+
private _show;
|
|
17
|
+
private _hide;
|
|
18
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-tooltip/bv-tooltip.css
|
|
2
|
+
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";
|
|
3
|
+
|
|
4
|
+
// components/bv-tooltip/bv-tooltip.ts
|
|
5
|
+
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>`;
|
|
6
|
+
var _sheet = null;
|
|
7
|
+
function getSheet() {
|
|
8
|
+
if (!_sheet) {
|
|
9
|
+
_sheet = new CSSStyleSheet();
|
|
10
|
+
_sheet.replaceSync(bv_tooltip_default);
|
|
11
|
+
}
|
|
12
|
+
return _sheet;
|
|
13
|
+
}
|
|
14
|
+
var _uid = 0;
|
|
15
|
+
var BvTooltip = class extends HTMLElement {
|
|
16
|
+
static observedAttributes = ["text", "position"];
|
|
17
|
+
_rendered = false;
|
|
18
|
+
_textEl = null;
|
|
19
|
+
_triggerEl = null;
|
|
20
|
+
_popupEl = null;
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
24
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype) {
|
|
25
|
+
shadow.adoptedStyleSheets = [getSheet()];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
get text() {
|
|
29
|
+
return this.getAttribute("text") ?? "";
|
|
30
|
+
}
|
|
31
|
+
set text(v) {
|
|
32
|
+
this.setAttribute("text", v);
|
|
33
|
+
}
|
|
34
|
+
get position() {
|
|
35
|
+
return this.getAttribute("position") ?? "top";
|
|
36
|
+
}
|
|
37
|
+
set position(v) {
|
|
38
|
+
this.setAttribute("position", v);
|
|
39
|
+
}
|
|
40
|
+
connectedCallback() {
|
|
41
|
+
this._render();
|
|
42
|
+
}
|
|
43
|
+
attributeChangedCallback(name, _old, _val) {
|
|
44
|
+
if (!this._rendered) return;
|
|
45
|
+
if (name === "text" && this._textEl) {
|
|
46
|
+
this._textEl.textContent = this.text;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
_render() {
|
|
50
|
+
if (this._rendered) return;
|
|
51
|
+
this._rendered = true;
|
|
52
|
+
const shadow = this.shadowRoot;
|
|
53
|
+
if (!shadow.adoptedStyleSheets.length) {
|
|
54
|
+
const s = document.createElement("style");
|
|
55
|
+
s.textContent = bv_tooltip_default;
|
|
56
|
+
shadow.appendChild(s);
|
|
57
|
+
}
|
|
58
|
+
const wrap = document.createElement("span");
|
|
59
|
+
wrap.className = "wrap";
|
|
60
|
+
const popupId = `bv-tooltip-popup-${++_uid}`;
|
|
61
|
+
const trigger = document.createElement("span");
|
|
62
|
+
trigger.className = "trigger";
|
|
63
|
+
trigger.setAttribute("tabindex", "0");
|
|
64
|
+
trigger.setAttribute("role", "button");
|
|
65
|
+
trigger.setAttribute("aria-label", "More information");
|
|
66
|
+
trigger.setAttribute("aria-describedby", popupId);
|
|
67
|
+
trigger.innerHTML = QUESTION_MARK_SVG;
|
|
68
|
+
this._triggerEl = trigger;
|
|
69
|
+
const popup = document.createElement("span");
|
|
70
|
+
popup.id = popupId;
|
|
71
|
+
popup.className = "popup";
|
|
72
|
+
popup.setAttribute("role", "tooltip");
|
|
73
|
+
this._popupEl = popup;
|
|
74
|
+
const textEl = document.createElement("span");
|
|
75
|
+
textEl.className = "text-content";
|
|
76
|
+
textEl.textContent = this.text;
|
|
77
|
+
this._textEl = textEl;
|
|
78
|
+
const slot = document.createElement("slot");
|
|
79
|
+
popup.append(textEl, slot);
|
|
80
|
+
wrap.append(trigger, popup);
|
|
81
|
+
shadow.appendChild(wrap);
|
|
82
|
+
trigger.addEventListener("mouseenter", () => this._show());
|
|
83
|
+
trigger.addEventListener("mouseleave", () => this._hide());
|
|
84
|
+
trigger.addEventListener("focus", () => this._show());
|
|
85
|
+
trigger.addEventListener("blur", () => this._hide());
|
|
86
|
+
}
|
|
87
|
+
_show() {
|
|
88
|
+
const popup = this._popupEl;
|
|
89
|
+
const trigger = this._triggerEl;
|
|
90
|
+
if (!popup || !trigger) return;
|
|
91
|
+
popup.style.top = "0";
|
|
92
|
+
popup.style.bottom = "auto";
|
|
93
|
+
popup.style.left = "0";
|
|
94
|
+
popup.style.right = "auto";
|
|
95
|
+
popup.style.transform = "none";
|
|
96
|
+
popup.style.display = "block";
|
|
97
|
+
popup.style.visibility = "hidden";
|
|
98
|
+
const tRect = trigger.getBoundingClientRect();
|
|
99
|
+
const pRect = popup.getBoundingClientRect();
|
|
100
|
+
const vw = window.innerWidth;
|
|
101
|
+
const vh = window.innerHeight;
|
|
102
|
+
const gap = 8;
|
|
103
|
+
const spaceAbove = tRect.top - gap;
|
|
104
|
+
const spaceBelow = vh - tRect.bottom - gap;
|
|
105
|
+
const preferBottom = this.position === "bottom";
|
|
106
|
+
const goBelow = preferBottom ? spaceBelow >= pRect.height || spaceBelow >= spaceAbove : spaceAbove < pRect.height;
|
|
107
|
+
if (goBelow) {
|
|
108
|
+
popup.style.top = "calc(100% + 8px)";
|
|
109
|
+
popup.style.bottom = "auto";
|
|
110
|
+
} else {
|
|
111
|
+
popup.style.bottom = "calc(100% + 8px)";
|
|
112
|
+
popup.style.top = "auto";
|
|
113
|
+
}
|
|
114
|
+
const rawLeft = tRect.left;
|
|
115
|
+
const rawRight = tRect.left + pRect.width;
|
|
116
|
+
let transformX = 0;
|
|
117
|
+
if (rawRight > vw - gap) {
|
|
118
|
+
transformX = vw - gap - rawRight;
|
|
119
|
+
}
|
|
120
|
+
if (rawLeft + transformX < gap) {
|
|
121
|
+
transformX = gap - rawLeft;
|
|
122
|
+
}
|
|
123
|
+
popup.style.left = "0";
|
|
124
|
+
popup.style.transform = transformX !== 0 ? `translateX(${transformX}px)` : "none";
|
|
125
|
+
popup.style.visibility = "";
|
|
126
|
+
}
|
|
127
|
+
_hide() {
|
|
128
|
+
const popup = this._popupEl;
|
|
129
|
+
if (!popup) return;
|
|
130
|
+
popup.style.display = "";
|
|
131
|
+
popup.style.top = "";
|
|
132
|
+
popup.style.bottom = "";
|
|
133
|
+
popup.style.left = "";
|
|
134
|
+
popup.style.right = "";
|
|
135
|
+
popup.style.transform = "";
|
|
136
|
+
popup.style.visibility = "";
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
if (!customElements.get("bv-tooltip")) {
|
|
140
|
+
customElements.define("bv-tooltip", BvTooltip);
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
BvTooltip
|
|
144
|
+
};
|
|
@@ -81,7 +81,7 @@ if (!customElements.get("bv-avatar")) {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-button/bv-button.css
|
|
84
|
-
var bv_button_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 these three properties per-instance:\n\n HTML: <bv-button style=\"--bv-button-bg: #e53e3e;\">\n Angular: <bv-button [style.--bv-button-bg]=\"brandColor\">\n JavaScript: btn.style.setProperty('--bv-button-bg', value)\n\n Hover is auto-computed from the base colors via color-mix().\n Override --bv-button-bg-hover / --bv-button-border-color-hover\n if you need explicit control over the hovered state.\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 /* Default values \u2014 map to global tokens (primary variant) */\n --bv-button-bg: var(--bv-color-primary);\n --bv-button-bg-hover: color-mix(in srgb, var(--bv-button-bg) 82%, black);\n --bv-button-color: var(--bv-color-neutral-0);\n --bv-button-border-color: var(--bv-color-primary);\n --bv-button-border-color-hover: color-mix(in srgb, var(--bv-button-border-color) 82%, black);\n --bv-button-font-family: var(--bv-font-family-base);\n --bv-button-font-size: var(--bv-font-size-sm);\n\n display: inline-block;\n font-family: var(--bv-font-family-base);\n}\n\n:host([hidden]) {\n /* `!important` so `hidden` always wins over :host([full-width]) / other display rules. */\n display: none !important;\n}\n\n:host([full-width]) {\n display: block;\n width: 100%;\n}\n\n/* \u2500\u2500 Variant tokens \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 Each variant re-points the component tokens to different global\n tokens. Apps can still override with inline styles \u2014 inline style\n always wins due to higher specificity.\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\n:host([variant='secondary']) {\n --bv-button-bg: var(--bv-color-secondary);\n --bv-button-border-color: var(--bv-color-secondary);\n --bv-button-color: var(--bv-color-secondary-foreground);\n}\n\n:host([variant='tertiary']) {\n --bv-button-bg: var(--bv-color-tertiary);\n --bv-button-border-color: var(--bv-color-tertiary);\n}\n\n:host([variant='danger']) {\n --bv-button-bg: var(--bv-color-danger);\n --bv-button-border-color: var(--bv-color-danger);\n}\n\n:host([variant='ghost']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-primary-light);\n --bv-button-color: var(--bv-color-primary);\n --bv-button-border-color: transparent;\n --bv-button-border-color-hover: transparent;\n}\n\n:host([variant='outline']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-primary-light);\n --bv-button-color: var(--bv-color-primary);\n --bv-button-border-color: var(--bv-color-primary);\n --bv-button-border-color-hover: var(--bv-color-primary);\n}\n\n/* \u2500\u2500 Base 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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n All visual properties read from the component-level tokens above.\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\n.btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--bv-spacing-xs);\n padding: 10px var(--bv-spacing-md);\n min-height: 40px;\n width: auto;\n font-family: var(--bv-button-font-family);\n font-size: var(--bv-button-font-size);\n font-style: normal;\n font-weight: var(--bv-font-weight-semibold);\n line-height: 20px;\n border: 1px solid var(--bv-button-border-color);\n border-radius: var(--bv-radius-lg);\n cursor: pointer;\n transition:\n background var(--bv-transition-fast),\n color var(--bv-transition-fast),\n border-color var(--bv-transition-fast),\n box-shadow var(--bv-transition-fast),\n opacity var(--bv-transition-fast);\n white-space: nowrap;\n user-select: none;\n text-decoration: none;\n outline: none;\n box-sizing: border-box;\n background: var(--bv-button-bg);\n color: var(--bv-button-color);\n box-shadow: var(--bv-shadow-sm);\n}\n\n:host([full-width]) .btn {\n width: 100%;\n}\n\n.btn:hover:not(:disabled) {\n background: var(--bv-button-bg-hover);\n border-color: var(--bv-button-border-color-hover);\n}\n\n.btn:active:not(:disabled) {\n transform: translateY(1px);\n}\n\n.btn:focus-visible {\n outline: 2px solid var(--bv-button-border-color);\n outline-offset: 2px;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Sizes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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([size='sm']) .btn {\n padding: 6px 12px;\n min-height: 32px;\n font-size: var(--bv-font-size-sm);\n}\n\n:host([size='lg']) .btn {\n padding: 12px var(--bv-spacing-lg);\n min-height: 48px;\n font-size: var(--bv-font-size-md);\n}\n\n/* \u2500\u2500 Icon \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n line-height: 0;\n}\n\n/* \u2500\u2500 Count badge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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-count {\n opacity: 0.8;\n font-weight: var(--bv-font-weight-regular);\n}\n\n/* \u2500\u2500 Loading spinner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.spinner {\n display: inline-block;\n width: 1em;\n height: 1em;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n flex-shrink: 0;\n animation: bv-spin 700ms linear infinite;\n}\n\n@keyframes bv-spin {\n to {\n transform: rotate(360deg);\n }\n}\n";
|
|
84
|
+
var bv_button_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 these three properties per-instance:\n\n HTML: <bv-button style=\"--bv-button-bg: #e53e3e;\">\n Angular: <bv-button [style.--bv-button-bg]=\"brandColor\">\n JavaScript: btn.style.setProperty('--bv-button-bg', value)\n\n Hover is auto-computed from the base colors via color-mix().\n Override --bv-button-bg-hover / --bv-button-border-color-hover\n if you need explicit control over the hovered state.\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 /* Default values \u2014 map to global tokens (primary variant) */\n --bv-button-bg: var(--bv-color-primary);\n --bv-button-bg-hover: color-mix(in srgb, var(--bv-button-bg) 82%, black);\n --bv-button-color: var(--bv-color-neutral-0);\n --bv-button-border-color: var(--bv-color-primary);\n --bv-button-border-color-hover: color-mix(in srgb, var(--bv-button-border-color) 82%, black);\n --bv-button-font-family: var(--bv-font-family-base);\n --bv-button-font-size: var(--bv-font-size-sm);\n\n display: inline-block;\n font-family: var(--bv-font-family-base);\n}\n\n:host([hidden]) {\n /* `!important` so `hidden` always wins over :host([full-width]) / other display rules. */\n display: none !important;\n}\n\n:host([full-width]) {\n display: block;\n width: 100%;\n}\n\n/* \u2500\u2500 Variant tokens \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 Each variant re-points the component tokens to different global\n tokens. Apps can still override with inline styles \u2014 inline style\n always wins due to higher specificity.\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\n:host([variant='secondary']) {\n --bv-button-bg: var(--bv-color-secondary);\n --bv-button-border-color: var(--bv-color-secondary);\n --bv-button-color: var(--bv-color-secondary-foreground);\n}\n\n:host([variant='tertiary']) {\n --bv-button-bg: var(--bv-color-tertiary);\n --bv-button-border-color: var(--bv-color-tertiary);\n}\n\n:host([variant='danger']) {\n --bv-button-bg: var(--bv-color-danger);\n --bv-button-border-color: var(--bv-color-danger);\n}\n\n:host([variant='ghost']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-primary-light);\n --bv-button-color: var(--bv-color-primary);\n --bv-button-border-color: transparent;\n --bv-button-border-color-hover: transparent;\n}\n\n:host([variant='outline']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-primary-light);\n --bv-button-color: var(--bv-color-primary);\n --bv-button-border-color: var(--bv-color-primary);\n --bv-button-border-color-hover: 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 --bv-button-border-color-hover: var(--bv-color-neutral-300);\n}\n\n/* \u2500\u2500 Base 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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n All visual properties read from the component-level tokens above.\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\n.btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--bv-spacing-xs);\n padding: 10px var(--bv-spacing-md);\n min-height: 40px;\n width: auto;\n font-family: var(--bv-button-font-family);\n font-size: var(--bv-button-font-size);\n font-style: normal;\n font-weight: var(--bv-font-weight-semibold);\n line-height: 20px;\n border: 1px solid var(--bv-button-border-color);\n border-radius: var(--bv-radius-lg);\n cursor: pointer;\n transition:\n background var(--bv-transition-fast),\n color var(--bv-transition-fast),\n border-color var(--bv-transition-fast),\n box-shadow var(--bv-transition-fast),\n opacity var(--bv-transition-fast);\n white-space: nowrap;\n user-select: none;\n text-decoration: none;\n outline: none;\n box-sizing: border-box;\n background: var(--bv-button-bg);\n color: var(--bv-button-color);\n box-shadow: var(--bv-shadow-sm);\n}\n\n:host([full-width]) .btn {\n width: 100%;\n}\n\n.btn:hover:not(:disabled) {\n background: var(--bv-button-bg-hover);\n border-color: var(--bv-button-border-color-hover);\n}\n\n.btn:active:not(:disabled) {\n transform: translateY(1px);\n}\n\n.btn:focus-visible {\n outline: 2px solid var(--bv-button-border-color);\n outline-offset: 2px;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Sizes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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([size='sm']) .btn {\n padding: 6px 12px;\n min-height: 32px;\n font-size: var(--bv-font-size-sm);\n}\n\n:host([size='lg']) .btn {\n padding: 12px var(--bv-spacing-lg);\n min-height: 48px;\n font-size: var(--bv-font-size-md);\n}\n\n/* \u2500\u2500 Icon \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n line-height: 0;\n}\n\n/* \u2500\u2500 Count badge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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-count {\n opacity: 0.8;\n font-weight: var(--bv-font-weight-regular);\n}\n\n/* \u2500\u2500 Loading spinner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.spinner {\n display: inline-block;\n width: 1em;\n height: 1em;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n flex-shrink: 0;\n animation: bv-spin 700ms linear infinite;\n}\n\n@keyframes bv-spin {\n to {\n transform: rotate(360deg);\n }\n}\n";
|
|
85
85
|
|
|
86
86
|
// components/bv-icon/icons.ts
|
|
87
87
|
var icons = {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { FilterDropdownOption } from '../../../components/bv-filter-dropdown/bv-filter-dropdown';
|
|
2
|
+
export declare const CATEGORY_OPTIONS: FilterDropdownOption[];
|
|
3
|
+
export declare const COURSE_OPTIONS: FilterDropdownOption[];
|
|
4
|
+
export declare const COURSE_SEAT_TIMES: Record<string, number>;
|
|
5
|
+
export declare const GROUP_OPTIONS: FilterDropdownOption[];
|
|
6
|
+
export declare const USER_OPTIONS: FilterDropdownOption[];
|
|
7
|
+
export type EnrollmentProgress = 'complete' | 'on-schedule' | 'behind-schedule' | 'pending-approval' | 'ready-to-pay' | 'enrolled';
|
|
8
|
+
export type EnrollmentType = 'internal' | 'external';
|
|
9
|
+
export interface Enrollment {
|
|
10
|
+
id: number;
|
|
11
|
+
courseId: string;
|
|
12
|
+
courseName: string;
|
|
13
|
+
publisher: string;
|
|
14
|
+
userGroup: string;
|
|
15
|
+
userId: string;
|
|
16
|
+
username: string;
|
|
17
|
+
fullName: string;
|
|
18
|
+
email: string;
|
|
19
|
+
hireDate: string;
|
|
20
|
+
lastLogin: string;
|
|
21
|
+
userStatus: 'active' | 'inactive';
|
|
22
|
+
enrollmentType: EnrollmentType;
|
|
23
|
+
hidden?: boolean;
|
|
24
|
+
progress: EnrollmentProgress;
|
|
25
|
+
enrolledDate: string;
|
|
26
|
+
completedDate: string | null;
|
|
27
|
+
certificateDate: string | null;
|
|
28
|
+
score: number | null;
|
|
29
|
+
requiredCredits: number | null;
|
|
30
|
+
earnedCredits: number | null;
|
|
31
|
+
remainingCredits: number | null;
|
|
32
|
+
}
|
|
33
|
+
export declare const ENROLLMENTS: Enrollment[];
|
|
34
|
+
export declare const CATEGORY_COURSES: Record<string, string[]>;
|
|
35
|
+
export declare function getCategoryForCourse(courseId: string): string;
|
|
36
|
+
export declare const GROUP_USERS: Record<string, string[]>;
|
|
37
|
+
export declare function getGroupForUser(userId: string): string;
|
|
38
|
+
export declare function getCoursesForCategories(categoryValues: string[]): string[];
|
|
39
|
+
export declare function getUsersForGroups(groupValues: string[]): string[];
|
|
40
|
+
export declare function filterEnrollments(enrollments: Enrollment[], params: {
|
|
41
|
+
basedOn: 'enrollments' | 'completions';
|
|
42
|
+
enrollmentType: 'all' | 'internal' | 'external';
|
|
43
|
+
categoryValues: string[];
|
|
44
|
+
courseValues: string[];
|
|
45
|
+
groupValues: string[];
|
|
46
|
+
userValues: string[];
|
|
47
|
+
}): Enrollment[];
|
|
48
|
+
export declare const PROGRESS_BADGE: Record<EnrollmentProgress, {
|
|
49
|
+
variant: string;
|
|
50
|
+
label: string;
|
|
51
|
+
}>;
|
|
52
|
+
export declare const ENROLLMENT_TYPE_BADGE: Record<EnrollmentType, {
|
|
53
|
+
variant: string;
|
|
54
|
+
label: string;
|
|
55
|
+
}>;
|