@vialiq/web-components 0.13.0 → 0.14.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/input/vi-input.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { unsafeCSS, css, html } from 'lit';
2
2
  import { customElement, property } from 'lit/decorators.js';
3
3
  import { F as FocusableMixin } from '../focusable-mixin-CmxOyPX5.js';
4
- import { V as ValidityMixin } from '../validity-mixin-H4aOFJEr.js';
4
+ import { V as ValidityMixin } from '../validity-mixin-DO0ycRH2.js';
5
5
  import { V as ViElement } from '../vi-element-C6GfDPs3.js';
6
6
  import { i as ifNonEmpty } from '../if-non-empty-DX8UGa-B.js';
7
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vialiq/web-components",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -103,8 +103,8 @@
103
103
  },
104
104
  "peerDependencies": {
105
105
  "@floating-ui/dom": ">=1.0.0",
106
- "@vialiq/flux-ui": "^0.11.0",
107
- "@vialiq/icons": "^0.1.1",
106
+ "@vialiq/flux-ui": "^0.12.0",
107
+ "@vialiq/icons": "^0.2.0",
108
108
  "lit": "^3.0.0"
109
109
  },
110
110
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  import { unsafeCSS, css, html } from 'lit';
2
2
  import { customElement, property } from 'lit/decorators.js';
3
- import { V as ValidityMixin } from '../validity-mixin-H4aOFJEr.js';
3
+ import { V as ValidityMixin } from '../validity-mixin-DO0ycRH2.js';
4
4
  import { V as ViElement } from '../vi-element-C6GfDPs3.js';
5
5
 
