@bluevolt-tech/lumen 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -23
- package/dist/components/_shared/adopt-styles.d.ts +8 -0
- package/dist/components/_shared/date-range-validator.d.ts +86 -0
- package/dist/components/_shared/dropdown-controller.d.ts +60 -0
- package/dist/components/_shared/selectable-card.d.ts +10 -0
- package/dist/components/bv-alert-banner/bv-alert-banner.js +19 -17
- package/dist/components/bv-avatar/bv-avatar.js +19 -11
- package/dist/components/bv-badge/bv-badge.js +19 -11
- package/dist/components/bv-button/bv-button.js +18 -16
- package/dist/components/bv-category-pill/bv-category-pill.js +18 -16
- package/dist/components/bv-checkbox/bv-checkbox.js +19 -11
- package/dist/components/bv-chip/bv-chip.js +19 -11
- package/dist/components/bv-course-detail/bv-course-detail.js +20 -34
- package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +24 -90
- package/dist/components/bv-course-grid-card/bv-course-grid-card.d.ts +2 -6
- package/dist/components/bv-course-grid-card/bv-course-grid-card.js +98 -105
- package/dist/components/bv-course-list-card/bv-course-list-card.d.ts +2 -6
- package/dist/components/bv-course-list-card/bv-course-list-card.js +98 -105
- package/dist/components/bv-course-outline/bv-course-outline.js +19 -11
- package/dist/components/bv-date-range-input/bv-date-range-input.d.ts +10 -6
- package/dist/components/bv-date-range-input/bv-date-range-input.js +602 -125
- package/dist/components/bv-date-range-picker/bv-date-range-picker.d.ts +71 -4
- package/dist/components/bv-date-range-picker/bv-date-range-picker.js +441 -76
- package/dist/components/bv-empty-state/bv-empty-state.js +20 -28
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +1 -4
- package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +80 -53
- package/dist/components/bv-filter-panel/bv-filter-panel.js +20 -22
- package/dist/components/bv-icon/bv-icon.js +19 -11
- package/dist/components/bv-input/bv-input.js +18 -16
- package/dist/components/bv-input-dropdown/bv-input-dropdown.d.ts +1 -4
- package/dist/components/bv-input-dropdown/bv-input-dropdown.js +79 -78
- package/dist/components/bv-modal/bv-modal.js +19 -11
- package/dist/components/bv-page-title/bv-page-title.js +19 -6
- package/dist/components/bv-pagination/bv-pagination.d.ts +1 -0
- package/dist/components/bv-pagination/bv-pagination.js +23 -186
- package/dist/components/bv-portal-header/bv-portal-header.js +25 -83
- package/dist/components/bv-portal-layout/bv-portal-layout.js +19 -11
- package/dist/components/bv-progress-bar/bv-progress-bar.js +19 -11
- package/dist/components/bv-promo-banner/bv-promo-banner.js +19 -11
- package/dist/components/bv-radio/bv-radio.js +19 -11
- package/dist/components/bv-searchbox/bv-searchbox.js +19 -11
- package/dist/components/bv-segmented-control/bv-segmented-control.js +18 -16
- package/dist/components/bv-select/bv-select.d.ts +1 -4
- package/dist/components/bv-select/bv-select.js +78 -44
- package/dist/components/bv-split-button/bv-split-button.d.ts +1 -4
- package/dist/components/bv-split-button/bv-split-button.js +78 -42
- package/dist/components/bv-star-rating/bv-star-rating.js +19 -11
- package/dist/components/bv-table/bv-table.d.ts +5 -0
- package/dist/components/bv-table/bv-table.js +70 -19
- package/dist/components/bv-toggle/bv-toggle.js +19 -11
- package/dist/components/bv-tooltip/bv-tooltip.js +20 -17
- package/dist/components/bv-user-row/bv-user-row.js +22 -50
- package/dist/components/bv-view-switcher/bv-view-switcher.js +19 -11
- package/dist/themes/base.css +1 -1
- package/package.json +8 -1
- package/themes/base.css +1 -1
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-course-list-card/bv-course-list-card.css
|
|
2
2
|
var bv_course_list_card_default = ":host {\n display: block;\n}\n\n.card {\n display: flex;\n align-items: stretch;\n gap: var(--bv-spacing-md);\n padding: 12px;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-xl);\n box-shadow: var(--bv-shadow-sm);\n cursor: pointer;\n transition:\n background var(--bv-transition-fast),\n border-color var(--bv-transition-fast),\n box-shadow var(--bv-transition-fast);\n}\n\n:host([selected]) .card {\n background: var(--bv-color-primary-50);\n border-color: var(--bv-color-primary);\n box-shadow: none;\n}\n\n.card:focus-visible {\n outline: var(--bv-focus-ring);\n outline-offset: 2px;\n}\n\n/* Thumbnail */\n.thumbnail-wrap {\n position: relative;\n flex-shrink: 0;\n width: 200px;\n min-height: 123px;\n border-radius: var(--bv-radius-lg);\n overflow: hidden;\n background: var(--bv-color-neutral-200);\n}\n\n.thumbnail {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n}\n\n.status-badge {\n position: absolute;\n top: 6px;\n right: 6px;\n padding: 0 var(--bv-spacing-sm);\n border-radius: var(--bv-radius-sm);\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 line-height: 18px;\n background: var(--bv-color-success-light);\n color: var(--bv-color-success-dark);\n}\n\n/* Content */\n.content {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n justify-content: space-between;\n}\n\n.meta {\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n.title {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-900);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.publisher {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-500);\n}\n\n.publisher strong {\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n}\n\n.description-wrap {\n height: 40px;\n display: flex;\n align-items: center;\n overflow: hidden;\n}\n\n.description {\n margin: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-700);\n line-height: 20px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.info-row {\n display: flex;\n gap: var(--bv-spacing-md);\n}\n\n.info-item {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-900);\n}\n\n.info-item strong {\n font-weight: var(--bv-font-weight-bold);\n}\n\n/* Actions */\n.actions {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-sm);\n flex-shrink: 0;\n width: 209px;\n justify-content: center;\n}\n\n/* Disabled selection: card body is no longer interactive */\n:host([disable-selection]) .card {\n cursor: default;\n}\n\n/* Loading skeleton */\n.skeleton {\n display: none;\n align-items: stretch;\n gap: var(--bv-spacing-md);\n flex: 1;\n min-width: 0;\n}\n\n:host([loading]) .card {\n cursor: default;\n}\n\n:host([loading]) .thumbnail-wrap,\n:host([loading]) .content,\n:host([loading]) .actions {\n display: none;\n}\n\n:host([loading]) .skeleton {\n display: flex;\n}\n\n.skeleton-thumb {\n flex-shrink: 0;\n width: 200px;\n min-height: 123px;\n border-radius: var(--bv-radius-lg);\n background: var(--bv-color-neutral-200);\n animation: bv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.skeleton-content {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-sm);\n flex: 1;\n min-width: 0;\n justify-content: center;\n}\n\n.skeleton-line {\n height: 12px;\n border-radius: var(--bv-radius-sm);\n background: var(--bv-color-neutral-200);\n animation: bv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.skeleton-title-line {\n height: 20px;\n width: 60%;\n}\n\n.skeleton-short-line {\n width: 40%;\n}\n\n.skeleton-actions {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-sm);\n flex-shrink: 0;\n width: 209px;\n justify-content: center;\n}\n\n.skeleton-button {\n height: 40px;\n border-radius: var(--bv-radius-md);\n background: var(--bv-color-neutral-200);\n animation: bv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n@keyframes bv-skeleton-shimmer {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n";
|
|
3
3
|
|
|
4
|
+
// components/_shared/adopt-styles.ts
|
|
5
|
+
var _sheetCache = /* @__PURE__ */ new Map();
|
|
6
|
+
function adoptStyles(shadow, css) {
|
|
7
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype && typeof CSSStyleSheet !== "undefined" && "replaceSync" in CSSStyleSheet.prototype) {
|
|
8
|
+
let sheet = _sheetCache.get(css);
|
|
9
|
+
if (!sheet) {
|
|
10
|
+
sheet = new CSSStyleSheet();
|
|
11
|
+
sheet.replaceSync(css);
|
|
12
|
+
_sheetCache.set(css, sheet);
|
|
13
|
+
}
|
|
14
|
+
shadow.adoptedStyleSheets = [sheet];
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const style = document.createElement("style");
|
|
18
|
+
style.textContent = css;
|
|
19
|
+
shadow.appendChild(style);
|
|
20
|
+
}
|
|
21
|
+
|
|
4
22
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-button/bv-button.css
|
|
5
23
|
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";
|
|
6
24
|
|
|
@@ -78,14 +96,6 @@ var rawIcons = {
|
|
|
78
96
|
};
|
|
79
97
|
|
|
80
98
|
// components/bv-button/bv-button.ts
|
|
81
|
-
var _sheet = null;
|
|
82
|
-
function getSheet() {
|
|
83
|
-
if (!_sheet) {
|
|
84
|
-
_sheet = new CSSStyleSheet();
|
|
85
|
-
_sheet.replaceSync(bv_button_default);
|
|
86
|
-
}
|
|
87
|
-
return _sheet;
|
|
88
|
-
}
|
|
89
99
|
var BvButton = class extends HTMLElement {
|
|
90
100
|
static observedAttributes = [
|
|
91
101
|
"variant",
|
|
@@ -101,10 +111,7 @@ var BvButton = class extends HTMLElement {
|
|
|
101
111
|
];
|
|
102
112
|
constructor() {
|
|
103
113
|
super();
|
|
104
|
-
|
|
105
|
-
if ("adoptedStyleSheets" in ShadowRoot.prototype) {
|
|
106
|
-
shadow.adoptedStyleSheets = [getSheet()];
|
|
107
|
-
}
|
|
114
|
+
adoptStyles(this.attachShadow({ mode: "open" }), bv_button_default);
|
|
108
115
|
}
|
|
109
116
|
// ── Accessors ────────────────────────────────────────────────
|
|
110
117
|
get variant() {
|
|
@@ -161,11 +168,6 @@ var BvButton = class extends HTMLElement {
|
|
|
161
168
|
const shadow = this.shadowRoot;
|
|
162
169
|
let btn = shadow.querySelector("button");
|
|
163
170
|
if (!btn) {
|
|
164
|
-
if (!shadow.adoptedStyleSheets.length) {
|
|
165
|
-
const styleEl = document.createElement("style");
|
|
166
|
-
styleEl.textContent = bv_button_default;
|
|
167
|
-
shadow.appendChild(styleEl);
|
|
168
|
-
}
|
|
169
171
|
btn = document.createElement("button");
|
|
170
172
|
btn.setAttribute("part", "button");
|
|
171
173
|
btn.appendChild(document.createElement("slot"));
|
|
@@ -219,6 +221,65 @@ if (!customElements.get("bv-button")) {
|
|
|
219
221
|
customElements.define("bv-button", BvButton);
|
|
220
222
|
}
|
|
221
223
|
|
|
224
|
+
// components/_shared/selectable-card.ts
|
|
225
|
+
function buildAriaLabel(host) {
|
|
226
|
+
const title = host.getAttribute("title") ?? "";
|
|
227
|
+
const publisher = host.getAttribute("publisher") ?? "";
|
|
228
|
+
const parts = [];
|
|
229
|
+
if (title) parts.push(title);
|
|
230
|
+
if (publisher) parts.push(`by ${publisher}`);
|
|
231
|
+
return parts.join(", ");
|
|
232
|
+
}
|
|
233
|
+
function setPrefixedStrong(el, prefix, val) {
|
|
234
|
+
if (!el) return;
|
|
235
|
+
const value = val ?? "";
|
|
236
|
+
if (!value) {
|
|
237
|
+
el.hidden = true;
|
|
238
|
+
el.replaceChildren();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
el.hidden = false;
|
|
242
|
+
const strong = document.createElement("strong");
|
|
243
|
+
strong.textContent = value;
|
|
244
|
+
if (prefix) el.replaceChildren(document.createTextNode(prefix), strong);
|
|
245
|
+
else el.replaceChildren(strong);
|
|
246
|
+
}
|
|
247
|
+
function syncSelectionA11y(host, card) {
|
|
248
|
+
const inert = host.disableSelection || host.loading;
|
|
249
|
+
card.setAttribute("tabindex", inert ? "-1" : "0");
|
|
250
|
+
if (inert) card.setAttribute("aria-disabled", "true");
|
|
251
|
+
else card.removeAttribute("aria-disabled");
|
|
252
|
+
}
|
|
253
|
+
function syncCardLoading(host, card) {
|
|
254
|
+
card.setAttribute("aria-busy", host.loading ? "true" : "false");
|
|
255
|
+
}
|
|
256
|
+
function bindCardSelection(host, card, actions) {
|
|
257
|
+
const toggle = () => {
|
|
258
|
+
host.selected = !host.selected;
|
|
259
|
+
host.dispatchEvent(
|
|
260
|
+
new CustomEvent("bv-select", {
|
|
261
|
+
bubbles: true,
|
|
262
|
+
composed: true,
|
|
263
|
+
detail: { selected: host.selected }
|
|
264
|
+
})
|
|
265
|
+
);
|
|
266
|
+
};
|
|
267
|
+
const isInert = () => host.disableSelection || host.loading;
|
|
268
|
+
const originatesFromActions = (e) => e.composedPath().includes(actions);
|
|
269
|
+
card.addEventListener("click", (e) => {
|
|
270
|
+
if (isInert()) return;
|
|
271
|
+
if (originatesFromActions(e)) return;
|
|
272
|
+
toggle();
|
|
273
|
+
});
|
|
274
|
+
card.addEventListener("keydown", (e) => {
|
|
275
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
276
|
+
if (isInert()) return;
|
|
277
|
+
if (originatesFromActions(e)) return;
|
|
278
|
+
e.preventDefault();
|
|
279
|
+
toggle();
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
222
283
|
// components/bv-course-list-card/bv-course-list-card.ts
|
|
223
284
|
var BvCourseListCard = class extends HTMLElement {
|
|
224
285
|
static observedAttributes = [
|
|
@@ -287,12 +348,7 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
287
348
|
_els = {};
|
|
288
349
|
constructor() {
|
|
289
350
|
super();
|
|
290
|
-
this.attachShadow({ mode: "open" });
|
|
291
|
-
if ("replaceSync" in CSSStyleSheet.prototype) {
|
|
292
|
-
const sheet = new CSSStyleSheet();
|
|
293
|
-
sheet.replaceSync(bv_course_list_card_default);
|
|
294
|
-
this.shadowRoot.adoptedStyleSheets = [sheet];
|
|
295
|
-
}
|
|
351
|
+
adoptStyles(this.attachShadow({ mode: "open" }), bv_course_list_card_default);
|
|
296
352
|
}
|
|
297
353
|
connectedCallback() {
|
|
298
354
|
this._render();
|
|
@@ -300,6 +356,7 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
300
356
|
attributeChangedCallback(name, _old, val) {
|
|
301
357
|
var _a;
|
|
302
358
|
if (!this._rendered) return;
|
|
359
|
+
const card = this._els.card;
|
|
303
360
|
const map = {
|
|
304
361
|
thumbnail: () => {
|
|
305
362
|
var _a2;
|
|
@@ -312,23 +369,21 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
312
369
|
}
|
|
313
370
|
},
|
|
314
371
|
title: () => {
|
|
315
|
-
var _a2;
|
|
316
372
|
if (this._els.title) this._els.title.textContent = val ?? "";
|
|
317
|
-
|
|
373
|
+
card == null ? void 0 : card.setAttribute("aria-label", buildAriaLabel(this));
|
|
318
374
|
},
|
|
319
375
|
publisher: () => {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
(_a2 = this._els.card) == null ? void 0 : _a2.setAttribute("aria-label", this._buildAriaLabel());
|
|
376
|
+
setPrefixedStrong(this._els.publisher, "By ", val);
|
|
377
|
+
card == null ? void 0 : card.setAttribute("aria-label", buildAriaLabel(this));
|
|
323
378
|
},
|
|
324
379
|
description: () => {
|
|
325
380
|
if (this._els.description) this._els.description.textContent = val ?? "";
|
|
326
381
|
},
|
|
327
382
|
duration: () => {
|
|
328
|
-
|
|
383
|
+
setPrefixedStrong(this._els.duration, "", val);
|
|
329
384
|
},
|
|
330
385
|
"last-updated": () => {
|
|
331
|
-
|
|
386
|
+
setPrefixedStrong(this._els.lastUpdated, "Last Updated: ", val);
|
|
332
387
|
},
|
|
333
388
|
"primary-label": () => {
|
|
334
389
|
if (this._els.primaryBtn) this._els.primaryBtn.textContent = val ?? "";
|
|
@@ -362,15 +417,16 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
362
417
|
if (this._els.secondaryBtn) this._els.secondaryBtn.hidden = this.hideSecondary;
|
|
363
418
|
},
|
|
364
419
|
selected: () => {
|
|
365
|
-
|
|
366
|
-
(_a2 = this._els.card) == null ? void 0 : _a2.setAttribute("aria-checked", this.selected ? "true" : "false");
|
|
420
|
+
card == null ? void 0 : card.setAttribute("aria-checked", this.selected ? "true" : "false");
|
|
367
421
|
},
|
|
368
422
|
"disable-selection": () => {
|
|
369
|
-
|
|
423
|
+
if (card) syncSelectionA11y(this, card);
|
|
370
424
|
},
|
|
371
425
|
loading: () => {
|
|
372
|
-
|
|
373
|
-
|
|
426
|
+
if (card) {
|
|
427
|
+
syncCardLoading(this, card);
|
|
428
|
+
syncSelectionA11y(this, card);
|
|
429
|
+
}
|
|
374
430
|
}
|
|
375
431
|
};
|
|
376
432
|
(_a = map[name]) == null ? void 0 : _a.call(map);
|
|
@@ -379,17 +435,11 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
379
435
|
if (this._rendered) return;
|
|
380
436
|
this._rendered = true;
|
|
381
437
|
const shadow = this.shadowRoot;
|
|
382
|
-
if (!shadow.adoptedStyleSheets.length) {
|
|
383
|
-
const s = document.createElement("style");
|
|
384
|
-
s.textContent = bv_course_list_card_default;
|
|
385
|
-
shadow.appendChild(s);
|
|
386
|
-
}
|
|
387
438
|
const card = document.createElement("div");
|
|
388
439
|
card.className = "card";
|
|
389
440
|
card.setAttribute("role", "checkbox");
|
|
390
|
-
card.setAttribute("tabindex", "0");
|
|
391
441
|
card.setAttribute("aria-checked", this.selected ? "true" : "false");
|
|
392
|
-
card.setAttribute("aria-label", this
|
|
442
|
+
card.setAttribute("aria-label", buildAriaLabel(this));
|
|
393
443
|
this._els.card = card;
|
|
394
444
|
const thumbWrap = document.createElement("div");
|
|
395
445
|
thumbWrap.className = "thumbnail-wrap";
|
|
@@ -416,7 +466,7 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
416
466
|
const publisher = document.createElement("span");
|
|
417
467
|
publisher.className = "publisher";
|
|
418
468
|
this._els.publisher = publisher;
|
|
419
|
-
|
|
469
|
+
setPrefixedStrong(publisher, "By ", this.getAttribute("publisher"));
|
|
420
470
|
meta.append(title, publisher);
|
|
421
471
|
const descriptionWrap = document.createElement("div");
|
|
422
472
|
descriptionWrap.className = "description-wrap";
|
|
@@ -430,11 +480,11 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
430
480
|
const duration = document.createElement("span");
|
|
431
481
|
duration.className = "info-item";
|
|
432
482
|
this._els.duration = duration;
|
|
433
|
-
|
|
483
|
+
setPrefixedStrong(duration, "", this.getAttribute("duration"));
|
|
434
484
|
const lastUpdated = document.createElement("span");
|
|
435
485
|
lastUpdated.className = "info-item";
|
|
436
486
|
this._els.lastUpdated = lastUpdated;
|
|
437
|
-
|
|
487
|
+
setPrefixedStrong(lastUpdated, "Last Updated: ", this.getAttribute("last-updated"));
|
|
438
488
|
infoRow.append(duration, lastUpdated);
|
|
439
489
|
content.append(meta, descriptionWrap, infoRow);
|
|
440
490
|
const actions = document.createElement("div");
|
|
@@ -469,66 +519,9 @@ var BvCourseListCard = class extends HTMLElement {
|
|
|
469
519
|
this._els.skeleton = skeleton;
|
|
470
520
|
card.append(thumbWrap, content, actions, skeleton);
|
|
471
521
|
shadow.appendChild(card);
|
|
472
|
-
this
|
|
473
|
-
this
|
|
474
|
-
|
|
475
|
-
if (this.disableSelection || this.loading) return;
|
|
476
|
-
const actionsEl = this._els.actions;
|
|
477
|
-
if (actionsEl && e.composedPath().includes(actionsEl)) return;
|
|
478
|
-
this._toggleSelected();
|
|
479
|
-
});
|
|
480
|
-
card.addEventListener("keydown", (e) => {
|
|
481
|
-
if (e.key !== "Enter" && e.key !== " ") return;
|
|
482
|
-
if (this.disableSelection || this.loading) return;
|
|
483
|
-
const actionsEl = this._els.actions;
|
|
484
|
-
if (actionsEl && e.composedPath().includes(actionsEl)) return;
|
|
485
|
-
e.preventDefault();
|
|
486
|
-
this._toggleSelected();
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
_toggleSelected() {
|
|
490
|
-
this.selected = !this.selected;
|
|
491
|
-
this.dispatchEvent(
|
|
492
|
-
new CustomEvent("bv-select", {
|
|
493
|
-
bubbles: true,
|
|
494
|
-
composed: true,
|
|
495
|
-
detail: { selected: this.selected }
|
|
496
|
-
})
|
|
497
|
-
);
|
|
498
|
-
}
|
|
499
|
-
_buildAriaLabel() {
|
|
500
|
-
const title = this.getAttribute("title") ?? "";
|
|
501
|
-
const publisher = this.getAttribute("publisher") ?? "";
|
|
502
|
-
const parts = [];
|
|
503
|
-
if (title) parts.push(title);
|
|
504
|
-
if (publisher) parts.push(`by ${publisher}`);
|
|
505
|
-
return parts.join(", ");
|
|
506
|
-
}
|
|
507
|
-
_setPrefixedStrong(el, prefix, val) {
|
|
508
|
-
if (!el) return;
|
|
509
|
-
const value = val ?? "";
|
|
510
|
-
if (!value) {
|
|
511
|
-
el.hidden = true;
|
|
512
|
-
el.replaceChildren();
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
el.hidden = false;
|
|
516
|
-
const strong = document.createElement("strong");
|
|
517
|
-
strong.textContent = value;
|
|
518
|
-
if (prefix) el.replaceChildren(document.createTextNode(prefix), strong);
|
|
519
|
-
else el.replaceChildren(strong);
|
|
520
|
-
}
|
|
521
|
-
_syncSelectionA11y() {
|
|
522
|
-
var _a, _b, _c;
|
|
523
|
-
const inert = this.disableSelection || this.loading;
|
|
524
|
-
(_a = this._els.card) == null ? void 0 : _a.setAttribute("tabindex", inert ? "-1" : "0");
|
|
525
|
-
if (inert) (_b = this._els.card) == null ? void 0 : _b.setAttribute("aria-disabled", "true");
|
|
526
|
-
else (_c = this._els.card) == null ? void 0 : _c.removeAttribute("aria-disabled");
|
|
527
|
-
}
|
|
528
|
-
_syncLoading() {
|
|
529
|
-
var _a;
|
|
530
|
-
const loading = this.loading;
|
|
531
|
-
(_a = this._els.card) == null ? void 0 : _a.setAttribute("aria-busy", loading ? "true" : "false");
|
|
522
|
+
syncCardLoading(this, card);
|
|
523
|
+
syncSelectionA11y(this, card);
|
|
524
|
+
bindCardSelection(this, card, actions);
|
|
532
525
|
}
|
|
533
526
|
};
|
|
534
527
|
if (!customElements.get("bv-course-list-card")) {
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
// css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-course-outline/bv-course-outline.css
|
|
2
2
|
var bv_course_outline_default = ":host {\n display: block;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Outer container \u2500\u2500 */\n\n.container {\n border: 0.5px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-xl);\n overflow: hidden;\n}\n\n.container-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: #f9fafb;\n border-bottom: 0.5px solid var(--bv-color-neutral-300);\n}\n\n.container-title {\n font-size: var(--bv-font-size-2xl);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-700);\n line-height: 32px;\n}\n\n.expand-all-btn {\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-bold);\n color: var(--bv-color-primary);\n line-height: 24px;\n white-space: nowrap;\n}\n\n.expand-all-btn:hover {\n text-decoration: underline;\n}\n\n.outline {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 24px;\n background: var(--bv-color-neutral-0);\n}\n\n/* \u2500\u2500 Section \u2500\u2500 */\n\n.section {\n background: var(--bv-color-neutral-0);\n border: 0.5px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-xl);\n overflow: hidden;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 20px;\n cursor: pointer;\n user-select: none;\n}\n\n.section-header:hover {\n background: linear-gradient(90deg, #fff, #f9fafb 15% 85%, #fff);\n}\n\n.section-header:focus-visible {\n outline: 2px solid var(--bv-color-primary);\n outline-offset: -2px;\n border-radius: var(--bv-radius-xl);\n}\n\n.section-header-left {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n flex: 1;\n min-width: 0;\n gap: 12px;\n}\n\n.section-title-row {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n}\n\n.section-title {\n font-size: var(--bv-font-size-lg);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n line-height: 28px;\n}\n\n.section-badge {\n display: inline-flex;\n align-items: center;\n padding: 0 8px;\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-full);\n font-size: 10px;\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-500);\n line-height: 18px;\n white-space: nowrap;\n}\n\n.section-chevron {\n flex-shrink: 0;\n width: 24px;\n height: 24px;\n color: var(--bv-color-neutral-500);\n transition: transform var(--bv-transition-fast);\n}\n\n.section-chevron svg {\n width: 100%;\n height: 100%;\n}\n\n.section--expanded .section-chevron {\n transform: rotate(180deg);\n}\n\n/* \u2500\u2500 Section body \u2500\u2500 */\n\n.section-body {\n display: none;\n border-top: 0.5px solid var(--bv-color-neutral-300);\n}\n\n.section--expanded .section-body {\n display: block;\n}\n\n/* \u2500\u2500 Description \u2500\u2500 */\n\n.section-desc-wrap {\n padding: 16px 20px 20px;\n}\n\n.section-desc {\n margin: 0 0 4px;\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-700);\n line-height: 24px;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.section-desc-wrap--expanded .section-desc {\n -webkit-line-clamp: unset;\n}\n\n.read-more {\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-primary);\n line-height: 24px;\n}\n\n.read-more:hover {\n text-decoration: underline;\n}\n\n/* \u2500\u2500 Module list \u2500\u2500 */\n\n.module-list {\n padding-left: 20px;\n padding-right: 20px;\n}\n\n.module-sep {\n height: 0;\n border-top: 0.5px solid var(--bv-color-neutral-300);\n margin-left: 20px;\n}\n\n.desc-sep {\n height: 0;\n border-top: 0.5px solid var(--bv-color-neutral-300);\n margin: 0 20px;\n}\n\n.module-row {\n display: flex;\n align-items: center;\n gap: 12px;\n min-height: 72px;\n padding: 0 0 0 20px;\n}\n\n.module-row:hover {\n background: linear-gradient(90deg, #fff, #f9fafb 15% 85%, #fff);\n}\n\n/* \u2500\u2500 Module icon \u2500\u2500 */\n\n.module-icon {\n flex-shrink: 0;\n width: 34px;\n height: 34px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.module-icon svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n/* \u2500\u2500 Module content \u2500\u2500 */\n\n.module-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.module-title-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.module-type-icon {\n flex-shrink: 0;\n width: 18px;\n height: 18px;\n color: var(--bv-color-neutral-500);\n display: flex;\n align-items: center;\n}\n\n.module-type-icon svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.module-title {\n flex: 1;\n min-width: 0;\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-700);\n line-height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Module status \u2500\u2500 */\n\n.module-status {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-bold);\n line-height: 20px;\n}\n\n.module-status span {\n white-space: nowrap;\n}\n\n.status-icon {\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n}\n\n.module-status--completed,\n.module-status--viewed,\n.module-status--pending-review {\n color: var(--bv-color-success-dark);\n}\n\n.module-status--in-progress,\n.module-status--not-started {\n color: var(--bv-color-neutral-700);\n}\n\n.module-status--max-retakes,\n.module-status--rejected {\n color: #f04438;\n}\n\n.module-status--seat-time {\n color: var(--bv-color-primary);\n}\n\n/* \u2500\u2500 Module actions \u2500\u2500 */\n\n.module-actions {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-shrink: 0;\n}\n\n.module-action-btn {\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-bold);\n color: var(--bv-color-primary);\n line-height: 20px;\n white-space: nowrap;\n}\n\n.module-action-btn:hover {\n text-decoration: underline;\n}\n\n/* \u2500\u2500 Pre-enrollment section \u2500\u2500 */\n\n.section--pre-enrollment .section-header {\n align-items: flex-start;\n}\n\n.pre-title-row {\n display: flex;\n align-items: center;\n gap: 16px;\n width: 100%;\n}\n\n.section-count-text {\n flex-shrink: 0;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-500);\n line-height: 20px;\n white-space: nowrap;\n}\n\n.section--pre-enrollment .section-chevron {\n margin-top: 2px;\n}\n\n.pre-section-desc-wrap {\n width: 100%;\n}\n\n/* \u2500\u2500 Pre-enrollment module list \u2500\u2500 */\n\n.pre-module-list {\n display: flex;\n flex-direction: column;\n padding: 0 20px;\n}\n\n.pre-module-list .module-sep {\n margin-left: 0;\n}\n\n.pre-module-wrap {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.pre-module-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 24px;\n padding: 16px 0;\n}\n\n.pre-module-list > .pre-module-wrap:first-child .pre-module-row {\n padding-top: 16px;\n}\n.pre-module-list > .pre-module-wrap:last-child .pre-module-row {\n padding-bottom: 16px;\n}\n\n.pre-module-row:hover {\n background: linear-gradient(90deg, #fff, #f9fafb 15% 85%, #fff);\n}\n\n.pre-module-title-group {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n}\n\n.pre-module-title {\n min-width: 0;\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-700);\n line-height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.pre-module-badges {\n display: flex;\n gap: 4px;\n align-items: center;\n flex-shrink: 0;\n}\n\n.pre-badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: var(--bv-radius-full);\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-medium);\n line-height: 18px;\n white-space: nowrap;\n}\n\n.pre-badge--inactive {\n background: var(--bv-color-neutral-700);\n color: var(--bv-color-neutral-0);\n}\n\n.pre-badge--optional {\n background: var(--bv-color-neutral-100);\n color: var(--bv-color-neutral-700);\n}\n\n.pre-module-toggle {\n flex-shrink: 0;\n width: 24px;\n height: 24px;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: var(--bv-color-neutral-700);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.pre-module-toggle:hover {\n color: var(--bv-color-primary);\n}\n\n.pre-module-toggle svg {\n width: 100%;\n height: 100%;\n}\n\n.pre-module-wrap--expanded .pre-module-row {\n padding-bottom: 0;\n}\n\n.pre-module-desc {\n padding: 0 0 16px;\n margin: 0;\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-700);\n line-height: 20px;\n}\n\n/* Empty state */\n.pre-section-empty {\n padding: 20px;\n margin: 0;\n font-size: var(--bv-font-size-md);\n color: var(--bv-color-neutral-500);\n line-height: 24px;\n}\n";
|
|
3
3
|
|
|
4
|
+
// components/_shared/adopt-styles.ts
|
|
5
|
+
var _sheetCache = /* @__PURE__ */ new Map();
|
|
6
|
+
function adoptStyles(shadow, css) {
|
|
7
|
+
if ("adoptedStyleSheets" in ShadowRoot.prototype && typeof CSSStyleSheet !== "undefined" && "replaceSync" in CSSStyleSheet.prototype) {
|
|
8
|
+
let sheet = _sheetCache.get(css);
|
|
9
|
+
if (!sheet) {
|
|
10
|
+
sheet = new CSSStyleSheet();
|
|
11
|
+
sheet.replaceSync(css);
|
|
12
|
+
_sheetCache.set(css, sheet);
|
|
13
|
+
}
|
|
14
|
+
shadow.adoptedStyleSheets = [sheet];
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const style = document.createElement("style");
|
|
18
|
+
style.textContent = css;
|
|
19
|
+
shadow.appendChild(style);
|
|
20
|
+
}
|
|
21
|
+
|
|
4
22
|
// components/bv-course-outline/bv-course-outline.ts
|
|
5
23
|
var BvCourseOutline = class extends HTMLElement {
|
|
6
24
|
static observedAttributes = ["sections", "mode"];
|
|
@@ -26,12 +44,7 @@ var BvCourseOutline = class extends HTMLElement {
|
|
|
26
44
|
}
|
|
27
45
|
constructor() {
|
|
28
46
|
super();
|
|
29
|
-
this.attachShadow({ mode: "open" });
|
|
30
|
-
if ("replaceSync" in CSSStyleSheet.prototype) {
|
|
31
|
-
const sheet = new CSSStyleSheet();
|
|
32
|
-
sheet.replaceSync(bv_course_outline_default);
|
|
33
|
-
this.shadowRoot.adoptedStyleSheets = [sheet];
|
|
34
|
-
}
|
|
47
|
+
adoptStyles(this.attachShadow({ mode: "open" }), bv_course_outline_default);
|
|
35
48
|
}
|
|
36
49
|
connectedCallback() {
|
|
37
50
|
this._render();
|
|
@@ -54,11 +67,6 @@ var BvCourseOutline = class extends HTMLElement {
|
|
|
54
67
|
if (this._rendered) return;
|
|
55
68
|
this._rendered = true;
|
|
56
69
|
const shadow = this.shadowRoot;
|
|
57
|
-
if (!shadow.adoptedStyleSheets.length) {
|
|
58
|
-
const s = document.createElement("style");
|
|
59
|
-
s.textContent = bv_course_outline_default;
|
|
60
|
-
shadow.appendChild(s);
|
|
61
|
-
}
|
|
62
70
|
const attr = this.getAttribute("sections");
|
|
63
71
|
if (attr !== null) {
|
|
64
72
|
try {
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import '../bv-date-range-picker/bv-date-range-picker.ts';
|
|
2
2
|
export declare class BvDateRangeInput extends HTMLElement {
|
|
3
|
-
static readonly observedAttributes: readonly ["label", "start", "end", "placeholder", "required"];
|
|
3
|
+
static readonly observedAttributes: readonly ["label", "start", "end", "placeholder", "required", "keep-open-while-invalid", "min", "max", "max-range-years", "validate-order", "validate-format", "show-range-limit-banner", "error-min", "error-max", "error-order", "error-format", "range-limit-message", "range-limit-heading", "error-min-severity", "error-max-severity", "error-format-severity", "error-order-severity", "range-limit-severity"];
|
|
4
4
|
private _rendered;
|
|
5
5
|
private _labelEl;
|
|
6
6
|
private _displayEl;
|
|
7
|
+
private _triggerEl;
|
|
7
8
|
private _pickerEl;
|
|
8
|
-
private
|
|
9
|
+
private _dropdown;
|
|
10
|
+
/**
|
|
11
|
+
* BTN-10312 — cached validity from the internal picker. `canClose` on the
|
|
12
|
+
* dropdown controller consults this to gate popup close when
|
|
13
|
+
* `keep-open-while-invalid` is set.
|
|
14
|
+
*/
|
|
15
|
+
private _pickerValidity;
|
|
9
16
|
constructor();
|
|
10
17
|
get start(): string;
|
|
11
18
|
set start(v: string);
|
|
@@ -13,11 +20,8 @@ export declare class BvDateRangeInput extends HTMLElement {
|
|
|
13
20
|
set end(v: string);
|
|
14
21
|
connectedCallback(): void;
|
|
15
22
|
disconnectedCallback(): void;
|
|
16
|
-
attributeChangedCallback(name: string, _old: string | null,
|
|
23
|
+
attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
|
|
17
24
|
private _render;
|
|
18
|
-
private _toggle;
|
|
19
|
-
private _open;
|
|
20
|
-
private _close;
|
|
21
25
|
private _syncLabel;
|
|
22
26
|
private _syncDisplay;
|
|
23
27
|
}
|