@ds-mo/ui 16.0.0 → 16.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.package-ready.json +1 -1
- package/dist/agent-patterns.json +1 -1
- package/dist/agent.json +5 -2
- package/dist/components/ds-agent-questionnaire.js +1 -1
- package/dist/components/ds-agent-response.js +1 -1
- package/dist/components/ds-banner.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-page-title.js +1 -1
- package/dist/components/ds-bar-title.js +1 -1
- package/dist/components/ds-bar-workflow.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/ds-calendar.js +1 -1
- package/dist/components/ds-card-chart.js +1 -1
- package/dist/components/ds-card-overview.js +1 -1
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-code-block.js +1 -1
- package/dist/components/ds-data-customize.js +1 -1
- package/dist/components/ds-data-filter.js +1 -1
- package/dist/components/ds-data-group.js +1 -1
- package/dist/components/ds-data-preferences.js +1 -1
- package/dist/components/ds-data-saved-views.js +1 -1
- package/dist/components/ds-data-search.js +1 -1
- package/dist/components/ds-data-sort.js +1 -1
- package/dist/components/ds-filter-menu.js +1 -1
- package/dist/components/ds-input-date.js +1 -1
- package/dist/components/ds-input-time.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-markdown.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-message-actions.js +1 -1
- package/dist/components/ds-message-composer.js +1 -1
- package/dist/components/ds-message-scroller.js +1 -1
- package/dist/components/ds-mobile-header.js +1 -1
- package/dist/components/ds-mobile-section-switcher.js +1 -1
- package/dist/components/ds-mobile-sheet-nav.js +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-pagination.js +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-tool-header.js +1 -1
- package/dist/components/ds-panel-tool-search.js +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-shell-app.js +1 -1
- package/dist/components/ds-shell-tools.js +1 -1
- package/dist/components/ds-table.js +1 -1
- package/dist/components/ds-table.js.map +1 -1
- package/dist/components/ds-time-picker.js +1 -1
- package/dist/components/ds-toast.js +1 -1
- package/dist/components/ds-toast.js.map +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/{p-BufAjyCA.js → p-9zDZcSc0.js} +2 -2
- package/dist/components/{p-SuM1Dske.js → p-B8jrUwL-.js} +2 -2
- package/dist/components/{p-DbBRCHst.js → p-BJB6kfA2.js} +2 -2
- package/dist/components/{p-a_-GSwE_.js → p-BK_SriZN.js} +2 -2
- package/dist/components/{p-DwiHy7ws.js → p-BKd0e8k8.js} +2 -2
- package/dist/components/{p-FsosWHV6.js → p-BNySDuzx.js} +2 -2
- package/dist/components/{p-DGznD-OD.js → p-BdJqRDKY.js} +2 -2
- package/dist/components/{p-CtBlyEwu.js → p-BgMeLCj3.js} +2 -2
- package/dist/components/{p-B6kIiHGc.js → p-BknNUjWh.js} +2 -2
- package/dist/components/{p-D1D_nwPJ.js → p-Bn-tsogb.js} +2 -2
- package/dist/components/{p-C9R-Yn0N.js → p-C3nUi5Lo.js} +2 -2
- package/dist/components/{p-9u2WDF0J.js → p-CbJx9swS.js} +2 -2
- package/dist/components/{p-ibSI50wY.js → p-CcWT4SzP.js} +2 -2
- package/dist/components/{p-BL98zGOI.js → p-Ckar-ZZa.js} +2 -2
- package/dist/components/{p-D4wFhnby.js → p-CvK-Gy-b.js} +2 -2
- package/dist/components/{p-8XJLNIKj.js → p-D9MqUHig.js} +2 -2
- package/dist/components/{p-BNimvRZy.js → p-DI5GEmid.js} +2 -2
- package/dist/components/p-DTlNtCX1.js +2 -0
- package/dist/components/p-DTlNtCX1.js.map +1 -0
- package/dist/components/p-D_kOVT6i.js +2 -0
- package/dist/components/{p-S6vTfjOk.js.map → p-D_kOVT6i.js.map} +1 -1
- package/dist/components/{p-DC_yjqdf.js → p-Ddkyu_wE.js} +2 -2
- package/dist/components/{p-CeaXdjwl.js → p-ZcZ0N7Ok.js} +2 -2
- package/dist/components/{p-BO0Tb3LT.js → p-ZumxIz-2.js} +2 -2
- package/dist/components/{p-BLPr2sCi.js → p-qnp-yeXl.js} +2 -2
- package/dist/components/{p-02bODFpT.js → p-txmcXZdy.js} +2 -2
- package/dist/components/{p-BiB2qjNS.js → p-xouEdChm.js} +2 -2
- package/dist/components/{p-Dp90dvw8.js → p-zdiRX3Sf.js} +2 -2
- package/dist/docs/components.json +13 -3
- package/dist/lib/toast/index.js +61 -20
- package/dist/lib/toast/index.js.map +2 -2
- package/dist/lib/toast/toast-types.d.ts +1 -0
- package/dist/mcp-data/registry/registry.json +4 -1
- package/dist/mcp-data/registry/table.json +22 -6
- package/dist/react/react-runtime.js +44 -1
- package/dist/types/components/Table/Table.d.ts +7 -2
- package/dist/types/components/Table/table-group-load-controller.d.ts +1 -1
- package/dist/types/components/Table/table-load-controller.d.ts +1 -2
- package/dist/types/components/Table/table-load-observer.d.ts +13 -0
- package/dist/types/toast/toast-types.d.ts +1 -0
- package/dist/types/utils/anchored-position-controller.d.ts +3 -2
- package/dist/vue/vue-runtime.js +13 -1
- package/package.json +15 -12
- package/dist/components/p-BMI0F08u.js +0 -2
- package/dist/components/p-BMI0F08u.js.map +0 -1
- package/dist/components/p-S6vTfjOk.js +0 -2
- /package/dist/components/{p-BufAjyCA.js.map → p-9zDZcSc0.js.map} +0 -0
- /package/dist/components/{p-SuM1Dske.js.map → p-B8jrUwL-.js.map} +0 -0
- /package/dist/components/{p-DbBRCHst.js.map → p-BJB6kfA2.js.map} +0 -0
- /package/dist/components/{p-a_-GSwE_.js.map → p-BK_SriZN.js.map} +0 -0
- /package/dist/components/{p-DwiHy7ws.js.map → p-BKd0e8k8.js.map} +0 -0
- /package/dist/components/{p-FsosWHV6.js.map → p-BNySDuzx.js.map} +0 -0
- /package/dist/components/{p-DGznD-OD.js.map → p-BdJqRDKY.js.map} +0 -0
- /package/dist/components/{p-CtBlyEwu.js.map → p-BgMeLCj3.js.map} +0 -0
- /package/dist/components/{p-B6kIiHGc.js.map → p-BknNUjWh.js.map} +0 -0
- /package/dist/components/{p-D1D_nwPJ.js.map → p-Bn-tsogb.js.map} +0 -0
- /package/dist/components/{p-C9R-Yn0N.js.map → p-C3nUi5Lo.js.map} +0 -0
- /package/dist/components/{p-9u2WDF0J.js.map → p-CbJx9swS.js.map} +0 -0
- /package/dist/components/{p-ibSI50wY.js.map → p-CcWT4SzP.js.map} +0 -0
- /package/dist/components/{p-BL98zGOI.js.map → p-Ckar-ZZa.js.map} +0 -0
- /package/dist/components/{p-D4wFhnby.js.map → p-CvK-Gy-b.js.map} +0 -0
- /package/dist/components/{p-8XJLNIKj.js.map → p-D9MqUHig.js.map} +0 -0
- /package/dist/components/{p-BNimvRZy.js.map → p-DI5GEmid.js.map} +0 -0
- /package/dist/components/{p-DC_yjqdf.js.map → p-Ddkyu_wE.js.map} +0 -0
- /package/dist/components/{p-CeaXdjwl.js.map → p-ZcZ0N7Ok.js.map} +0 -0
- /package/dist/components/{p-BO0Tb3LT.js.map → p-ZumxIz-2.js.map} +0 -0
- /package/dist/components/{p-BLPr2sCi.js.map → p-qnp-yeXl.js.map} +0 -0
- /package/dist/components/{p-02bODFpT.js.map → p-txmcXZdy.js.map} +0 -0
- /package/dist/components/{p-BiB2qjNS.js.map → p-xouEdChm.js.map} +0 -0
- /package/dist/components/{p-Dp90dvw8.js.map → p-zdiRX3Sf.js.map} +0 -0
|
@@ -6,8 +6,51 @@ import { createComponent as createLitComponent } from '@lit/react';
|
|
|
6
6
|
export function createComponent({ defineCustomElement, tagName, transformTag, ...options }) {
|
|
7
7
|
defineCustomElement?.();
|
|
8
8
|
const resolvedTagName = transformTag ? transformTag(tagName) : tagName;
|
|
9
|
-
|
|
9
|
+
const events = Object.entries(options.events ?? {});
|
|
10
|
+
const Bridge = createLitComponent({
|
|
10
11
|
...options,
|
|
12
|
+
// Own subscriptions so unmount releases application callbacks. Lit retains
|
|
13
|
+
// ownership of custom-element properties and native React props.
|
|
14
|
+
events: {},
|
|
11
15
|
tagName: resolvedTagName,
|
|
12
16
|
});
|
|
17
|
+
if (events.length === 0)
|
|
18
|
+
return Bridge;
|
|
19
|
+
const React = options.react;
|
|
20
|
+
const useBrowserLayoutEffect = typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
|
|
21
|
+
const Component = React.forwardRef((props, ref) => {
|
|
22
|
+
const element = React.useRef(null);
|
|
23
|
+
const elementProps = { ...props };
|
|
24
|
+
for (const [prop] of events)
|
|
25
|
+
delete elementProps[prop];
|
|
26
|
+
useBrowserLayoutEffect(() => {
|
|
27
|
+
const node = element.current;
|
|
28
|
+
if (!node)
|
|
29
|
+
return;
|
|
30
|
+
const subscriptions = [];
|
|
31
|
+
for (const [prop, name] of events) {
|
|
32
|
+
const handler = props[prop];
|
|
33
|
+
if (typeof handler !== 'function')
|
|
34
|
+
continue;
|
|
35
|
+
const listener = event => handler(event);
|
|
36
|
+
node.addEventListener(name, listener);
|
|
37
|
+
subscriptions.push([name, listener]);
|
|
38
|
+
}
|
|
39
|
+
return () => {
|
|
40
|
+
for (const [name, listener] of subscriptions)
|
|
41
|
+
node.removeEventListener(name, listener);
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
const setRef = React.useCallback((node) => {
|
|
45
|
+
element.current = node;
|
|
46
|
+
if (typeof ref === 'function')
|
|
47
|
+
ref(node);
|
|
48
|
+
else if (ref)
|
|
49
|
+
ref.current = node;
|
|
50
|
+
}, [ref]);
|
|
51
|
+
const bridgeProps = { ...elementProps, ref: setRef };
|
|
52
|
+
return React.createElement(Bridge, bridgeProps);
|
|
53
|
+
});
|
|
54
|
+
Component.displayName = options.displayName ?? resolvedTagName;
|
|
55
|
+
return Component;
|
|
13
56
|
}
|
|
@@ -3,6 +3,9 @@ import type { TableCellSpan, TableCellRange, TableCellsChangeDetail } from './ta
|
|
|
3
3
|
import type { PaginationChangeDetail } from '../Pagination/pagination-types';
|
|
4
4
|
import type { MenuItemData } from '../Menu/menu-types';
|
|
5
5
|
import type { TableCaptionVisibility, TableChromeLayout, TableCellActionDetail, TableColumn, DataFieldsConfigChangeDetail, TableDataMode, TableDataModeChangeDetail, DataGroup, TableGroupCollapseChangeDetail, TableGroupLoadMoreDetail, DataGroupingState, TableLoadMoreDetail, TableLoadMoreMode, TablePaginationState, TableRow, TableRowActivateDetail, TableSelectionChangeDetail, TableSelectionMode, DataSortChangeDetail, DataSortState } from './table-types';
|
|
6
|
+
/**
|
|
7
|
+
* @slot error-actions - Application-owned recovery controls below the initial error message.
|
|
8
|
+
*/
|
|
6
9
|
export declare class Table {
|
|
7
10
|
el: HTMLElement;
|
|
8
11
|
/** Stable column definitions. Assign through JavaScript. */
|
|
@@ -166,6 +169,7 @@ export declare class Table {
|
|
|
166
169
|
private headerUsesToolbar;
|
|
167
170
|
private captionTrailingPresent;
|
|
168
171
|
private footerSlotPresence;
|
|
172
|
+
private errorActionsPresent;
|
|
169
173
|
private fitPageSize;
|
|
170
174
|
private actionMenu;
|
|
171
175
|
private actionMenuInitialFocusVisible;
|
|
@@ -209,7 +213,7 @@ export declare class Table {
|
|
|
209
213
|
private renderedModel;
|
|
210
214
|
private stickyGroupConnected;
|
|
211
215
|
private headerSlotObserver;
|
|
212
|
-
private
|
|
216
|
+
private contentSlotObserver;
|
|
213
217
|
private captionCompactDisconnect;
|
|
214
218
|
private fitResizeObserver;
|
|
215
219
|
private fitObservedViewport;
|
|
@@ -242,7 +246,8 @@ export declare class Table {
|
|
|
242
246
|
private syncHeaderSlotPresence;
|
|
243
247
|
private connectHeaderSlotObserver;
|
|
244
248
|
private syncFooterSlotPresence;
|
|
245
|
-
private
|
|
249
|
+
private syncContentSlotPresence;
|
|
250
|
+
private connectContentSlotObserver;
|
|
246
251
|
private connectStickyGroup;
|
|
247
252
|
private syncStickyGroupConnection;
|
|
248
253
|
private disconnectStickyGroup;
|
|
@@ -21,7 +21,7 @@ export declare class TableGroupLoadController {
|
|
|
21
21
|
private readonly options;
|
|
22
22
|
readonly intersectionSupported: boolean;
|
|
23
23
|
private connected;
|
|
24
|
-
private
|
|
24
|
+
private readonly observer;
|
|
25
25
|
private snapshots;
|
|
26
26
|
private pending;
|
|
27
27
|
constructor(options: TableGroupLoadControllerOptions);
|
|
@@ -25,8 +25,7 @@ export declare class TableLoadController {
|
|
|
25
25
|
private readonly options;
|
|
26
26
|
readonly intersectionSupported: boolean;
|
|
27
27
|
private connected;
|
|
28
|
-
private
|
|
29
|
-
private observedSentinel;
|
|
28
|
+
private readonly observer;
|
|
30
29
|
private requestPending;
|
|
31
30
|
private requestedRowCount;
|
|
32
31
|
private previousLoadedRowCount;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Reconciles loading sentinels without rebuilding an observer on every render. */
|
|
2
|
+
export declare class TableLoadObserver {
|
|
3
|
+
private readonly intersect;
|
|
4
|
+
private observer;
|
|
5
|
+
private targets;
|
|
6
|
+
private root;
|
|
7
|
+
private margin;
|
|
8
|
+
private revision;
|
|
9
|
+
constructor(intersect: (id: string, target: HTMLElement) => void);
|
|
10
|
+
refresh(targets: ReadonlyMap<HTMLElement, string>, root: HTMLElement | null, threshold: number): void;
|
|
11
|
+
disconnect(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=table-load-observer.d.ts.map
|
|
@@ -63,6 +63,7 @@ export interface ToastManager<Data = unknown> {
|
|
|
63
63
|
update(id: string, updates: Partial<ToastOptions<Data>>): void;
|
|
64
64
|
close(id: string, reason?: ToastCloseReason): void;
|
|
65
65
|
closeAll(reason?: ToastCloseReason): void;
|
|
66
|
+
/** A replaced, retyped, or dismissed loading toast ignores its old promise's presentation result; progress copy may still update. */
|
|
66
67
|
promise<Value>(promiseValue: PromiseLike<Value>, options: ToastPromiseOptions<Value, Data>): Promise<Value>;
|
|
67
68
|
subscribe(listener: ToastListener<Data>): () => void;
|
|
68
69
|
getSnapshot(): readonly ToastRecord<Data>[];
|
|
@@ -72,6 +72,7 @@ export declare class AnchoredPositionController {
|
|
|
72
72
|
private readonly options;
|
|
73
73
|
private scrollResizeHandler;
|
|
74
74
|
private resizeObserver;
|
|
75
|
+
private resizeTargets;
|
|
75
76
|
private retryRaf;
|
|
76
77
|
private liveRaf;
|
|
77
78
|
private anchorMotionRaf;
|
|
@@ -113,8 +114,8 @@ export declare class AnchoredPositionController {
|
|
|
113
114
|
private eventCanMoveAnchor;
|
|
114
115
|
private scheduleAnchorMotionUpdate;
|
|
115
116
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
117
|
+
* Keep only the current connected anchor and popup observed. Replaced or
|
|
118
|
+
* detached elements must not remain retained until the overlay closes.
|
|
118
119
|
*/
|
|
119
120
|
observeResizeTargets(): void;
|
|
120
121
|
}
|
package/dist/vue/vue-runtime.js
CHANGED
|
@@ -212,7 +212,19 @@ var defineContainer = (name, defineCustomElement, componentProps = [], emitProps
|
|
|
212
212
|
emits
|
|
213
213
|
});
|
|
214
214
|
};
|
|
215
|
+
|
|
216
|
+
// src/framework/vue-runtime.ts
|
|
217
|
+
function defineContainer2(...args) {
|
|
218
|
+
const component = defineContainer(...args);
|
|
219
|
+
const { props } = component;
|
|
220
|
+
for (const name of args[2] ?? []) {
|
|
221
|
+
if (name.startsWith("aria") && typeof props[name]?.default === "symbol") {
|
|
222
|
+
props[name] = { ...props[name], default: void 0 };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return component;
|
|
226
|
+
}
|
|
215
227
|
export {
|
|
216
|
-
defineContainer,
|
|
228
|
+
defineContainer2 as defineContainer,
|
|
217
229
|
defineStencilSSRComponent
|
|
218
230
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ds-mo/ui",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.1.1",
|
|
4
4
|
"description": "CompoMo — composable web components styled with TokoMo design tokens",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web-components",
|
|
@@ -95,8 +95,9 @@
|
|
|
95
95
|
"pretest": "node scripts/generate-icon-catalog.mjs",
|
|
96
96
|
"build": "stencil build && node scripts/finalize-package.mjs",
|
|
97
97
|
"verify:pack": "node scripts/verify-framework-proxies.mjs && node scripts/verify-npm-pack.mjs && node scripts/verify-package-imports.mjs",
|
|
98
|
-
"verify:local": "npm run format:check && npm run typecheck && npm run typecheck:storybook && npm run lint && npm test && npm run build && npm run agent:validate && npm run verify:pack",
|
|
99
|
-
"verify:local:full": "npm run verify:local && npm run test:e2e:chromium",
|
|
98
|
+
"verify:local": "npm run format:check && npm run verify:storybook-compatibility && npm run typecheck && npm run typecheck:storybook && npm run lint && npm test && npm run build && npm run agent:validate && npm run verify:pack",
|
|
99
|
+
"verify:local:full": "npm run verify:local && npm run test:e2e:chromium && npm run test:framework-consumers",
|
|
100
|
+
"test:framework-consumers": "node scripts/verify-package-imports.mjs --browser",
|
|
100
101
|
"perf:measure": "node --import tsx/esm scripts/measure-performance.mjs && node scripts/measure-bundles.mjs",
|
|
101
102
|
"test": "node --import tsx/esm --test tests/*.test.ts",
|
|
102
103
|
"test:e2e": "npm run build && playwright test",
|
|
@@ -128,7 +129,9 @@
|
|
|
128
129
|
"registry:build": "node scripts/build-registry.mjs",
|
|
129
130
|
"agent:validate": "node scripts/validate-agent-contract.mjs",
|
|
130
131
|
"agent:validate:trilogy": "node scripts/validate-trilogy-manifests.mjs",
|
|
131
|
-
"mcp": "node scripts/mcp-server.mjs"
|
|
132
|
+
"mcp": "node scripts/mcp-server.mjs",
|
|
133
|
+
"test:visual": "playwright test --config playwright.visual.config.ts",
|
|
134
|
+
"verify:storybook-compatibility": "npm ls storybook @storybook/addon-vitest vitest @vitest/browser-playwright"
|
|
132
135
|
},
|
|
133
136
|
"peerDependencies": {
|
|
134
137
|
"@angular/core": ">=19 <23",
|
|
@@ -192,11 +195,11 @@
|
|
|
192
195
|
"@stencil/core": "^4.43.5",
|
|
193
196
|
"@stencil/react-output-target": "^1.6.0",
|
|
194
197
|
"@stencil/vue-output-target": "^0.14.1",
|
|
195
|
-
"@storybook/addon-a11y": "^10.
|
|
196
|
-
"@storybook/addon-docs": "^10.
|
|
197
|
-
"@storybook/addon-vitest": "^10.
|
|
198
|
-
"@storybook/web-components": "^10.
|
|
199
|
-
"@storybook/web-components-vite": "^10.
|
|
198
|
+
"@storybook/addon-a11y": "^10.6.1",
|
|
199
|
+
"@storybook/addon-docs": "^10.6.1",
|
|
200
|
+
"@storybook/addon-vitest": "^10.6.1",
|
|
201
|
+
"@storybook/web-components": "^10.6.1",
|
|
202
|
+
"@storybook/web-components-vite": "^10.6.1",
|
|
200
203
|
"@types/d3-array": "^3.2.2",
|
|
201
204
|
"@types/d3-scale": "^4.0.9",
|
|
202
205
|
"@types/d3-shape": "^3.1.8",
|
|
@@ -204,7 +207,7 @@
|
|
|
204
207
|
"@types/react": "^19.2.17",
|
|
205
208
|
"@types/react-dom": "^19.2.3",
|
|
206
209
|
"@types/sax": "^1.2.7",
|
|
207
|
-
"@vitest/browser-playwright": "^5.0.
|
|
210
|
+
"@vitest/browser-playwright": "^5.0.3",
|
|
208
211
|
"ajv": "^8.20.0",
|
|
209
212
|
"axe-core": "^4.12.1",
|
|
210
213
|
"colord": "^2.9.4",
|
|
@@ -223,13 +226,13 @@
|
|
|
223
226
|
"prettier": "3.8.3",
|
|
224
227
|
"react": "^19.2.7",
|
|
225
228
|
"react-dom": "^19.2.7",
|
|
226
|
-
"storybook": "^10.
|
|
229
|
+
"storybook": "^10.6.1",
|
|
227
230
|
"svg-tags": "^1.0.0",
|
|
228
231
|
"tsx": "^4.23.0",
|
|
229
232
|
"typescript": "~6.0.3",
|
|
230
233
|
"typescript-eslint": "^8.63.0",
|
|
231
234
|
"vite": "^8.1.4",
|
|
232
|
-
"vitest": "^5.0.
|
|
235
|
+
"vitest": "^5.0.3",
|
|
233
236
|
"vue": "^3.5.41",
|
|
234
237
|
"vue-router": "^5.2.0",
|
|
235
238
|
"zod": "^4.4.3"
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{p as t,H as i,h as s,a as o,t as n}from"./index.js";import{d as e}from"./p-DMPn_dt7.js";import{b as r,T as h,a,r as l}from"./p-mSCnWLhL.js";import{r as d}from"./p-CVYjLzYI.js";import{C as c}from"./p-CuwopElg.js";const p=new Set(["⌘","⇧","⌥","⌃"]);const u={alt:"⌥",cmd:"⌘",command:"⌘",control:"⌃",ctrl:"⌃",option:"⌥",shift:"⇧"};function f(t){return u[t.toLowerCase()]??t}function m(t){const i=t.trim();if(!i)return[];if(i.includes("+")){return i.split("+").map((t=>t.trim())).filter(Boolean).map(f)}if(/\s/.test(i)){return i.split(/\s+/).filter(Boolean).map(f)}const s=Array.from(i);const o=[];while(s.length>1&&p.has(s[0])){o.push(s.shift())}o.push(s.join(""));return o}const g={top:"bottom",right:"left",bottom:"top",left:"right"};function v(t,i){const{anchorRect:s,popupWidth:o,popupHeight:n,align:e,sideOffsetPx:r,alignOffsetPx:h}=t;if(i==="top"||i==="bottom"){return{x:e==="start"?s.left+h:e==="end"?s.right-o+h:s.left+s.width/2-o/2+h,y:i==="top"?s.top-n-r:s.bottom+r}}return{x:i==="left"?s.left-o-r:s.right+r,y:e==="start"?s.top+h:e==="end"?s.bottom-n+h:s.top+s.height/2-n/2+h}}function y(t){const i=t.collisionRect??{top:0,left:0,right:t.viewportWidth,bottom:t.viewportHeight};return{top:i.top+t.viewportPadPx,left:i.left+t.viewportPadPx,right:i.right-t.viewportPadPx,bottom:i.bottom-t.viewportPadPx}}function b(t,i,s){const{popupWidth:o,popupHeight:n}=t;const e=y(t);if(i==="top"||i==="bottom"){return Math.max(e.top-s.y,0)+Math.max(s.y+n-e.bottom,0)}return Math.max(e.left-s.x,0)+Math.max(s.x+o-e.right,0)}function w(t,i,s,o){const n=Math.max(s,o-i);return Math.min(Math.max(t,s),n)}function x(t){const i=y(t);const s=v(t,t.side);const o=g[t.side];const n=v(t,o);const e=b(t,t.side,s);const r=b(t,o,n);const h=e>0&&r<e;const a=h?o:t.side;const l=h?n:s;const d=a==="top"?t.anchorRect.top-i.top-t.sideOffsetPx:a==="bottom"?i.bottom-t.anchorRect.bottom-t.sideOffsetPx:i.bottom-i.top;return{x:w(l.x,t.popupWidth,i.left,i.right),y:w(l.y,t.popupHeight,i.top,i.bottom),resolvedSide:a,availableHeight:Math.max(0,d)}}const C=8;class O{constructor(t){this.scrollResizeHandler=null;this.resizeObserver=null;this.retryRaf=null;this.liveRaf=null;this.anchorMotionRaf=null;this.activeAnchorMotions=0;this.ownerDocument=null;this.last=null;this.isReady=false;this.generation=0;this.retryGeneration=0;this.anchorMotionStartHandler=t=>{if(!this.eventCanMoveAnchor(t))return;this.activeAnchorMotions+=1;this.scheduleAnchorMotionUpdate()};this.anchorMotionEndHandler=t=>{if(!this.eventCanMoveAnchor(t))return;this.activeAnchorMotions=Math.max(0,this.activeAnchorMotions-1);this.scheduleAnchorMotionUpdate()};this.options=t}get ready(){return this.isReady}observe(){this.bindListeners()}unobserve(){this.unbindListeners();this.cancel();this.last=null;this.isReady=false}schedule(t){this.cancelRetry();this.isReady=false;const i=this.generation;const s=this.retryGeneration;const o=()=>i===this.generation&&s===this.retryGeneration;let n=this.options.retryBudget??C;const e=()=>{if(!o())return;this.retryRaf=null;const i=this.update();if(!o())return;if(i){this.isReady=true;this.options.onReady?.();if(o())t?.();return}if(n>0){n-=1;this.retryRaf=requestAnimationFrame(e)}};this.retryRaf=requestAnimationFrame(e)}update(){const t=this.options.getAnchor();if(!t?.isConnected)return false;const i=this.options.getPopup();if(!i?.isConnected)return false;this.observeResizeTargets();if(this.options.topLayer&&typeof i.showPopover==="function"&&!i.matches(":popover-open")){try{i.showPopover()}catch{return false}}const s=this.options.measure(t,i);if(!s)return false;const o=x(s);if(!this.last||this.last.x!==o.x||this.last.y!==o.y||this.last.resolvedSide!==o.resolvedSide||this.last.availableHeight!==o.availableHeight){this.last=o;this.options.apply(o)}return true}scheduleLiveUpdate(){const t=this.generation;const i=this.options.liveUpdate??"sync";if(i==="sync"){this.update();return}if(this.liveRaf!==null)return;if(i==="frame"){this.liveRaf=requestAnimationFrame((()=>{if(t!==this.generation)return;this.liveRaf=null;this.update()}));return}this.liveRaf=requestAnimationFrame((()=>{if(t!==this.generation)return;this.update();if(t!==this.generation)return;this.liveRaf=requestAnimationFrame((()=>{if(t!==this.generation)return;this.liveRaf=null;this.update()}))}))}cancel(){this.generation+=1;this.cancelRetry();if(this.liveRaf!==null){cancelAnimationFrame(this.liveRaf);this.liveRaf=null}if(this.anchorMotionRaf!==null){cancelAnimationFrame(this.anchorMotionRaf);this.anchorMotionRaf=null}}cancelRetry(){this.retryGeneration+=1;if(this.retryRaf===null)return;cancelAnimationFrame(this.retryRaf);this.retryRaf=null}bindListeners(){this.unbindListeners();this.scrollResizeHandler=()=>this.scheduleLiveUpdate();window.addEventListener("scroll",this.scrollResizeHandler,true);window.addEventListener("resize",this.scrollResizeHandler);if(this.options.observeResize&&typeof ResizeObserver!=="undefined"){const t=new ResizeObserver((()=>{if(this.resizeObserver===t)this.scheduleLiveUpdate()}));this.resizeObserver=t;this.observeResizeTargets()}if(this.options.observeAnchorMotion){this.ownerDocument=this.options.getAnchor()?.ownerDocument??this.options.getOwnerDocument?.()??null;this.ownerDocument?.addEventListener("transitionrun",this.anchorMotionStartHandler,true);this.ownerDocument?.addEventListener("transitionend",this.anchorMotionEndHandler,true);this.ownerDocument?.addEventListener("transitioncancel",this.anchorMotionEndHandler,true);this.ownerDocument?.addEventListener("animationstart",this.anchorMotionStartHandler,true);this.ownerDocument?.addEventListener("animationend",this.anchorMotionEndHandler,true);this.ownerDocument?.addEventListener("animationcancel",this.anchorMotionEndHandler,true)}}unbindListeners(){if(this.scrollResizeHandler){window.removeEventListener("scroll",this.scrollResizeHandler,true);window.removeEventListener("resize",this.scrollResizeHandler);this.scrollResizeHandler=null}this.resizeObserver?.disconnect();this.resizeObserver=null;this.ownerDocument?.removeEventListener("transitionrun",this.anchorMotionStartHandler,true);this.ownerDocument?.removeEventListener("transitionend",this.anchorMotionEndHandler,true);this.ownerDocument?.removeEventListener("transitioncancel",this.anchorMotionEndHandler,true);this.ownerDocument?.removeEventListener("animationstart",this.anchorMotionStartHandler,true);this.ownerDocument?.removeEventListener("animationend",this.anchorMotionEndHandler,true);this.ownerDocument?.removeEventListener("animationcancel",this.anchorMotionEndHandler,true);this.ownerDocument=null;this.activeAnchorMotions=0}eventCanMoveAnchor(t){const i=this.options.getAnchor();const s=t.target;if(!i||!(s instanceof Element))return false;return s===i||s.contains(i)}scheduleAnchorMotionUpdate(){if(this.anchorMotionRaf!==null)return;const t=this.generation;const i=()=>{if(t!==this.generation)return;this.anchorMotionRaf=null;this.update();if(t!==this.generation)return;if(this.activeAnchorMotions<=0||!this.options.getAnchor()?.isConnected){this.activeAnchorMotions=0;return}this.anchorMotionRaf=requestAnimationFrame(i)};this.anchorMotionRaf=requestAnimationFrame(i)}observeResizeTargets(){if(!this.resizeObserver)return;const t=this.options.getPopup();if(t)this.resizeObserver.observe(t);const i=this.options.getAnchor();if(i)this.resizeObserver.observe(i)}}const P="data-ds-overlay-boundary";function k(t){if(t.assignedSlot)return t.assignedSlot;if(t.parentElement)return t.parentElement;const i=t.getRootNode();return i instanceof ShadowRoot?i.host:null}function z(t){let i=t;while(i){if(i instanceof HTMLElement&&i.hasAttribute(P)){return i}i=k(i)}return null}function A(t,i){if(i==="viewport")return undefined;return(i??z(t))?.getBoundingClientRect()}const F=()=>`.sc-ds-tooltip-h,.sc-ds-tooltip:where(.ds-table),.sc-ds-tooltip:where(.tooltip-popup),.sc-ds-tooltip:where(.ds-radius){--ds-radius-control:var(--dimension-radius-025);--ds-radius-card:var(--dimension-radius-050);--ds-radius-modal:var(--dimension-radius-050);--ds-radius-menu:var(--dimension-radius-075);--ds-radius-tooltip-control:var(--dimension-radius-025);--ds-radius-tooltip-menu:var(--dimension-radius-075);--ds-radius-table:var(--dimension-radius-050)}.ds-control--lg.sc-ds-tooltip,.ds-control--lg.sc-ds-tooltip-h,.ds-control--md.sc-ds-tooltip-h,.ds-control--md.sc-ds-tooltip,.ds-control--sm.sc-ds-tooltip-h,.ds-control--sm.sc-ds-tooltip,.ds-control--xs.sc-ds-tooltip-h,.ds-control--xs.sc-ds-tooltip{--ds-control-radius:var(--ds-radius-control)}.ds-control--lg.sc-ds-tooltip-h,.ds-control--lg.sc-ds-tooltip{--ds-control-height:var(--dimension-size-500);--ds-control-icon:var(--dimension-iconography-lg);--ds-control-padding-inline:var(--dimension-space-100);--ds-control-label-inset:var(--dimension-space-050);--ds-control-gap:var(--dimension-space-050)}.ds-control--md.sc-ds-tooltip-h,.ds-control--md.sc-ds-tooltip{--ds-control-height:var(--dimension-size-400);--ds-control-icon:var(--dimension-iconography-md);--ds-control-padding-inline:var(--dimension-space-075);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-050)}.ds-control--sm.sc-ds-tooltip-h,.ds-control--sm.sc-ds-tooltip{--ds-control-height:var(--dimension-size-300);--ds-control-icon:var(--dimension-iconography-sm);--ds-control-padding-inline:var(--dimension-space-050);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-025)}.ds-control--xs.sc-ds-tooltip-h,.ds-control--xs.sc-ds-tooltip{--ds-control-height:var(--dimension-size-200);--ds-control-icon:var(--dimension-iconography-xs);--ds-control-padding-inline:var(--dimension-space-025);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:0}.ds-control--lg.sc-ds-tooltip,.ds-control--lg.sc-ds-tooltip-h,.ds-control--md.sc-ds-tooltip-h,.ds-control--md.sc-ds-tooltip,.ds-control--sm.sc-ds-tooltip-h,.ds-control--sm.sc-ds-tooltip,.ds-control--xs.sc-ds-tooltip-h,.ds-control--xs.sc-ds-tooltip{--ds-control-radius:var(--ds-radius-control)}.ds-control--lg.sc-ds-tooltip-h,.ds-control--lg.sc-ds-tooltip{--ds-control-height:var(--dimension-size-500);--ds-control-icon:var(--dimension-iconography-lg);--ds-control-padding-inline:var(--dimension-space-100);--ds-control-label-inset:var(--dimension-space-050);--ds-control-gap:var(--dimension-space-050)}.ds-control--md.sc-ds-tooltip-h,.ds-control--md.sc-ds-tooltip{--ds-control-height:var(--dimension-size-400);--ds-control-icon:var(--dimension-iconography-md);--ds-control-padding-inline:var(--dimension-space-075);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-050)}.ds-control--sm.sc-ds-tooltip-h,.ds-control--sm.sc-ds-tooltip{--ds-control-height:var(--dimension-size-300);--ds-control-icon:var(--dimension-iconography-sm);--ds-control-padding-inline:var(--dimension-space-050);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:var(--dimension-space-025)}.ds-control--xs.sc-ds-tooltip-h,.ds-control--xs.sc-ds-tooltip{--ds-control-height:var(--dimension-size-200);--ds-control-icon:var(--dimension-iconography-xs);--ds-control-padding-inline:var(--dimension-space-025);--ds-control-label-inset:var(--dimension-space-025);--ds-control-gap:0}.key-hint-group.sc-ds-tooltip{display:inline-flex;align-items:center;gap:var(--dimension-stroke-width-012);width:max-content;flex-shrink:0}.key-hint.sc-ds-tooltip{box-sizing:border-box;min-width:var(--ds-control-icon, var(--dimension-iconography-md));width:var(--ds-control-icon, var(--dimension-iconography-md));height:var(--ds-control-icon, var(--dimension-iconography-md));padding-inline:0;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;background-color:var(--color-background-secondary);border:var(--dimension-stroke-width-015) solid var(--color-border-tertiary);border-bottom-width:var(--dimension-stroke-width-025);border-radius:var(--dimension-radius-025);color:var(--color-foreground-secondary)}.key-hint--wide.sc-ds-tooltip{width:calc(var(--ds-control-icon, var(--dimension-iconography-md)) * 1.5)}.key-hint__label.sc-ds-tooltip{display:inline-flex;width:max-content;min-width:max-content;font-family:var(--typography-font-family-ui);font-size:var(--typography-fontsize-xs);line-height:1;font-weight:var(--typography-weight-regular);letter-spacing:0;text-transform:uppercase;color:inherit}.ds-control--xs.sc-ds-tooltip .key-hint__label.sc-ds-tooltip{font-size:calc(var(--typography-fontsize-xs) * 0.78)}@media (forced-colors: active){.sc-ds-tooltip:root,.sc-ds-tooltip-h,.ds-forced-colors-scope.sc-ds-tooltip{--ds-forced-color-surface:Canvas;--ds-forced-color-content:CanvasText;--ds-forced-color-control-boundary:ButtonText;--ds-forced-color-selected:Highlight;--ds-forced-color-on-selected:HighlightText;--ds-forced-color-disabled:GrayText}}.tooltip-popup.sc-ds-tooltip{box-sizing:border-box;background-color:var(--color-background-primary);border-radius:var(--ds-radius-tooltip-control, var(--dimension-radius-025));box-shadow:var(--effect-elevation-elevated-floating);white-space:nowrap;pointer-events:none;animation:tooltipFadeIn var(--effect-motion-short-2) forwards;will-change:transform;backface-visibility:hidden}.tooltip-popup--instant.sc-ds-tooltip{animation:none;opacity:1}.tooltip-popup--closing.sc-ds-tooltip{animation:tooltipFadeOut var(--effect-motion-short-3) forwards}.tooltip-inner.sc-ds-tooltip{box-sizing:border-box;height:var(--ds-control-height, var(--dimension-size-400));display:flex;align-items:center;gap:var(--ds-control-gap, var(--dimension-space-050));padding:0 var(--ds-control-padding-inline, var(--dimension-space-075))}.tooltip-inner.sc-ds-tooltip>ds-text.sc-ds-tooltip{flex-shrink:0;min-width:max-content;max-width:none;padding:0 var(--ds-control-label-inset, var(--dimension-space-025));color:var(--color-foreground-primary)}.tooltip-popup--wrap.sc-ds-tooltip{white-space:normal;max-inline-size:var(--dimension-panel-width-xs)}.tooltip-popup--wrap.sc-ds-tooltip .tooltip-inner.sc-ds-tooltip{height:auto;min-height:var(--ds-control-height, var(--dimension-size-400));padding-block:var(--dimension-space-050);align-items:flex-start}.tooltip-popup--wrap.sc-ds-tooltip .tooltip-inner.sc-ds-tooltip>ds-text.sc-ds-tooltip{flex:1 1 auto;min-width:0;max-width:100%;white-space:pre-line}@keyframes tooltipFadeIn{from{opacity:0}to{opacity:1}}@keyframes tooltipFadeOut{from{opacity:1}to{opacity:0}}@media (prefers-reduced-motion: reduce){.tooltip-popup.sc-ds-tooltip,.tooltip-popup--instant.sc-ds-tooltip{animation:none;opacity:1}.tooltip-popup--closing.sc-ds-tooltip{animation:none;opacity:0}}@media (forced-colors: active){.tooltip-popup.sc-ds-tooltip{box-shadow:none;outline:var(--dimension-stroke-width-012) solid var(--ds-forced-color-content);outline-offset:calc(-1 * var(--dimension-stroke-width-012))}}`;const M={md:h.size400,sm:h.size300,xs:h.size200};let L=0;let T=0;let R=null;function q(t){const i=document.createElement("ds-text");i.as="span";i.variant=t.variant;i.emphasis=t.emphasis??false;i.color=t.color??"inherit";if(t.wrap)i.wrap=t.wrap;i.textContent=t.text;return i}function D(t,i=false){t.style.flexShrink=i?"1":"0";t.style.minWidth=i?"0":"max-content";t.style.maxWidth=i?"100%":"none";t.style.whiteSpace=i?"pre-line":"";t.style.padding="0 var(--ds-control-label-inset, var(--dimension-space-025))";t.style.color="var(--color-foreground-primary)"}const E=t(class t extends i{constructor(t){super();if(t!==false){this.__registerHost()}this.size="md";this.side="top";this.align="center";this.sideOffset=r.space050;this.alignOffset=0;this.delay=h.animationDelayMedium3;this.shortcutKeyPosition="end";this.describedBy=true;this.wrapLabel=false;this.tooltipId=`ds-tooltip-${++T}`;this.delayTimer=null;this.closeTimer=null;this.anchor=null;this.popupEl=null;this.anchorObserver=null;this.didLoad=false;this.position=new O({getAnchor:()=>this.anchor,getPopup:()=>this.popupEl,getOwnerDocument:()=>this.el.ownerDocument,measure:(t,i)=>({anchorRect:t.getBoundingClientRect(),popupWidth:i.offsetWidth||this.tooltipFallbackWidthPx,popupHeight:i.offsetHeight||this.tooltipFallbackHeightPx,side:this.side,align:this.align,sideOffsetPx:this.sideOffsetPx,alignOffsetPx:this.alignOffsetPx,viewportPadPx:this.viewportPadPx,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,collisionRect:A(t,this.boundary)}),apply:({x:t,y:i,resolvedSide:s})=>{if(!this.popupEl)return;this.popupEl.dataset.side=s;this.popupEl.style.transform=`translate(${Math.round(t)}px, ${Math.round(i)}px)`},liveUpdate:"frame",observeResize:true});this.skipEnterAnimation=false;this.isOpen=false;this.programmaticAnchor=false;this.lastInteractionWasKeyboard=false;this.pointerEnterHandler=t=>{if(t.pointerType==="touch")return;this.show()};this.pointerLeaveHandler=t=>{if(t.pointerType==="touch")return;this.hide()};this.pointerDownHandler=t=>{this.lastInteractionWasKeyboard=false;if(t.pointerType==="touch"&&(this.isOpen||this.popupEl))this.hideInstant()};this.keyDownHandler=()=>{this.lastInteractionWasKeyboard=true};this.focusHandler=()=>{if(this.lastInteractionWasKeyboard||this.anchor?.matches(":focus-visible"))this.show()};this.blurHandler=t=>{const i=t.relatedTarget;if(i&&this.anchor?.contains(i))return;this.hide()};this.escapeHandler=t=>{if(t.key!=="Escape"||!this.isOpen)return;t.preventDefault();this.hide()};this.handleSlotChange=()=>{if(this.programmaticAnchor)return;const t=this.el.querySelector("slot");const i=t?.assignedElements?.()[0]??this.el.firstElementChild;if(i===this.anchor||i?.tagName==="SLOT")return;if(this.isOpen||this.popupEl)this.hideInstant();this.unbindAnchor();this.bindAnchor()}}connectedCallback(){if(!this.didLoad)return;this.connectAnchor()}componentDidLoad(){this.didLoad=true;this.connectAnchor()}connectAnchor(){this.bindAnchor();if(this.anchorObserver)return;this.anchorObserver=new MutationObserver((()=>this.handleSlotChange()));this.anchorObserver.observe(this.el,{childList:true})}disconnectedCallback(){if(R===this)R=null;this.anchorObserver?.disconnect();this.anchorObserver=null;this.unbindAnchor();this.clearTimers();this.destroyPopup()}onContentOrPositionChange(){if(!this.label?.trim()){if(this.isOpen||this.popupEl)this.hideInstant();return}if(!this.popupEl||!this.isOpen)return;this.renderPopupContent();this.schedulePosition()}get viewportPadPx(){return d(h.space050,h.space050)}get sideOffsetPx(){return d(this.sideOffset,h.space050)}get alignOffsetPx(){return d(this.alignOffset,0)}get hoverDelayMs(){return a(this.delay,h.animationDelayMedium3)}get instantReopenMs(){return a(h.animationDurationMedium1,h.animationDurationMedium1)}get fadeOutMs(){return l(h.motionShort3,h.animationDurationShort3)}get tooltipFallbackWidthPx(){return d(h.tooltipFallbackWidth,h.tooltipFallbackWidth)}get tooltipFallbackHeightPx(){const t=M[this.size];return d(t,t)}async presentFrom(t,i){if(i!=null)this.label=i;if(!this.label?.trim()){this.hide();return}const s=this.anchor===t;if(!s){this.unbindAnchor();this.anchor=t;this.programmaticAnchor=true;if(this.popupEl&&this.describedBy)this.linkDescribedBy()}if(this.popupEl){this.renderPopupContent();this.schedulePosition();return}if(this.delayTimer&&s)return;this.show()}async dismiss(){this.hide()}bindAnchor(){if(this.programmaticAnchor)return;const t=this.el.querySelector("slot");const i=t?.assignedElements?.()??[];const s=i[0]??this.el.firstElementChild;if(!s||s.tagName==="SLOT"||s===this.anchor)return;this.anchor=s;s.addEventListener("pointerenter",this.pointerEnterHandler);s.addEventListener("pointerleave",this.pointerLeaveHandler);s.addEventListener("pointerdown",this.pointerDownHandler);s.addEventListener("keydown",this.keyDownHandler);s.addEventListener("focusin",this.focusHandler);s.addEventListener("focusout",this.blurHandler)}unbindAnchor(){if(!this.anchor)return;this.unlinkDescribedBy();if(!this.programmaticAnchor){this.anchor.removeEventListener("pointerenter",this.pointerEnterHandler);this.anchor.removeEventListener("pointerleave",this.pointerLeaveHandler);this.anchor.removeEventListener("pointerdown",this.pointerDownHandler);this.anchor.removeEventListener("keydown",this.keyDownHandler);this.anchor.removeEventListener("focusin",this.focusHandler);this.anchor.removeEventListener("focusout",this.blurHandler)}this.anchor=null;this.programmaticAnchor=false}linkDescribedBy(){if(!this.describedBy||!this.anchor||!this.popupEl)return;const t=new Set((this.anchor.getAttribute("aria-describedby")??"").split(/\s+/).filter(Boolean));t.add(this.tooltipId);this.anchor.setAttribute("aria-describedby",Array.from(t).join(" "))}unlinkDescribedBy(){if(!this.anchor)return;const t=(this.anchor.getAttribute("aria-describedby")??"").split(/\s+/).filter((t=>t&&t!==this.tooltipId));if(t.length)this.anchor.setAttribute("aria-describedby",t.join(" "));else this.anchor.removeAttribute("aria-describedby")}clearTimers(){if(this.delayTimer){clearTimeout(this.delayTimer);this.delayTimer=null}if(this.closeTimer){clearTimeout(this.closeTimer);this.closeTimer=null}}setupOpenListeners(){this.position.observe();document.addEventListener("keydown",this.escapeHandler)}teardownOpenListeners(){this.position.unobserve();document.removeEventListener("keydown",this.escapeHandler)}destroyPopup(){this.teardownOpenListeners();this.unlinkDescribedBy();if(!this.popupEl)return;this.popupEl.remove();this.popupEl=null}schedulePosition(){if(!this.popupEl)return;const t=()=>{const t=this.popupEl?.querySelector(":scope > .tooltip-inner > ds-text");if(t instanceof i)D(t,this.wrapLabel)};requestAnimationFrame((()=>{t();this.position.update();requestAnimationFrame((()=>{t();this.position.update()}))}));this.position.observeResizeTargets()}hideInstant(){this.clearTimers();L=Date.now();if(R===this)R=null;this.destroyPopup();this.isOpen=false;this.skipEnterAnimation=false}show(){if(!this.label?.trim())return;this.clearTimers();let t=Date.now()-L<this.instantReopenMs;if(R&&R!==this){R.hideInstant();t=true}R=this;this.skipEnterAnimation=t;if(t){this.mountPopup();return}this.delayTimer=setTimeout((()=>{this.delayTimer=null;if(!this.label?.trim())return;this.mountPopup()}),this.hoverDelayMs)}hide(){this.clearTimers();if(!this.popupEl&&!this.isOpen)return;L=Date.now();if(!this.popupEl){this.isOpen=false;return}this.popupEl.classList.remove("tooltip-popup--instant");this.popupEl.classList.add("tooltip-popup--closing");if(this.fadeOutMs===0){if(R===this)R=null;this.destroyPopup();this.isOpen=false;this.skipEnterAnimation=false;return}this.closeTimer=setTimeout((()=>{this.closeTimer=null;if(R===this)R=null;this.destroyPopup();this.isOpen=false;this.skipEnterAnimation=false}),this.fadeOutMs)}mountPopup(){if(!this.popupEl){const t=document.createElement("div");t.id=this.tooltipId;t.setAttribute("role","tooltip");t.className="tooltip-popup ds-forced-colors-scope sc-ds-tooltip";Object.assign(t.style,{position:"fixed",left:"0",top:"0",zIndex:"var(--dimension-z-index-tooltip)",pointerEvents:"none"});document.body.appendChild(t);this.popupEl=t}this.setupOpenListeners();this.linkDescribedBy();this.popupEl.classList.toggle("tooltip-popup--instant",this.skipEnterAnimation);this.popupEl.classList.toggle("tooltip-popup--wrap",this.wrapLabel);this.popupEl.classList.remove("tooltip-popup--closing");this.renderPopupContent();this.schedulePosition();this.isOpen=true}renderPopupContent(){if(!this.popupEl)return;this.popupEl.classList.toggle("tooltip-popup--wrap",this.wrapLabel);const t=c[this.size];const i=this.size==="md"?"ds-control--md":this.size==="sm"?"ds-control--sm":"ds-control--xs";const s="sc-ds-tooltip";const o=document.createElement("div");o.className=`tooltip-inner ${i} ${s}`;const n=t=>{if(!this.shortcutKey||this.shortcutKeyPosition!==t)return;const i=document.createElement("span");i.className=`key-hint-group ${s}`;i.setAttribute("aria-hidden","true");for(const t of m(this.shortcutKey)){const o=document.createElement("span");const n=Array.from(t).length>1?" key-hint--wide":"";o.className=`key-hint${n} ${s}`;const e=document.createElement("span");e.className=`key-hint__label ${s}`;e.textContent=t;o.appendChild(e);i.appendChild(o)}o.appendChild(i)};n("start");const e=q({variant:t,wrap:this.wrapLabel?"wrap":"nowrap",text:this.label});D(e,this.wrapLabel);o.appendChild(e);n("end");this.popupEl.replaceChildren(o)}render(){return s(o,{key:"a91ea35cad4d388682b562745b5079553b1cfd4f",style:{display:"contents"}},s("slot",{key:"2ecadc1cd67d800114e42cc7f66c2d2566a475d2",onSlotchange:this.handleSlotChange}))}get el(){return this}static get watchers(){return{label:[{onContentOrPositionChange:0}],size:[{onContentOrPositionChange:0}],side:[{onContentOrPositionChange:0}],align:[{onContentOrPositionChange:0}],sideOffset:[{onContentOrPositionChange:0}],alignOffset:[{onContentOrPositionChange:0}],boundary:[{onContentOrPositionChange:0}],shortcutKey:[{onContentOrPositionChange:0}],shortcutKeyPosition:[{onContentOrPositionChange:0}],wrapLabel:[{onContentOrPositionChange:0}]}}static get style(){return F()}},[262,"ds-tooltip",{label:[1],size:[1],side:[1],align:[1],sideOffset:[8,"side-offset"],alignOffset:[8,"align-offset"],boundary:[1],delay:[8],shortcutKey:[1,"shortcut-key"],shortcutKeyPosition:[1,"shortcut-key-position"],describedBy:[4,"described-by"],wrapLabel:[4,"wrap-label"],presentFrom:[64],dismiss:[64]},undefined,{label:[{onContentOrPositionChange:0}],size:[{onContentOrPositionChange:0}],side:[{onContentOrPositionChange:0}],align:[{onContentOrPositionChange:0}],sideOffset:[{onContentOrPositionChange:0}],alignOffset:[{onContentOrPositionChange:0}],boundary:[{onContentOrPositionChange:0}],shortcutKey:[{onContentOrPositionChange:0}],shortcutKeyPosition:[{onContentOrPositionChange:0}],wrapLabel:[{onContentOrPositionChange:0}]}]);function H(){if(typeof customElements==="undefined"){return}const t=["ds-tooltip","ds-text"];t.forEach((t=>{switch(t){case"ds-tooltip":if(!customElements.get(n(t))){customElements.define(n(t),E)}break;case"ds-text":if(!customElements.get(n(t))){e()}break}}))}H();export{O as A,E as T,P as a,x as c,H as d,A as r};
|
|
2
|
-
//# sourceMappingURL=p-BMI0F08u.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["MODIFIER_GLYPHS","Set","MODIFIER_LABELS","alt","cmd","command","control","ctrl","option","shift","canonicalKeyLabel","label","toLowerCase","shortcutKeyLabels","shortcut","normalized","trim","includes","split","map","part","filter","Boolean","test","characters","Array","from","labels","length","has","push","join","OPPOSITE_SIDE","top","right","bottom","left","rawPosition","input","side","anchorRect","anchor","popupWidth","popupHeight","align","sideOffsetPx","alignOffsetPx","x","width","y","height","collisionBounds","boundary","collisionRect","viewportWidth","viewportHeight","viewportPadPx","mainAxisOverflow","position","bounds","Math","max","clampToBounds","value","size","minimum","maximumEdge","maximum","min","computeAnchoredPosition","preferred","oppositeSide","opposite","preferredOverflow","oppositeOverflow","useOpposite","resolvedSide","availableHeight","POSITION_RETRY_BUDGET","AnchoredPositionController","constructor","options","this","scrollResizeHandler","resizeObserver","retryRaf","liveRaf","anchorMotionRaf","activeAnchorMotions","ownerDocument","last","isReady","generation","retryGeneration","anchorMotionStartHandler","event","eventCanMoveAnchor","scheduleAnchorMotionUpdate","anchorMotionEndHandler","ready","observe","bindListeners","unobserve","unbindListeners","cancel","schedule","onReady","cancelRetry","current","remaining","retryBudget","attempt","measured","update","requestAnimationFrame","getAnchor","isConnected","popup","getPopup","observeResizeTargets","topLayer","showPopover","matches","measure","next","apply","scheduleLiveUpdate","mode","liveUpdate","cancelAnimationFrame","window","addEventListener","observeResize","ResizeObserver","observer","observeAnchorMotion","getOwnerDocument","removeEventListener","disconnect","target","Element","contains","tick","ANCHORED_OVERLAY_BOUNDARY_ATTRIBUTE","composedParentElement","element","assignedSlot","parentElement","root","getRootNode","ShadowRoot","host","findAnchoredOverlayBoundary","HTMLElement","hasAttribute","resolveAnchoredOverlayBoundaryRect","explicitBoundary","undefined","getBoundingClientRect","tooltipCss","FALLBACK_HEIGHT","md","TOKEN_DEFAULTS","size400","sm","size300","xs","size200","lastDismissedAt","tooltipIdCounter","activeTooltip","createDsText","opts","el","document","createElement","as","variant","emphasis","color","wrap","textContent","text","styleTooltipLabel","wrapLabel","style","flexShrink","minWidth","maxWidth","whiteSpace","padding","Tooltip","__stencil_proxyCustomElement","registerHost","sideOffset","TOKEN_CSS_LENGTHS","space050","alignOffset","delay","animationDelayMedium3","shortcutKeyPosition","describedBy","tooltipId","delayTimer","closeTimer","popupEl","anchorObserver","didLoad","tip","offsetWidth","tooltipFallbackWidthPx","offsetHeight","tooltipFallbackHeightPx","innerWidth","innerHeight","dataset","transform","round","skipEnterAnimation","isOpen","programmaticAnchor","lastInteractionWasKeyboard","pointerEnterHandler","pointerType","show","pointerLeaveHandler","hide","pointerDownHandler","hideInstant","keyDownHandler","focusHandler","blurHandler","e","relatedTarget","escapeHandler","key","preventDefault","handleSlotChange","slot","querySelector","assignedElements","firstElementChild","tagName","unbindAnchor","bindAnchor","connectedCallback","connectAnchor","componentDidLoad","MutationObserver","childList","disconnectedCallback","clearTimers","destroyPopup","onContentOrPositionChange","renderPopupContent","schedulePosition","resolveCssLengthPx","hoverDelayMs","resolveCssTimeMs","instantReopenMs","animationDurationMedium1","fadeOutMs","resolveMotionTimeMs","motionShort3","animationDurationShort3","tooltipFallbackWidth","token","presentFrom","sameAnchor","linkDescribedBy","dismiss","slotted","child","unlinkDescribedBy","ids","getAttribute","add","setAttribute","id","removeAttribute","clearTimeout","setupOpenListeners","teardownOpenListeners","remove","reapplyLabelStyles","Date","now","instant","mountPopup","setTimeout","classList","className","Object","assign","zIndex","pointerEvents","body","appendChild","toggle","textVariant","CONTROL_TEXT_VARIANT","density","sc","inner","appendShortcut","shortcutKey","group","hint","wide","replaceChildren","render","h","Host","display","onSlotchange"],"sources":["src/wc/utils/shortcut-key.ts","src/wc/utils/anchored-position.ts","src/wc/utils/anchored-position-controller.ts","src/wc/utils/anchored-overlay-boundary.ts","src/wc/components/Tooltip/Tooltip.css?tag=ds-tooltip&encapsulation=scoped","src/wc/components/Tooltip/Tooltip.tsx"],"sourcesContent":["const MODIFIER_GLYPHS = new Set(['⌘', '⇧', '⌥', '⌃']);\nconst MODIFIER_LABELS: Readonly<Record<string, string>> = {\n alt: '⌥',\n cmd: '⌘',\n command: '⌘',\n control: '⌃',\n ctrl: '⌃',\n option: '⌥',\n shift: '⇧',\n};\n\nfunction canonicalKeyLabel(label: string): string {\n return MODIFIER_LABELS[label.toLowerCase()] ?? label;\n}\n\n/** Split a shortcut chord into the labels rendered on individual keycaps. */\nexport function shortcutKeyLabels(shortcut: string): string[] {\n const normalized = shortcut.trim();\n if (!normalized) return [];\n\n if (normalized.includes('+')) {\n return normalized\n .split('+')\n .map(part => part.trim())\n .filter(Boolean)\n .map(canonicalKeyLabel);\n }\n\n if (/\\s/.test(normalized)) {\n return normalized.split(/\\s+/).filter(Boolean).map(canonicalKeyLabel);\n }\n\n const characters = Array.from(normalized);\n const labels: string[] = [];\n while (characters.length > 1 && MODIFIER_GLYPHS.has(characters[0])) {\n labels.push(characters.shift()!);\n }\n labels.push(characters.join(''));\n return labels;\n}\n","export type AnchoredSide = 'top' | 'right' | 'bottom' | 'left';\nexport type AnchoredAlign = 'start' | 'center' | 'end';\n\nexport type AnchoredCollisionRect = Pick<\n DOMRectReadOnly,\n 'top' | 'left' | 'right' | 'bottom' | 'width' | 'height'\n>;\n\nexport interface AnchoredPositionInput {\n anchorRect: Pick<DOMRectReadOnly, 'top' | 'left' | 'right' | 'bottom' | 'width' | 'height'>;\n popupWidth: number;\n popupHeight: number;\n side: AnchoredSide;\n align: AnchoredAlign;\n sideOffsetPx: number;\n alignOffsetPx: number;\n viewportPadPx: number;\n viewportWidth: number;\n viewportHeight: number;\n /** Optional page or panel collision rectangle in viewport-fixed coordinates. */\n collisionRect?: AnchoredCollisionRect;\n}\n\nexport interface AnchoredPosition {\n x: number;\n y: number;\n /** Side actually used, which differs from the request when placement flipped. */\n resolvedSide: AnchoredSide;\n /** Vertical room available on the resolved side inside the padded viewport. */\n availableHeight: number;\n}\n\nconst OPPOSITE_SIDE: Record<AnchoredSide, AnchoredSide> = {\n top: 'bottom',\n right: 'left',\n bottom: 'top',\n left: 'right',\n};\n\n/** Unclamped coordinates for one candidate side. */\nfunction rawPosition(\n input: AnchoredPositionInput,\n side: AnchoredSide\n): Pick<AnchoredPosition, 'x' | 'y'> {\n const { anchorRect: anchor, popupWidth, popupHeight, align, sideOffsetPx, alignOffsetPx } = input;\n\n if (side === 'top' || side === 'bottom') {\n return {\n x:\n align === 'start'\n ? anchor.left + alignOffsetPx\n : align === 'end'\n ? anchor.right - popupWidth + alignOffsetPx\n : anchor.left + anchor.width / 2 - popupWidth / 2 + alignOffsetPx,\n y: side === 'top' ? anchor.top - popupHeight - sideOffsetPx : anchor.bottom + sideOffsetPx,\n };\n }\n\n return {\n x: side === 'left' ? anchor.left - popupWidth - sideOffsetPx : anchor.right + sideOffsetPx,\n y:\n align === 'start'\n ? anchor.top + alignOffsetPx\n : align === 'end'\n ? anchor.bottom - popupHeight + alignOffsetPx\n : anchor.top + anchor.height / 2 - popupHeight / 2 + alignOffsetPx,\n };\n}\n\n/** Total main-axis spill past the padded viewport for a candidate position. */\nfunction collisionBounds(input: AnchoredPositionInput) {\n const boundary = input.collisionRect ?? {\n top: 0,\n left: 0,\n right: input.viewportWidth,\n bottom: input.viewportHeight,\n };\n return {\n top: boundary.top + input.viewportPadPx,\n left: boundary.left + input.viewportPadPx,\n right: boundary.right - input.viewportPadPx,\n bottom: boundary.bottom - input.viewportPadPx,\n };\n}\n\nfunction mainAxisOverflow(\n input: AnchoredPositionInput,\n side: AnchoredSide,\n position: Pick<AnchoredPosition, 'x' | 'y'>\n): number {\n const { popupWidth, popupHeight } = input;\n const bounds = collisionBounds(input);\n\n if (side === 'top' || side === 'bottom') {\n return (\n Math.max(bounds.top - position.y, 0) + Math.max(position.y + popupHeight - bounds.bottom, 0)\n );\n }\n\n return (\n Math.max(bounds.left - position.x, 0) + Math.max(position.x + popupWidth - bounds.right, 0)\n );\n}\n\nfunction clampToBounds(value: number, size: number, minimum: number, maximumEdge: number): number {\n const maximum = Math.max(minimum, maximumEdge - size);\n return Math.min(Math.max(value, minimum), maximum);\n}\n\n/**\n * Pure viewport-fixed anchored-popup layout math shared by every element-anchored\n * overlay: menus, selects, tooltips, and anchored toasts.\n *\n * `side` is preferred. When the popup spills past the padded collision boundary and\n * the opposite side spills less, placement flips on the main axis; the result is\n * then clamped into that boundary on both axes. The viewport is the fallback when\n * no page or panel collision rectangle is supplied. Cross-axis `align` is applied\n * before clamping so `alignOffsetPx` stays an additive nudge.\n *\n * Callers own their own anchor semantics — inner-cell alignment offsets and\n * minimum widths belong to the calling component, not here.\n * @see choice-popup-alignment.ts for the choice-cell alignment transform.\n */\nexport function computeAnchoredPosition(input: AnchoredPositionInput): AnchoredPosition {\n const bounds = collisionBounds(input);\n const preferred = rawPosition(input, input.side);\n const oppositeSide = OPPOSITE_SIDE[input.side];\n const opposite = rawPosition(input, oppositeSide);\n const preferredOverflow = mainAxisOverflow(input, input.side, preferred);\n const oppositeOverflow = mainAxisOverflow(input, oppositeSide, opposite);\n const useOpposite = preferredOverflow > 0 && oppositeOverflow < preferredOverflow;\n const resolvedSide = useOpposite ? oppositeSide : input.side;\n const position = useOpposite ? opposite : preferred;\n const availableHeight =\n resolvedSide === 'top'\n ? input.anchorRect.top - bounds.top - input.sideOffsetPx\n : resolvedSide === 'bottom'\n ? bounds.bottom - input.anchorRect.bottom - input.sideOffsetPx\n : bounds.bottom - bounds.top;\n\n return {\n x: clampToBounds(position.x, input.popupWidth, bounds.left, bounds.right),\n y: clampToBounds(position.y, input.popupHeight, bounds.top, bounds.bottom),\n resolvedSide,\n availableHeight: Math.max(0, availableHeight),\n };\n}\n","import {\n computeAnchoredPosition,\n type AnchoredPosition,\n type AnchoredPositionInput,\n} from './anchored-position';\n\n/** Frames to wait for an anchor and popup to become measurable before giving up. */\nconst POSITION_RETRY_BUDGET = 8;\n\n/**\n * How the scroll/resize path reschedules. Each consumer family measured\n * differently before consolidation, and the differences are preserved verbatim\n * so placement timing is unchanged.\n *\n * - `sync` — measure inside the listener. Selects.\n * - `frame` — coalesce and measure on the next frame. Tooltips.\n * - `double-frame` — coalesce, measure next frame, then measure once more the\n * frame after. Scroll-driven owners such as ShellPage commit a compact-header\n * render in the frame after the scroll event, so a single frame reads a stale\n * anchor rect. Menus.\n */\nexport type AnchoredLiveUpdateMode = 'sync' | 'frame' | 'double-frame';\n\nexport interface AnchoredPositionControllerOptions {\n /** Resolve the anchor at measure time; positioning retries while this is null. */\n getAnchor: () => HTMLElement | null;\n /** Resolve the popup at measure time; positioning retries while this is null. */\n getPopup: () => HTMLElement | null;\n /** Stable owner fallback when framework bindings assign open before anchor. */\n getOwnerDocument?: () => Document | null;\n /**\n * Build the layout input for one measurement pass.\n *\n * The owning component keeps its own anchor semantics here — inner-cell align\n * offsets, minimum widths, and token resolution stay with the component rather\n * than moving into this controller. Return `null` when the component's own\n * guards say the popup is not measurable yet, which schedules a retry.\n */\n measure: (anchor: HTMLElement, popup: HTMLElement) => AnchoredPositionInput | null;\n /** Commit a changed position. Not called when the result is unchanged. */\n apply: (position: AnchoredPosition) => void;\n /**\n * Move a `popover=\"manual\"` popup into the native top layer before measuring.\n *\n * Use this for popups that remain in their owner's DOM tree. The top layer\n * gives `position: fixed` viewport coordinates even when an application\n * ancestor establishes a fixed-position containing block through containment,\n * transforms, or filters.\n */\n topLayer?: boolean;\n /** Fired once per `start()` when the first measurement succeeds. */\n onReady?: () => void;\n /** Scroll/resize behavior. Defaults to `sync`. */\n liveUpdate?: AnchoredLiveUpdateMode;\n /**\n * Re-measure when the popup or anchor resizes. Tooltips need this because the\n * label's `ds-text` upgrade changes the measured width after mount.\n */\n observeResize?: boolean;\n /**\n * Follow CSS transitions or animations that move the anchor without resizing\n * it. The observer only runs a measurement loop while related motion is active.\n */\n observeAnchorMotion?: boolean;\n retryBudget?: number;\n}\n\n/**\n * Lifecycle owner for an element-anchored popup: listener binding, measurement\n * retries, frame coalescing, and teardown.\n *\n * Pairs with `computeAnchoredPosition`, which owns the geometry. Split this way\n * because the geometry is pure and exhaustively testable while the lifecycle is\n * timing-dependent; keeping them separate means the risky half lives in exactly\n * one place.\n *\n * Not suitable for overlays that place several popups in one shared pass — Toast\n * positions N anchored records inside a single layout commit and keeps its own\n * scheduler, using only the geometry function.\n */\nexport class AnchoredPositionController {\n private readonly options: AnchoredPositionControllerOptions;\n private scrollResizeHandler: (() => void) | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private retryRaf: number | null = null;\n private liveRaf: number | null = null;\n private anchorMotionRaf: number | null = null;\n private activeAnchorMotions = 0;\n private ownerDocument: Document | null = null;\n private last: AnchoredPosition | null = null;\n private isReady = false;\n private generation = 0;\n private retryGeneration = 0;\n private readonly anchorMotionStartHandler = (event: Event) => {\n if (!this.eventCanMoveAnchor(event)) return;\n this.activeAnchorMotions += 1;\n this.scheduleAnchorMotionUpdate();\n };\n private readonly anchorMotionEndHandler = (event: Event) => {\n if (!this.eventCanMoveAnchor(event)) return;\n this.activeAnchorMotions = Math.max(0, this.activeAnchorMotions - 1);\n this.scheduleAnchorMotionUpdate();\n };\n\n constructor(options: AnchoredPositionControllerOptions) {\n this.options = options;\n }\n\n /** `true` once a measurement has succeeded, for gating popup reveal. */\n get ready(): boolean {\n return this.isReady;\n }\n\n /**\n * Bind scroll/resize tracking for an opening popup.\n *\n * Deliberately does not schedule placement: every consumer binds listeners and\n * then schedules in its own order, and folding both into one call produced two\n * overlapping retry loops. Call `schedule()` or `update()` separately.\n */\n observe(): void {\n this.bindListeners();\n }\n\n /** Unbind tracking, cancel pending frames, and clear the cached position. */\n unobserve(): void {\n this.unbindListeners();\n this.cancel();\n this.last = null;\n this.isReady = false;\n }\n\n /**\n * Retry measurement each frame until it succeeds or the budget runs out, so a\n * popup is never revealed at 0,0 after a failed first pass.\n */\n schedule(onReady?: () => void): void {\n this.cancelRetry();\n this.isReady = false;\n const generation = this.generation;\n const retryGeneration = this.retryGeneration;\n const current = () =>\n generation === this.generation && retryGeneration === this.retryGeneration;\n\n let remaining = this.options.retryBudget ?? POSITION_RETRY_BUDGET;\n\n const attempt = () => {\n if (!current()) return;\n this.retryRaf = null;\n const measured = this.update();\n if (!current()) return;\n if (measured) {\n this.isReady = true;\n this.options.onReady?.();\n if (current()) onReady?.();\n return;\n }\n if (remaining > 0) {\n remaining -= 1;\n this.retryRaf = requestAnimationFrame(attempt);\n }\n };\n\n this.retryRaf = requestAnimationFrame(attempt);\n }\n\n /** Measure and commit once. @returns `false` when the popup is not measurable. */\n update(): boolean {\n const anchor = this.options.getAnchor();\n if (!anchor?.isConnected) return false;\n const popup = this.options.getPopup();\n if (!popup?.isConnected) return false;\n this.observeResizeTargets();\n\n if (\n this.options.topLayer &&\n typeof popup.showPopover === 'function' &&\n !popup.matches(':popover-open')\n ) {\n try {\n popup.showPopover();\n } catch {\n // The popup may not be connected yet. The scheduled retry will try again\n // on the next frame instead of measuring it in the wrong coordinate space.\n return false;\n }\n }\n\n const input = this.options.measure(anchor, popup);\n if (!input) return false;\n\n const next = computeAnchoredPosition(input);\n if (\n !this.last ||\n this.last.x !== next.x ||\n this.last.y !== next.y ||\n this.last.resolvedSide !== next.resolvedSide ||\n this.last.availableHeight !== next.availableHeight\n ) {\n this.last = next;\n this.options.apply(next);\n }\n return true;\n }\n\n /** Reposition an already-open popup without hiding it. */\n scheduleLiveUpdate(): void {\n const generation = this.generation;\n const mode = this.options.liveUpdate ?? 'sync';\n if (mode === 'sync') {\n this.update();\n return;\n }\n\n if (this.liveRaf !== null) return;\n\n if (mode === 'frame') {\n this.liveRaf = requestAnimationFrame(() => {\n if (generation !== this.generation) return;\n this.liveRaf = null;\n this.update();\n });\n return;\n }\n\n // double-frame stays coalesced until the second frame resolves.\n this.liveRaf = requestAnimationFrame(() => {\n if (generation !== this.generation) return;\n this.update();\n if (generation !== this.generation) return;\n this.liveRaf = requestAnimationFrame(() => {\n if (generation !== this.generation) return;\n this.liveRaf = null;\n this.update();\n });\n });\n }\n\n /** Cancel pending retry and live frames without unbinding listeners. */\n cancel(): void {\n this.generation += 1;\n this.cancelRetry();\n if (this.liveRaf !== null) {\n cancelAnimationFrame(this.liveRaf);\n this.liveRaf = null;\n }\n if (this.anchorMotionRaf !== null) {\n cancelAnimationFrame(this.anchorMotionRaf);\n this.anchorMotionRaf = null;\n }\n }\n\n private cancelRetry(): void {\n this.retryGeneration += 1;\n if (this.retryRaf === null) return;\n cancelAnimationFrame(this.retryRaf);\n this.retryRaf = null;\n }\n\n private bindListeners(): void {\n this.unbindListeners();\n this.scrollResizeHandler = () => this.scheduleLiveUpdate();\n // Capture phase so scrolling inside any ancestor repositions the popup.\n window.addEventListener('scroll', this.scrollResizeHandler, true);\n window.addEventListener('resize', this.scrollResizeHandler);\n\n if (this.options.observeResize && typeof ResizeObserver !== 'undefined') {\n const observer = new ResizeObserver(() => {\n if (this.resizeObserver === observer) this.scheduleLiveUpdate();\n });\n this.resizeObserver = observer;\n this.observeResizeTargets();\n }\n\n if (this.options.observeAnchorMotion) {\n this.ownerDocument =\n this.options.getAnchor()?.ownerDocument ?? this.options.getOwnerDocument?.() ?? null;\n this.ownerDocument?.addEventListener('transitionrun', this.anchorMotionStartHandler, true);\n this.ownerDocument?.addEventListener('transitionend', this.anchorMotionEndHandler, true);\n this.ownerDocument?.addEventListener('transitioncancel', this.anchorMotionEndHandler, true);\n this.ownerDocument?.addEventListener('animationstart', this.anchorMotionStartHandler, true);\n this.ownerDocument?.addEventListener('animationend', this.anchorMotionEndHandler, true);\n this.ownerDocument?.addEventListener('animationcancel', this.anchorMotionEndHandler, true);\n }\n }\n\n private unbindListeners(): void {\n if (this.scrollResizeHandler) {\n window.removeEventListener('scroll', this.scrollResizeHandler, true);\n window.removeEventListener('resize', this.scrollResizeHandler);\n this.scrollResizeHandler = null;\n }\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.ownerDocument?.removeEventListener('transitionrun', this.anchorMotionStartHandler, true);\n this.ownerDocument?.removeEventListener('transitionend', this.anchorMotionEndHandler, true);\n this.ownerDocument?.removeEventListener('transitioncancel', this.anchorMotionEndHandler, true);\n this.ownerDocument?.removeEventListener('animationstart', this.anchorMotionStartHandler, true);\n this.ownerDocument?.removeEventListener('animationend', this.anchorMotionEndHandler, true);\n this.ownerDocument?.removeEventListener('animationcancel', this.anchorMotionEndHandler, true);\n this.ownerDocument = null;\n this.activeAnchorMotions = 0;\n }\n\n private eventCanMoveAnchor(event: Event): boolean {\n const anchor = this.options.getAnchor();\n const target = event.target;\n if (!anchor || !(target instanceof Element)) return false;\n // Motion on the anchor or one of its layout ancestors can move its rect.\n // Descendant-only animation is irrelevant unless it resizes the anchor,\n // which the ResizeObserver path already covers.\n return target === anchor || target.contains(anchor);\n }\n\n private scheduleAnchorMotionUpdate(): void {\n if (this.anchorMotionRaf !== null) return;\n const generation = this.generation;\n const tick = () => {\n if (generation !== this.generation) return;\n this.anchorMotionRaf = null;\n this.update();\n if (generation !== this.generation) return;\n if (this.activeAnchorMotions <= 0 || !this.options.getAnchor()?.isConnected) {\n this.activeAnchorMotions = 0;\n return;\n }\n this.anchorMotionRaf = requestAnimationFrame(tick);\n };\n this.anchorMotionRaf = requestAnimationFrame(tick);\n }\n\n /**\n * Re-attach the resize observer after the popup remounts. Safe to call\n * repeatedly; `ResizeObserver.observe` ignores duplicate targets.\n */\n observeResizeTargets(): void {\n if (!this.resizeObserver) return;\n const popup = this.options.getPopup();\n if (popup) this.resizeObserver.observe(popup);\n const anchor = this.options.getAnchor();\n if (anchor) this.resizeObserver.observe(anchor);\n }\n}\n","import type { AnchoredCollisionRect } from './anchored-position';\n\n/** Attribute placed on a page or panel whose visible rectangle owns anchored overlays. */\nexport const ANCHORED_OVERLAY_BOUNDARY_ATTRIBUTE = 'data-ds-overlay-boundary';\n\n/** An element-owned collision rectangle, or an explicit escape to the viewport. */\nexport type AnchoredOverlayBoundary = HTMLElement | 'viewport';\n\nfunction composedParentElement(element: Element): Element | null {\n if (element.assignedSlot) return element.assignedSlot;\n if (element.parentElement) return element.parentElement;\n const root = element.getRootNode();\n return root instanceof ShadowRoot ? root.host : null;\n}\n\n/**\n * Find the nearest collision owner through light DOM, assigned slots, and open\n * shadow roots. The popup may live in the top layer or a body portal; ownership\n * follows its anchor instead of the popup's rendering location.\n */\nexport function findAnchoredOverlayBoundary(anchor: Element): HTMLElement | null {\n let current: Element | null = anchor;\n while (current) {\n if (\n current instanceof HTMLElement &&\n current.hasAttribute(ANCHORED_OVERLAY_BOUNDARY_ATTRIBUTE)\n ) {\n return current;\n }\n current = composedParentElement(current);\n }\n return null;\n}\n\n/** Resolve an explicit owner first, then the nearest composed-tree boundary. */\nexport function resolveAnchoredOverlayBoundaryRect(\n anchor: Element,\n explicitBoundary?: AnchoredOverlayBoundary\n): AnchoredCollisionRect | undefined {\n if (explicitBoundary === 'viewport') return undefined;\n return (explicitBoundary ?? findAnchoredOverlayBoundary(anchor))?.getBoundingClientRect();\n}\n","@import '../../utils/radius.css';\n@import '../../utils/control-density.css';\n@import '../../utils/key-hint.css';\n@import '../../utils/forced-colors.css';\n\n.tooltip-popup {\n box-sizing: border-box;\n background-color: var(--color-background-primary);\n border-radius: var(--ds-radius-tooltip-control, var(--dimension-radius-025));\n box-shadow: var(--effect-elevation-elevated-floating);\n white-space: nowrap;\n pointer-events: none;\n animation: tooltipFadeIn var(--effect-motion-short-2) forwards;\n will-change: transform;\n backface-visibility: hidden;\n}\n\n/* Warm handoff between nearby triggers — no enter fade (avoids 20–100ms lag). */\n.tooltip-popup--instant {\n animation: none;\n opacity: 1;\n}\n\n.tooltip-popup--closing {\n animation: tooltipFadeOut var(--effect-motion-short-3) forwards;\n}\n\n/* Density: md / sm / xs via `.ds-control--*` on `.tooltip-inner`. */\n.tooltip-inner {\n box-sizing: border-box;\n height: var(--ds-control-height, var(--dimension-size-400));\n display: flex;\n align-items: center;\n gap: var(--ds-control-gap, var(--dimension-space-050));\n padding: 0 var(--ds-control-padding-inline, var(--dimension-space-075));\n}\n\n/*\n * Label layout lives on ds-text (metric-box + control label-inset).\n * NOTE: Stencil scopes this to `ds-text.sc-ds-tooltip`, but portaled\n * createElement ds-text loses that class when Text's <Host class> renders.\n * `renderPopupContent` therefore also sets these as inline styles.\n */\n.tooltip-inner > ds-text {\n flex-shrink: 0;\n min-width: max-content;\n max-width: none;\n padding: 0 var(--ds-control-label-inset, var(--dimension-space-025));\n color: var(--color-foreground-primary);\n}\n\n.tooltip-popup--wrap {\n white-space: normal;\n max-inline-size: var(--dimension-panel-width-xs);\n}\n\n.tooltip-popup--wrap .tooltip-inner {\n height: auto;\n min-height: var(--ds-control-height, var(--dimension-size-400));\n padding-block: var(--dimension-space-050);\n align-items: flex-start;\n}\n\n.tooltip-popup--wrap .tooltip-inner > ds-text {\n flex: 1 1 auto;\n min-width: 0;\n max-width: 100%;\n white-space: pre-line;\n}\n\n@keyframes tooltipFadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes tooltipFadeOut {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .tooltip-popup,\n .tooltip-popup--instant {\n animation: none;\n opacity: 1;\n }\n\n .tooltip-popup--closing {\n animation: none;\n opacity: 0;\n }\n}\n\n@media (forced-colors: active) {\n .tooltip-popup {\n box-shadow: none;\n outline: var(--dimension-stroke-width-012) solid var(--ds-forced-color-content);\n outline-offset: calc(-1 * var(--dimension-stroke-width-012));\n }\n}\n","import { Component, Prop, Element, Method, Watch, h, Host } from '@stencil/core';\nimport {\n CONTROL_TEXT_VARIANT,\n resolveCssLengthPx,\n resolveCssTimeMs,\n resolveMotionTimeMs,\n TOKEN_CSS_LENGTHS,\n TOKEN_DEFAULTS,\n} from '../../utils';\nimport type { TextVariant } from '../Text/text-types';\nimport { shortcutKeyLabels } from '../../utils/shortcut-key';\nimport { AnchoredPositionController } from '../../utils/anchored-position-controller';\nimport {\n resolveAnchoredOverlayBoundaryRect,\n type AnchoredOverlayBoundary,\n} from '../../utils/anchored-overlay-boundary';\n// Side-effect: register `ds-text` — the portal builds it via createElement, not JSX.\nimport '../Text/Text';\n\nexport type TooltipSide = 'top' | 'right' | 'bottom' | 'left';\nexport type TooltipAlign = 'start' | 'center' | 'end';\nexport type TooltipSize = 'md' | 'sm' | 'xs';\n\nconst FALLBACK_HEIGHT: Record<TooltipSize, string> = {\n md: TOKEN_DEFAULTS.size400,\n sm: TOKEN_DEFAULTS.size300,\n xs: TOKEN_DEFAULTS.size200,\n};\n\nlet lastDismissedAt = 0;\nlet tooltipIdCounter = 0;\n/** Currently open tooltip — force-cleared on warm handoff so tips don't cross-fade. */\nlet activeTooltip: Tooltip | null = null;\n\ntype DsTextEl = HTMLElement & {\n as: string;\n variant: TextVariant;\n emphasis: boolean;\n color: string;\n wrap: string;\n};\n\nfunction createDsText(opts: {\n variant: TextVariant;\n emphasis?: boolean;\n color?: string;\n wrap?: 'wrap' | 'nowrap' | 'balance' | 'pretty';\n text: string;\n}): DsTextEl {\n const el = document.createElement('ds-text') as DsTextEl;\n el.as = 'span';\n el.variant = opts.variant;\n el.emphasis = opts.emphasis ?? false;\n el.color = opts.color ?? 'inherit';\n if (opts.wrap) el.wrap = opts.wrap;\n el.textContent = opts.text;\n return el;\n}\n\n/**\n * Control-density label styles for portaled ds-text.\n * Scoped CSS requires `sc-ds-tooltip` on the host, but Text's `<Host class>`\n * overwrites imperative className — so these must be inline to stick.\n */\nfunction styleTooltipLabel(el: HTMLElement, wrapLabel = false) {\n el.style.flexShrink = wrapLabel ? '1' : '0';\n el.style.minWidth = wrapLabel ? '0' : 'max-content';\n el.style.maxWidth = wrapLabel ? '100%' : 'none';\n el.style.whiteSpace = wrapLabel ? 'pre-line' : '';\n el.style.padding = '0 var(--ds-control-label-inset, var(--dimension-space-025))';\n el.style.color = 'var(--color-foreground-primary)';\n}\n\n/**\n * Imperative body portal for the popup.\n * Stencil must not own the portaled node — moving a VDOM child to `document.body`\n * causes recreate → re-portal → @State loops that freeze the page.\n */\n@Component({\n tag: 'ds-tooltip',\n styleUrl: 'Tooltip.css',\n scoped: true,\n})\nexport class Tooltip {\n @Element() el!: HTMLElement;\n\n /**\n * Tooltip text. Empty/whitespace skips show — useful when the wrapper must stay\n * mounted for layout/animation stability (e.g. PanelNav expand/collapse).\n */\n @Prop() label!: string;\n\n /** Control density (height, padding, type). */\n @Prop() size: TooltipSize = 'md';\n\n @Prop() side: TooltipSide = 'top';\n @Prop() align: TooltipAlign = 'center';\n /** Gap between anchor and tooltip — number (px) or TokoMo length. */\n @Prop() sideOffset: number | string = TOKEN_CSS_LENGTHS.space050;\n /** Cross-axis offset — number (px) or TokoMo length. */\n @Prop() alignOffset: number | string = 0;\n /** Explicit collision owner, `viewport`, or the nearest data-ds-overlay-boundary ancestor. */\n @Prop() boundary: AnchoredOverlayBoundary | undefined;\n /**\n * Hover show delay before the tooltip appears.\n * Default: `--effect-animation-delay-medium-3` (1000ms). Accepts a number (ms)\n * or a TokoMo time token / `var(--effect-animation-delay-*)`. Applies to the\n * initial hover/focus show only — after a recent dismiss, reopen is instant.\n * Prefer the default; override only for denser chrome or rare/destructive actions.\n */\n @Prop() delay: number | string = TOKEN_DEFAULTS.animationDelayMedium3;\n @Prop() shortcutKey: string | undefined;\n @Prop() shortcutKeyPosition: 'start' | 'end' = 'end';\n /**\n * Link the trigger with aria-describedby while the popup is open. Disable when\n * the label is already in the DOM, such as a truncated table cell.\n */\n @Prop() describedBy = true;\n /** Allow wrapping at a panel-xs max width and preserve explicit line breaks. */\n @Prop() wrapLabel = false;\n\n private tooltipId = `ds-tooltip-${++tooltipIdCounter}`;\n private delayTimer: ReturnType<typeof setTimeout> | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n private anchor: HTMLElement | null = null;\n private popupEl: HTMLElement | null = null;\n private anchorObserver: MutationObserver | null = null;\n private didLoad = false;\n private readonly position = new AnchoredPositionController({\n getAnchor: () => this.anchor,\n getPopup: () => this.popupEl,\n getOwnerDocument: () => this.el.ownerDocument,\n measure: (anchor, tip) => ({\n anchorRect: anchor.getBoundingClientRect(),\n // Fall back to token metrics until `ds-text` upgrades and reports a width.\n popupWidth: tip.offsetWidth || this.tooltipFallbackWidthPx,\n popupHeight: tip.offsetHeight || this.tooltipFallbackHeightPx,\n side: this.side,\n align: this.align,\n sideOffsetPx: this.sideOffsetPx,\n alignOffsetPx: this.alignOffsetPx,\n viewportPadPx: this.viewportPadPx,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n collisionRect: resolveAnchoredOverlayBoundaryRect(anchor, this.boundary),\n }),\n apply: ({ x, y, resolvedSide }) => {\n if (!this.popupEl) return;\n this.popupEl.dataset.side = resolvedSide;\n this.popupEl.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`;\n },\n liveUpdate: 'frame',\n observeResize: true,\n });\n private skipEnterAnimation = false;\n private isOpen = false;\n private programmaticAnchor = false;\n private lastInteractionWasKeyboard = false;\n private pointerEnterHandler = (event: PointerEvent) => {\n if (event.pointerType === 'touch') return;\n this.show();\n };\n private pointerLeaveHandler = (event: PointerEvent) => {\n if (event.pointerType === 'touch') return;\n this.hide();\n };\n private pointerDownHandler = (event: PointerEvent) => {\n this.lastInteractionWasKeyboard = false;\n if (event.pointerType === 'touch' && (this.isOpen || this.popupEl)) this.hideInstant();\n };\n private keyDownHandler = () => {\n this.lastInteractionWasKeyboard = true;\n };\n /** focusin/focusout so nested focus targets (e.g. ds-button-* inner button) still open the tip. */\n private focusHandler = () => {\n if (this.lastInteractionWasKeyboard || this.anchor?.matches(':focus-visible')) this.show();\n };\n private blurHandler: (e: FocusEvent) => void = e => {\n const next = e.relatedTarget as Node | null;\n if (next && this.anchor?.contains(next)) return;\n this.hide();\n };\n private escapeHandler = (event: KeyboardEvent) => {\n if (event.key !== 'Escape' || !this.isOpen) return;\n event.preventDefault();\n this.hide();\n };\n\n connectedCallback() {\n if (!this.didLoad) return;\n this.connectAnchor();\n }\n\n componentDidLoad() {\n this.didLoad = true;\n this.connectAnchor();\n }\n\n private connectAnchor() {\n this.bindAnchor();\n if (this.anchorObserver) return;\n this.anchorObserver = new MutationObserver(() => this.handleSlotChange());\n this.anchorObserver.observe(this.el, { childList: true });\n }\n\n disconnectedCallback() {\n if (activeTooltip === this) activeTooltip = null;\n this.anchorObserver?.disconnect();\n this.anchorObserver = null;\n this.unbindAnchor();\n this.clearTimers();\n this.destroyPopup();\n }\n\n @Watch('label')\n @Watch('size')\n @Watch('side')\n @Watch('align')\n @Watch('sideOffset')\n @Watch('alignOffset')\n @Watch('boundary')\n @Watch('shortcutKey')\n @Watch('shortcutKeyPosition')\n @Watch('wrapLabel')\n onContentOrPositionChange() {\n if (!this.label?.trim()) {\n if (this.isOpen || this.popupEl) this.hideInstant();\n return;\n }\n if (!this.popupEl || !this.isOpen) return;\n this.renderPopupContent();\n this.schedulePosition();\n }\n\n private get viewportPadPx(): number {\n return resolveCssLengthPx(TOKEN_DEFAULTS.space050, TOKEN_DEFAULTS.space050);\n }\n\n private get sideOffsetPx(): number {\n return resolveCssLengthPx(this.sideOffset, TOKEN_DEFAULTS.space050);\n }\n\n private get alignOffsetPx(): number {\n return resolveCssLengthPx(this.alignOffset, 0);\n }\n\n private get hoverDelayMs(): number {\n return resolveCssTimeMs(this.delay, TOKEN_DEFAULTS.animationDelayMedium3);\n }\n\n private get instantReopenMs(): number {\n return resolveCssTimeMs(\n TOKEN_DEFAULTS.animationDurationMedium1,\n TOKEN_DEFAULTS.animationDurationMedium1\n );\n }\n\n private get fadeOutMs(): number {\n return resolveMotionTimeMs(TOKEN_DEFAULTS.motionShort3, TOKEN_DEFAULTS.animationDurationShort3);\n }\n\n private get tooltipFallbackWidthPx(): number {\n return resolveCssLengthPx(\n TOKEN_DEFAULTS.tooltipFallbackWidth,\n TOKEN_DEFAULTS.tooltipFallbackWidth\n );\n }\n\n private get tooltipFallbackHeightPx(): number {\n const token = FALLBACK_HEIGHT[this.size];\n return resolveCssLengthPx(token, token);\n }\n\n /**\n * Present against an external anchor the host already measured.\n * Does not bind hover or focus on that anchor — the owner drives show/hide.\n */\n @Method()\n async presentFrom(anchor: HTMLElement, label?: string) {\n if (label != null) this.label = label;\n if (!this.label?.trim()) {\n this.hide();\n return;\n }\n const sameAnchor = this.anchor === anchor;\n if (!sameAnchor) {\n this.unbindAnchor();\n this.anchor = anchor;\n this.programmaticAnchor = true;\n if (this.popupEl && this.describedBy) this.linkDescribedBy();\n }\n if (this.popupEl) {\n this.renderPopupContent();\n this.schedulePosition();\n return;\n }\n if (this.delayTimer && sameAnchor) return;\n this.show();\n }\n\n /** Dismiss a popup opened through presentFrom or the slotted trigger. */\n @Method()\n async dismiss() {\n this.hide();\n }\n\n private bindAnchor() {\n if (this.programmaticAnchor) return;\n const slot = this.el.querySelector('slot') as HTMLSlotElement | null;\n const slotted = slot?.assignedElements?.() ?? [];\n const child = (slotted[0] ?? this.el.firstElementChild) as HTMLElement | null;\n if (!child || child.tagName === 'SLOT' || child === this.anchor) return;\n this.anchor = child;\n child.addEventListener('pointerenter', this.pointerEnterHandler);\n child.addEventListener('pointerleave', this.pointerLeaveHandler);\n child.addEventListener('pointerdown', this.pointerDownHandler);\n child.addEventListener('keydown', this.keyDownHandler);\n child.addEventListener('focusin', this.focusHandler);\n child.addEventListener('focusout', this.blurHandler);\n }\n\n private unbindAnchor() {\n if (!this.anchor) return;\n this.unlinkDescribedBy();\n if (!this.programmaticAnchor) {\n this.anchor.removeEventListener('pointerenter', this.pointerEnterHandler);\n this.anchor.removeEventListener('pointerleave', this.pointerLeaveHandler);\n this.anchor.removeEventListener('pointerdown', this.pointerDownHandler);\n this.anchor.removeEventListener('keydown', this.keyDownHandler);\n this.anchor.removeEventListener('focusin', this.focusHandler);\n this.anchor.removeEventListener('focusout', this.blurHandler);\n }\n this.anchor = null;\n this.programmaticAnchor = false;\n }\n\n private linkDescribedBy() {\n if (!this.describedBy || !this.anchor || !this.popupEl) return;\n const ids = new Set(\n (this.anchor.getAttribute('aria-describedby') ?? '').split(/\\s+/).filter(Boolean)\n );\n ids.add(this.tooltipId);\n this.anchor.setAttribute('aria-describedby', Array.from(ids).join(' '));\n }\n\n private unlinkDescribedBy() {\n if (!this.anchor) return;\n const ids = (this.anchor.getAttribute('aria-describedby') ?? '')\n .split(/\\s+/)\n .filter(id => id && id !== this.tooltipId);\n if (ids.length) this.anchor.setAttribute('aria-describedby', ids.join(' '));\n else this.anchor.removeAttribute('aria-describedby');\n }\n\n private handleSlotChange = () => {\n if (this.programmaticAnchor) return;\n const slot = this.el.querySelector('slot') as HTMLSlotElement | null;\n const next = (slot?.assignedElements?.()[0] ?? this.el.firstElementChild) as HTMLElement | null;\n if (next === this.anchor || next?.tagName === 'SLOT') return;\n if (this.isOpen || this.popupEl) this.hideInstant();\n this.unbindAnchor();\n this.bindAnchor();\n };\n\n private clearTimers() {\n if (this.delayTimer) {\n clearTimeout(this.delayTimer);\n this.delayTimer = null;\n }\n if (this.closeTimer) {\n clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n }\n\n private setupOpenListeners() {\n // Binds scroll/resize + the resize observer; placement itself is scheduled\n // by schedulePosition() so the label restyle stays interleaved.\n this.position.observe();\n document.addEventListener('keydown', this.escapeHandler);\n }\n\n private teardownOpenListeners() {\n this.position.unobserve();\n document.removeEventListener('keydown', this.escapeHandler);\n }\n\n private destroyPopup() {\n this.teardownOpenListeners();\n this.unlinkDescribedBy();\n if (!this.popupEl) return;\n this.popupEl.remove();\n this.popupEl = null;\n }\n\n /**\n * Position after `ds-text` upgrades and lays out. Measuring synchronously in\n * `mountPopup` reads a collapsed/fallback width and places left/right tips wrong.\n */\n private schedulePosition() {\n if (!this.popupEl) return;\n\n const reapplyLabelStyles = () => {\n const label = this.popupEl?.querySelector(':scope > .tooltip-inner > ds-text');\n if (label instanceof HTMLElement) styleTooltipLabel(label, this.wrapLabel);\n };\n\n requestAnimationFrame(() => {\n reapplyLabelStyles();\n this.position.update();\n requestAnimationFrame(() => {\n reapplyLabelStyles();\n this.position.update();\n });\n });\n\n // The popup remounts on every show, so re-target the observer bound in start().\n this.position.observeResizeTargets();\n }\n\n /** Drop the open tip immediately (warm handoff to another tooltip). */\n private hideInstant() {\n this.clearTimers();\n lastDismissedAt = Date.now();\n if (activeTooltip === this) activeTooltip = null;\n this.destroyPopup();\n this.isOpen = false;\n this.skipEnterAnimation = false;\n }\n\n private show() {\n // Empty label = wrapper present for DOM stability (e.g. PanelNav expand/collapse)\n // but no tip should appear.\n if (!this.label?.trim()) return;\n this.clearTimers();\n let instant = Date.now() - lastDismissedAt < this.instantReopenMs;\n if (activeTooltip && activeTooltip !== this) {\n activeTooltip.hideInstant();\n instant = true;\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- module singleton tracks the active instance\n activeTooltip = this;\n this.skipEnterAnimation = instant;\n if (instant) {\n this.mountPopup();\n return;\n }\n this.delayTimer = setTimeout(() => {\n this.delayTimer = null;\n if (!this.label?.trim()) return;\n this.mountPopup();\n }, this.hoverDelayMs);\n }\n\n private hide() {\n this.clearTimers();\n if (!this.popupEl && !this.isOpen) return;\n lastDismissedAt = Date.now();\n if (!this.popupEl) {\n this.isOpen = false;\n return;\n }\n this.popupEl.classList.remove('tooltip-popup--instant');\n this.popupEl.classList.add('tooltip-popup--closing');\n if (this.fadeOutMs === 0) {\n if (activeTooltip === this) activeTooltip = null;\n this.destroyPopup();\n this.isOpen = false;\n this.skipEnterAnimation = false;\n return;\n }\n this.closeTimer = setTimeout(() => {\n this.closeTimer = null;\n if (activeTooltip === this) activeTooltip = null;\n this.destroyPopup();\n this.isOpen = false;\n this.skipEnterAnimation = false;\n }, this.fadeOutMs);\n }\n\n private mountPopup() {\n if (!this.popupEl) {\n const tip = document.createElement('div');\n tip.id = this.tooltipId;\n tip.setAttribute('role', 'tooltip');\n // `sc-ds-tooltip` is required for Stencil scoped CSS to match outside the host.\n tip.className = 'tooltip-popup ds-forced-colors-scope sc-ds-tooltip';\n Object.assign(tip.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n zIndex: 'var(--dimension-z-index-tooltip)',\n pointerEvents: 'none',\n });\n document.body.appendChild(tip);\n this.popupEl = tip;\n }\n\n this.setupOpenListeners();\n this.linkDescribedBy();\n this.popupEl.classList.toggle('tooltip-popup--instant', this.skipEnterAnimation);\n this.popupEl.classList.toggle('tooltip-popup--wrap', this.wrapLabel);\n this.popupEl.classList.remove('tooltip-popup--closing');\n this.renderPopupContent();\n this.schedulePosition();\n this.isOpen = true;\n }\n\n private renderPopupContent() {\n if (!this.popupEl) return;\n this.popupEl.classList.toggle('tooltip-popup--wrap', this.wrapLabel);\n const textVariant = CONTROL_TEXT_VARIANT[this.size];\n const density =\n this.size === 'md'\n ? 'ds-control--md'\n : this.size === 'sm'\n ? 'ds-control--sm'\n : 'ds-control--xs';\n // Every layout node needs `sc-ds-tooltip` so scoped selectors (`.foo.sc-ds-tooltip`) match.\n const sc = 'sc-ds-tooltip';\n\n const inner = document.createElement('div');\n inner.className = `tooltip-inner ${density} ${sc}`;\n\n const appendShortcut = (position: 'start' | 'end') => {\n if (!this.shortcutKey || this.shortcutKeyPosition !== position) return;\n const group = document.createElement('span');\n group.className = `key-hint-group ${sc}`;\n group.setAttribute('aria-hidden', 'true');\n\n for (const label of shortcutKeyLabels(this.shortcutKey)) {\n const hint = document.createElement('span');\n const wide = Array.from(label).length > 1 ? ' key-hint--wide' : '';\n hint.className = `key-hint${wide} ${sc}`;\n const text = document.createElement('span');\n text.className = `key-hint__label ${sc}`;\n text.textContent = label;\n hint.appendChild(text);\n group.appendChild(hint);\n }\n inner.appendChild(group);\n };\n\n appendShortcut('start');\n\n // ds-text is the layout box (metric-box + 2px control label-inset).\n // Inline styles required — see styleTooltipLabel.\n const label = createDsText({\n variant: textVariant,\n wrap: this.wrapLabel ? 'wrap' : 'nowrap',\n text: this.label,\n });\n styleTooltipLabel(label, this.wrapLabel);\n inner.appendChild(label);\n\n appendShortcut('end');\n\n this.popupEl.replaceChildren(inner);\n }\n\n render() {\n return (\n <Host style={{ display: 'contents' }}>\n <slot onSlotchange={this.handleSlotChange} />\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|