6
6
  const radioGroupStyles = "@charset \"UTF-8\";@layer reset,components,utilities;@layer components{.radio-group{border:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--vi-radio-group-spacing-field-gap, var(--vi-spacing-xs, 8px));width:100%}.radio-group-legend{font-family:var(--vi-font-family-base, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);font-size:var(--vi-radio-group-label-font-size, var(--vi-font-size-base, 16px));font-weight:var(--vi-font-weight-semibold, 600);color:var(--vi-radio-group-label-color, var(--vi-text-primary, #111827));padding:0;margin:0;margin-block-end:var(--vi-radio-group-legend-margin-bottom, var(--vi-spacing-xs, 8px))}.radio-group-items{display:flex;gap:var(--vi-radio-group-gap, 8px)}.radio-group-items[orientation=vertical]{flex-direction:column}.radio-group-items[orientation=horizontal]{flex-direction:row;flex-wrap:wrap;gap:var(--vi-radio-group-gap-horizontal, 24px)}.radio-group-helper{display:block;font-family:var(--vi-font-family-base, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);font-size:var(--vi-radio-group-helper-font-size, var(--vi-font-size-xs, 12px));color:var(--vi-radio-group-helper-color, var(--vi-text-helper, #9e9e9e))}.radio-group-validation{display:block;font-family:var(--vi-font-family-base, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);font-size:var(--vi-radio-group-validation-font-size, var(--vi-font-size-xs, 12px));color:var(--vi-radio-group-validation-color, var(--vi-text-helper, #9e9e9e));margin-block-start:var(--vi-radio-group-validation-margin-top, var(--vi-spacing-xs, 8px))}.radio-group-validation.radio-group-validation--invalid{color:var(--vi-radio-group-error-color, var(--vi-color-error, #ef4444))}.radio-group-validation.radio-group-validation--valid{color:var(--vi-radio-group-success-color, var(--vi-color-success, #489167))}.radio-wrapper{display:inline-flex;align-items:center;gap:var(--vi-radio-label-gap, 8px);cursor:pointer;font-family:var(--vi-font-family-base, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);font-size:var(--vi-radio-label-font-size, var(--vi-font-size-base, 16px));line-height:var(--vi-line-height-normal, 1.5);color:var(--vi-radio-label-color, var(--vi-text-primary, #111827));position:relative;-webkit-user-select:none;user-select:none}.radio-input{position:absolute!important;clip-path:inset(50%)!important;overflow:hidden!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;border:0!important;white-space:nowrap!important}.radio-circle{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;width:var(--vi-radio-size, 18px);height:var(--vi-radio-size, 18px);border:var(--vi-border-width-base, 2px) solid var(--vi-radio-border-color, var(--vi-outline, #e5e7eb));border-radius:50%;background-color:var(--vi-radio-background-color, var(--vi-color-background, #ffffff));transition:border-color .15s ease,box-shadow .15s ease;flex-shrink:0}.radio-dot{box-sizing:border-box;width:var(--vi-radio-dot-size, 8px);height:var(--vi-radio-dot-size, 8px);border-radius:50%;background-color:var(--vi-radio-dot-color, var(--vi-color-primary, #3676d0));transform:scale(0);opacity:0;transition:transform .15s cubic-bezier(.4,0,.2,1),opacity .15s ease}.radio-input:checked+.radio-circle{border-color:var(--vi-radio-border-color-checked, var(--vi-color-primary, #3676d0))}.radio-input:checked+.radio-circle .radio-dot{transform:scale(1);opacity:1}.radio-input:focus-visible+.radio-circle{outline:var(--vi-border-width-base, 2px) solid var(--vi-radio-focus-ring-color, var(--vi-focus, #3676d0));outline-offset:2px;box-shadow:0 0 0 3px var(--vi-radio-focus-ring-glow, var(--vi-color-blue-200, #cee6ff))}.radio-wrapper:hover:not(.radio-wrapper--disabled) .radio-circle{border-color:var(--vi-radio-border-color-hover, var(--vi-border-inverse-03, #757575))}.radio-wrapper:hover:not(.radio-wrapper--disabled) .radio-input:checked+.radio-circle{border-color:var(--vi-radio-border-color-checked-hover, var(--vi-color-primary, #3676d0))}.radio-wrapper--disabled{cursor:not-allowed;opacity:var(--vi-radio-disabled-opacity, .5)}.radio-wrapper--disabled .radio-circle{background-color:var(--vi-layer-disabled, #f3f4f6);border-color:var(--vi-border-02, #eeeeee)}.radio-wrapper--disabled .radio-dot{background-color:var(--vi-text-disabled, #9e9e9e)}@media(prefers-reduced-motion:reduce){.radio-circle,.radio-dot{transition:none}}}:host{display:block;outline:none}:host([disabled]){cursor:not-allowed;pointer-events:none}:host([status=invalid]){--vi-radio-group-label-color: var(--vi-color-error, #ef4444)}::slotted(*){font-family:inherit;font-size:inherit;color:inherit}:host([size=xs]){--vi-radio-group-label-font-size: var(--vi-font-size-xs, 12px);--vi-radio-group-legend-margin-bottom: 4px}:host([size=sm]){--vi-radio-group-label-font-size: var(--vi-font-size-sm, 14px);--vi-radio-group-legend-margin-bottom: 6px}:host([size=lg]){--vi-radio-group-label-font-size: var(--vi-font-size-lg, 18px);--vi-radio-group-legend-margin-bottom: 10px}";
@@ -5,8 +5,15 @@ export type TooltipPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bot
5
5
  export type TooltipTrigger = 'hover focus' | 'hover' | 'focus' | 'click';
