blue-web 1.19.1 → 1.21.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.
@@ -0,0 +1 @@
1
+ (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.shadowRoot.innerHTML='<button part="base" type="button">Hello world</button>'}}customElements.get("bl-button")||customElements.define("bl-button",t)})();
@@ -0,0 +1,6 @@
1
+ declare class Button extends HTMLElement {
2
+ constructor();
3
+ connectedCallback(): void;
4
+ }
5
+ export { Button };
6
+ export default Button;
@@ -0,0 +1,16 @@
1
+ class Button extends HTMLElement {
2
+ constructor() {
3
+ super();
4
+ this.attachShadow({
5
+ mode: "open"
6
+ });
7
+ }
8
+ connectedCallback() {
9
+ this.shadowRoot.innerHTML = /* html*/"<button part=\"base\" type=\"button\">Hello world</button>";
10
+ }
11
+ }
12
+ if (!customElements.get("bl-button")) {
13
+ customElements.define("bl-button", Button);
14
+ }
15
+ export { Button };
16
+ export default Button;
@@ -1 +1 @@
1
- (()=>{"use strict";var n={762:(n,e,t)=>{function o(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}t.d(e,{Os:()=>a});const a=()=>o()+o()+"-"+o()+"-"+o()+"-"+o()+"-"+o()+o()+o()},786:(n,e,t)=>{t.d(e,{k:()=>a});const o={Cancel:["Cancel","Abbrechen"],Yes:["Yes","Ja"],No:["No","Nein"],Message:["Message","Nachricht"],"Toggle menu":["Toggle menu","Menü umschalten"],"Close all":["Close all","Alle schließen"],Error:["Error","Fehler"],Information:["Information","Information"]};function a(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0,t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;return e=e||navigator.language.toLowerCase().indexOf("de")>-1?"de-DE":"en-US",t=t||o,t[n]?e.indexOf("de-")>-1?t[n][1]:t[n][0]:n}}},e={};function t(o){var a=e[o];if(void 0!==a)return a.exports;var l=e[o]={exports:{}};return n[o](l,l.exports,t),l.exports}t.d=(n,e)=>{for(var o in e)t.o(e,o)&&!t.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:e[o]})},t.o=(n,e)=>Object.prototype.hasOwnProperty.call(n,e);var o=t(762),a=t(786);async function l(n,e){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},{title:l=(0,a.k)("Message"),icon:c,switchPrimaryBtn:i=!1,acceptBtnText:r=("verify"===n?(0,a.k)("Yes"):"OK"),cancelBtnText:s=("verify"===n?(0,a.k)("No"):(0,a.k)("Cancel")),inputType:d="text",defaultValue:u}="string"==typeof t?JSON.parse(t):t;const m=(0,o.Os)();return document.getElementById(m)||document.body.insertAdjacentHTML("beforeend",'<dialog class="blue-modal modal" id="'.concat(m,'" aria-labelledby="').concat(m,'-label">\n <div class="modal-dialog">\n <div class="modal-content">\n <form>\n <div class="modal-header">\n ').concat(c?'<div class="me-2">'.concat(c,"</div>"):"",'\n <h1 class="modal-title fs-5" id="').concat(m,'-label">').concat(l,'</h1>\n <button\n type="button"\n class="btn-close"\n aria-label="').concat(s,'"\n onclick="document.getElementById(\'').concat(m,'\').close()"\n ></button>\n </div>\n <div class="modal-body">\n ').concat("ask"===n?'<label for="'.concat(m,'-input">').concat(e,'</label>\n <input\n type="').concat(d,'"\n ').concat(void 0!==u?' value="'.concat(u,'"'):"",'\n id="').concat(m,'-input"\n class="form-control mt-3"\n />'):e,'\n </div>\n <div class="modal-footer">\n ').concat("verify"===n||"ask"===n?'<button\n type="button"\n class="btn '.concat(i?"btn-primary":"blue-btn-plain-primary",'"\n onclick="document.getElementById(\'').concat(m,"').close()\"\n >\n ").concat(s,"\n </button>"):"",'\n <button\n type="submit"\n class="btn ').concat(i?"blue-btn-plain-primary":"btn-primary",'"\n >\n ').concat(r,'\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <form method="dialog" class="blue-modal-backdrop">\n <button>').concat(s,"</button>\n </form>\n </dialog>")),new Promise(e=>{var t;const o=document.getElementById(m),a=()=>{const n=document.getElementById(m);n&&n.remove()};null==o||o.showModal(),null==o||o.addEventListener("close",()=>{a(),e(!1)}),null==o||null===(t=o.querySelector(".modal-content > form"))||void 0===t||t.addEventListener("submit",t=>{t.preventDefault(),"ask"===n&&(o.close(),a(),e((null==o?void 0:o.querySelector("input")).value||"")),o.close(),a(),e(!0)})})}window.blueWeb=window.blueWeb||{},window.blueWeb.dialog={ask:async function(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return await l("ask",n,e)},tell:async function(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};await l("tell",n,e)},verify:async function(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return!0===await l("verify",n,e)}}})();
1
+ (()=>{"use strict";var n={762:(n,e,t)=>{function o(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}t.d(e,{Os:()=>a});const a=()=>o()+o()+"-"+o()+"-"+o()+"-"+o()+"-"+o()+o()+o()},786:(n,e,t)=>{t.d(e,{k:()=>a});const o={Cancel:["Cancel","Abbrechen"],Yes:["Yes","Ja"],No:["No","Nein"],Message:["Message","Nachricht"],"Toggle menu":["Toggle menu","Menü umschalten"],"Close all":["Close all","Alle schließen"],Error:["Error","Fehler"],Information:["Information","Information"],Loading:["Loading","Laden"],Successful:["Successful","Erfolgreich"]};function a(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0,t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;return e=e||navigator.language.toLowerCase().indexOf("de")>-1?"de-DE":"en-US",t=t||o,t[n]?e.indexOf("de-")>-1?t[n][1]:t[n][0]:n}}},e={};function t(o){var a=e[o];if(void 0!==a)return a.exports;var l=e[o]={exports:{}};return n[o](l,l.exports,t),l.exports}t.d=(n,e)=>{for(var o in e)t.o(e,o)&&!t.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:e[o]})},t.o=(n,e)=>Object.prototype.hasOwnProperty.call(n,e);var o=t(762),a=t(786);async function l(n,e){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},{title:l=(0,a.k)("Message"),icon:c,switchPrimaryBtn:i=!1,acceptBtnText:r=("verify"===n?(0,a.k)("Yes"):"OK"),cancelBtnText:s=("verify"===n?(0,a.k)("No"):(0,a.k)("Cancel")),inputType:d="text",defaultValue:u}="string"==typeof t?JSON.parse(t):t;const m=(0,o.Os)();return document.getElementById(m)||document.body.insertAdjacentHTML("beforeend",'<dialog class="blue-modal modal" id="'.concat(m,'" aria-labelledby="').concat(m,'-label">\n <div class="modal-dialog">\n <div class="modal-content">\n <form>\n <div class="modal-header">\n ').concat(c?'<div class="me-2">'.concat(c,"</div>"):"",'\n <h1 class="modal-title fs-5" id="').concat(m,'-label">').concat(l,'</h1>\n <button\n type="button"\n class="btn-close"\n aria-label="').concat(s,'"\n onclick="document.getElementById(\'').concat(m,'\').close()"\n ></button>\n </div>\n <div class="modal-body">\n ').concat("ask"===n?'<label for="'.concat(m,'-input">').concat(e,'</label>\n <input\n type="').concat(d,'"\n ').concat(void 0!==u?' value="'.concat(u,'"'):"",'\n id="').concat(m,'-input"\n class="form-control mt-3"\n />'):e,'\n </div>\n <div class="modal-footer">\n ').concat("verify"===n||"ask"===n?'<button\n type="button"\n class="btn '.concat(i?"btn-primary":"blue-btn-plain-primary",'"\n onclick="document.getElementById(\'').concat(m,"').close()\"\n >\n ").concat(s,"\n </button>"):"",'\n <button\n type="submit"\n class="btn ').concat(i?"blue-btn-plain-primary":"btn-primary",'"\n >\n ').concat(r,'\n </button>\n </div>\n </form>\n </div>\n </div>\n\n <form method="dialog" class="blue-modal-backdrop">\n <button>').concat(s,"</button>\n </form>\n </dialog>")),new Promise(e=>{var t;const o=document.getElementById(m),a=()=>{const n=document.getElementById(m);n&&n.remove()};null==o||o.showModal(),null==o||o.addEventListener("close",()=>{a(),e(!1)}),null==o||null===(t=o.querySelector(".modal-content > form"))||void 0===t||t.addEventListener("submit",t=>{t.preventDefault(),"ask"===n&&(o.close(),a(),e((null==o?void 0:o.querySelector("input")).value||"")),o.close(),a(),e(!0)})})}window.blueWeb=window.blueWeb||{},window.blueWeb.dialog={ask:async function(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return await l("ask",n,e)},tell:async function(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};await l("tell",n,e)},verify:async function(n){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return!0===await l("verify",n,e)}}})();
@@ -0,0 +1,129 @@
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
+ import { DxfViewer as DxfViewerLib } from "dxf-viewer";
5
+ export class DxfViewer extends HTMLElement {
6
+ constructor() {
7
+ super(...arguments);
8
+ _defineProperty(this, "viewer", null);
9
+ _defineProperty(this, "container", null);
10
+ _defineProperty(this, "resizeObserver", null);
11
+ _defineProperty(this, "THREE", null);
12
+ }
13
+ static get observedAttributes() {
14
+ return ["src", "clear-color", "auto-resize"];
15
+ }
16
+ async connectedCallback() {
17
+ if (!this.THREE) {
18
+ this.THREE = await import("three");
19
+ }
20
+ this.render();
21
+ this.loadDxf();
22
+ }
23
+ disconnectedCallback() {
24
+ this.cleanup();
25
+ }
26
+ attributeChangedCallback(name, oldValue, newValue) {
27
+ if (oldValue === newValue) return;
28
+ if (name === "src") {
29
+ this.loadDxf();
30
+ }
31
+ }
32
+ render() {
33
+ this.container = document.createElement("div");
34
+ this.container.style.width = "100%";
35
+ this.container.style.height = "100%";
36
+ this.container.style.minHeight = "400px";
37
+ this.appendChild(this.container);
38
+ if (this.getAttribute("auto-resize") !== "false") {
39
+ this.resizeObserver = new ResizeObserver(() => {
40
+ if (this.viewer && this.container) {
41
+ this.viewer.SetSize(this.container.clientWidth, this.container.clientHeight);
42
+ }
43
+ });
44
+ this.resizeObserver.observe(this.container);
45
+ }
46
+ }
47
+ async loadDxf() {
48
+ if (!this.container) return;
49
+ const src = this.getAttribute("src");
50
+ if (!src) return;
51
+ try {
52
+ if (this.viewer) {
53
+ this.viewer.Destroy();
54
+ this.viewer = null;
55
+ }
56
+ this.container.innerHTML = "";
57
+ this.viewer = new DxfViewerLib(this.container, {
58
+ clearColor: this.parseClearColor(this.getAttribute("clear-color") || "#ffffff"),
59
+ autoResize: this.getAttribute("auto-resize") !== "false",
60
+ sceneOptions: {
61
+ wireframeMesh: this.getAttribute("wireframe") === "true"
62
+ }
63
+ });
64
+ const fontsAttr = this.getAttribute("fonts");
65
+ const fonts = fontsAttr ? fontsAttr.split(",").map(f => f.trim()) : null;
66
+ await this.viewer.Load({
67
+ url: src,
68
+ fonts: fonts
69
+ });
70
+ this.viewer.Subscribe("loaded", () => {
71
+ this.dispatchEvent(new CustomEvent("dxf-loaded", {
72
+ detail: {
73
+ viewer: this.viewer
74
+ }
75
+ }));
76
+ });
77
+ this.viewer.Subscribe("message", event => {
78
+ console.log("DXF Viewer message:", event.message);
79
+ });
80
+ } catch (error) {
81
+ console.error("Error loading DXF file:", error);
82
+ this.dispatchEvent(new CustomEvent("dxf-error", {
83
+ detail: {
84
+ error
85
+ }
86
+ }));
87
+ }
88
+ }
89
+ parseClearColor(color) {
90
+ if (!this.THREE) return null;
91
+ if (!color) return new this.THREE.Color(0xffffff);
92
+ return new this.THREE.Color(color);
93
+ }
94
+ cleanup() {
95
+ if (this.resizeObserver) {
96
+ this.resizeObserver.disconnect();
97
+ this.resizeObserver = null;
98
+ }
99
+ if (this.viewer) {
100
+ this.viewer.Destroy();
101
+ this.viewer = null;
102
+ }
103
+ }
104
+ getViewer() {
105
+ return this.viewer;
106
+ }
107
+ async reload() {
108
+ await this.loadDxf();
109
+ }
110
+ showLayer(name, show) {
111
+ if (this.viewer) {
112
+ this.viewer.ShowLayer(name, show);
113
+ }
114
+ }
115
+ fitView(minX, maxX, minY, maxY) {
116
+ let padding = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
117
+ if (this.viewer) {
118
+ this.viewer.FitView(minX, maxX, minY, maxY, padding);
119
+ }
120
+ }
121
+ getLayers() {
122
+ return this.viewer ? Array.from(this.viewer.GetLayers()) : [];
123
+ }
124
+ getBounds() {
125
+ var _this$viewer;
126
+ return ((_this$viewer = this.viewer) === null || _this$viewer === void 0 ? void 0 : _this$viewer.GetBounds()) || null;
127
+ }
128
+ }
129
+ customElements.define("dxf-viewer", DxfViewer);
@@ -1 +1 @@
1
- (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML='<slot style="border-radius: inherit"></slot>',this.activeIndex=-1,this.items=[],this.inputElement=null}connectedCallback(){this.setAttribute("role","listbox"),this.tabIndex=-1,this.updateItems();const t=this.getAttribute("for");this.inputElement=t?document.getElementById(t):null,this.inputElement&&(this.inputElement.setAttribute("role","combobox"),this.inputElement.setAttribute("aria-controls",this.id),this.inputElement.setAttribute("aria-expanded","true"),this.inputElement.addEventListener("keydown",this.onKeyDown.bind(this))),this.addEventListener("keydown",this.onKeyDown.bind(this)),this.addEventListener("click",t=>{const e=t.target instanceof Element?t.target.closest("[data-blue-select-list-index]"):null;if(e&&e.hasAttribute("data-blue-select-list-index")){const t=Number(e.getAttribute("data-blue-select-list-index"));this.select(t)}})}updateItems(){this.items=Array.from(this.children),this.items.forEach((t,e)=>{t.hasAttribute("id")||t.setAttribute("id","".concat(this.id,"-option-").concat(e)),t.setAttribute("data-blue-select-list-index",e.toString()),t.setAttribute("aria-selected","false"),t.setAttribute("role","option"),t.tabIndex=-1})}onKeyDown(t){if(this.items.length)if("ArrowDown"===t.key)t.preventDefault(),this.activeIndex=(this.activeIndex+1)%this.items.length,this.updateActiveItem();else if("ArrowUp"===t.key)t.preventDefault(),this.activeIndex=(this.activeIndex-1+this.items.length)%this.items.length,this.updateActiveItem();else if("Enter"===t.key&&this.activeIndex>=0){const t=this.items[this.activeIndex];null==t||t.click()}}updateActiveItem(){this.items.forEach((t,e)=>{const i=e===this.activeIndex;t.classList.toggle("active",i),t.setAttribute("aria-selected",i.toString())});const t=this.items[this.activeIndex];t&&this.inputElement&&(this.inputElement.setAttribute("aria-activedescendant",t.id),t.scrollIntoView({block:"nearest"}))}select(t){this.activeIndex=t,this.updateActiveItem();const e=this.items[t];e&&(this.dispatchEvent(new CustomEvent("bl-select",{detail:{index:t,item:e},bubbles:!0,composed:!0})),e.click())}}customElements.define("bl-select-list",t)})();
1
+ (()=>{"use strict";var t={};function e(t,e,i){return(e=function(t){var e=function(t){if("object"!=typeof t||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,"string");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}t.d=(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},t.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class i extends Event{constructor(t,e){super(i.eventName,{bubbles:!0,composed:!0}),this.index=t,this.item=e}}e(i,"eventName","bl-select");class s extends HTMLElement{constructor(){super(),e(this,"handleChildrenChanged",()=>{var t;const e=null===(t=this.items[this.activeIndex])||void 0===t?void 0:t.id;if(this.updateItems(),e){const t=this.items.findIndex(t=>t.id===e);this.activeIndex=t>=0?t:-1}else this.activeIndex=-1;this.updateActiveItem()}),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML='<slot style="border-radius: inherit"></slot>',this.activeIndex=-1,this.items=[],this.inputElement=null,this.slotElement=null,this.observer=null}get activeClass(){return this.getAttribute("active-class")||"active"}connectedCallback(){var t,e;this.setAttribute("role","listbox"),this.tabIndex=-1,this.updateItems(),this.syncActiveIndexFromDataSelected(),this.updateActiveItem();const i=this.getAttribute("for");this.inputElement=i?document.getElementById(i):null,this.inputElement&&(this.inputElement.setAttribute("role","combobox"),this.inputElement.setAttribute("aria-controls",this.id),this.inputElement.setAttribute("aria-expanded","true"),this.inputElement.addEventListener("keydown",this.onKeyDown.bind(this))),this.addEventListener("keydown",this.onKeyDown.bind(this)),this.addEventListener("click",t=>{const e=t.target instanceof Element?t.target.closest("[data-select-list-index]"):null;if(e&&e.hasAttribute("data-select-list-index")){const t=Number(e.getAttribute("data-select-list-index"));this.select(t)}}),this.observer=new MutationObserver(t=>{t.some(t=>"childList"===t.type)&&this.handleChildrenChanged(),t.some(t=>"attributes"===t.type&&"data-selected"===t.attributeName)&&(this.syncActiveIndexFromDataSelected(),this.updateActiveItem())}),this.observer.observe(this,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-selected"]}),this.slotElement=null===(t=this.shadowRoot)||void 0===t?void 0:t.querySelector("slot"),null===(e=this.slotElement)||void 0===e||e.addEventListener("slotchange",this.handleChildrenChanged)}disconnectedCallback(){var t,e;null===(t=this.observer)||void 0===t||t.disconnect(),this.observer=null,null===(e=this.slotElement)||void 0===e||e.removeEventListener("slotchange",this.handleChildrenChanged)}syncActiveIndexFromDataSelected(){const t=this.items.findIndex(t=>t.hasAttribute("data-selected"));t>=0&&(this.activeIndex=t)}updateItems(){const t=["button:not([disabled])","a[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])",'[tabindex]:not([tabindex="-1"])','[role="option"]'].join(", ");this.items=Array.from(this.querySelectorAll(t)),this.items.forEach((t,e)=>{t.hasAttribute("id")||t.setAttribute("id","".concat(this.id,"-option-").concat(e)),t.setAttribute("data-select-list-index",e.toString()),t.setAttribute("aria-selected","false"),t.setAttribute("role","option"),t.tabIndex=-1})}onKeyDown(t){if(this.items.length)if("ArrowDown"===t.key)t.preventDefault(),this.activeIndex=(this.activeIndex+1)%this.items.length,this.updateActiveItem();else if("ArrowUp"===t.key)t.preventDefault(),this.activeIndex=(this.activeIndex-1+this.items.length)%this.items.length,this.updateActiveItem();else if("Enter"===t.key&&this.activeIndex>=0){t.preventDefault();const e=this.items[this.activeIndex];null==e||e.click()}}updateActiveItem(){const t=this.activeClass.split(" ");this.items.forEach((e,i)=>{const s=i===this.activeIndex;t.forEach(t=>{e.classList.toggle(t,s)}),e.setAttribute("aria-selected",s.toString())});const e=this.items[this.activeIndex];e&&this.inputElement?(this.inputElement.setAttribute("aria-activedescendant",e.id),e.scrollIntoView({block:"nearest"})):this.inputElement&&this.inputElement.removeAttribute("aria-activedescendant")}select(t){this.activeIndex=t,this.items.forEach(t=>t.removeAttribute("data-selected"));const e=this.items[t];e&&(e.setAttribute("data-selected",""),this.dispatchEvent(new i(t,e)),this.updateActiveItem())}}customElements.get("bl-select-list")||customElements.define("bl-select-list",s)})();
@@ -1,3 +1,9 @@
1
+ declare class BlSelectEvent extends Event {
2
+ static readonly eventName = "bl-select";
3
+ readonly index: number;
4
+ readonly item: HTMLElement;
5
+ constructor(index: number, item: HTMLElement);
6
+ }
1
7
  /**
2
8
  * A Web Component that provides a keyboard-accessible selectable list, typically used for dropdowns or autocomplete lists.
3
9
  * Together with `popover` and CSS Anchoring, it's also useful to create a dropdown list.
@@ -5,22 +11,29 @@
5
11
  *
6
12
  * The Web Component will automatically set attributes for accessibility.
7
13
  *
8
- * @element blue-select-list
14
+ * @element bl-select-list
9
15
  * @attr {string} for - The id of the input element to associate as the combobox controller.
16
+ * @attr {string} active-class - The CSS class name to apply to the active item (default: "active").
10
17
  * @slot - The list options.
11
18
  * @example
12
19
  * <input id="my-input" />
13
- * <blue-select-list for="my-input">
20
+ * <bl-select-list for="my-input">
14
21
  * <div>Option 1</div>
15
22
  * <div>Option 2</div>
16
- * </blue-select-list>
23
+ * </bl-select-list>
17
24
  */
18
- export declare class SelectList extends HTMLElement {
25
+ declare class SelectList extends HTMLElement {
19
26
  activeIndex: number;
20
27
  items: HTMLElement[];
21
28
  inputElement: HTMLElement | null;
29
+ slotElement: HTMLSlotElement | null;
30
+ observer: MutationObserver | null;
22
31
  constructor();
32
+ get activeClass(): string;
23
33
  connectedCallback(): void;
34
+ disconnectedCallback(): void;
35
+ handleChildrenChanged: () => void;
36
+ syncActiveIndexFromDataSelected(): void;
24
37
  updateItems(): void;
25
38
  onKeyDown(e: {
26
39
  key: string;
@@ -29,3 +42,5 @@ export declare class SelectList extends HTMLElement {
29
42
  updateActiveItem(): void;
30
43
  select(index: number): void;
31
44
  }
45
+ export { SelectList, BlSelectEvent };
46
+ export default SelectList;
@@ -1,3 +1,17 @@
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
+ class BlSelectEvent extends Event {
5
+ constructor(index, item) {
6
+ super(BlSelectEvent.eventName, {
7
+ bubbles: true,
8
+ composed: true
9
+ });
10
+ this.index = index;
11
+ this.item = item;
12
+ }
13
+ }
14
+
1
15
  /**
2
16
  * A Web Component that provides a keyboard-accessible selectable list, typically used for dropdowns or autocomplete lists.
3
17
  * Together with `popover` and CSS Anchoring, it's also useful to create a dropdown list.
@@ -5,19 +19,33 @@
5
19
  *
6
20
  * The Web Component will automatically set attributes for accessibility.
7
21
  *
8
- * @element blue-select-list
22
+ * @element bl-select-list
9
23
  * @attr {string} for - The id of the input element to associate as the combobox controller.
24
+ * @attr {string} active-class - The CSS class name to apply to the active item (default: "active").
10
25
  * @slot - The list options.
11
26
  * @example
12
27
  * <input id="my-input" />
13
- * <blue-select-list for="my-input">
28
+ * <bl-select-list for="my-input">
14
29
  * <div>Option 1</div>
15
30
  * <div>Option 2</div>
16
- * </blue-select-list>
31
+ * </bl-select-list>
17
32
  */
18
- export class SelectList extends HTMLElement {
33
+ _defineProperty(BlSelectEvent, "eventName", "bl-select");
34
+ class SelectList extends HTMLElement {
19
35
  constructor() {
20
36
  super();
37
+ _defineProperty(this, "handleChildrenChanged", () => {
38
+ var _this$items$this$acti;
39
+ const previousActiveId = (_this$items$this$acti = this.items[this.activeIndex]) === null || _this$items$this$acti === void 0 ? void 0 : _this$items$this$acti.id;
40
+ this.updateItems();
41
+ if (previousActiveId) {
42
+ const newIndex = this.items.findIndex(el => el.id === previousActiveId);
43
+ this.activeIndex = newIndex >= 0 ? newIndex : -1;
44
+ } else {
45
+ this.activeIndex = -1;
46
+ }
47
+ this.updateActiveItem();
48
+ });
21
49
  this.attachShadow({
22
50
  mode: "open"
23
51
  });
@@ -25,13 +53,19 @@ export class SelectList extends HTMLElement {
25
53
  this.activeIndex = -1;
26
54
  this.items = [];
27
55
  this.inputElement = null;
56
+ this.slotElement = null;
57
+ this.observer = null;
58
+ }
59
+ get activeClass() {
60
+ return this.getAttribute("active-class") || "active";
28
61
  }
29
62
  connectedCallback() {
63
+ var _this$shadowRoot, _this$slotElement;
30
64
  this.setAttribute("role", "listbox");
31
65
  this.tabIndex = -1;
32
66
  this.updateItems();
33
-
34
- // Input zuweisen über Attribut oder fallback
67
+ this.syncActiveIndexFromDataSelected();
68
+ this.updateActiveItem();
35
69
  const inputId = this.getAttribute("for");
36
70
  this.inputElement = inputId ? document.getElementById(inputId) : null;
37
71
  if (this.inputElement) {
@@ -42,20 +76,50 @@ export class SelectList extends HTMLElement {
42
76
  }
43
77
  this.addEventListener("keydown", this.onKeyDown.bind(this));
44
78
  this.addEventListener("click", e => {
45
- const target = e.target instanceof Element ? e.target.closest("[data-blue-select-list-index]") : null;
46
- if (target && target.hasAttribute("data-blue-select-list-index")) {
47
- const index = Number(target.getAttribute("data-blue-select-list-index"));
79
+ const target = e.target instanceof Element ? e.target.closest("[data-select-list-index]") : null;
80
+ if (target && target.hasAttribute("data-select-list-index")) {
81
+ const index = Number(target.getAttribute("data-select-list-index"));
48
82
  this.select(index);
49
83
  }
50
84
  });
85
+ this.observer = new MutationObserver(mutations => {
86
+ if (mutations.some(m => m.type === "childList")) {
87
+ this.handleChildrenChanged();
88
+ }
89
+ if (mutations.some(m => m.type === "attributes" && m.attributeName === "data-selected")) {
90
+ this.syncActiveIndexFromDataSelected();
91
+ this.updateActiveItem();
92
+ }
93
+ });
94
+ this.observer.observe(this, {
95
+ childList: true,
96
+ subtree: true,
97
+ attributes: true,
98
+ attributeFilter: ["data-selected"]
99
+ });
100
+ this.slotElement = (_this$shadowRoot = this.shadowRoot) === null || _this$shadowRoot === void 0 ? void 0 : _this$shadowRoot.querySelector("slot");
101
+ (_this$slotElement = this.slotElement) === null || _this$slotElement === void 0 || _this$slotElement.addEventListener("slotchange", this.handleChildrenChanged);
102
+ }
103
+ disconnectedCallback() {
104
+ var _this$observer, _this$slotElement2;
105
+ (_this$observer = this.observer) === null || _this$observer === void 0 || _this$observer.disconnect();
106
+ this.observer = null;
107
+ (_this$slotElement2 = this.slotElement) === null || _this$slotElement2 === void 0 || _this$slotElement2.removeEventListener("slotchange", this.handleChildrenChanged);
108
+ }
109
+ syncActiveIndexFromDataSelected() {
110
+ const selectedIndex = this.items.findIndex(el => el.hasAttribute("data-selected"));
111
+ if (selectedIndex >= 0) {
112
+ this.activeIndex = selectedIndex;
113
+ }
51
114
  }
52
115
  updateItems() {
53
- this.items = Array.from(this.children);
116
+ const selectableSelectors = ["button:not([disabled])", "a[href]", "input:not([disabled])", "select:not([disabled])", "textarea:not([disabled])", '[tabindex]:not([tabindex="-1"])', '[role="option"]'].join(", ");
117
+ this.items = Array.from(this.querySelectorAll(selectableSelectors));
54
118
  this.items.forEach((el, i) => {
55
119
  if (!el.hasAttribute("id")) {
56
120
  el.setAttribute("id", "".concat(this.id, "-option-").concat(i));
57
121
  }
58
- el.setAttribute("data-blue-select-list-index", i.toString());
122
+ el.setAttribute("data-select-list-index", i.toString());
59
123
  el.setAttribute("aria-selected", "false");
60
124
  el.setAttribute("role", "option");
61
125
  el.tabIndex = -1;
@@ -72,14 +136,18 @@ export class SelectList extends HTMLElement {
72
136
  this.activeIndex = (this.activeIndex - 1 + this.items.length) % this.items.length;
73
137
  this.updateActiveItem();
74
138
  } else if (e.key === "Enter" && this.activeIndex >= 0) {
139
+ e.preventDefault();
75
140
  const item = this.items[this.activeIndex];
76
141
  item === null || item === void 0 || item.click();
77
142
  }
78
143
  }
79
144
  updateActiveItem() {
145
+ const activeClassNames = this.activeClass.split(" ");
80
146
  this.items.forEach((el, i) => {
81
147
  const active = i === this.activeIndex;
82
- el.classList.toggle("active", active);
148
+ activeClassNames.forEach(activeClassName => {
149
+ el.classList.toggle(activeClassName, active);
150
+ });
83
151
  el.setAttribute("aria-selected", active.toString());
84
152
  });
85
153
  const activeItem = this.items[this.activeIndex];
@@ -88,24 +156,23 @@ export class SelectList extends HTMLElement {
88
156
  activeItem.scrollIntoView({
89
157
  block: "nearest"
90
158
  });
159
+ } else if (this.inputElement) {
160
+ this.inputElement.removeAttribute("aria-activedescendant");
91
161
  }
92
162
  }
93
163
  select(index) {
94
164
  this.activeIndex = index;
95
- this.updateActiveItem();
165
+ this.items.forEach(el => el.removeAttribute("data-selected"));
96
166
  const selectedItem = this.items[index];
97
167
  if (selectedItem) {
98
- // Fire a custom event with the selected item and index
99
- this.dispatchEvent(new CustomEvent("bl-select", {
100
- detail: {
101
- index,
102
- item: selectedItem
103
- },
104
- bubbles: true,
105
- composed: true
106
- }));
107
- selectedItem.click();
168
+ selectedItem.setAttribute("data-selected", "");
169
+ this.dispatchEvent(new BlSelectEvent(index, selectedItem));
170
+ this.updateActiveItem();
108
171
  }
109
172
  }
110
173
  }
111
- customElements.define("bl-select-list", SelectList);
174
+ if (!customElements.get("bl-select-list")) {
175
+ customElements.define("bl-select-list", SelectList);
176
+ }
177
+ export { SelectList, BlSelectEvent };
178
+ export default SelectList;
package/dist/js/shared.js CHANGED
@@ -6,7 +6,9 @@ const phrases = {
6
6
  "Toggle menu": ["Toggle menu", "Menü umschalten"],
7
7
  "Close all": ["Close all", "Alle schließen"],
8
8
  Error: ["Error", "Fehler"],
9
- Information: ["Information", "Information"]
9
+ Information: ["Information", "Information"],
10
+ Loading: ["Loading", "Laden"],
11
+ Successful: ["Successful", "Erfolgreich"]
10
12
  };
11
13
  export function getPhrase(keyword) {
12
14
  let countryCode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;