@bluevolt-tech/lumen 1.5.2 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/components/bv-alert-banner/bv-alert-banner.d.ts +33 -0
  2. package/dist/components/bv-alert-banner/bv-alert-banner.js +206 -0
  3. package/dist/components/bv-badge/bv-badge.d.ts +1 -1
  4. package/dist/components/bv-badge/bv-badge.js +1 -1
  5. package/dist/components/bv-button/bv-button.d.ts +1 -1
  6. package/dist/components/bv-button/bv-button.js +1 -1
  7. package/dist/components/bv-checkbox/bv-checkbox.js +1 -1
  8. package/dist/components/bv-course-detail-modal/bv-course-detail-modal.js +1 -1
  9. package/dist/components/bv-course-grid-card/bv-course-grid-card.d.ts +4 -0
  10. package/dist/components/bv-course-grid-card/bv-course-grid-card.js +75 -18
  11. package/dist/components/bv-course-list-card/bv-course-list-card.d.ts +4 -0
  12. package/dist/components/bv-course-list-card/bv-course-list-card.js +75 -18
  13. package/dist/components/bv-date-range-input/bv-date-range-input.d.ts +23 -0
  14. package/dist/components/bv-date-range-input/bv-date-range-input.js +950 -0
  15. package/dist/components/bv-date-range-picker/bv-date-range-picker.d.ts +56 -0
  16. package/dist/components/bv-date-range-picker/bv-date-range-picker.js +778 -0
  17. package/dist/components/bv-empty-state/bv-empty-state.js +1 -1
  18. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.d.ts +20 -5
  19. package/dist/components/bv-filter-dropdown/bv-filter-dropdown.js +263 -25
  20. package/dist/components/bv-filter-panel/bv-filter-panel.js +1 -1
  21. package/dist/components/bv-input/bv-input.d.ts +24 -0
  22. package/dist/components/bv-input/bv-input.js +148 -0
  23. package/dist/components/bv-input-dropdown/bv-input-dropdown.d.ts +46 -0
  24. package/dist/components/bv-input-dropdown/bv-input-dropdown.js +501 -0
  25. package/dist/components/bv-pagination/bv-pagination.d.ts +13 -1
  26. package/dist/components/bv-pagination/bv-pagination.js +290 -9
  27. package/dist/components/bv-portal-header/bv-portal-header.js +2 -2
  28. package/dist/components/bv-searchbox/bv-searchbox.js +1 -1
  29. package/dist/components/bv-segmented-control/bv-segmented-control.d.ts +26 -0
  30. package/dist/components/bv-segmented-control/bv-segmented-control.js +128 -0
  31. package/dist/components/bv-select/bv-select.d.ts +41 -0
  32. package/dist/components/bv-select/bv-select.js +240 -0
  33. package/dist/components/bv-split-button/bv-split-button.d.ts +37 -0
  34. package/dist/components/bv-split-button/bv-split-button.js +264 -0
  35. package/dist/components/bv-table/bv-table.d.ts +15 -0
  36. package/dist/components/bv-table/bv-table.js +260 -33
  37. package/dist/components/bv-toggle/bv-toggle.d.ts +2 -1
  38. package/dist/components/bv-toggle/bv-toggle.js +2 -2
  39. package/dist/components/bv-tooltip/bv-tooltip.d.ts +18 -0
  40. package/dist/components/bv-tooltip/bv-tooltip.js +144 -0
  41. package/dist/components/bv-user-row/bv-user-row.js +1 -1
  42. package/dist/storybook/stories/screens/cet-report.data.d.ts +55 -0
  43. package/dist/storybook/stories/screens/cet-report.data.js +3697 -0
  44. package/dist/themes/base.css +15 -1
  45. package/package.json +42 -1
  46. package/themes/base.css +15 -1
@@ -85,7 +85,7 @@ function getIllustrationSvg(name) {
85
85
  }
86
86
 
87
87
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-button/bv-button.css
88
- 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";
88
+ 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";
89
89
 
90
90
  // components/bv-icon/icons.ts