6
6
  /**
7
7
  * vi-tooltip
8
+ *
8
9
  * A floating hint providing supplementary info on hover or focus using Floating UI.
9
10
  *
11
+ * **Developer Notes & Architecture:**
12
+ * - **Positioning Strategy**: Tooltips always use `strategy: absolute` natively, but users can override this via the `popper-options` property if they need `fixed` hoisting to escape tight containers.
13
+ * - **Z-Index**: `OverlayManager` guarantees tooltips render above modals and dropdowns.
14
+ * - **Accessibility**: Automatically calculates whether its slotted content is interactive (contains links/buttons). If so, it uses `aria-details`; if plain text, it uses `aria-describedby`.
15
+ * - **Teleportation**: `vi-tooltip` does **not** teleport its floating panel to `document.body`. This is an explicit design choice to preserve Shadow DOM encapsulation for the `<slot name="content">` and scoped styling.
16
+ *
10
17
  * @element vi-tooltip
11
18
  * @attr content - Plain text tooltip content
12
19
  * @attr placement - Preferred position: top | top-start | top-end | bottom | bottom-start | bottom-end | left | right (default: top)
@@ -48,6 +55,7 @@ export declare class ViTooltip extends ViElement {
48
55
  private _hideTimeout?;
49
56
  private _triggerElement;
50
57
  private _cleanupAutoUpdate?;
58
+ private _overlayZIndex;
51
59
  private _panelId;
52
60
  constructor();
53
61
  connectedCallback(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"vi-tooltip.d.ts","sourceRoot":"","sources":["../../../../libs/web-components/src/tooltip/vi-tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAE9F,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAOL,KAAK,qBAAqB,EAC3B,MAAM,kBAAkB,CAAC;AAG1B,MAAM,MAAM,gBAAgB,GACxB,KAAK,GAAG,WAAW,GAAG,SAAS,GAC/B,QAAQ,GAAG,cAAc,GAAG,YAAY,GACxC,MAAM,GAAG,OAAO,CAAC;AAErB,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,SAAU,SAAQ,SAAS;IACtC,OAAgB,MAAM,0BAAoC;IAE9B,QAAQ,CAAC,OAAO,SAAM;IAEP,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAS;IAE5D,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAiB;IAEjD,QAAQ,CAAC,KAAK,SAAO;IAEI,QAAQ,CAAC,SAAS,SAAO;IAE1B,QAAQ,CAAC,QAAQ,SAAO;IAEhC,QAAQ,CAAC,QAAQ,UAAS;IAEtE;;;;MAIE;IAeD,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAM;IAEpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACrD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IAEtF,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,kBAAkB,CAAC,CAAa;IAExC,OAAO,CAAC,QAAQ,CAAoE;;IAO3E,iBAAiB,IAAI,IAAI;IAI3B,oBAAoB,IAAI,IAAI;cAYhB,YAAY,IAAI,IAAI;IAI9B,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAc/C,6BAA6B;IAC7B,IAAI,IAAI,IAAI;IAgBd,6BAA6B;IAC7B,IAAI,CAAC,SAAS,UAAQ,GAAG,IAAI;IAe3B,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,eAAe,CAIrB;IAEF,OAAO,CAAC,eAAe,CAIrB;IAEF,OAAO,CAAC,UAAU,CAIhB;IAEF,OAAO,CAAC,WAAW,CAIjB;IAEF,OAAO,CAAC,QAAQ,CAQd;IAEF,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,gBAAgB;IAiEf,MAAM,IAAI,cAAc;CAsClC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
1
+ {"version":3,"file":"vi-tooltip.d.ts","sourceRoot":"","sources":["../../../../libs/web-components/src/tooltip/vi-tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAE9F,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAOL,KAAK,qBAAqB,EAC3B,MAAM,kBAAkB,CAAC;AAI1B,MAAM,MAAM,gBAAgB,GACxB,KAAK,GAAG,WAAW,GAAG,SAAS,GAC/B,QAAQ,GAAG,cAAc,GAAG,YAAY,GACxC,MAAM,GAAG,OAAO,CAAC;AAErB,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,SAAU,SAAQ,SAAS;IACtC,OAAgB,MAAM,0BAAoC;IAE9B,QAAQ,CAAC,OAAO,SAAM;IAEP,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAS;IAE5D,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAiB;IAEjD,QAAQ,CAAC,KAAK,SAAO;IAEI,QAAQ,CAAC,SAAS,SAAO;IAE1B,QAAQ,CAAC,QAAQ,SAAO;IAEhC,QAAQ,CAAC,QAAQ,UAAS;IAEtE;;;;MAIE;IAeD,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAM;IAEpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACrD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IAEtF,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,kBAAkB,CAAC,CAAa;IACxC,OAAO,CAAC,cAAc,CAAuB;IAE7C,OAAO,CAAC,QAAQ,CAAoE;;IAO3E,iBAAiB,IAAI,IAAI;IAIzB,oBAAoB,IAAI,IAAI;cAkBlB,YAAY,IAAI,IAAI;IAO9B,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAgB/C,6BAA6B;IAC7B,IAAI,IAAI,IAAI;IAgBd,6BAA6B;IAC7B,IAAI,CAAC,SAAS,UAAQ,GAAG,IAAI;IAe3B,OAAO,CAAC,YAAY;IAgCpB,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,eAAe,CAIrB;IAEF,OAAO,CAAC,eAAe,CAIrB;IAEF,OAAO,CAAC,UAAU,CAIhB;IAEF,OAAO,CAAC,WAAW,CAIjB;IAEF,OAAO,CAAC,QAAQ,CAQd;IAEF,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,gBAAgB;IAoEf,MAAM,IAAI,cAAc;CAsClC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
@@ -3,7 +3,114 @@ import { customElement, property, state, query } from 'lit/decorators.js';
3
3
  import { V as ViElement } from '../vi-element-C6GfDPs3.js';
4
4
  import { autoUpdate, offset, flip, shift, arrow, computePosition } from '@floating-ui/dom';
5
5
 
6
- const tooltipStyles = "@charset \"UTF-8\";@layer reset,components,utilities;.tooltip-panel{position:fixed;z-index:var(--vi-tooltip-z-index, 9999);pointer-events:none;opacity:0;transform:scale(.95);transition:opacity .15s ease-out,transform .15s ease-out;margin:0;border:none;background:transparent;padding:0;overflow:visible;font-family:var(--vi-font-family-base, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif)}.tooltip-panel[popover]:popover-open{display:block;pointer-events:auto;opacity:1;transform:scale(1)}.tooltip-panel{transition-property:opacity,transform,display,overlay;transition-behavior:allow-discrete}@media(prefers-reduced-motion:reduce){.tooltip-panel{transition:none;transform:none}}.tooltip-content{background-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827));color:var(--vi-tooltip-color, var(--vi-text-primary-inverse, #ffffff));font-size:var(--vi-tooltip-font-size, 12px);line-height:1.4;padding:var(--vi-tooltip-padding, 6px 10px);border-radius:var(--vi-tooltip-border-radius, 4px);box-shadow:var(--vi-tooltip-shadow, var(--vi-shadow-md, 0 4px 6px -1px rgba(0, 0, 0, .1)));max-width:var(--vi-tooltip-max-width, 240px);word-wrap:break-word;white-space:normal;position:relative}.tooltip-arrow{position:absolute;width:0;height:0;border-style:solid;border-color:transparent;pointer-events:none}.tooltip-panel[placement^=top] .tooltip-arrow,.tooltip-panel[data-placement^=top] .tooltip-arrow{bottom:calc(-1 * var(--vi-tooltip-arrow-size, 6px));left:50%;transform:translate(-50%);border-width:var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px) 0;border-top-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement^=bottom] .tooltip-arrow,.tooltip-panel[data-placement^=bottom] .tooltip-arrow{top:calc(-1 * var(--vi-tooltip-arrow-size, 6px));left:50%;transform:translate(-50%);border-width:0 var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px);border-bottom-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement=left] .tooltip-arrow,.tooltip-panel[data-placement=left] .tooltip-arrow{right:calc(-1 * var(--vi-tooltip-arrow-size, 6px));top:50%;transform:translateY(-50%);border-width:var(--vi-tooltip-arrow-size, 6px) 0 var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px);border-left-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement=right] .tooltip-arrow,.tooltip-panel[data-placement=right] .tooltip-arrow{left:calc(-1 * var(--vi-tooltip-arrow-size, 6px));top:50%;transform:translateY(-50%);border-width:var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px) 0;border-right-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement$=-start] .tooltip-arrow,.tooltip-panel[data-placement$=-start] .tooltip-arrow{left:12px;transform:none}.tooltip-panel[placement$=-end] .tooltip-arrow,.tooltip-panel[data-placement$=-end] .tooltip-arrow{left:auto;right:12px;transform:none}:host{display:inline-block}";
6
+ const tooltipStyles = "@charset \"UTF-8\";@layer reset,components,utilities;.tooltip-panel{position:fixed;z-index:var(--vi-tooltip-z-index, var(--vi-tooltip-z-index, 1070));pointer-events:none;opacity:0;transform:scale(.95);transition:opacity .15s ease-out,transform .15s ease-out;margin:0;border:none;background:transparent;padding:0;overflow:visible;font-family:var(--vi-font-family-base, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif)}.tooltip-panel[popover]:popover-open{display:block;pointer-events:auto;opacity:1;transform:scale(1)}.tooltip-panel{transition-property:opacity,transform,display,overlay;transition-behavior:allow-discrete}@media(prefers-reduced-motion:reduce){.tooltip-panel{transition:none;transform:none}}.tooltip-content{background-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827));color:var(--vi-tooltip-color, var(--vi-text-primary-inverse, #ffffff));font-size:var(--vi-tooltip-font-size, 12px);line-height:1.4;padding:var(--vi-tooltip-padding, 6px 10px);border-radius:var(--vi-tooltip-border-radius, 4px);box-shadow:var(--vi-tooltip-shadow, var(--vi-shadow-md, 0 4px 6px -1px rgba(0, 0, 0, .1)));max-width:var(--vi-tooltip-max-width, 240px);word-wrap:break-word;white-space:normal;position:relative}.tooltip-arrow{position:absolute;width:0;height:0;border-style:solid;border-color:transparent;pointer-events:none}.tooltip-panel[placement^=top] .tooltip-arrow,.tooltip-panel[data-placement^=top] .tooltip-arrow{bottom:calc(-1 * var(--vi-tooltip-arrow-size, 6px));left:50%;transform:translate(-50%);border-width:var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px) 0;border-top-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement^=bottom] .tooltip-arrow,.tooltip-panel[data-placement^=bottom] .tooltip-arrow{top:calc(-1 * var(--vi-tooltip-arrow-size, 6px));left:50%;transform:translate(-50%);border-width:0 var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px);border-bottom-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement=left] .tooltip-arrow,.tooltip-panel[data-placement=left] .tooltip-arrow{right:calc(-1 * var(--vi-tooltip-arrow-size, 6px));top:50%;transform:translateY(-50%);border-width:var(--vi-tooltip-arrow-size, 6px) 0 var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px);border-left-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement=right] .tooltip-arrow,.tooltip-panel[data-placement=right] .tooltip-arrow{left:calc(-1 * var(--vi-tooltip-arrow-size, 6px));top:50%;transform:translateY(-50%);border-width:var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px) var(--vi-tooltip-arrow-size, 6px) 0;border-right-color:var(--vi-tooltip-background, var(--vi-layer-inverse, #111827))}.tooltip-panel[placement$=-start] .tooltip-arrow,.tooltip-panel[data-placement$=-start] .tooltip-arrow{left:12px;transform:none}.tooltip-panel[placement$=-end] .tooltip-arrow,.tooltip-panel[data-placement$=-end] .tooltip-arrow{left:auto;right:12px;transform:none}:host{display:inline-block}";
7
+
8
+ /**
9
+ * OverlayManagerService
10
+ *
11
+ * A singleton service responsible for managing the z-index stacking context
12
+ * of all floating elements (Modals, Dropdowns, Tooltips, Toasts) across the application.
13
+ *
14
+ * It ensures that newly opened overlays always appear on top of existing ones by
15
+ * maintaining a registry and dynamically calculating the next highest z-index.
16
+ * It also manages global state side-effects, such as locking `document.body` scroll
17
+ * when a modal is active.
18
+ */ class OverlayManagerService {
19
+ _baseZIndexCache;
20
+ get baseZIndex() {
21
+ if (this._baseZIndexCache !== undefined) return this._baseZIndexCache;
22
+ if (typeof document !== 'undefined' && typeof getComputedStyle !== 'undefined') {
23
+ // Derive base stacking context from the modal z-index token (minus 10 to start slightly below it)
24
+ const cssVar = getComputedStyle(document.documentElement).getPropertyValue('--vi-modal-z-index').trim();
25
+ const parsed = parseInt(cssVar, 10);
26
+ this._baseZIndexCache = !isNaN(parsed) ? parsed - 10 : 1040;
27
+ } else {
28
+ this._baseZIndexCache = 1040;
29
+ }
30
+ return this._baseZIndexCache;
31
+ }
32
+ overlays = [];
33
+ _previousOverflow = null;
34
+ /**
35
+ * Registers an element as an active overlay.
36
+ * Calculates and returns the appropriate z-index for this overlay.
37
+ *
38
+ * @param element The DOM element being registered (e.g., the modal dialog or dropdown listbox)
39
+ * @param type The type of overlay, used to determine behaviors like scroll-locking.
40
+ * @returns The calculated z-index to be applied to the element.
41
+ */ register(element, type = 'dropdown') {
42
+ this.unregister(element); // Ensure no duplicates
43
+ let highestZIndex = this.baseZIndex;
44
+ if (this.overlays.length > 0) {
45
+ highestZIndex = Math.max(...this.overlays.map((o)=>o.zIndex));
46
+ }
47
+ // Increment by 10 to allow room for backdrops (which typically sit at z-index - 1)
48
+ const newZIndex = highestZIndex + 10;
49
+ this.overlays.push({
50
+ element,
51
+ type,
52
+ zIndex: newZIndex
53
+ });
54
+ this._updateBodyScroll();
55
+ return newZIndex;
56
+ }
57
+ /**
58
+ * Unregisters an element, removing it from the overlay stack.
59
+ * Should be called when the overlay is closed or disconnected from the DOM.
60
+ *
61
+ * @param element The DOM element to unregister.
62
+ */ unregister(element) {
63
+ this.overlays = this.overlays.filter((o)=>o.element !== element);
64
+ this._updateBodyScroll();
65
+ }
66
+ /**
67
+ * Gets the assigned z-index for an element if it is currently registered.
68
+ *
69
+ * @param element The DOM element to query.
70
+ * @returns The z-index number, or null if the element is not registered.
71
+ */ getZIndex(element) {
72
+ const item = this.overlays.find((o)=>o.element === element);
73
+ return item ? item.zIndex : null;
74
+ }
75
+ /**
76
+ * Evaluates whether the provided element is currently the top-most active overlay.
77
+ * Useful for trapping focus or handling global Escape key presses.
78
+ *
79
+ * @param element The DOM element to check.
80
+ * @returns True if the element has the highest z-index in the registry.
81
+ */ isTopOverlay(element) {
82
+ if (this.overlays.length === 0) return false;
83
+ const topOverlay = this.overlays.reduce((prev, current)=>prev.zIndex > current.zIndex ? prev : current);
84
+ return topOverlay.element === element;
85
+ }
86
+ /**
87
+ * Locks or unlocks the document.body scroll based on the presence of modals.
88
+ * Modals require the body to be unscrollable to trap scroll inside the modal.
89
+ * It applies a utility class `vi-scroll-locked` to the body.
90
+ */ _updateBodyScroll() {
91
+ const hasModal = this.overlays.some((o)=>o.type === 'modal');
92
+ if (hasModal) {
93
+ // Prevent double-setting if already locked
94
+ if (!document.body.classList.contains('vi-scroll-locked')) {
95
+ document.body.classList.add('vi-scroll-locked');
96
+ this._previousOverflow = document.body.style.getPropertyValue('overflow') || null;
97
+ document.body.style.setProperty('overflow', 'hidden', 'important');
98
+ }
99
+ } else {
100
+ if (document.body.classList.contains('vi-scroll-locked')) {
101
+ document.body.classList.remove('vi-scroll-locked');
102
+ if (this._previousOverflow !== null) {
103
+ document.body.style.setProperty('overflow', this._previousOverflow);
104
+ } else {
105
+ document.body.style.removeProperty('overflow');
106
+ }
107
+ this._previousOverflow = null;
108
+ }
109
+ }
110
+ }
111
+ }
112
+ // Export as a singleton
113
+ const OverlayManager = new OverlayManagerService();
7
114
 
