@popovandrii/ui-elements 0.2.1 → 0.4.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 CHANGED
@@ -10,6 +10,7 @@ Lightweight TypeScript UI component library — **SpinBox**, **Select** (with se
10
10
  - SPA-friendly lifecycle: idempotent `scan()`, optional root scoping and `MutationObserver` auto re-scan, teardown-only `destroy()`
11
11
  - Custom DOM events + programmatic `setValue`
12
12
  - Ripple and flash animations (opt-out per element)
13
+ - Themed label tooltip (`.UIql`) with optional viewport-aware auto-flip
13
14
  - Ships as ES, CJS and UMD bundles with type declarations
14
15
 
15
16
  ## Components
@@ -73,6 +74,13 @@ Theming has two layers:
73
74
  - **`theme-*.css`** — optional. Each provides one palette scoped under a higher-specificity
74
75
  `html[data-theme="..."]` selector, so it overrides the `:root` default whenever the matching
75
76
  `data-theme` is set — regardless of CSS import order.
77
+ - **`base.css`** — optional, opt-in. A small page normalize/reset (body, headings, links, form
78
+ controls, tables…). It is **not** bundled into `style.css` so importing the components never
79
+ restyles your page; import it only if you want the reset, alongside `style.css`/a theme.
80
+
81
+ When no `data-theme` is set, `style.css` also follows the OS via
82
+ `@media (prefers-color-scheme: dark)`, so the dark palette applies automatically in dark mode.
83
+ Any explicit `data-theme` always wins over this fallback.
76
84
 
77
85
  Zero-config (light theme, no `data-theme` needed):
78
86
 
@@ -85,6 +93,7 @@ Add theme files only when you need other palettes or runtime switching:
85
93
  ```js
86
94
  import "@popovandrii/ui-elements/style.css"; // required base (also = light default)
87
95
 
96
+ // import "@popovandrii/ui-elements/base.css"; // optional opt-in page normalize/reset
88
97
  // import "@popovandrii/ui-elements/theme-dark.css";
89
98
  // import "@popovandrii/ui-elements/theme-light-neon.css";
90
99
  // import "@popovandrii/ui-elements/theme-dark-neon.css";
@@ -191,6 +200,11 @@ document.addEventListener("ui-select-change", (e) => {
191
200
 
192
201
  ## Programmatic `setValue`
193
202
 
203
+ Every component shares one signature: `setValue(el, value, options?)`, where `el`
204
+ is the component's root element and `options` is `{ silent?, flash? }` — `silent: true`
205
+ suppresses the change event, `flash: false` skips the flash animation (both default off /
206
+ on respectively). Button additionally accepts `{ label }`.
207
+
194
208
  ```js
195
209
  const sp = new SpinBox();
196
210
  sp.setValue(document.getElementById("mySpinbox"), 3.1415);
@@ -199,13 +213,16 @@ const sl = new Select();
199
213
  sl.setValue(document.getElementById("mySelect"), "name"); // matches data-value
200
214
 
201
215
  const sw = new Switch();
202
- sw.setValue("idSwitchElement", true); // (inputId, boolean)
216
+ sw.setValue(document.getElementById("mySwitch"), true); // (el, boolean)
203
217
 
204
218
  const bg = new ButtonGroup();
205
219
  bg.setValue(document.getElementById("myGroup"), "btncheck2"); // matches input[value]
206
220
 
207
221
  const btn = new Button();
208
- btn.setValue(document.getElementById("myButton"), "/api/users/42", "Edit profile"); // value + optional label
222
+ btn.setValue(document.getElementById("myButton"), "/api/users/42", { label: "Edit profile" });
223
+
224
+ // Quiet bulk fill — write the value without emitting or flashing:
225
+ sl.setValue(document.getElementById("mySelect"), "name", { silent: true, flash: false });
209
226
  ```
210
227
 
211
228
  ## Lifecycle (SPA-friendly)
@@ -285,6 +302,52 @@ Opt out per element or for any ancestor container:
285
302
  <body class="ui-no-ripple ui-no-flash">
286
303
  ```
287
304
 
305
+ ## Label tooltip (`.UIql`)
306
+
307
+ A small question-mark icon with a hover/focus tooltip you can drop into any
308
+ component label. It's pure CSS — the visible hint text lives in the inner
309
+ `<span>`:
310
+
311
+ ```html
312
+ <div class="UIsp-label">
313
+ Amount
314
+ <span class="UIql" tabindex="0" aria-label="Help">
315
+ <span class="UIql__text" role="tooltip">Your hint goes here.</span>
316
+ </span>
317
+ </div>
318
+ ```
319
+
320
+ - **Themed automatically** — nested in any component (spin box, switch, select,
321
+ button, button-group) the circle and bubble inherit that component's color;
322
+ standalone they fall back to grey. Override the `--ql-*` custom properties
323
+ (`--ql-bg`, `--ql-fg`, `--ql-border`, `--ql-tip-bg`, `--ql-tip-fg`) to retheme.
324
+ - **Opens on hover and keyboard focus**, and a mouse click keeps it open until
325
+ you click away (`tabindex="0"` is required for the focus/click behavior).
326
+ - **Stays on screen** — the bubble is capped to the viewport width. Near a
327
+ viewport edge, add `.UIql--right` (opens right, for icons near the left edge)
328
+ or `.UIql--left` (opens left, for icons near the right edge).
329
+
330
+ ### Auto-flip the tooltip (optional)
331
+
332
+ To place those edge modifiers automatically, call `initQuestionTooltips()`
333
+ **once**. It attaches one delegated listener pair to a root (`document` by
334
+ default), so every `.UIql` — including ones added to the DOM later — is handled
335
+ with no per-element wiring. Before a tooltip opens it measures the room on each
336
+ side, flips the bubble inward if needed, and caps its width to the available
337
+ space (re-adapting on resize):
338
+
339
+ ```js
340
+ import { initQuestionTooltips } from "@popovandrii/ui-elements";
341
+
342
+ const teardown = initQuestionTooltips(); // whole page
343
+ // initQuestionTooltips(myDialog); // or scope to a container
344
+ // teardown(); // remove the listeners
345
+ ```
346
+
347
+ It's optional — the CSS works on its own; the helper just sets the modifiers for
348
+ you (pure CSS can't detect the viewport edge across all browsers). With the UMD
349
+ build it's `UiElements.initQuestionTooltips()`.
350
+
288
351
  ## Usage without a bundler (NodeJS + Express, UMD)
289
352
 
290
353
  Serve the package's `dist` folder as static assets:
@@ -326,6 +389,8 @@ examples:
326
389
  - [ButtonGroup (radio)](docs/button-group-radio/README.md) — radio group styled as buttons
327
390
  - [Button](docs/button/README.md) — styled button / link with event dispatch
328
391
 
392
+ The shared [label tooltip (`.UIql`)](#label-tooltip-uiql) works with any of them.
393
+
329
394
  <p align="center">
330
395
  <img src="https://gitlab.com/AndreyPopov/ui-elements/-/raw/main/docs/images/button-group-UI.png" alt="ButtonGroup Preview" width="700">
331
396
  </p>
@@ -366,10 +431,15 @@ npm publish --access public
366
431
  npm info @popovandrii/ui-elements@latest
367
432
  ```
368
433
 
434
+ `npm publish` runs the `prepublishOnly` script (`node build.js`) automatically, so a
435
+ fresh `dist/` is always built before the tarball is packed — no manual build step
436
+ needed. (`npm pack` does **not** run it; build manually if you pack by hand.)
437
+
369
438
  ### Releasing
370
439
 
371
- `dist/` is git-ignored, so always build before packing or publishing. Tags use the
372
- `vX.Y.Z` scheme and point at the merge commit on `main`.
440
+ `dist/` is git-ignored and never committed it is generated at publish time by
441
+ `prepublishOnly`. Tags use the `vX.Y.Z` scheme and point at the merge commit on
442
+ `main`.
373
443
 
374
444
  ```sh
375
445
  # 1. Bump the version on dev (no auto-tag — we tag on main after the merge)
@@ -384,7 +454,7 @@ git fetch origin
384
454
  git tag -a v0.2.0 origin/main -m "Release 0.2.0"
385
455
  git push origin v0.2.0
386
456
 
387
- # 4. Build and publish to npm — see "Publishing" above
457
+ # 4. Publish to npm (dist/ is built automatically) — see "Publishing" above
388
458
  ```
389
459
 
390
460
  On GitLab, create the release from **Deploy → Releases → New release**, pick the
package/dist/Button.d.ts CHANGED
@@ -18,7 +18,22 @@ export declare class Button {
18
18
  constructor(selectors?: Partial<SelectorMap>, debug?: boolean, options?: InitOptions);
19
19
  /** Watch the root for added/removed nodes and re-scan (debounced). */
20
20
  private observe;
21
- setValue(el: HTMLElement, value: string, label?: string): void;
21
+ /**
22
+ * Sets the button's value (and, for an anchor, its `href`).
23
+ *
24
+ * Unified `setValue(el, value, options)` signature shared across components.
25
+ * Button emits no change event, so `silent` is accepted for signature
26
+ * parity but has no effect here.
27
+ * @param el The `.UIb` element to update.
28
+ * @param value New `data-value` (and `href` when `el` is an `<a>`).
29
+ * @param flash When `false`, the flash animation is skipped (default `true`).
30
+ * @param label Optional new text content for the button.
31
+ */
32
+ setValue(el: HTMLElement, value: string, { flash, label, }?: {
33
+ silent?: boolean;
34
+ flash?: boolean;
35
+ label?: string;
36
+ }): void;
22
37
  destroy(): void;
23
38
  private disableEl;
24
39
  private enableEl;
@@ -21,7 +21,19 @@ export declare class ButtonGroup {
21
21
  /** Watch the root for added/removed nodes and re-scan (debounced). */
22
22
  private observe;
23
23
  destroy(): void;
24
- setValue(el: HTMLElement, value: string): void;
24
+ /**
25
+ * Selects the option whose input `value` matches.
26
+ *
27
+ * Unified `setValue(el, value, options)` signature shared across components.
28
+ * @param el The `.UIbg` group element.
29
+ * @param value Value of the option to select.
30
+ * @param silent When `true`, the `ui-button-group-change` event is not emitted.
31
+ * @param flash When `false`, the flash animation is skipped (default `true`).
32
+ */
33
+ setValue(el: HTMLElement, value: string, { silent, flash, }?: {
34
+ silent?: boolean;
35
+ flash?: boolean;
36
+ }): void;
25
37
  /** Bind every not-yet-bound `.UIbg`. Safe to call repeatedly (SPA re-render). */
26
38
  scan(): void;
27
39
  private ripple;
package/dist/Select.d.ts CHANGED
@@ -36,12 +36,18 @@ export declare class Select {
36
36
  dispose(): void;
37
37
  private disableEl;
38
38
  /**
39
+ * Selects the option whose `data-value` matches.
39
40
  *
40
- * @param el ID elements
41
- * @param value string or number
42
- * @returns
41
+ * Unified `setValue(el, value, options)` signature shared across components.
42
+ * @param el The `.UIselect` element.
43
+ * @param value Value of the option to select.
44
+ * @param silent When `true`, the `ui-select-change` event is not emitted.
45
+ * @param flash When `false`, the flash animation is skipped (default `true`).
43
46
  */
44
- setValue(el: HTMLElement, value: string | number): void;
47
+ setValue(el: HTMLElement, value: string | number, { silent, flash, }?: {
48
+ silent?: boolean;
49
+ flash?: boolean;
50
+ }): void;
45
51
  /** Bind every not-yet-bound `.UIselect`. Safe to call repeatedly (SPA re-render). */
46
52
  scan(): void;
47
53
  private itemArrow;
package/dist/SpinBox.d.ts CHANGED
@@ -18,13 +18,45 @@ export declare class SpinBox {
18
18
  private root;
19
19
  private observer;
20
20
  private rescanTimer;
21
+ /**
22
+ * Per-element value applier registered during {@link scan}. Clamps to
23
+ * min/max, formats, syncs the +/- buttons and aria, and (unless silent)
24
+ * emits `ui-spinbox-change`. Reused by {@link setValue} and {@link refresh}
25
+ * so they share the exact same logic as the input `change` handler.
26
+ */
27
+ private valueControls;
21
28
  constructor(selectors?: Partial<SelectorMap>, debug?: boolean, options?: InitOptions);
22
29
  /** Watch the root for added/removed nodes and re-scan (debounced). */
23
30
  private observe;
24
31
  private state;
25
32
  destroy(): void;
26
33
  private disableEl;
27
- setValue(el: HTMLElement, value: string | number): void;
34
+ /**
35
+ * Programmatically set a spin box value.
36
+ *
37
+ * The value is always clamped to min/max and the +/- buttons are kept in
38
+ * sync. Two independent flags control the side-effects:
39
+ *
40
+ * - `silent` (default `false`) — when `true`, the `ui-spinbox-change` event
41
+ * is not emitted. Use it to fill a form from data without triggering
42
+ * consumer side-effects on every field.
43
+ * - `flash` (default `true`) — when `false`, the flash animation is skipped.
44
+ * Use it to suppress the glow by design, independently of the event.
45
+ *
46
+ * For a quiet bulk fill, combine both: `{ silent: true, flash: false }`.
47
+ */
48
+ setValue(el: HTMLElement, value: string | number, { silent, flash, }?: {
49
+ silent?: boolean;
50
+ flash?: boolean;
51
+ }): void;
52
+ /** Brief `box-shadow` glow on the element (unless an ancestor opts out). */
53
+ private playFlash;
54
+ /**
55
+ * Re-sync the +/- buttons (and aria) to the current input value without
56
+ * changing the value's meaning or emitting any event. Handy after the value
57
+ * was assigned directly to the input, bypassing {@link setValue}.
58
+ */
59
+ refresh(el: HTMLElement): void;
28
60
  getValidDataNumber: (el: HTMLElement, attr: string) => number;
29
61
  /** Bind every not-yet-bound `.UIsp`. Safe to call repeatedly (SPA re-render). */
30
62
  scan(): void;
package/dist/Switch.d.ts CHANGED
@@ -23,11 +23,18 @@ export declare class Switch {
23
23
  /** Bind every not-yet-bound `.UIsw`. Safe to call repeatedly (SPA re-render). */
24
24
  scan(): void;
25
25
  /**
26
- * Sets the state of a specific switch by its ID.
27
- * @param id ID of the internal input element
28
- * @param checked State (true/false)
26
+ * Sets the state of a switch element.
27
+ *
28
+ * Unified `setValue(el, value, options)` signature shared across components.
29
+ * @param el The `.UIsw` element to update.
30
+ * @param value New checked state (true/false).
31
+ * @param silent When `true`, the `ui-switch-change` event is not emitted.
32
+ * @param flash When `false`, the flash animation is skipped (default `true`).
29
33
  */
30
- setValue(id: string, value: boolean): void;
34
+ setValue(el: HTMLElement, value: boolean, { silent, flash, }?: {
35
+ silent?: boolean;
36
+ flash?: boolean;
37
+ }): void;
31
38
  private ripple;
32
39
  private customEvent;
33
40
  }
package/dist/base.css ADDED
@@ -0,0 +1 @@
1
+ body{background-color:var(--c-g-50);color:var(--c-g-950);padding:0;transition:background .4s}html{-webkit-text-size-adjust:100%;line-height:1.15}body{margin:0}main{display:block}h1{margin:.67em 0;font-size:2em}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace;font-size:1em}a{color:inherit;background-color:#0000;text-decoration:none}img{border-style:none}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}fieldset{border:1px solid var(--c-g-300);margin:0;padding:.35em .75em .625em}legend{padding:0}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}table{border-collapse:collapse;border-spacing:0}
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{selectors;spinBoxes=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIsp`,btn:`UIsp__btn`,input:`UIsp__input`,disabledBtn:`disabled`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}state=(e,t,n,r=0,i=0)=>{e==r||e<r?(t.classList.add(this.selectors.disabledBtn),t.disabled=!0):(t.classList.remove(this.selectors.disabledBtn),t.disabled=!1),i!==0&&(e==i||e>i?(n.classList.add(this.selectors.disabledBtn),n.disabled=!0):(n.classList.remove(this.selectors.disabledBtn),n.disabled=!1))};destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.spinBoxes?.forEach(e=>delete e.dataset.uispBound),this.spinBoxes=null,this.abortController=new AbortController}disableEl(e){let t=e.querySelector(`.${this.selectors.input}`),n=e.querySelectorAll(`.${this.selectors.btn}`);t&&(t.disabled=!0),n.forEach(e=>{e.classList.add(this.selectors.disabledBtn),e.disabled=!0}),e.setAttribute(`tabindex`,`-1`),e.setAttribute(`aria-disabled`,`true`)}setValue(e,t){let n=e.querySelector(`.${this.selectors.input}`);if(!n){this.debug&&console.warn(`UISpinBox: input not found`);return}n.value=String(t),n.dispatchEvent(new Event(`change`)),!e.closest(`.ui-no-flash`)&&(e.classList.remove(`UIsp--flash`),e.offsetWidth,e.classList.add(`UIsp--flash`),n.addEventListener(`animationend`,()=>e.classList.remove(`UIsp--flash`),{once:!0}))}getValidDataNumber=(e,t)=>{let n=e.getAttribute(`data-${t}`);return n===null||n.trim()===``||isNaN(Number(n))?0:Number(n)};scan(){this.spinBoxes=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.spinBoxes.forEach(t=>{if(t.dataset.uispBound)return;t.dataset.uispBound=`1`;let n,r=t.querySelectorAll(`.${this.selectors.btn}`),i=t.querySelector(`.${this.selectors.input}`);this.debug&&(r||console.log(`Buttons (${this.selectors.btn}) not found in container`),i||console.log(`Input (${this.selectors.input}) not found in container`));let a=r[0],o=r[1];i.disabled=!1,[a,o].forEach(e=>{e.classList.remove(this.selectors.disabledBtn),e.disabled=!1}),t.setAttribute(`tabindex`,`0`),t.removeAttribute(`aria-disabled`);let s=t.hasAttribute(`data-decimals`)?this.getValidDataNumber(t,`decimals`):this.getValidDataNumber(t,`step`),c=Math.min(Math.max(Math.trunc(s),0),100),l=this.getValidDataNumber(t,`min`),u=this.getValidDataNumber(t,`max`);if(t.hasAttribute(`data-disabled`)){Number(i.value)<=l&&(i.value=l.toFixed(c)),u===0?i.value=Number(i.value).toFixed(c):Number(i.value)>=u&&(i.value=u.toFixed(c)),this.disableEl(t),t.addEventListener(`click`,e=>{e.preventDefault(),e.stopImmediatePropagation()},{capture:!0,signal:e});return}let d=e=>{t.setAttribute(`aria-valuenow`,String(e)),t.setAttribute(`aria-valuetext`,`${e} items`)};Number(i.value)<=l&&(i.value=l.toFixed(c)),u===0?i.value=Number(i.value).toFixed(c):(Number(i.value)>=u&&(i.value=u.toFixed(c)),u&&t.setAttribute(`aria-valuemax`,u.toFixed(c))),l&&t.setAttribute(`aria-valuemin`,l.toFixed(c)),this.state(Number(i.value),a,o,l,u),d(i.value);let f=null,p=(e,t=1)=>{i.value=String(Math.abs(Number(i.value)));let n=parseFloat(i.value)||0;return n+=e*t/10**c,e===1&&u!==0&&n>u&&(n=u),e===-1&&n<l&&(n=l),i.value=n.toFixed(c),this.state(Number(i.value),a,o,l,u),d(i.value),i.value},m=(e,t=150)=>{f===null&&(f=window.setInterval(e,t))},h=()=>{f!==null&&(clearInterval(f),f=null)};o.addEventListener(`mousedown`,e=>{let t=e.shiftKey?3:1;m(()=>p(1,t))},{signal:e}),o.addEventListener(`touchstart`,()=>m(()=>p(1)),{signal:e}),[`mouseup`,`mouseleave`,`mouseout`,`touchend`,`touchcancel`].forEach(t=>{o.addEventListener(t,h,{signal:e})}),o.addEventListener(`click`,e=>{let t=e.shiftKey?3:1;f===null&&(n=p(1,t),this.ripple(o),this.customEvent(i,n))},{signal:e}),a.addEventListener(`click`,e=>{let t=e.shiftKey?3:1;f===null&&(n=p(-1,t),this.ripple(a),this.customEvent(i,n))},{signal:e}),a.addEventListener(`mousedown`,e=>{let t=e.shiftKey?3:1;m(()=>p(-1,t),100)},{signal:e}),a.addEventListener(`touchstart`,()=>m(()=>p(-1),100),{signal:e}),[`mouseup`,`mouseleave`,`mouseout`,`touchend`,`touchcancel`].forEach(t=>{a.addEventListener(t,h,{signal:e})}),i.addEventListener(`keydown`,e=>{let t=e.key,n=e.shiftKey?5:1;if([`Backspace`,`Delete`,`ArrowLeft`,`ArrowRight`,`Tab`,`Enter`,`Home`,`End`].includes(t)||(e.ctrlKey||e.metaKey)&&[`a`,`c`,`v`,`x`].includes(t.toLowerCase()))return;if([`e`,`+`,`-`].includes(t)){e.preventDefault();return}if(t===`ArrowUp`||t===`ArrowDown`){e.preventDefault(),p(t===`ArrowUp`?1:-1,n);return}let r=t===`,`?`.`:t,a=/^[0-9]$/.test(r),o=r===`.`,s=i.value.includes(`.`);(c===0&&!a||c>0&&!(a||o)||o&&s)&&e.preventDefault()},{signal:e}),i.addEventListener(`keyup`,e=>{(e.key===`ArrowUp`||e.key===`ArrowDown`)&&this.customEvent(i,i.value)},{signal:e}),i.addEventListener(`change`,()=>{Number(i.value)<l&&(i.value=l.toFixed(c)),Number(i.value)>u&&u!==0?i.value=u.toFixed(c):i.value=Number(i.value).toFixed(c),this.state(Number(i.value),a,o,l,u),this.customEvent(i,i.value)},{signal:e})})}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`ui-ripple`),e.offsetWidth,e.classList.add(`ui-ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`ui-ripple`),{once:!0}))}customEvent(e,t){let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.log(`CustomEvent: data.detail `,n.detail),e.dispatchEvent(new CustomEvent(`ui-spinbox-change`,n))}},t=class{selectors;main=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIsw`,label:`UIsw-label`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.main?.forEach(e=>delete e.dataset.uiswBound),this.main=null,this.abortController=new AbortController}scan(){this.main=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.main.forEach(t=>{if(t.dataset.uiswBound)return;t.dataset.uiswBound=`1`;let n=t.querySelector(`.${this.selectors.label}`),r=t.querySelector(`input`);n&&n.id&&t.setAttribute(`aria-labelledby`,n.id),t.hasAttribute(`data-originally-disabled`)||t.setAttribute(`data-originally-disabled`,String(r?.disabled??!1));let i=t.getAttribute(`data-originally-disabled`)===`true`;r&&(r.disabled=!1),t.setAttribute(`tabindex`,`0`),t.removeAttribute(`aria-disabled`),i&&(r&&(r.disabled=!0),t.setAttribute(`tabindex`,`-1`),t.setAttribute(`aria-disabled`,`true`),t.addEventListener(`click`,e=>{e.preventDefault(),e.stopImmediatePropagation()},{capture:!0,signal:e})),r&&(r.checked?t.setAttribute(`aria-checked`,`true`):t.setAttribute(`aria-checked`,`false`),r.addEventListener(`change`,()=>{t.setAttribute(`aria-checked`,String(r.checked)),this.customEvent(r,String(r.checked))},{signal:e}),t.addEventListener(`click`,e=>{if(e.target.tagName===`INPUT`)return;let n=e.target.closest(`label`);n||(r.checked=!r.checked),n||r.dispatchEvent(new Event(`change`));let i=t.querySelector(`.UIsw-slider`);i&&this.ripple(i)},{signal:e}),t.addEventListener(`keydown`,e=>{if(r.disabled)return;let n=null;if(e.key===`ArrowRight`?n=!0:e.key===`ArrowLeft`&&(n=!1),n!==null&&(e.preventDefault(),r.checked!==n)){r.checked=n,r.dispatchEvent(new Event(`change`));let e=t.querySelector(`.UIsw-slider`);e&&this.ripple(e)}},{signal:e}))})}setValue(e,t){this.main?.forEach(n=>{let r=n.querySelector(`input#${e}`);if(r){r.checked=t,this.debug&&console.log(`SetValue:`,r.checked),n.setAttribute(`aria-checked`,String(t)),this.customEvent(r,String(t));let e=n.querySelector(`.UIsw-slider`);e&&!n.closest(`.ui-no-flash`)&&(n.classList.remove(`UIsw--flash`),n.offsetWidth,n.classList.add(`UIsw--flash`),e.addEventListener(`animationend`,()=>n.classList.remove(`UIsw--flash`),{once:!0}))}})}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`ui-ripple`),e.offsetWidth,e.classList.add(`ui-ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`ui-ripple`),{once:!0}))}customEvent(e,t){let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.log(`CustomEvent:`,n.detail),e.dispatchEvent(new CustomEvent(`ui-switch-change`,n))}},n=class e{selectors;main=null;itemArrowInitialized=new WeakSet;abortController=new AbortController;globalAbortController=new AbortController;debug;root;observer=null;rescanTimer=null;selectMap=new Map;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={idPrefix:`UI-option-`,main:`UIselect`,selected:`UIselect-selected`,arrow:`UIselect-arrow`,optionsList:`UIselect-options`,search:`UIselect-options__search`,items:`UIselect-options__items`,flash:`UIselect--flash`,excludedItems:[`divider`,`test`]};this.selectors={...r,...e},this.scan(),this.initGlobalListener(this.selectors),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}filterExcluded(e,t){return Array.from(e).filter(e=>!t.some(t=>typeof t==`string`?e.classList.contains(t)||e.id===t:e===t))}filterSearch(e,t){let n=t.trim().toLowerCase();return e.filter(e=>{let t=e.dataset.value?.toLowerCase()||``,r=e.textContent?.toLowerCase()||``;return t.includes(n)||r.includes(n)})}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),e.closeAll(this.selectors),this.abortController.abort(),this.main?.forEach(e=>delete e.dataset.uiselBound),this.selectMap.clear(),this.itemArrowInitialized=new WeakSet,this.main=null,this.abortController=new AbortController}dispose(){this.destroy(),this.globalAbortController.abort()}disableEl(e){e.setAttribute(`tabindex`,`-1`),e.setAttribute(`aria-disabled`,`true`)}setValue(e,t){let n=this.selectMap.get(e);if(!n){this.debug&&console.warn(`UISelect: element not registered`);return}let{input:r,selected:i}=n,a=e.querySelector(`.${this.selectors.optionsList}`);if(!a)return;let o=Array.from(a.querySelectorAll(`.${this.selectors.items} ul li`)),s=this.filterExcluded(o,this.selectors.excludedItems),c=s.find(e=>String(e.dataset.value)===String(t));if(!c){this.debug&&console.warn(`UISelect: value "${t}" not found`);return}s.forEach(e=>e.removeAttribute(`aria-selected`)),c.setAttribute(`aria-selected`,`true`),i.textContent=c.textContent??``,r.value=String(t),r.setAttribute(`value`,String(t)),e.setAttribute(`aria-activedescendant`,c.id||`${this.selectors.idPrefix}${s.indexOf(c)}`),this.customEvent(e,String(t)),e.closest(`.ui-no-flash`)||(e.classList.remove(this.selectors.flash),e.offsetWidth,e.classList.add(this.selectors.flash),e.addEventListener(`animationend`,()=>e.classList.remove(this.selectors.flash),{once:!0}))}scan(){this.main=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.main.forEach(t=>{if(t.dataset.uiselBound)return;let n=t.querySelector(`input[type='hidden']`);try{if(!n)throw Error(`<input type="hidden" name="YourUniqueId">`)}catch(e){return console.warn(`Not found:`,e.message)}t.dataset.uiselBound=`1`;let r=t.querySelector(`.${this.selectors.selected}`),i=t.querySelector(`.${this.selectors.arrow}`),a=t.querySelector(`.${this.selectors.optionsList}`),o=t.querySelector(`.${this.selectors.search} input`);if(t.setAttribute(`tabindex`,`0`),t.removeAttribute(`aria-disabled`),t.hasAttribute(`data-disabled`)){this.disableEl(t),t.addEventListener(`click`,e=>{e.preventDefault(),e.stopImmediatePropagation()},{capture:!0,signal:e});return}this.selectMap.set(t,{input:n,selected:r}),i&&i.addEventListener(`click`,()=>{this.toggle(t,a)},{signal:e}),r.addEventListener(`click`,()=>{this.toggle(t,a)},{signal:e}),t.addEventListener(`click`,()=>{this.itemsPosition(a)},{signal:e});let s=a.querySelectorAll(`.${this.selectors.items} ul li`),c=this.filterExcluded(s,this.selectors.excludedItems),l=t.querySelector(`[aria-selected='true']`);l&&this.defaultSelect(t,l,r,n),o&&o.addEventListener(`input`,i=>{let o=i.target.value.trim(),l=o?new Set(this.filterSearch(c,o)):null;s.forEach(e=>{e.hidden=l?!l.has(e):!1}),this.itemArrow(t,a,r,n,e)},{signal:e}),this.itemArrow(t,a,r,n,e),this.items(t,a,c,r,n,e)})}itemArrow(e,t,n,r,i){if(this.itemArrowInitialized.has(e))return;this.itemArrowInitialized.add(e);let a=-1,o=n.textContent?n.textContent:``,s=e.querySelector(`.${this.selectors.search} input`);e.addEventListener(`keydown`,i=>{if(i.key===`Tab`){this.close(e,t);return}s&&s.focus();let c=Array.from(t.querySelectorAll(`.${this.selectors.optionsList} ul li`)),l=this.filterExcluded(c,this.selectors.excludedItems),u=l.length;if(u!==0)if(i.key===`ArrowDown`){i.preventDefault(),e.getAttribute(`aria-expanded`)===`false`&&this.toggle(e,t),a=(a+1)%u,n.textContent=l[a].textContent,l.forEach(e=>e.removeAttribute(`aria-selected`)),l[a].setAttribute(`aria-selected`,`true`);let r=l[a].id||`${this.selectors.idPrefix}${a}`;e.setAttribute(`aria-activedescendant`,r),l[a].scrollIntoView({block:`nearest`})}else if(i.key===`ArrowUp`){i.preventDefault(),a=(a-1+u)%u,n.textContent=l[a].textContent,l.forEach(e=>e.removeAttribute(`aria-selected`)),l[a].setAttribute(`aria-selected`,`true`);let t=l[a].id||`${this.selectors.idPrefix}${a}`;e.setAttribute(`aria-activedescendant`,t),l[a].scrollIntoView({block:`nearest`})}else if(i.key===`Enter`)if(i.preventDefault(),a>=0){n.textContent=l[a].textContent,l.forEach(e=>e.removeAttribute(`aria-selected`)),l[a].setAttribute(`aria-selected`,`true`);let i=l[a].id||`${this.selectors.idPrefix}${a}`;e.setAttribute(`aria-activedescendant`,i),r.value=String(l[a].dataset.value),this.customEvent(e,r.value),this.close(e,t)}else this.toggle(e,t);else i.key===`Escape`&&(e.getAttribute(`aria-activedescendant`)||(n.textContent=o),this.close(e,t))},{signal:i})}itemsPosition(e){let t=e.querySelector(`[aria-selected="true"]`);t&&t.scrollIntoView({block:`nearest`})}items(e,t,n,r,i,a){n.forEach((o,s)=>{o.addEventListener(`click`,()=>{let a=n[s];if(a){r.textContent=a.textContent,n.forEach(e=>e.removeAttribute(`aria-selected`)),a.setAttribute(`aria-selected`,`true`);let o=a.id||`${this.selectors.idPrefix}${s}`;e.setAttribute(`aria-expanded`,`false`),e.setAttribute(`aria-activedescendant`,o),i.value=String(n[s].dataset.value),this.customEvent(e,i.value),this.close(e,t)}},{signal:a})})}defaultSelect(e,t,n,r){t&&(r.setAttribute(`value`,t.dataset.value??``),n.textContent=t.textContent??``,e.setAttribute(`aria-activedescendant`,t.id||``))}customEvent(e,t){let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.log(`CustomEvent:`,n.detail),e.dispatchEvent(new CustomEvent(`ui-select-change`,n))}toggle(t,n){e.closeAll(this.selectors),n.hidden?(n.hidden=!1,t.setAttribute(`aria-expanded`,`true`)):this.close(t,n)}close(e,t){t.hidden=!0,e.setAttribute(`aria-expanded`,`false`)}static closeAll(e){document.querySelectorAll(`.${e.main}`).forEach(t=>{let n=t.querySelector(`.${e.optionsList}`);n.hidden=!0,t.setAttribute(`aria-expanded`,`false`)})}initGlobalListener(t){document.addEventListener(`click`,n=>{let r=n.target;[...document.querySelectorAll(`.${t.main}`)].some(e=>e.contains(r))||e.closeAll(t)},{signal:this.globalAbortController.signal})}},r=class{selectors;main=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIbg`,btn:`UIbg-btn`,input:`UIbg-input`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.main?.forEach(e=>delete e.dataset.uibgBound),this.main=null,this.abortController=new AbortController}setValue(e,t){let n=e.querySelectorAll(`.${this.selectors.input}`),r=e.querySelectorAll(`.${this.selectors.btn}`),i=Array.from(n).findIndex(e=>e.value===t&&!e.disabled);if(i===-1){this.debug&&console.warn(`UIButtonGroup: value "${t}" not found or disabled`);return}n.forEach((e,t)=>{e.checked=t===i,t===i?e.setAttribute(`checked`,``):e.removeAttribute(`checked`)}),r.forEach((e,t)=>{e.setAttribute(`aria-checked`,String(t===i)),e.setAttribute(`tabindex`,t===i?`0`:`-1`)}),this.customEvent(n[i]);let a=r[i];a&&!e.closest(`.ui-no-flash`)&&(a.classList.remove(`UIbg--flash`),a.offsetWidth,a.classList.add(`UIbg--flash`),a.addEventListener(`animationend`,()=>a.classList.remove(`UIbg--flash`),{once:!0}))}scan(){this.main=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.main.forEach(t=>{if(t.dataset.uibgBound)return;t.dataset.uibgBound=`1`,t.querySelectorAll(`.${this.selectors.input}`).forEach(e=>{e.hasAttribute(`data-originally-disabled`)||e.setAttribute(`data-originally-disabled`,String(e.disabled)),e.disabled=e.getAttribute(`data-originally-disabled`)===`true`}),t.removeAttribute(`aria-disabled`);let n=t.querySelector(`.${this.selectors.input}:checked`);n&&this.customEvent(n);let r=t.querySelectorAll(`.${this.selectors.btn}`);r.forEach(t=>{t.addEventListener(`click`,()=>{r.forEach(e=>{e.setAttribute(`aria-checked`,`false`),e.setAttribute(`tabindex`,`-1`)}),t.setAttribute(`aria-checked`,`true`),t.setAttribute(`tabindex`,`0`),t.focus(),this.ripple(t)},{signal:e}),t.addEventListener(`keydown`,e=>{let n=Array.from(r).indexOf(t);if(e.key===`ArrowRight`&&n++,e.key===`ArrowLeft`&&n--,n<0&&(n=r.length-1),n>=r.length&&(n=0),e.key===`Enter`){let t=i[n];t&&!t.disabled&&(i.forEach(e=>{e.checked=!1,e.removeAttribute(`checked`)}),t.checked=!0,t.setAttribute(`checked`,``),this.customEvent(t)),e.preventDefault();return}let a=r[n];a&&(r.forEach(e=>e.setAttribute(`tabindex`,`-1`)),a.setAttribute(`tabindex`,`0`),a.focus())},{signal:e})});let i=t.querySelectorAll(`.${this.selectors.input}`);i.forEach((t,n)=>{this.debug&&(t.id||console.error(`Input #${n} in group has no ID!`),(!t.value||t.value===`on`)&&console.warn(`Input #${t.id} does not have a value specified (currently "${t.value}")`));let a=r[n];a&&(t.tabIndex=-1,a.setAttribute(`role`,`radio`),a.setAttribute(`aria-checked`,String(t.checked)),a.setAttribute(`tabindex`,t.checked?`0`:`-1`),t.disabled?a.setAttribute(`aria-disabled`,`true`):a.removeAttribute(`aria-disabled`),t.addEventListener(`click`,()=>{i.forEach(e=>{e.checked=!1,e.removeAttribute(`checked`)}),i[n].checked=!0,i[n].setAttribute(`checked`,``),this.customEvent(t)},{signal:e}))});let a=Array.from(i).find(e=>e.checked&&!e.disabled)||Array.from(i).find(e=>!e.disabled);if(a){let e=t.querySelector(`label[for="${a.id}"]`);e&&e.setAttribute(`tabindex`,`0`)}})}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`ui-ripple`),e.offsetWidth,e.classList.add(`ui-ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`ui-ripple`),{once:!0}))}customEvent(e){let t={detail:{id:e.id,value:e.value},bubbles:!0};this.debug&&console.log(`CustomEvent:`,t.detail),e.dispatchEvent(new CustomEvent(`ui-button-group-change`,t))}},i=class{selectors;buttons=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIb`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}setValue(e,t,n){e.dataset.value=t,e.tagName===`A`&&(e.href=t),n!==void 0&&(e.textContent=n),!e.closest(`.ui-no-flash`)&&(e.classList.remove(`UIb--flash`),e.offsetWidth,e.classList.add(`UIb--flash`),e.addEventListener(`animationend`,()=>e.classList.remove(`UIb--flash`),{once:!0}))}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.buttons?.forEach(e=>delete e.dataset.uibBound),this.buttons=null,this.abortController=new AbortController}disableEl(e){e.tagName===`BUTTON`?e.disabled=!0:(e.setAttribute(`aria-disabled`,`true`),e.setAttribute(`tabindex`,`-1`))}enableEl(e){e.tagName===`BUTTON`?e.disabled=!1:(e.removeAttribute(`aria-disabled`),e.setAttribute(`tabindex`,`0`))}isDisabled(e){return e.tagName===`BUTTON`?e.disabled:e.getAttribute(`aria-disabled`)===`true`}setDisabled(e,t){e.setAttribute(`data-originally-disabled`,String(t)),t?this.disableEl(e):this.enableEl(e)}scan(){this.buttons=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.buttons.forEach(t=>{t.dataset.uibBound||(t.dataset.uibBound=`1`,t.hasAttribute(`data-originally-disabled`)||t.setAttribute(`data-originally-disabled`,String(this.isDisabled(t))),t.getAttribute(`data-originally-disabled`)===`true`?this.disableEl(t):this.enableEl(t),t.addEventListener(`click`,e=>{if(this.isDisabled(t)){e.preventDefault(),e.stopImmediatePropagation();return}t.tagName===`A`&&e.preventDefault(),this.ripple(t),this.customEvent(t,String(t.dataset.value))},{signal:e}))})}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`UIb--ripple`),e.offsetWidth,e.classList.add(`UIb--ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`UIb--ripple`),{once:!0}))}customEvent(e,t){if(!t||t===`undefined`||t.trim()===``){console.warn(`Button data-value="" Not set!`);return}let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.info(`Button CustomEvent:`,n.detail),e.dispatchEvent(new CustomEvent(`ui-button-change`,n))}},a=null,o=null,s=null,c=null,l=null;function u(...e){return a??=new i(...e)}function d(...e){return l??=new r(...e)}function f(...e){return o??=new n(...e)}function p(...t){return s??=new e(...t)}function m(...e){return c??=new t(...e)}function h(){a=null,o=null,s=null,c=null,l=null}exports.Button=i,exports.ButtonGroup=r,exports.Select=n,exports.SpinBox=e,exports.Switch=t,exports.getButtonGroupManager=d,exports.getButtonManager=u,exports.getSelectManager=f,exports.getSpinBoxManager=p,exports.getSwitchManager=m,exports.resetManagers=h;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{selectors;spinBoxes=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;valueControls=new WeakMap;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIsp`,btn:`UIsp__btn`,input:`UIsp__input`,disabledBtn:`disabled`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}state=(e,t,n,r=0,i=0)=>{e==r||e<r?(t.classList.add(this.selectors.disabledBtn),t.disabled=!0):(t.classList.remove(this.selectors.disabledBtn),t.disabled=!1),i!==0&&(e==i||e>i?(n.classList.add(this.selectors.disabledBtn),n.disabled=!0):(n.classList.remove(this.selectors.disabledBtn),n.disabled=!1))};destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.spinBoxes?.forEach(e=>{delete e.dataset.uispBound,this.valueControls.delete(e)}),this.spinBoxes=null,this.abortController=new AbortController}disableEl(e){let t=e.querySelector(`.${this.selectors.input}`),n=e.querySelectorAll(`.${this.selectors.btn}`);t&&(t.disabled=!0),n.forEach(e=>{e.classList.add(this.selectors.disabledBtn),e.disabled=!0}),e.setAttribute(`tabindex`,`-1`),e.setAttribute(`aria-disabled`,`true`)}setValue(e,t,{silent:n=!1,flash:r=!0}={}){let i=e.querySelector(`.${this.selectors.input}`);if(!i){this.debug&&console.warn(`UISpinBox: input not found`);return}if(n){let n=this.valueControls.get(e);n?n(t,!0):i.value=String(t)}else i.value=String(t),i.dispatchEvent(new Event(`change`));r&&this.playFlash(e,i)}playFlash(e,t){e.closest(`.ui-no-flash`)||(e.classList.remove(`UIsp--flash`),e.offsetWidth,e.classList.add(`UIsp--flash`),t.addEventListener(`animationend`,()=>e.classList.remove(`UIsp--flash`),{once:!0}))}refresh(e){let t=this.valueControls.get(e);if(!t){this.debug&&console.warn(`UISpinBox: element not bound`);return}let n=e.querySelector(`.${this.selectors.input}`);if(!n){this.debug&&console.warn(`UISpinBox: input not found`);return}t(n.value,!0)}getValidDataNumber=(e,t)=>{let n=e.getAttribute(`data-${t}`);return n===null||n.trim()===``||isNaN(Number(n))?0:Number(n)};scan(){this.spinBoxes=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.spinBoxes.forEach(t=>{if(t.dataset.uispBound)return;t.dataset.uispBound=`1`;let n,r=t.querySelectorAll(`.${this.selectors.btn}`),i=t.querySelector(`.${this.selectors.input}`),a=r[0],o=r[1];if(!i||!a||!o){this.debug&&(r.length<2&&console.log(`Buttons (${this.selectors.btn}) not found in container`),i||console.log(`Input (${this.selectors.input}) not found in container`));return}i.disabled=!1,[a,o].forEach(e=>{e.classList.remove(this.selectors.disabledBtn),e.disabled=!1}),t.setAttribute(`tabindex`,`0`),t.removeAttribute(`aria-disabled`);let s=t.hasAttribute(`data-decimals`)?this.getValidDataNumber(t,`decimals`):this.getValidDataNumber(t,`step`),c=Math.min(Math.max(Math.trunc(s),0),100),l=this.getValidDataNumber(t,`min`),u=this.getValidDataNumber(t,`max`),d=t.hasAttribute(`data-negative`);if(t.hasAttribute(`data-disabled`)){Number(i.value)<=l&&(i.value=l.toFixed(c)),u===0?i.value=Number(i.value).toFixed(c):Number(i.value)>=u&&(i.value=u.toFixed(c)),this.disableEl(t),t.addEventListener(`click`,e=>{e.preventDefault(),e.stopImmediatePropagation()},{capture:!0,signal:e});return}let f=t.getAttribute(`data-unit`)?.trim(),p=e=>{t.setAttribute(`aria-valuenow`,String(e)),t.setAttribute(`aria-valuetext`,f?`${e} ${f}`:String(e))},m=(e,t)=>{let n=Number(e);Number.isNaN(n)&&(n=l),n<l&&(n=l),u!==0&&n>u&&(n=u),i.value=n.toFixed(c),this.state(n,a,o,l,u),p(i.value),t||this.customEvent(i,i.value)};this.valueControls.set(t,m),Number(i.value)<=l&&(i.value=l.toFixed(c)),u===0?i.value=Number(i.value).toFixed(c):(Number(i.value)>=u&&(i.value=u.toFixed(c)),u&&t.setAttribute(`aria-valuemax`,u.toFixed(c))),l&&t.setAttribute(`aria-valuemin`,l.toFixed(c)),this.state(Number(i.value),a,o,l,u),p(i.value);let h=null,g=(e,t=1)=>{d||(i.value=String(Math.abs(Number(i.value))));let n=parseFloat(i.value)||0;return n+=e*t/10**c,e===1&&u!==0&&n>u&&(n=u),e===-1&&n<l&&(n=l),i.value=n.toFixed(c),this.state(Number(i.value),a,o,l,u),p(i.value),i.value},_=!1,v=(e,t=150)=>{h===null&&(_=!1,h=window.setInterval(e,t))},y=()=>{h!==null&&(clearInterval(h),h=null,_&&this.customEvent(i,i.value))},b=(e,t,n)=>{_=!0,g(e,t),n.disabled&&(y(),_=!1)},x=(t,r,a)=>{t.addEventListener(`mousedown`,e=>{let n=e.shiftKey?3:1;v(()=>b(r,n,t),a)},{signal:e}),t.addEventListener(`touchstart`,()=>v(()=>b(r,1,t),a),{signal:e}),[`mouseup`,`touchend`].forEach(n=>{t.addEventListener(n,y,{signal:e})}),[`mouseleave`,`touchcancel`].forEach(n=>{t.addEventListener(n,()=>{y(),_=!1},{signal:e})}),t.addEventListener(`click`,e=>{if(_){_=!1;return}h===null&&(n=g(r,e.shiftKey?3:1),this.ripple(t),this.customEvent(i,n))},{signal:e})};x(o,1,150),x(a,-1,100),i.addEventListener(`keydown`,e=>{let t=e.key,n=e.shiftKey?5:1;if([`Backspace`,`Delete`,`ArrowLeft`,`ArrowRight`,`Tab`,`Enter`,`Home`,`End`].includes(t)||(e.ctrlKey||e.metaKey)&&[`a`,`c`,`v`,`x`].includes(t.toLowerCase()))return;if([`e`,`+`].includes(t)){e.preventDefault();return}if(t===`-`){let t=i.selectionStart===0,n=(i.selectionEnd??0)>0;(!d||!t||i.value.includes(`-`)&&!n)&&e.preventDefault();return}if(t===`ArrowUp`||t===`ArrowDown`){e.preventDefault(),g(t===`ArrowUp`?1:-1,n);return}let r=t===`,`?`.`:t,a=/^[0-9]$/.test(r),o=r===`.`,s=i.value.includes(`.`);(c===0&&!a||c>0&&!(a||o)||o&&s)&&e.preventDefault()},{signal:e}),i.addEventListener(`keyup`,e=>{(e.key===`ArrowUp`||e.key===`ArrowDown`)&&this.customEvent(i,i.value)},{signal:e}),i.addEventListener(`change`,()=>m(i.value,!1),{signal:e})})}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`ui-ripple`),e.offsetWidth,e.classList.add(`ui-ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`ui-ripple`),{once:!0}))}customEvent(e,t){let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.log(`CustomEvent: data.detail `,n.detail),e.dispatchEvent(new CustomEvent(`ui-spinbox-change`,n))}},t=class{selectors;main=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIsw`,label:`UIsw-label`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.main?.forEach(e=>delete e.dataset.uiswBound),this.main=null,this.abortController=new AbortController}scan(){this.main=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.main.forEach(t=>{if(t.dataset.uiswBound)return;t.dataset.uiswBound=`1`;let n=t.querySelector(`.${this.selectors.label}`),r=t.querySelector(`input`);n&&n.id&&t.setAttribute(`aria-labelledby`,n.id),t.hasAttribute(`data-originally-disabled`)||t.setAttribute(`data-originally-disabled`,String(r?.disabled??!1));let i=t.getAttribute(`data-originally-disabled`)===`true`;r&&(r.disabled=!1),t.setAttribute(`tabindex`,`0`),t.removeAttribute(`aria-disabled`),i&&(r&&(r.disabled=!0),t.setAttribute(`tabindex`,`-1`),t.setAttribute(`aria-disabled`,`true`),t.addEventListener(`click`,e=>{e.preventDefault(),e.stopImmediatePropagation()},{capture:!0,signal:e})),r&&(r.checked?t.setAttribute(`aria-checked`,`true`):t.setAttribute(`aria-checked`,`false`),r.addEventListener(`change`,()=>{t.setAttribute(`aria-checked`,String(r.checked)),this.customEvent(r,String(r.checked))},{signal:e}),t.addEventListener(`click`,e=>{if(e.target.tagName===`INPUT`)return;let n=e.target.closest(`label`);n||(r.checked=!r.checked),n||r.dispatchEvent(new Event(`change`));let i=t.querySelector(`.UIsw-slider`);i&&this.ripple(i)},{signal:e}),t.addEventListener(`keydown`,e=>{if(r.disabled)return;let n=null;if(e.key===`ArrowRight`?n=!0:e.key===`ArrowLeft`?n=!1:(e.key===` `||e.key===`Enter`)&&(n=!r.checked),n!==null&&(e.preventDefault(),r.checked!==n)){r.checked=n,r.dispatchEvent(new Event(`change`));let e=t.querySelector(`.UIsw-slider`);e&&this.ripple(e)}},{signal:e}))})}setValue(e,t,{silent:n=!1,flash:r=!0}={}){let i=e.querySelector(`input`);if(!i){this.debug&&console.warn(`UISwitch: input not found`);return}i.checked=t,this.debug&&console.log(`SetValue:`,i.checked),e.setAttribute(`aria-checked`,String(t)),n||this.customEvent(i,String(t));let a=e.querySelector(`.UIsw-slider`);r&&a&&!e.closest(`.ui-no-flash`)&&(e.classList.remove(`UIsw--flash`),e.offsetWidth,e.classList.add(`UIsw--flash`),a.addEventListener(`animationend`,()=>e.classList.remove(`UIsw--flash`),{once:!0}))}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`ui-ripple`),e.offsetWidth,e.classList.add(`ui-ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`ui-ripple`),{once:!0}))}customEvent(e,t){let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.log(`CustomEvent:`,n.detail),e.dispatchEvent(new CustomEvent(`ui-switch-change`,n))}},n=class e{selectors;main=null;itemArrowInitialized=new WeakSet;abortController=new AbortController;globalAbortController=new AbortController;debug;root;observer=null;rescanTimer=null;selectMap=new Map;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={idPrefix:`UI-option-`,main:`UIselect`,selected:`UIselect-selected`,arrow:`UIselect-arrow`,optionsList:`UIselect-options`,search:`UIselect-options__search`,items:`UIselect-options__items`,flash:`UIselect--flash`,excludedItems:[`divider`,`test`]};this.selectors={...r,...e},this.scan(),this.initGlobalListener(this.selectors),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}filterExcluded(e,t){return Array.from(e).filter(e=>!t.some(t=>typeof t==`string`?e.classList.contains(t)||e.id===t:e===t))}filterSearch(e,t){let n=t.trim().toLowerCase();return e.filter(e=>{let t=e.dataset.value?.toLowerCase()||``,r=e.textContent?.toLowerCase()||``;return t.includes(n)||r.includes(n)})}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),e.closeAll(this.selectors),this.abortController.abort(),this.main?.forEach(e=>delete e.dataset.uiselBound),this.selectMap.clear(),this.itemArrowInitialized=new WeakSet,this.main=null,this.abortController=new AbortController}dispose(){this.destroy(),this.globalAbortController.abort()}disableEl(e){e.setAttribute(`tabindex`,`-1`),e.setAttribute(`aria-disabled`,`true`)}setValue(e,t,{silent:n=!1,flash:r=!0}={}){let i=this.selectMap.get(e);if(!i){this.debug&&console.warn(`UISelect: element not registered`);return}let{input:a,selected:o}=i,s=e.querySelector(`.${this.selectors.optionsList}`);if(!s)return;let c=Array.from(s.querySelectorAll(`.${this.selectors.items} ul li`)),l=this.filterExcluded(c,this.selectors.excludedItems),u=l.find(e=>String(e.dataset.value)===String(t));if(!u){this.debug&&console.warn(`UISelect: value "${t}" not found`);return}l.forEach(e=>e.removeAttribute(`aria-selected`)),u.setAttribute(`aria-selected`,`true`),o.textContent=u.textContent??``,a.value=String(t),a.setAttribute(`value`,String(t)),e.setAttribute(`aria-activedescendant`,u.id||`${this.selectors.idPrefix}${l.indexOf(u)}`),n||this.customEvent(e,String(t)),r&&!e.closest(`.ui-no-flash`)&&(e.classList.remove(this.selectors.flash),e.offsetWidth,e.classList.add(this.selectors.flash),e.addEventListener(`animationend`,()=>e.classList.remove(this.selectors.flash),{once:!0}))}scan(){this.main=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.main.forEach(t=>{if(t.dataset.uiselBound)return;let n=t.querySelector(`input[type='hidden']`);try{if(!n)throw Error(`<input type="hidden" name="YourUniqueId">`)}catch(e){return console.warn(`Not found:`,e.message)}t.dataset.uiselBound=`1`;let r=t.querySelector(`.${this.selectors.selected}`),i=t.querySelector(`.${this.selectors.arrow}`),a=t.querySelector(`.${this.selectors.optionsList}`),o=t.querySelector(`.${this.selectors.search} input`);if(t.setAttribute(`tabindex`,`0`),t.removeAttribute(`aria-disabled`),t.hasAttribute(`data-disabled`)){this.disableEl(t),t.addEventListener(`click`,e=>{e.preventDefault(),e.stopImmediatePropagation()},{capture:!0,signal:e});return}this.selectMap.set(t,{input:n,selected:r}),i&&i.addEventListener(`click`,()=>{this.toggle(t,a)},{signal:e}),r.addEventListener(`click`,()=>{this.toggle(t,a)},{signal:e}),t.addEventListener(`click`,()=>{this.itemsPosition(a)},{signal:e});let s=a.querySelectorAll(`.${this.selectors.items} ul li`),c=this.filterExcluded(s,this.selectors.excludedItems),l=t.querySelector(`[aria-selected='true']`);l&&this.defaultSelect(t,l,r,n),o&&o.addEventListener(`input`,i=>{let o=i.target.value.trim(),l=o?new Set(this.filterSearch(c,o)):null;s.forEach(e=>{e.hidden=l?!l.has(e):!1}),this.itemArrow(t,a,r,n,e)},{signal:e}),this.itemArrow(t,a,r,n,e),this.items(t,a,c,r,n,e)})}itemArrow(e,t,n,r,i){if(this.itemArrowInitialized.has(e))return;this.itemArrowInitialized.add(e);let a=n.textContent?n.textContent:``,o=e.querySelector(`.${this.selectors.search} input`);e.addEventListener(`keydown`,i=>{if(i.key===`Tab`){this.close(e,t);return}o&&o.focus();let s=Array.from(t.querySelectorAll(`.${this.selectors.items} ul li`)),c=this.filterExcluded(s,this.selectors.excludedItems).filter(e=>!e.hidden),l=c.length;if(l===0)return;let u=c.findIndex(e=>e.getAttribute(`aria-selected`)===`true`),d=t=>{let r=c[t];n.textContent=r.textContent,s.forEach(e=>e.removeAttribute(`aria-selected`)),r.setAttribute(`aria-selected`,`true`),e.setAttribute(`aria-activedescendant`,r.id||`${this.selectors.idPrefix}${t}`),r.scrollIntoView({block:`nearest`})};if(i.key===`ArrowDown`)i.preventDefault(),t.hidden&&this.toggle(e,t),d((u+1)%l);else if(i.key===`ArrowUp`)i.preventDefault(),d(u<=0?l-1:u-1);else if(i.key===`Enter`)if(i.preventDefault(),t.hidden)this.toggle(e,t);else if(u>=0){let i=c[u];n.textContent=i.textContent,e.setAttribute(`aria-activedescendant`,i.id||`${this.selectors.idPrefix}${u}`),r.value=String(i.dataset.value),this.customEvent(e,r.value),this.close(e,t)}else this.toggle(e,t);else i.key===`Escape`&&(e.getAttribute(`aria-activedescendant`)||(n.textContent=a),this.close(e,t))},{signal:i})}itemsPosition(e){let t=e.querySelector(`[aria-selected="true"]`);t&&t.scrollIntoView({block:`nearest`})}items(e,t,n,r,i,a){n.forEach((o,s)=>{o.addEventListener(`click`,()=>{let a=n[s];if(a){r.textContent=a.textContent,n.forEach(e=>e.removeAttribute(`aria-selected`)),a.setAttribute(`aria-selected`,`true`);let o=a.id||`${this.selectors.idPrefix}${s}`;e.setAttribute(`aria-expanded`,`false`),e.setAttribute(`aria-activedescendant`,o),i.value=String(n[s].dataset.value),this.customEvent(e,i.value),this.close(e,t)}},{signal:a})})}defaultSelect(e,t,n,r){t&&(r.setAttribute(`value`,t.dataset.value??``),n.textContent=t.textContent??``,e.setAttribute(`aria-activedescendant`,t.id||``))}customEvent(e,t){let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.log(`CustomEvent:`,n.detail),e.dispatchEvent(new CustomEvent(`ui-select-change`,n))}toggle(t,n){e.closeAll(this.selectors),n.hidden?(n.hidden=!1,t.setAttribute(`aria-expanded`,`true`)):this.close(t,n)}close(e,t){t.hidden=!0,e.setAttribute(`aria-expanded`,`false`)}static closeAll(e){document.querySelectorAll(`.${e.main}`).forEach(t=>{let n=t.querySelector(`.${e.optionsList}`);n&&(n.hidden=!0,t.setAttribute(`aria-expanded`,`false`))})}initGlobalListener(t){document.addEventListener(`click`,n=>{let r=n.target;[...document.querySelectorAll(`.${t.main}`)].some(e=>e.contains(r))||e.closeAll(t)},{signal:this.globalAbortController.signal})}},r=class{selectors;main=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIbg`,btn:`UIbg-btn`,input:`UIbg-input`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.main?.forEach(e=>delete e.dataset.uibgBound),this.main=null,this.abortController=new AbortController}setValue(e,t,{silent:n=!1,flash:r=!0}={}){let i=e.querySelectorAll(`.${this.selectors.input}`),a=e.querySelectorAll(`.${this.selectors.btn}`),o=Array.from(i).findIndex(e=>e.value===t&&!e.disabled);if(o===-1){this.debug&&console.warn(`UIButtonGroup: value "${t}" not found or disabled`);return}i.forEach((e,t)=>{e.checked=t===o,t===o?e.setAttribute(`checked`,``):e.removeAttribute(`checked`)}),a.forEach((e,t)=>{e.setAttribute(`aria-checked`,String(t===o)),e.setAttribute(`tabindex`,t===o?`0`:`-1`)}),n||this.customEvent(i[o]);let s=a[o];r&&s&&!e.closest(`.ui-no-flash`)&&(s.classList.remove(`UIbg--flash`),s.offsetWidth,s.classList.add(`UIbg--flash`),s.addEventListener(`animationend`,()=>s.classList.remove(`UIbg--flash`),{once:!0}))}scan(){this.main=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.main.forEach(t=>{if(t.dataset.uibgBound)return;t.dataset.uibgBound=`1`;let n=t.querySelectorAll(`.${this.selectors.input}`);n.forEach(e=>{e.hasAttribute(`data-originally-disabled`)||e.setAttribute(`data-originally-disabled`,String(e.disabled)),e.disabled=e.getAttribute(`data-originally-disabled`)===`true`}),t.removeAttribute(`aria-disabled`);let r=t.querySelector(`.${this.selectors.input}:checked`);r&&this.customEvent(r);let i=t.querySelectorAll(`.${this.selectors.btn}`),a=e=>{let t=n[e],r=i[e];!t||t.disabled||!r||(n.forEach(e=>{e.checked=!1,e.removeAttribute(`checked`)}),t.checked=!0,t.setAttribute(`checked`,``),i.forEach(e=>{e.setAttribute(`aria-checked`,`false`),e.setAttribute(`tabindex`,`-1`)}),r.setAttribute(`aria-checked`,`true`),r.setAttribute(`tabindex`,`0`),r.focus(),this.ripple(r),this.customEvent(t))};i.forEach((t,r)=>{t.addEventListener(`click`,()=>{let e=n[r];!e||e.disabled||(i.forEach(e=>{e.setAttribute(`aria-checked`,`false`),e.setAttribute(`tabindex`,`-1`)}),t.setAttribute(`aria-checked`,`true`),t.setAttribute(`tabindex`,`0`),t.focus(),this.ripple(t))},{signal:e}),t.addEventListener(`keydown`,e=>{let r=Array.from(i).indexOf(t);if(e.key===` `||e.key===`Enter`){e.preventDefault(),a(r);return}let o=0;if(e.key===`ArrowRight`||e.key===`ArrowDown`)o=1;else if(e.key===`ArrowLeft`||e.key===`ArrowUp`)o=-1;else return;e.preventDefault();let s=r;for(let e=0;e<i.length&&(s+=o,s<0&&(s=i.length-1),s>=i.length&&(s=0),!(n[s]&&!n[s].disabled));e++);s!==r&&a(s)},{signal:e})}),n.forEach((t,r)=>{this.debug&&(t.id||console.error(`Input #${r} in group has no ID!`),(!t.value||t.value===`on`)&&console.warn(`Input #${t.id} does not have a value specified (currently "${t.value}")`));let a=i[r];a&&(t.tabIndex=-1,a.setAttribute(`role`,`radio`),a.setAttribute(`aria-checked`,String(t.checked)),a.setAttribute(`tabindex`,t.checked?`0`:`-1`),t.disabled?a.setAttribute(`aria-disabled`,`true`):a.removeAttribute(`aria-disabled`),t.addEventListener(`click`,()=>{n.forEach(e=>{e.checked=!1,e.removeAttribute(`checked`)}),n[r].checked=!0,n[r].setAttribute(`checked`,``),this.customEvent(t)},{signal:e}))});let o=Array.from(n).find(e=>e.checked&&!e.disabled)||Array.from(n).find(e=>!e.disabled);if(o){let e=t.querySelector(`label[for="${o.id}"]`);e&&e.setAttribute(`tabindex`,`0`)}})}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`ui-ripple`),e.offsetWidth,e.classList.add(`ui-ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`ui-ripple`),{once:!0}))}customEvent(e){let t={detail:{id:e.id,value:e.value},bubbles:!0};this.debug&&console.log(`CustomEvent:`,t.detail),e.dispatchEvent(new CustomEvent(`ui-button-group-change`,t))}},i=class{selectors;buttons=null;abortController=new AbortController;debug;root;observer=null;rescanTimer=null;constructor(e={},t=!1,n={}){this.debug=t,this.root=n.root??document;let r={main:`UIb`};this.selectors={...r,...e},this.scan(),n.observe&&this.observe()}observe(){let e=this.root===document?document.body:this.root;this.observer=new MutationObserver(()=>{this.rescanTimer===null&&(this.rescanTimer=window.setTimeout(()=>{this.rescanTimer=null,this.scan()},50))}),this.observer.observe(e,{childList:!0,subtree:!0})}setValue(e,t,{flash:n=!0,label:r}={}){e.dataset.value=t,e.tagName===`A`&&(e.href=t),r!==void 0&&(e.textContent=r),!(!n||e.closest(`.ui-no-flash`))&&(e.classList.remove(`UIb--flash`),e.offsetWidth,e.classList.add(`UIb--flash`),e.addEventListener(`animationend`,()=>e.classList.remove(`UIb--flash`),{once:!0}))}destroy(){this.observer?.disconnect(),this.observer=null,this.rescanTimer!==null&&(clearTimeout(this.rescanTimer),this.rescanTimer=null),this.abortController.abort(),this.buttons?.forEach(e=>delete e.dataset.uibBound),this.buttons=null,this.abortController=new AbortController}disableEl(e){e.tagName===`BUTTON`?e.disabled=!0:(e.setAttribute(`aria-disabled`,`true`),e.setAttribute(`tabindex`,`-1`))}enableEl(e){e.tagName===`BUTTON`?e.disabled=!1:(e.removeAttribute(`aria-disabled`),e.setAttribute(`tabindex`,`0`))}isDisabled(e){return e.tagName===`BUTTON`?e.disabled:e.getAttribute(`aria-disabled`)===`true`}setDisabled(e,t){e.setAttribute(`data-originally-disabled`,String(t)),t?this.disableEl(e):this.enableEl(e)}scan(){this.buttons=this.root.querySelectorAll(`.${this.selectors.main}`);let e=this.abortController.signal;this.buttons.forEach(t=>{t.dataset.uibBound||(t.dataset.uibBound=`1`,t.hasAttribute(`data-originally-disabled`)||t.setAttribute(`data-originally-disabled`,String(this.isDisabled(t))),t.getAttribute(`data-originally-disabled`)===`true`?this.disableEl(t):this.enableEl(t),t.addEventListener(`click`,e=>{if(this.isDisabled(t)){e.preventDefault(),e.stopImmediatePropagation();return}if(t.tagName===`A`){let n=t.getAttribute(`href`);(!n||n===`#`)&&e.preventDefault()}this.ripple(t),this.customEvent(t,String(t.dataset.value))},{signal:e}))})}ripple(e){e.closest(`.ui-no-ripple`)||(e.classList.remove(`UIb--ripple`),e.offsetWidth,e.classList.add(`UIb--ripple`),e.addEventListener(`animationend`,()=>e.classList.remove(`UIb--ripple`),{once:!0}))}customEvent(e,t){if(!t||t===`undefined`||t.trim()===``){this.debug&&console.warn(`Button data-value="" Not set!`);return}let n={detail:{id:e.id,value:t},bubbles:!0};this.debug&&console.info(`Button CustomEvent:`,n.detail),e.dispatchEvent(new CustomEvent(`ui-button-change`,n))}};function a(e=document){let t=new AbortController,n=()=>15*(parseFloat(getComputedStyle(document.documentElement).fontSize)||16),r=e=>{let t=e.querySelector(`.UIql__text`);if(!t)return;let r=e.getBoundingClientRect(),i=r.left+r.width/2,a=document.documentElement.clientWidth,o=n(),s=i-8,c=a-i-8;e.classList.remove(`UIql--left`,`UIql--right`),i-o/2>=8&&i+o/2<=a-8?t.style.maxWidth=``:c>=s?(e.classList.add(`UIql--right`),t.style.maxWidth=`${Math.min(o,c)}px`):(e.classList.add(`UIql--left`),t.style.maxWidth=`${Math.min(o,s)}px`)},i=e=>{let t=e.target?.closest?.(`.UIql`);t&&r(t)};return e.addEventListener(`pointerover`,i,{signal:t.signal}),e.addEventListener(`focusin`,i,{signal:t.signal}),window.addEventListener(`resize`,()=>{e.querySelectorAll(`.UIql:hover, .UIql:focus`).forEach(r)},{signal:t.signal}),()=>t.abort()}var o=null,s=null,c=null,l=null,u=null;function d(...e){return o??=new i(...e)}function f(...e){return u??=new r(...e)}function p(...e){return s??=new n(...e)}function m(...t){return c??=new e(...t)}function h(...e){return l??=new t(...e)}function g(){o?.destroy(),u?.destroy(),s?.dispose(),c?.destroy(),l?.destroy(),o=null,s=null,c=null,l=null,u=null}exports.Button=i,exports.ButtonGroup=r,exports.Select=n,exports.SpinBox=e,exports.Switch=t,exports.getButtonGroupManager=f,exports.getButtonManager=d,exports.getSelectManager=p,exports.getSpinBoxManager=m,exports.getSwitchManager=h,exports.initQuestionTooltips=a,exports.resetManagers=g;
package/dist/index.d.ts CHANGED
@@ -8,10 +8,17 @@ export { Switch } from './Switch';
8
8
  export { Select } from './Select';
9
9
  export { ButtonGroup } from './ButtonGroup';
10
10
  export { Button } from './Button';
11
+ export { initQuestionTooltips } from './questionLabel';
11
12
  export declare function getButtonManager(...args: ConstructorParameters<typeof Button>): Button;
12
13
  export declare function getButtonGroupManager(...args: ConstructorParameters<typeof ButtonGroup>): ButtonGroup;
13
14
  export declare function getSelectManager(...args: ConstructorParameters<typeof Select>): Select;
14
15
  export declare function getSpinBoxManager(...args: ConstructorParameters<typeof SpinBox>): SpinBox;
15
16
  export declare function getSwitchManager(...args: ConstructorParameters<typeof Switch>): Switch;
16
- /** Drop the cached singletons so the next getXManager() builds a fresh one. */
17
+ /**
18
+ * Tear down the cached singletons and drop them so the next getXManager()
19
+ * builds a fresh one. Each teardown is idempotent, so this is safe even if the
20
+ * consumer already called destroy() on a manager. Select gets the full
21
+ * dispose() (its lifetime-scoped outside-click listener too); the rest only
22
+ * own scan-scoped listeners, which destroy() releases.
23
+ */
17
24
  export declare function resetManagers(): void;