91
91
  var icons = {
@@ -1,26 +1,41 @@
1
1
  export interface FilterDropdownOption {
2
2
  label: string;
3
3
  value: string;
4
+ inactive?: boolean;
5
+ italic?: boolean;
6
+ depth?: number;
4
7
  }
5
8
  export declare class BvFilterDropdown extends HTMLElement {
6
- static readonly observedAttributes: string[];
9
+ static readonly observedAttributes: readonly ["options", "value", "placeholder", "multi", "searchable", "show-inactive-toggle", "values", "disabled", "open"];
7
10
  private _rendered;
8
11
  private _labelEl;
9
12
  private _panelEl;
10
13
  private _options;
11
14
  private _value;
15
+ private _selectedValues;
16
+ private _showInactive;
17
+ private _searchQuery;
12
18
  private _offClick;
13
19
  constructor();
20
+ get value(): string;
21
+ get values(): string[];
22
+ get multi(): boolean;
23
+ get disabled(): boolean;
24
+ set disabled(v: boolean);
14
25
  connectedCallback(): void;
15
26
  disconnectedCallback(): void;
16
- get value(): string;
17
27
  attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
28
+ private _parseValuesAttr;
18
29
  private _render;
19
30
  private _toggle;
20
31
  private _open;
21
32
  private _close;
22
33
  private _syncLabel;
23
- private _renderOptions;
24
- private _syncSelected;
25
- private _select;
34
+ private _rebuildPanel;
35
+ private _buildSinglePanel;
36
+ private _syncSingleSelected;
37
+ private _selectSingle;
38
+ private _buildMultiPanel;
39
+ private _onSelectAll;
40
+ private _onToggleItem;
26
41
  }
@@ -1,51 +1,114 @@
1
1
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-filter-dropdown/bv-filter-dropdown.css
2
- var bv_filter_dropdown_default = ":host {\n display: inline-block;\n position: relative;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Trigger \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 10px 16px;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-lg);\n box-shadow: var(--bv-shadow-sm);\n cursor: pointer;\n font-family: inherit;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-secondary-foreground);\n line-height: 20px;\n white-space: nowrap;\n user-select: none;\n transition:\n border-color var(--bv-transition-fast),\n background var(--bv-transition-fast);\n}\n\n.trigger:hover {\n background: var(--bv-color-secondary-light);\n}\n\n:host([open]) .trigger {\n border-color: var(--bv-color-primary);\n background: var(--bv-color-neutral-0);\n}\n\n.trigger-chevron {\n display: flex;\n color: var(--bv-color-secondary-foreground);\n transition: transform var(--bv-transition-fast);\n flex-shrink: 0;\n}\n\n:host([open]) .trigger-chevron {\n transform: rotate(180deg);\n}\n\n/* \u2500\u2500 Dropdown panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.panel {\n display: none;\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 100%;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-lg);\n box-shadow: var(--bv-shadow-md);\n z-index: 200;\n overflow: hidden;\n padding: 4px 0;\n}\n\n:host([open]) .panel {\n display: block;\n}\n\n/* \u2500\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 9px 14px;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-700);\n cursor: pointer;\n white-space: nowrap;\n transition: background var(--bv-transition-fast);\n}\n\n.option:hover {\n background: var(--bv-color-secondary);\n}\n\n.option[aria-selected='true'] {\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n background: var(--bv-color-secondary-light);\n}\n\n.option-check {\n display: none;\n color: var(--bv-color-primary);\n flex-shrink: 0;\n}\n\n.option[aria-selected='true'] .option-check {\n display: flex;\n}\n";
2
+ var bv_filter_dropdown_default = ":host {\n display: inline-block;\n position: relative;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Trigger \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 12px 16px;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-lg);\n box-shadow: var(--bv-shadow-sm);\n cursor: pointer;\n font-family: inherit;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-secondary-foreground);\n line-height: 20px;\n white-space: nowrap;\n user-select: none;\n transition:\n border-color var(--bv-transition-fast),\n background var(--bv-transition-fast);\n}\n\n.trigger:hover {\n background: var(--bv-color-secondary-light);\n}\n\n:host([open]) .trigger {\n border-color: var(--bv-color-primary);\n background: var(--bv-color-neutral-0);\n}\n\n:host([disabled]) .trigger {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n background: var(--bv-color-neutral-100);\n}\n\n:host([disabled]) .trigger:hover {\n background: var(--bv-color-neutral-100);\n}\n\n.trigger-chevron {\n display: flex;\n color: var(--bv-color-secondary-foreground);\n transition: transform var(--bv-transition-fast);\n flex-shrink: 0;\n}\n\n:host([open]) .trigger-chevron {\n transform: rotate(180deg);\n}\n\n/* \u2500\u2500 Dropdown panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.panel {\n display: none;\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n width: max-content;\n min-width: 100%;\n max-width: 600px;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-lg);\n box-shadow: var(--bv-shadow-md);\n z-index: 200;\n overflow: hidden;\n padding: 4px 0;\n}\n\n:host([open]) .panel {\n display: block;\n}\n\n/* \u2500\u2500 Single-mode options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 9px 14px;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-700);\n cursor: pointer;\n white-space: nowrap;\n transition: background var(--bv-transition-fast);\n}\n\n.option:hover {\n background: var(--bv-color-secondary);\n}\n\n.option[aria-selected='true'] {\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n background: var(--bv-color-secondary-light);\n}\n\n.option-check {\n display: none;\n color: var(--bv-color-primary);\n flex-shrink: 0;\n}\n\n.option[aria-selected='true'] .option-check {\n display: flex;\n}\n\n/* \u2500\u2500 Multi-mode search \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.panel-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--bv-color-neutral-200);\n}\n\n.search-icon {\n display: flex;\n color: var(--bv-color-neutral-400);\n flex-shrink: 0;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n color: var(--bv-color-neutral-700);\n background: transparent;\n min-width: 0;\n}\n\n.search-input::placeholder {\n color: var(--bv-color-neutral-400);\n}\n\n/* \u2500\u2500 Multi-mode header (Select All + toggle) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n}\n\n.select-all-row {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-neutral-700);\n user-select: none;\n flex: 1;\n padding: 2px 0;\n}\n\n.select-all-row:hover {\n color: var(--bv-color-neutral-900);\n}\n\n/* \u2500\u2500 Show Inactive toggle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.inactive-toggle-label {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n user-select: none;\n flex-shrink: 0;\n}\n\n.toggle-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n}\n\n.toggle-track {\n display: inline-flex;\n align-items: center;\n width: 28px;\n height: 16px;\n background: var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-full);\n padding: 2px;\n transition: background var(--bv-transition-fast);\n flex-shrink: 0;\n}\n\n.toggle-input:checked ~ .toggle-track {\n background: var(--bv-color-primary);\n}\n\n.toggle-thumb {\n width: 12px;\n height: 12px;\n background: var(--bv-color-neutral-0);\n border-radius: var(--bv-radius-full);\n transition: transform var(--bv-transition-fast);\n flex-shrink: 0;\n}\n\n.toggle-input:checked ~ .toggle-track .toggle-thumb {\n transform: translateX(12px);\n}\n\n.toggle-text {\n font-size: var(--bv-font-size-xs);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-600);\n white-space: nowrap;\n}\n\n/* \u2500\u2500 Panel 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 */\n\n.panel-divider {\n height: 1px;\n background: var(--bv-color-neutral-200);\n margin: 0;\n}\n\n/* \u2500\u2500 Multi-mode options list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.options-list {\n max-height: 260px;\n overflow-y: auto;\n padding: 4px 0;\n}\n\n.option--multi {\n justify-content: flex-start;\n white-space: normal;\n min-width: 200px;\n}\n\n/* Depth-based indentation */\n.option--multi[data-depth='1'] {\n padding-left: 30px;\n}\n\n.option--multi[data-depth='2'] {\n padding-left: 46px;\n}\n\n/* In multi mode, checkbox is always visible */\n.option--multi .option-check {\n display: flex;\n width: 16px;\n height: 16px;\n border: 1.5px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-sm);\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: var(--bv-color-neutral-0);\n color: transparent;\n transition:\n border-color var(--bv-transition-fast),\n background var(--bv-transition-fast);\n}\n\n.option--multi .option-check.checked {\n background: var(--bv-color-primary);\n border-color: var(--bv-color-primary);\n color: var(--bv-color-neutral-0);\n}\n\n.option--multi:hover .option-check:not(.checked) {\n border-color: var(--bv-color-primary);\n}\n\n/* In multi mode, override the single-mode aria-selected styles */\n.option--multi[aria-selected='true'] {\n font-weight: var(--bv-font-weight-regular);\n background: transparent;\n color: var(--bv-color-neutral-700);\n}\n\n.option--multi:hover {\n background: var(--bv-color-secondary);\n}\n\n/* Inactive options */\n.option--inactive .option-label {\n color: var(--bv-color-neutral-400);\n}\n\n/* Italic labels (Uncategorized, Ungrouped) */\n.option-label--italic {\n font-style: italic;\n color: var(--bv-color-neutral-500);\n}\n\n.option-label {\n line-height: 1.4;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Select All row checkbox */\n.select-all-row .option-check {\n display: flex;\n width: 16px;\n height: 16px;\n border: 1.5px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-sm);\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: var(--bv-color-neutral-0);\n color: transparent;\n transition:\n border-color var(--bv-transition-fast),\n background var(--bv-transition-fast);\n}\n\n.select-all-row .option-check.checked {\n background: var(--bv-color-primary);\n border-color: var(--bv-color-primary);\n color: var(--bv-color-neutral-0);\n}\n";
3
3
 
4
4
  // components/bv-filter-dropdown/bv-filter-dropdown.ts
5
5
  var CHEVRON_DOWN = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>`;
6
6
  var CHECK = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;
7
+ var SEARCH_ICON = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>`;
8
+ var _sheet = null;
9
+ function getSheet() {
10
+ if (!_sheet) {
11
+ _sheet = new CSSStyleSheet();
12
+ _sheet.replaceSync(bv_filter_dropdown_default);
13
+ }
14
+ return _sheet;
15
+ }
7
16
  var BvFilterDropdown = class extends HTMLElement {
8
- static observedAttributes = ["options", "value", "placeholder"];
17
+ static observedAttributes = [
18
+ "options",
19
+ "value",
20
+ "placeholder",
21
+ "multi",
22
+ "searchable",
23
+ "show-inactive-toggle",
24
+ "values",
25
+ "disabled",
26
+ "open"
27
+ ];
9
28
  _rendered = false;
10
29
  _labelEl = null;
11
30
  _panelEl = null;
12
31
  _options = [];
32
+ // Single-select state
13
33
  _value = "";
34
+ // Multi-select state — null means "all selected" (no filter applied)
35
+ _selectedValues = null;
36
+ _showInactive = false;
37
+ _searchQuery = "";
14
38
  _offClick = null;
15
39
  constructor() {
16
40
  super();
17
- this.attachShadow({ mode: "open" });
18
- if ("replaceSync" in CSSStyleSheet.prototype) {
19
- const sheet = new CSSStyleSheet();
20
- sheet.replaceSync(bv_filter_dropdown_default);
21
- this.shadowRoot.adoptedStyleSheets = [sheet];
41
+ const shadow = this.attachShadow({ mode: "open" });
42
+ if ("adoptedStyleSheets" in ShadowRoot.prototype) {
43
+ shadow.adoptedStyleSheets = [getSheet()];
22
44
  }
23
45
  }
46
+ get value() {
47
+ return this._value;
48
+ }
49
+ get values() {
50
+ return this._selectedValues ? [...this._selectedValues] : [];
51
+ }
52
+ get multi() {
53
+ return this.hasAttribute("multi");
54
+ }
55
+ get disabled() {
56
+ return this.hasAttribute("disabled");
57
+ }
58
+ set disabled(v) {
59
+ if (v) this.setAttribute("disabled", "");
60
+ else this.removeAttribute("disabled");
61
+ }
24
62
  connectedCallback() {
25
63
  this._render();
26
64
  }
27
65
  disconnectedCallback() {
28
66
  if (this._offClick) document.removeEventListener("click", this._offClick);
29
67
  }
30
- get value() {
31
- return this._value;
32
- }
33
68
  attributeChangedCallback(name, _old, val) {
69
+ var _a;
34
70
  if (name === "options") {
35
71
  try {
36
72
  this._options = JSON.parse(val ?? "[]");
37
73
  } catch {
38
74
  this._options = [];
39
75
  }
40
- if (this._rendered) this._renderOptions();
76
+ if (this._rendered) this._rebuildPanel();
41
77
  }
42
- if (name === "value") {
78
+ if (name === "value" && !this.multi) {
43
79
  this._value = val ?? "";
44
- if (this._rendered) this._syncLabel();
45
- if (this._rendered) this._syncSelected();
80
+ if (this._rendered) {
81
+ this._syncLabel();
82
+ this._syncSingleSelected();
83
+ }
46
84
  }
47
- if (name === "placeholder" && this._rendered) {
48
- this._syncLabel();
85
+ if (name === "values" && this.multi) {
86
+ this._parseValuesAttr(val);
87
+ if (this._rendered) {
88
+ this._syncLabel();
89
+ this._rebuildPanel();
90
+ }
91
+ }
92
+ if (name === "placeholder" && this._rendered) this._syncLabel();
93
+ if ((name === "multi" || name === "searchable" || name === "show-inactive-toggle") && this._rendered) {
94
+ this._rebuildPanel();
95
+ }
96
+ if (name === "open" && this._rendered) {
97
+ const trigger = this.shadowRoot.querySelector(".trigger");
98
+ if (trigger) trigger.setAttribute("aria-expanded", val !== null ? "true" : "false");
99
+ if (val === null) (_a = this._panelEl) == null ? void 0 : _a.style.removeProperty("display");
100
+ }
101
+ }
102
+ _parseValuesAttr(val) {
103
+ if (!val) {
104
+ this._selectedValues = null;
105
+ return;
106
+ }
107
+ try {
108
+ const arr = JSON.parse(val);
109
+ this._selectedValues = arr.length === 0 ? null : new Set(arr);
110
+ } catch {
111
+ this._selectedValues = null;
49
112
  }
50
113
  }
51
114
  _render() {
@@ -63,6 +126,7 @@ var BvFilterDropdown = class extends HTMLElement {
63
126
  this._options = [];
64
127
  }
65
128
  this._value = this.getAttribute("value") ?? "";
129
+ this._parseValuesAttr(this.getAttribute("values"));
66
130
  const trigger = document.createElement("button");
67
131
  trigger.type = "button";
68
132
  trigger.className = "trigger";
@@ -82,10 +146,11 @@ var BvFilterDropdown = class extends HTMLElement {
82
146
  const panel = document.createElement("div");
83
147
  panel.className = "panel";
84
148
  panel.setAttribute("role", "listbox");
149
+ if (this.multi) panel.setAttribute("aria-multiselectable", "true");
85
150
  this._panelEl = panel;
86
151
  shadow.append(trigger, panel);
87
152
  this._syncLabel();
88
- this._renderOptions();
153
+ this._rebuildPanel();
89
154
  this._offClick = (e) => {
90
155
  if (!this.contains(e.target) && !shadow.contains(e.target)) {
91
156
  this._close();
@@ -97,6 +162,7 @@ var BvFilterDropdown = class extends HTMLElement {
97
162
  });
98
163
  }
99
164
  _toggle() {
165
+ if (this.hasAttribute("disabled")) return;
100
166
  if (this.hasAttribute("open")) this._close();
101
167
  else this._open();
102
168
  }
@@ -104,6 +170,7 @@ var BvFilterDropdown = class extends HTMLElement {
104
170
  var _a;
105
171
  this.setAttribute("open", "");
106
172
  (_a = this.shadowRoot.querySelector(".trigger")) == null ? void 0 : _a.setAttribute("aria-expanded", "true");
173
+ this.dispatchEvent(new CustomEvent("bv-open", { bubbles: true, composed: true }));
107
174
  }
108
175
  _close() {
109
176
  var _a;
@@ -112,28 +179,47 @@ var BvFilterDropdown = class extends HTMLElement {
112
179
  }
113
180
  _syncLabel() {
114
181
  if (!this._labelEl) return;
115
- const match = this._options.find((o) => o.value === this._value);
116
- this._labelEl.textContent = (match == null ? void 0 : match.label) ?? this.getAttribute("placeholder") ?? "Select";
182
+ const placeholder = this.getAttribute("placeholder") ?? "All";
183
+ if (this.multi) {
184
+ if (!this._selectedValues || this._selectedValues.size === 0) {
185
+ this._labelEl.textContent = placeholder;
186
+ } else {
187
+ this._labelEl.textContent = `${this._selectedValues.size} selected`;
188
+ }
189
+ } else {
190
+ const match = this._options.find((o) => o.value === this._value);
191
+ this._labelEl.textContent = (match == null ? void 0 : match.label) ?? placeholder;
192
+ }
117
193
  }
118
- _renderOptions() {
194
+ _rebuildPanel() {
119
195
  if (!this._panelEl) return;
120
196
  this._panelEl.innerHTML = "";
197
+ if (this.multi) {
198
+ this._buildMultiPanel(this._panelEl);
199
+ } else {
200
+ this._buildSinglePanel(this._panelEl);
201
+ }
202
+ }
203
+ // ── Single mode ───────────────────────────────────────────
204
+ _buildSinglePanel(panel) {
121
205
  for (const opt of this._options) {
122
206
  const item = document.createElement("div");
123
207
  item.className = "option";
124
208
  item.setAttribute("role", "option");
125
209
  item.setAttribute("aria-selected", opt.value === this._value ? "true" : "false");
210
+ item.title = opt.label;
126
211
  const text = document.createElement("span");
212
+ text.className = "option-label";
127
213
  text.textContent = opt.label;
128
214
  const check = document.createElement("span");
129
215
  check.className = "option-check";
130
216
  check.innerHTML = CHECK;
131
217
  item.append(text, check);
132
- item.addEventListener("click", () => this._select(opt));
133
- this._panelEl.appendChild(item);
218
+ item.addEventListener("click", () => this._selectSingle(opt));
219
+ panel.appendChild(item);
134
220
  }
135
221
  }
136
- _syncSelected() {
222
+ _syncSingleSelected() {
137
223
  var _a;
138
224
  (_a = this._panelEl) == null ? void 0 : _a.querySelectorAll(".option").forEach((el, i) => {
139
225
  const opt = this._options[i];
@@ -141,11 +227,11 @@ var BvFilterDropdown = class extends HTMLElement {
141
227
  });
142
228
  this._syncLabel();
143
229
  }
144
- _select(opt) {
230
+ _selectSingle(opt) {
145
231
  this._value = opt.value;
146
232
  this.setAttribute("value", opt.value);
147
233
  this._syncLabel();
148
- this._syncSelected();
234
+ this._syncSingleSelected();
149
235
  this._close();
150
236
  this.dispatchEvent(
151
237
  new CustomEvent("bv-change", {
@@ -155,6 +241,158 @@ var BvFilterDropdown = class extends HTMLElement {
155
241
  })
156
242
  );
157
243
  }
244
+ // ── Multi mode ────────────────────────────────────────────
245
+ _buildMultiPanel(panel) {
246
+ const searchable = this.hasAttribute("searchable");
247
+ const showInactiveToggle = this.hasAttribute("show-inactive-toggle");
248
+ if (searchable) {
249
+ const searchWrap = document.createElement("div");
250
+ searchWrap.className = "panel-search";
251
+ const searchIcon = document.createElement("span");
252
+ searchIcon.className = "search-icon";
253
+ searchIcon.innerHTML = SEARCH_ICON;
254
+ const searchInput = document.createElement("input");
255
+ searchInput.type = "text";
256
+ searchInput.className = "search-input";
257
+ searchInput.placeholder = "Search...";
258
+ searchInput.value = this._searchQuery;
259
+ searchInput.setAttribute("aria-label", "Search options");
260
+ searchInput.addEventListener("input", (e) => {
261
+ var _a;
262
+ e.stopPropagation();
263
+ this._searchQuery = e.target.value;
264
+ this._rebuildPanel();
265
+ const restored = (_a = this._panelEl) == null ? void 0 : _a.querySelector(".search-input");
266
+ if (restored) {
267
+ restored.focus();
268
+ restored.setSelectionRange(restored.value.length, restored.value.length);
269
+ }
270
+ });
271
+ searchInput.addEventListener("click", (e) => e.stopPropagation());
272
+ searchWrap.append(searchIcon, searchInput);
273
+ panel.appendChild(searchWrap);
274
+ }
275
+ const header = document.createElement("div");
276
+ header.className = "panel-header";
277
+ const allSelected = this._selectedValues === null;
278
+ const selectAllBtn = document.createElement("div");
279
+ selectAllBtn.className = "select-all-row";
280
+ selectAllBtn.setAttribute("role", "option");
281
+ selectAllBtn.setAttribute("aria-selected", allSelected ? "true" : "false");
282
+ const saCheck = document.createElement("span");
283
+ saCheck.className = allSelected ? "option-check checked" : "option-check";
284
+ saCheck.innerHTML = CHECK;
285
+ const saText = document.createElement("span");
286
+ saText.className = "option-label";
287
+ saText.textContent = "Select All";
288
+ selectAllBtn.append(saCheck, saText);
289
+ selectAllBtn.addEventListener("click", (e) => {
290
+ e.stopPropagation();
291
+ this._onSelectAll();
292
+ });
293
+ header.appendChild(selectAllBtn);
294
+ if (showInactiveToggle) {
295
+ const toggleLabel = document.createElement("label");
296
+ toggleLabel.className = "inactive-toggle-label";
297
+ const toggleInput = document.createElement("input");
298
+ toggleInput.type = "checkbox";
299
+ toggleInput.className = "toggle-input";
300
+ toggleInput.checked = this._showInactive;
301
+ toggleInput.setAttribute("aria-label", "Show inactive");
302
+ toggleInput.addEventListener("change", (e) => {
303
+ e.stopPropagation();
304
+ this._showInactive = e.target.checked;
305
+ this._rebuildPanel();
306
+ });
307
+ toggleInput.addEventListener("click", (e) => e.stopPropagation());
308
+ const toggleTrack = document.createElement("span");
309
+ toggleTrack.className = "toggle-track";
310
+ const toggleThumb = document.createElement("span");
311
+ toggleThumb.className = "toggle-thumb";
312
+ toggleTrack.appendChild(toggleThumb);
313
+ const toggleText = document.createElement("span");
314
+ toggleText.className = "toggle-text";
315
+ toggleText.textContent = "Show Inactive";
316
+ toggleLabel.append(toggleInput, toggleTrack, toggleText);
317
+ header.appendChild(toggleLabel);
318
+ }
319
+ panel.appendChild(header);
320
+ const divider = document.createElement("div");
321
+ divider.className = "panel-divider";
322
+ panel.appendChild(divider);
323
+ const optList = document.createElement("div");
324
+ optList.className = "options-list";
325
+ const query = this._searchQuery.toLowerCase().trim();
326
+ for (const opt of this._options) {
327
+ if (opt.inactive && !this._showInactive) continue;
328
+ if (query && !opt.label.toLowerCase().includes(query)) continue;
329
+ const item = document.createElement("div");
330
+ item.className = "option option--multi";
331
+ if (opt.inactive) item.classList.add("option--inactive");
332
+ item.setAttribute("role", "option");
333
+ item.setAttribute("data-value", opt.value);
334
+ item.title = opt.label;
335
+ const depth = opt.depth ?? 0;
336
+ if (depth > 0) item.setAttribute("data-depth", String(depth));
337
+ const isChecked = !this._selectedValues || this._selectedValues.has(opt.value);
338
+ item.setAttribute("aria-selected", isChecked ? "true" : "false");
339
+ const checkSpan = document.createElement("span");
340
+ checkSpan.className = isChecked ? "option-check checked" : "option-check";
341
+ checkSpan.innerHTML = CHECK;
342
+ const labelSpan = document.createElement("span");
343
+ labelSpan.className = opt.italic ? "option-label option-label--italic" : "option-label";
344
+ labelSpan.textContent = opt.label;
345
+ item.append(checkSpan, labelSpan);
346
+ item.addEventListener("click", (e) => {
347
+ e.stopPropagation();
348
+ this._onToggleItem(opt);
349
+ });
350
+ optList.appendChild(item);
351
+ }
352
+ panel.appendChild(optList);
353
+ }
354
+ _onSelectAll() {
355
+ this._selectedValues = this._selectedValues === null ? /* @__PURE__ */ new Set() : null;
356
+ this._syncLabel();
357
+ this._rebuildPanel();
358
+ this.dispatchEvent(
359
+ new CustomEvent("bv-change", {
360
+ bubbles: true,
361
+ composed: true,
362
+ detail: {
363
+ values: this._selectedValues ? [...this._selectedValues] : [],
364
+ allSelected: this._selectedValues === null
365
+ }
366
+ })
367
+ );
368
+ }
369
+ _onToggleItem(opt) {
370
+ const allActive = this._options.filter((o) => !o.inactive || this._showInactive);
371
+ if (!this._selectedValues) {
372
+ this._selectedValues = new Set(allActive.map((o) => o.value).filter((v) => v !== opt.value));
373
+ } else if (this._selectedValues.has(opt.value)) {
374
+ this._selectedValues.delete(opt.value);
375
+ if (this._selectedValues.size === 0) {
376
+ }
377
+ } else {
378
+ this._selectedValues.add(opt.value);
379
+ if (this._selectedValues.size === allActive.length) {
380
+ this._selectedValues = null;
381
+ }
382
+ }
383
+ this._syncLabel();
384
+ this._rebuildPanel();
385
+ this.dispatchEvent(
386
+ new CustomEvent("bv-change", {
387
+ bubbles: true,
388
+ composed: true,
389
+ detail: {
390
+ values: this._selectedValues ? [...this._selectedValues] : [],
391
+ allSelected: this._selectedValues === null
392
+ }
393
+ })
394
+ );
395
+ }
158
396
  };
159
397
  if (!customElements.get("bv-filter-dropdown")) {
160
398
  customElements.define("bv-filter-dropdown", BvFilterDropdown);
@@ -2,7 +2,7 @@
2
2
  var bv_filter_panel_default = ":host {\n display: block;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-200);\n}\n\n/* Self-hide when there are no groups to show. */\n:host([empty]) {\n display: none;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n border-bottom: 1px solid var(--bv-color-neutral-200);\n}\n\n.panel-title {\n margin: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-2xl);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n}\n\n.clear-btn {\n background: none;\n border: none;\n padding: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-primary);\n cursor: pointer;\n}\n\n.clear-btn:hover {\n text-decoration: underline;\n}\n\n.groups {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-lg);\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n}\n\n.group {\n}\n\n.group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n padding-bottom: var(--bv-spacing-sm);\n}\n\n.group-label {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-lg);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n}\n\n.group-chevron {\n width: 20px;\n height: 20px;\n color: var(--bv-color-neutral-500);\n transition: transform var(--bv-transition-fast);\n}\n\n.group-chevron.collapsed {\n transform: rotate(180deg);\n}\n\n.group-options {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.group-options.hidden {\n display: none;\n}\n\n.option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--bv-spacing-xs);\n}\n\n.option bv-checkbox {\n flex: 1;\n min-width: 0;\n}\n\n.option-count {\n display: inline-flex;\n align-items: center;\n padding: 2px var(--bv-spacing-sm);\n background: var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-full);\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-600);\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Loading skeleton */\n.skeleton {\n display: none;\n flex-direction: column;\n gap: var(--bv-spacing-lg);\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n}\n\n:host([loading]) .groups {\n display: none;\n}\n\n:host([loading]) .skeleton {\n display: flex;\n}\n\n.skeleton-group {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-sm);\n}\n\n.skeleton-line {\n height: 14px;\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-heading {\n height: 20px;\n width: 55%;\n margin-bottom: 4px;\n}\n\n.skeleton-short-line {\n width: 70%;\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
4
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-checkbox/bv-checkbox.css
5
- var bv_checkbox_default = ":host {\n display: inline-flex;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Size 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\u2500 */\n\n:host,\n:host([size='sm']) {\n --_box-size: 16px;\n --_box-radius: 4px;\n --_gap: 8px;\n --_check-size: 10px;\n --_label-size: var(--bv-font-size-sm);\n --_label-lh: 20px;\n}\n\n:host([size='md']) {\n --_box-size: 20px;\n --_box-radius: 6px;\n --_gap: 12px;\n --_check-size: 12px;\n --_label-size: var(--bv-font-size-md);\n --_label-lh: 24px;\n}\n\n/* \u2500\u2500 Layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.wrap {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--_gap);\n cursor: pointer;\n user-select: none;\n}\n\n:host([disabled]) .wrap {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* \u2500\u2500 Box \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.box {\n width: var(--_box-size);\n height: var(--_box-size);\n border-radius: var(--_box-radius);\n border: 1px solid var(--bv-color-neutral-300);\n background: var(--bv-color-neutral-0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin-top: 2px;\n transition:\n background var(--bv-transition-fast),\n border-color var(--bv-transition-fast);\n}\n\n:host([checked]) .box,\n:host([indeterminate]) .box {\n background: var(--bv-color-primary-50);\n border-color: var(--bv-color-primary);\n}\n\n/* \u2500\u2500 Check 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 */\n\n.check {\n display: none;\n width: var(--_check-size);\n height: var(--_check-size);\n color: var(--bv-color-primary);\n line-height: 0;\n}\n\n.check svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n:host([checked]) .check,\n:host([indeterminate]) .check {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* \u2500\u2500 Label \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.label {\n font-size: var(--_label-size);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-secondary-foreground);\n line-height: var(--_label-lh);\n}\n";
5
+ var bv_checkbox_default = ":host {\n display: inline-flex;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Size 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\u2500 */\n\n:host,\n:host([size='sm']) {\n --_box-size: 16px;\n --_box-radius: 4px;\n --_gap: 8px;\n --_check-size: 10px;\n --_label-size: var(--bv-font-size-sm);\n --_label-lh: 20px;\n}\n\n:host([size='md']) {\n --_box-size: 20px;\n --_box-radius: 6px;\n --_gap: 12px;\n --_check-size: 12px;\n --_label-size: var(--bv-font-size-md);\n --_label-lh: 24px;\n}\n\n/* \u2500\u2500 Layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.wrap {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--_gap);\n cursor: pointer;\n user-select: none;\n}\n\n:host([disabled]) .wrap {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* \u2500\u2500 Box \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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.box {\n width: var(--_box-size);\n height: var(--_box-size);\n border-radius: var(--_box-radius);\n border: 1px solid var(--bv-color-neutral-300);\n background: var(--bv-color-neutral-0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin-top: 2px;\n transition:\n background var(--bv-transition-fast),\n border-color var(--bv-transition-fast);\n}\n\n:host([checked]) .box,\n:host([indeterminate]) .box {\n background: var(--bv-color-primary-50);\n border-color: var(--bv-color-primary);\n}\n\n/* \u2500\u2500 Check 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 */\n\n.check {\n display: none;\n width: var(--_check-size);\n height: var(--_check-size);\n color: var(--bv-color-primary);\n line-height: 0;\n}\n\n.check svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n:host([checked]) .check,\n:host([indeterminate]) .check {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* \u2500\u2500 Label \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.label {\n font-size: var(--_label-size);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-secondary-foreground);\n line-height: var(--_label-lh);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n";
6
6
 
7
7
  // components/bv-checkbox/bv-checkbox.ts
8
8
  var CHECK_ICON = `<svg viewBox="0 0 11.3333 8.41667" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -0,0 +1,24 @@
1
+ export type InputType = 'text' | 'email' | 'password' | 'number';
2
+ export interface InputChangeDetail {
3
+ value: string;
4
+ }
5
+ export declare class BvInput extends HTMLElement {
6
+ static readonly observedAttributes: readonly ["label", "type", "placeholder", "value", "name", "error", "required", "disabled"];
7
+ private _rendered;
8
+ private _labelEl;
9
+ private _inputEl;
10
+ private _errorEl;
11
+ constructor();
12
+ get value(): string;
13
+ set value(v: string);
14
+ get disabled(): boolean;
15
+ set disabled(v: boolean);
16
+ get required(): boolean;
17
+ set required(v: boolean);
18
+ connectedCallback(): void;
19
+ attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
20
+ private _render;
21
+ private _syncLabel;
22
+ private _syncError;
23
+ private _syncDisabled;
24
+ }