8
115
  function applyDecs2203RFactory() {
9
116
  function createAddInitializerMethod(initializers, decoratorFinishedRef) {
@@ -591,6 +698,7 @@ new class extends _identity {
591
698
  _hideTimeout;
592
699
  _triggerElement = null;
593
700
  _cleanupAutoUpdate;
701
+ _overlayZIndex = null;
594
702
  _panelId = `vi-tooltip-panel-${Math.random().toString(36).substring(2, 9)}`;
595
703
  constructor(){
596
704
  super();
@@ -606,16 +714,25 @@ new class extends _identity {
606
714
  this._cleanupAutoUpdate();
607
715
  this._cleanupAutoUpdate = undefined;
608
716
  }
717
+ if (this._tooltipPanel && this._overlayZIndex !== null) {
718
+ OverlayManager.unregister(this._tooltipPanel);
719
+ this._overlayZIndex = null;
720
+ }
609
721
  this._removeTriggerAria();
610
722
  super.disconnectedCallback();
611
723
  }
612
724
  firstUpdated() {
613
- this._updateTriggerElement();
725
+ // Defer initialization to avoid Lit's "change in update" warning
726
+ Promise.resolve().then(()=>{
727
+ this._updateTriggerElement();
728
+ });
614
729
  }
615
730
  updated(changed) {
616
731
  super.updated(changed);
617
732
  if (changed.has('disabled') && this.disabled && this._open) {
618
- this._closeTooltip();
733
+ Promise.resolve().then(()=>{
734
+ this._closeTooltip();
735
+ });
619
736
  }
620
737
  if (changed.has('maxWidth') && this._tooltipPanel) {
621
738
  this._tooltipPanel.style.setProperty('--vi-tooltip-max-width', `${this.maxWidth}px`);
@@ -661,6 +778,9 @@ new class extends _identity {
661
778
  } catch {
662
779
  panel.style.display = 'block';
663
780
  }
781
+ // Register with OverlayManager
782
+ this._overlayZIndex = OverlayManager.register(panel, 'tooltip');
783
+ panel.style.zIndex = this._overlayZIndex.toString();
664
784
  this._positionTooltip();
665
785
  // Start autoUpdate monitoring for bounds changes
666
786
  this._cleanupAutoUpdate = autoUpdate(trigger, panel, ()=>{
@@ -686,6 +806,9 @@ new class extends _identity {
686
806
  } catch {
687
807
  panel.style.display = 'none';
688
808
  }
809
+ OverlayManager.unregister(panel);
810
+ panel.style.removeProperty('z-index');
811
+ this._overlayZIndex = null;
689
812
  if (this._cleanupAutoUpdate) {
690
813
  this._cleanupAutoUpdate();
691
814
  this._cleanupAutoUpdate = undefined;
@@ -837,7 +960,10 @@ new class extends _identity {
837
960
  Object.assign(panel.style, {
838
961
  position: strategy,
839
962
  left: `${x}px`,
840
- top: `${y}px`
963
+ top: `${y}px`,
964
+ right: 'auto',
965
+ bottom: 'auto',
966
+ margin: '0'
841
967
  });
842
968
  // Update data-placement attribute to trigger arrow CSS styles
843
969
  panel.setAttribute('data-placement', placement);
@@ -880,11 +1006,11 @@ new class extends _identity {
880
1006
  </span>
881
1007
 
882
1008
  <div
883
- popover="manual"
884
1009
  id=${_panelId}
885
1010
  class="tooltip-panel"
886
1011
  part="tooltip"
887
1012
  role=${this._isInteractive ? 'dialog' : 'tooltip'}
1013
+ popover="manual"
888
1014
  aria-modal=${this._isInteractive ? 'false' : nothing}
889
1015
  aria-label=${this._isInteractive ? content || 'Tooltip' : nothing}
890
1016
  placement=${placement}
@@ -458,7 +458,7 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
458
458
  * Whether this control will participate in form validation.
459
459
  * Per spec, disabled controls return false (they are not candidates).
460
460
  */ get willValidate() {
461
- return this._internals.willValidate;
461
+ return !this.disabled && this._internals.willValidate;
462
462
  }
463
463
  // ── Extension hooks for subclasses ────────────────────────────────────────
464
464
  /**