@design-factory/core 22.0.0-next.1 → 22.0.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.
@@ -71,6 +71,7 @@ const createExtendedAlert = extendWidgetProps(
71
71
  alertDefaultConfig,
72
72
  alertConfigValidator,
73
73
  {
74
+ dismissible: false,
74
75
  transition: alertFadeTransition
75
76
  }
76
77
  );
@@ -74,6 +74,12 @@ export interface AlertState extends CommonAlertState, AlertExtraPropsAndState {
74
74
  * Represents the properties for the alert component.
75
75
  */
76
76
  export interface AlertProps extends CommonAlertProps, AlertExtraProps {
77
+ /**
78
+ * If `true`, alert can be dismissed by the user.
79
+ *
80
+ * @defaultValue `false`
81
+ */
82
+ dismissible: boolean;
77
83
  }
78
84
  /**
79
85
  * Represents the API for an alert component.
@@ -1,4 +1,4 @@
1
- import { c } from "../../alert-Db6cG6JE.js";
1
+ import { c } from "../../alert-klFrSyNy.js";
2
2
  export {
3
3
  c as createAlert
4
4
  };
@@ -1,4 +1,4 @@
1
- import { c, g } from "../../dropdown-Bjj2ql6d.js";
1
+ import { c, g } from "../../dropdown-BZiBfdNu.js";
2
2
  export {
3
3
  c as createDropdown,
4
4
  g as getDropdownDefaultConfig
@@ -1,174 +1,6 @@
1
- import { writable, derived, computed, readable } from "@amadeus-it-group/tansu";
2
- import { createHasFocus, activeElement$ } from "../../services/focustrack.js";
3
- import { createHasMouseInside } from "../../services/mousetrack.js";
4
- import { typePlacement, createPositioning } from "../../services/positioning.js";
5
- import { createTransition } from "../../services/transitions/baseTransitions.js";
6
- import { createSimpleClassTransition } from "../../services/transitions/simpleClassTransition.js";
7
- import { debounceSignal } from "../../utils/debounceSignal.js";
8
- import { w as addEvent, s as mergeDirectives, g as createAttributesDirective, o as directiveSubscribe } from "../../directive-CMT2vEDg.js";
9
- import { createEdgeState } from "../../utils/edgeState.js";
10
- import { generateId } from "../../utils/id.js";
11
- import { writablesForProps, stateStores } from "../../utils/stores.js";
12
- import { createWidgetFactory } from "../../utils/widget.js";
13
- import { a as createTypeStringSpacedArray, d as typeBoolean, l as typeStringOrNull, c as createTypeEnum } from "../../writables-_7BriMb2.js";
14
- const verticalPlacement = ["top", "top-start", "top-end", "bottom", "bottom-start", "bottom-end"];
15
- const horizontalPlacement = ["end", "end-end", "end-start", "start", "start-end", "start-start"];
16
- const defaultPlacement = [...verticalPlacement, ...horizontalPlacement];
17
- const fadeTransition = createSimpleClassTransition({
18
- animationPendingClasses: ["df-fade"],
19
- animationPendingShowClasses: ["df-show"],
20
- showClasses: ["df-show", "df-fade"],
21
- hideClasses: ["df-hidden", "df-fade"]
22
- });
23
- const defaultTooltipConfig = {
24
- animated: true,
25
- content: "",
26
- disabled: false,
27
- placement: defaultPlacement,
28
- size: "md"
29
- };
30
- const tooltipConfigValidator = {
31
- animated: typeBoolean,
32
- content: typeStringOrNull,
33
- disabled: typeBoolean,
34
- placement: createTypeStringSpacedArray((placement) => {
35
- if (placement === "auto") {
36
- return defaultPlacement;
37
- } else if (placement === "vertical") {
38
- return verticalPlacement;
39
- } else if (placement === "horizontal") {
40
- return horizontalPlacement;
41
- }
42
- return typePlacement.normalizeValue(placement);
43
- }),
44
- size: createTypeEnum(["sm", "md", "lg"])
45
- };
46
- const DEBOUNCE_DELAY = 200;
47
- const createTooltip = createWidgetFactory(
48
- "tooltip",
49
- (config) => {
50
- const [{ placement$, animated$, disabled$, content$, ...stateProps }, patch] = writablesForProps(
51
- defaultTooltipConfig,
52
- config,
53
- tooltipConfigValidator
54
- );
55
- const floating = createPositioning({
56
- props: {
57
- placement: placement$
58
- }
59
- });
60
- const { directive: hasFocusDirective, hasFocus$ } = createHasFocus();
61
- const forceVisibleOnFocus$ = writable(false);
62
- const hasVisibleFocus$ = derived(
63
- [hasFocus$, activeElement$, forceVisibleOnFocus$],
64
- ([hasFocus, activeElement, forceVisibleOnFocus], set) => {
65
- if (hasFocus) {
66
- if (forceVisibleOnFocus || activeElement?.matches(":focus-visible")) {
67
- set(true);
68
- }
69
- } else {
70
- set(false);
71
- }
72
- },
73
- false
74
- );
75
- const debouncedHasVisibleFocus$ = debounceSignal(hasVisibleFocus$, (value) => value ? DEBOUNCE_DELAY : -1);
76
- const { directive: hasMouseInsideDirective, hasMouseInside$ } = createHasMouseInside();
77
- const debouncedHasMouseInside$ = debounceSignal(hasMouseInside$, DEBOUNCE_DELAY);
78
- const visible$ = createEdgeState(
79
- {
80
- mouseInside: debouncedHasMouseInside$,
81
- hasVisibleFocus: debouncedHasVisibleFocus$
82
- },
83
- computed(() => disabled$() || !content$() || floating.stores.referenceHidden$())
84
- );
85
- const transition = createTransition({
86
- props: {
87
- transition: fadeTransition,
88
- visible: visible$,
89
- animated: animated$,
90
- animatedOnInit: true
91
- }
92
- });
93
- const escDismiss$ = readable(void 0, {
94
- onUse: () => addEvent(
95
- document.documentElement,
96
- "keydown",
97
- (event) => {
98
- if (visible$() && event.key === "Escape") {
99
- void transition.api.toggle(false);
100
- event.preventDefault();
101
- event.stopPropagation();
102
- }
103
- },
104
- { capture: true }
105
- )
106
- });
107
- const id$ = computed(generateId);
108
- return {
109
- ...stateStores({
110
- ...stateProps,
111
- content$,
112
- animated$,
113
- disabled$,
114
- placement$,
115
- visible$: transition.stores.visible$,
116
- hidden$: transition.stores.hidden$
117
- }),
118
- patch,
119
- api: {},
120
- directives: {
121
- referenceDirective: mergeDirectives(
122
- floating.directives.referenceDirective,
123
- hasFocusDirective,
124
- hasMouseInsideDirective,
125
- createAttributesDirective(() => ({
126
- attributes: {
127
- "aria-describedby": computed(() => transition.stores.hidden$() ? void 0 : id$())
128
- },
129
- styles: {
130
- // prevents the trigger element from being selected when long-pressing on touch devices
131
- userSelect: computed(() => disabled$() ? void 0 : "none")
132
- },
133
- events: {
134
- contextmenu: (event) => {
135
- if (event.pointerType === "touch" && !disabled$()) {
136
- event.preventDefault();
137
- if (hasVisibleFocus$()) {
138
- void transition.api.toggle(true);
139
- } else {
140
- forceVisibleOnFocus$.set(true);
141
- event.currentTarget?.focus?.();
142
- forceVisibleOnFocus$.set(false);
143
- }
144
- }
145
- }
146
- }
147
- }))
148
- ),
149
- floatingDirective: mergeDirectives(
150
- floating.directives.floatingDirective,
151
- transition.directives.directive,
152
- hasMouseInsideDirective,
153
- directiveSubscribe(escDismiss$),
154
- createAttributesDirective(() => ({
155
- attributes: {
156
- role: readable("tooltip"),
157
- id: id$
158
- },
159
- events: {
160
- mousedown: (event) => {
161
- if (hasVisibleFocus$() && debouncedHasMouseInside$() && !event.defaultPrevented) {
162
- visible$.skipNextSourceValue("hasVisibleFocus", false);
163
- }
164
- }
165
- }
166
- }))
167
- )
168
- }
169
- };
170
- }
171
- );
1
+ import { c, d, t } from "../../tooltip-Cl7tQomt.js";
172
2
  export {
173
- createTooltip
3
+ c as createTooltip,
4
+ d as defaultPlacement,
5
+ t as tooltipPlacementValidator
174
6
  };
@@ -1,5 +1,5 @@
1
1
  import { type Placement } from '../../services/positioning';
2
- import type { Directive, SSRHTMLElement, Widget, WidgetFactory } from '../../types';
2
+ import type { Directive, PickRequired, SSRHTMLElement, Widget, WidgetFactory, WritableWithDefaultOptions } from '../../types';
3
3
  /**
4
4
  * Valid placement values for the tooltip.
5
5
  * Includes all individual {@link Placement} values plus `'auto'`, `'vertical'` and `'horizontal'` shortcuts.
@@ -9,6 +9,10 @@ import type { Directive, SSRHTMLElement, Widget, WidgetFactory } from '../../typ
9
9
  * - `'horizontal'` expands to `'end end-end end-start start start-end start-start'`
10
10
  */
11
11
  export type TooltipPlacement = Placement | 'auto' | 'vertical' | 'horizontal';
12
+ /**
13
+ * Default tooltip placements, in order of preference (vertical first, then horizontal).
14
+ */
15
+ export declare const defaultPlacement: Placement[];
12
16
  export type TooltipSize = 'sm' | 'md' | 'lg';
13
17
  export interface TooltipCommonPropsAndState {
14
18
  /**
@@ -55,6 +59,11 @@ export interface TooltipDirectives {
55
59
  floatingDirective: Directive<void, SSRHTMLElement>;
56
60
  }
57
61
  export type TooltipWidget = Widget<TooltipProps, TooltipState, Record<string, never>, TooltipDirectives>;
62
+ /**
63
+ * Validator for the tooltip `placement` prop. Normalizes a space-separated string or array of placements, expanding the
64
+ * `'auto'`, `'vertical'` and `'horizontal'` shortcuts to their respective placement lists.
65
+ */
66
+ export declare const tooltipPlacementValidator: PickRequired<WritableWithDefaultOptions<Placement[]>, 'normalizeValue' | 'equal'>;
58
67
  /**
59
68
  * Create a TooltipWidget with given config props
60
69
  * @param config - an optional tooltip config
@@ -0,0 +1 @@
1
+ export * from './tooltip-overflow';
@@ -0,0 +1,78 @@
1
+ import { derived, computed, asWritable } from "@amadeus-it-group/tansu";
2
+ import { createResizeObserver } from "../../services/resizeObserver.js";
3
+ import { i as createBrowserStoreDirective, s as mergeDirectives } from "../../directive-CMT2vEDg.js";
4
+ import { noop } from "../../utils/func.js";
5
+ import { writablesForProps, stateStores } from "../../utils/stores.js";
6
+ import { createWidgetFactory } from "../../utils/widget.js";
7
+ import { k as typeString, l as typeStringOrNull, d as typeBoolean, c as createTypeEnum } from "../../writables-_7BriMb2.js";
8
+ import { t as tooltipPlacementValidator, d as defaultPlacement } from "../../tooltip-Cl7tQomt.js";
9
+ const defaultOverflowTooltipConfig = {
10
+ animated: true,
11
+ content: "",
12
+ placement: defaultPlacement,
13
+ size: "md",
14
+ iconAriaLabel: "Show full text"
15
+ };
16
+ const overflowTooltipConfigValidator = {
17
+ animated: typeBoolean,
18
+ content: typeStringOrNull,
19
+ placement: tooltipPlacementValidator,
20
+ size: createTypeEnum(["sm", "md", "lg"]),
21
+ iconAriaLabel: typeString
22
+ };
23
+ const createOverflowTooltip = createWidgetFactory(
24
+ "tooltip",
25
+ // reuses the same config as the tooltip widget
26
+ (config) => {
27
+ const [{ content$, ...stateProps }, patch] = writablesForProps(
28
+ defaultOverflowTooltipConfig,
29
+ config,
30
+ overflowTooltipConfigValidator
31
+ );
32
+ const { directive: elementDirective, element$ } = createBrowserStoreDirective();
33
+ const textContent$ = derived(
34
+ element$,
35
+ (el, set) => {
36
+ if (!el) {
37
+ set("");
38
+ return noop;
39
+ }
40
+ set(el.textContent?.trim() ?? "");
41
+ const observer = new MutationObserver(() => set(el.textContent?.trim() ?? ""));
42
+ observer.observe(el, { childList: true, characterData: true, subtree: true });
43
+ return () => observer.disconnect();
44
+ },
45
+ ""
46
+ );
47
+ const { directive: resizeDirective, dimensions$ } = createResizeObserver();
48
+ const overflowing$ = computed(() => {
49
+ dimensions$();
50
+ textContent$();
51
+ const el = element$();
52
+ if (!el) {
53
+ return false;
54
+ }
55
+ return el.offsetWidth < el.scrollWidth;
56
+ });
57
+ const resolvedContent$ = asWritable(
58
+ computed(() => content$() || textContent$()),
59
+ content$.set
60
+ );
61
+ const referenceDirective = mergeDirectives(elementDirective, resizeDirective);
62
+ return {
63
+ ...stateStores({
64
+ ...stateProps,
65
+ content$: resolvedContent$,
66
+ overflowing$
67
+ }),
68
+ patch,
69
+ api: {},
70
+ directives: {
71
+ referenceDirective
72
+ }
73
+ };
74
+ }
75
+ );
76
+ export {
77
+ createOverflowTooltip
78
+ };
@@ -0,0 +1,34 @@
1
+ import type { Directive, Widget, WidgetFactory } from '../../types';
2
+ import { TooltipCommonPropsAndState } from '../tooltip/tooltip';
3
+ export interface OverflowTooltipCommonPropsAndState extends Omit<TooltipCommonPropsAndState, 'disabled'> {
4
+ /**
5
+ * Text content to be displayed inside the tooltip.
6
+ * When empty, defaults to the element's textContent.
7
+ */
8
+ content: string | null;
9
+ /**
10
+ * Aria label for the tooltip ellipsis icon.
11
+ */
12
+ iconAriaLabel: string;
13
+ }
14
+ export interface OverflowTooltipState extends OverflowTooltipCommonPropsAndState {
15
+ /**
16
+ * Whether the element is currently overflowing.
17
+ */
18
+ overflowing: boolean;
19
+ }
20
+ export interface OverflowTooltipProps extends OverflowTooltipCommonPropsAndState {
21
+ }
22
+ export interface OverflowTooltipDirectives {
23
+ /**
24
+ * Directive to apply to the reference element.
25
+ */
26
+ referenceDirective: Directive;
27
+ }
28
+ export type OverflowTooltipWidget = Widget<OverflowTooltipProps, OverflowTooltipState, Record<string, never>, OverflowTooltipDirectives>;
29
+ /**
30
+ * Create a OverflowTooltipWidget with given config props
31
+ * @param config - an optional overflow-tooltip config
32
+ * @returns a OverflowTooltipWidget
33
+ */
34
+ export declare const createOverflowTooltip: WidgetFactory<OverflowTooltipWidget>;
@@ -1,8 +1,8 @@
1
- import { computed, readable, derived } from "@amadeus-it-group/tansu";
1
+ import { computed, readable } from "@amadeus-it-group/tansu";
2
2
  import { createHasFocus } from "./services/focustrack.js";
3
3
  import { createNavManager } from "./services/navManager.js";
4
4
  import { typePlacementArray, createPositioning } from "./services/positioning.js";
5
- import { s as mergeDirectives, g as createAttributesDirective, d as browserDirective, o as directiveSubscribe, b as bindDirective } from "./directive-CMT2vEDg.js";
5
+ import { s as mergeDirectives, g as createAttributesDirective, d as browserDirective, b as bindDirective, w as addEvent } from "./directive-CMT2vEDg.js";
6
6
  import { noop } from "./utils/func.js";
7
7
  import { generateId } from "./utils/id.js";
8
8
  import { i as isFocusable, f as findPreviousFocusableElement, a as findNextFocusableElement, b as findNextElementSkippingSubtree, c as findNextElement } from "./isFocusable-C2iRr0zh.js";
@@ -83,11 +83,6 @@ const createDropdown = createWidgetFactory(
83
83
  End: ({ event }) => {
84
84
  event.preventDefault();
85
85
  focusLast({ event });
86
- },
87
- Escape: ({ event }) => {
88
- event.preventDefault();
89
- toggle(false);
90
- anchorElement?.focus();
91
86
  }
92
87
  },
93
88
  selector: (menuElement) => menuElement.querySelectorAll(menuItemSelector)
@@ -100,18 +95,54 @@ const createDropdown = createWidgetFactory(
100
95
  });
101
96
  const positioningBeforeRef$ = computed(() => positioning.stores.placement$()?.startsWith("top"));
102
97
  const { directive: hasFocusDirective, hasFocus$ } = createHasFocus();
103
- let previousHasFocus = false;
104
- const autoClose$ = derived(hasFocus$, (hasFocus) => {
105
- if (previousHasFocus && !hasFocus) {
106
- toggle(false);
107
- }
108
- previousHasFocus = hasFocus;
109
- });
110
98
  function toggle(opened) {
111
99
  opened$.update((currentOpened) => {
112
100
  return opened !== void 0 ? opened : !currentOpened;
113
101
  });
114
102
  }
103
+ const menuDismissDirective = browserDirective((menuElement) => {
104
+ let hadFocus = hasFocus$();
105
+ const unsubscribeFocus = hasFocus$.subscribe((hasFocus) => {
106
+ if (hadFocus && !hasFocus) {
107
+ toggle(false);
108
+ }
109
+ hadFocus = hasFocus;
110
+ });
111
+ const isInsideDropdown = (event) => {
112
+ const eventPath = event.composedPath();
113
+ return eventPath.includes(menuElement) || !!anchorElement && eventPath.includes(anchorElement);
114
+ };
115
+ const removeClickEvent = addEvent(
116
+ document.documentElement,
117
+ "click",
118
+ (event) => {
119
+ if (opened$() && !isInsideDropdown(event)) {
120
+ toggle(false);
121
+ }
122
+ },
123
+ { capture: true }
124
+ );
125
+ const removeKeydownEvent = addEvent(
126
+ document.documentElement,
127
+ "keydown",
128
+ (event) => {
129
+ if (opened$() && event.key === "Escape") {
130
+ toggle(false);
131
+ anchorElement?.focus();
132
+ event.preventDefault();
133
+ event.stopPropagation();
134
+ }
135
+ },
136
+ { capture: true }
137
+ );
138
+ return {
139
+ destroy: () => {
140
+ unsubscribeFocus();
141
+ removeClickEvent();
142
+ removeKeydownEvent();
143
+ }
144
+ };
145
+ });
115
146
  const menuIdIfNeeded$ = computed(() => opened$() && container$() === "body" ? menuId$() : void 0);
116
147
  const idIfOpen$ = computed(() => opened$() ? id$() : void 0);
117
148
  return {
@@ -127,7 +158,7 @@ const createDropdown = createWidgetFactory(
127
158
  positioning.directives.floatingDirective,
128
159
  bindDirective(navDirective, navManagerConfig$),
129
160
  hasFocusDirective,
130
- directiveSubscribe(autoClose$),
161
+ menuDismissDirective,
131
162
  createAttributesDirective(() => ({
132
163
  events: {
133
164
  // Clicking a non-interactive region of the menu (separator, padding, headers, aria-disabled items)
@@ -200,9 +231,6 @@ const createDropdown = createWidgetFactory(
200
231
  event.preventDefault();
201
232
  refreshElements(true);
202
233
  focusLast();
203
- } else if (key === "Escape") {
204
- event.preventDefault();
205
- toggle(false);
206
234
  } else if (key === "Tab") {
207
235
  const before = positioningBeforeRef$();
208
236
  if (!!event.shiftKey === before) {
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { FACTORY_WIDGET_NAME, INVALID_VALUE } from "./types.js";
2
2
  import { c, a, f, g } from "./accordion-DUFLBQkV.js";
3
- import { c as c2 } from "./alert-Db6cG6JE.js";
3
+ import { c as c2 } from "./alert-klFrSyNy.js";
4
4
  import { c as c3, g as g2 } from "./collapse-D8Jo56k9.js";
5
- import { c as c4, g as g3 } from "./dropdown-Bjj2ql6d.js";
5
+ import { c as c4, g as g3 } from "./dropdown-BZiBfdNu.js";
6
6
  import { c as c5, g as g4, m, a as a2, b } from "./modal-CQWh2Sm5.js";
7
7
  import { c as c6, g as g5 } from "./pagination-DIRcpdRE.js";
8
8
  import { c as c7, g as g6 } from "./progressbar-Bth8r3Qu.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@design-factory/core",
3
3
  "description": "Internal package used by the Design Factory.",
4
- "version": "22.0.0-next.1",
4
+ "version": "22.0.0",
5
5
  "type": "module",
6
6
  "main": "./index.cjs",
7
7
  "module": "./index.js",
@@ -0,0 +1,177 @@
1
+ import { writable, derived, computed, readable } from "@amadeus-it-group/tansu";
2
+ import { createHasFocus, activeElement$ } from "./services/focustrack.js";
3
+ import { createHasMouseInside } from "./services/mousetrack.js";
4
+ import { typePlacement, createPositioning } from "./services/positioning.js";
5
+ import { createTransition } from "./services/transitions/baseTransitions.js";
6
+ import { createSimpleClassTransition } from "./services/transitions/simpleClassTransition.js";
7
+ import { debounceSignal } from "./utils/debounceSignal.js";
8
+ import { w as addEvent, s as mergeDirectives, g as createAttributesDirective, o as directiveSubscribe } from "./directive-CMT2vEDg.js";
9
+ import { createEdgeState } from "./utils/edgeState.js";
10
+ import { generateId } from "./utils/id.js";
11
+ import { writablesForProps, stateStores } from "./utils/stores.js";
12
+ import { createWidgetFactory } from "./utils/widget.js";
13
+ import { a as createTypeStringSpacedArray, d as typeBoolean, l as typeStringOrNull, c as createTypeEnum } from "./writables-_7BriMb2.js";
14
+ const verticalPlacement = ["top", "top-start", "top-end", "bottom", "bottom-start", "bottom-end"];
15
+ const horizontalPlacement = ["end", "end-end", "end-start", "start", "start-end", "start-start"];
16
+ const defaultPlacement = [...verticalPlacement, ...horizontalPlacement];
17
+ const fadeTransition = createSimpleClassTransition({
18
+ animationPendingClasses: ["df-fade"],
19
+ animationPendingShowClasses: ["df-show"],
20
+ showClasses: ["df-show", "df-fade"],
21
+ hideClasses: ["df-hidden", "df-fade"]
22
+ });
23
+ const defaultTooltipConfig = {
24
+ animated: true,
25
+ content: "",
26
+ disabled: false,
27
+ placement: defaultPlacement,
28
+ size: "md"
29
+ };
30
+ const tooltipPlacementValidator = createTypeStringSpacedArray((placement) => {
31
+ if (placement === "auto") {
32
+ return defaultPlacement;
33
+ } else if (placement === "vertical") {
34
+ return verticalPlacement;
35
+ } else if (placement === "horizontal") {
36
+ return horizontalPlacement;
37
+ }
38
+ return typePlacement.normalizeValue(placement);
39
+ });
40
+ const tooltipConfigValidator = {
41
+ animated: typeBoolean,
42
+ content: typeStringOrNull,
43
+ disabled: typeBoolean,
44
+ placement: tooltipPlacementValidator,
45
+ size: createTypeEnum(["sm", "md", "lg"])
46
+ };
47
+ const DEBOUNCE_DELAY = 200;
48
+ const createTooltip = createWidgetFactory(
49
+ "tooltip",
50
+ (config) => {
51
+ const [{ placement$, animated$, disabled$, content$, ...stateProps }, patch] = writablesForProps(
52
+ defaultTooltipConfig,
53
+ config,
54
+ tooltipConfigValidator
55
+ );
56
+ const floating = createPositioning({
57
+ props: {
58
+ placement: placement$
59
+ }
60
+ });
61
+ const { directive: hasFocusDirective, hasFocus$ } = createHasFocus();
62
+ const forceVisibleOnFocus$ = writable(false);
63
+ const hasVisibleFocus$ = derived(
64
+ [hasFocus$, activeElement$, forceVisibleOnFocus$],
65
+ ([hasFocus, activeElement, forceVisibleOnFocus], set) => {
66
+ if (hasFocus) {
67
+ if (forceVisibleOnFocus || activeElement?.matches(":focus-visible")) {
68
+ set(true);
69
+ }
70
+ } else {
71
+ set(false);
72
+ }
73
+ },
74
+ false
75
+ );
76
+ const debouncedHasVisibleFocus$ = debounceSignal(hasVisibleFocus$, (value) => value ? DEBOUNCE_DELAY : -1);
77
+ const { directive: hasMouseInsideDirective, hasMouseInside$ } = createHasMouseInside();
78
+ const debouncedHasMouseInside$ = debounceSignal(hasMouseInside$, DEBOUNCE_DELAY);
79
+ const visible$ = createEdgeState(
80
+ {
81
+ mouseInside: debouncedHasMouseInside$,
82
+ hasVisibleFocus: debouncedHasVisibleFocus$
83
+ },
84
+ computed(() => disabled$() || !content$() || floating.stores.referenceHidden$())
85
+ );
86
+ const transition = createTransition({
87
+ props: {
88
+ transition: fadeTransition,
89
+ visible: visible$,
90
+ animated: animated$,
91
+ animatedOnInit: true
92
+ }
93
+ });
94
+ const escDismiss$ = readable(void 0, {
95
+ onUse: () => addEvent(
96
+ document.documentElement,
97
+ "keydown",
98
+ (event) => {
99
+ if (visible$() && event.key === "Escape") {
100
+ void transition.api.toggle(false);
101
+ event.preventDefault();
102
+ event.stopPropagation();
103
+ }
104
+ },
105
+ { capture: true }
106
+ )
107
+ });
108
+ const id$ = computed(generateId);
109
+ return {
110
+ ...stateStores({
111
+ ...stateProps,
112
+ content$,
113
+ animated$,
114
+ disabled$,
115
+ placement$,
116
+ visible$: transition.stores.visible$,
117
+ hidden$: transition.stores.hidden$
118
+ }),
119
+ patch,
120
+ api: {},
121
+ directives: {
122
+ referenceDirective: mergeDirectives(
123
+ floating.directives.referenceDirective,
124
+ hasFocusDirective,
125
+ hasMouseInsideDirective,
126
+ createAttributesDirective(() => ({
127
+ attributes: {
128
+ "aria-describedby": computed(() => transition.stores.hidden$() ? void 0 : id$())
129
+ },
130
+ styles: {
131
+ // prevents the trigger element from being selected when long-pressing on touch devices
132
+ userSelect: computed(() => disabled$() ? void 0 : "none")
133
+ },
134
+ events: {
135
+ contextmenu: (event) => {
136
+ if (event.pointerType === "touch" && !disabled$()) {
137
+ event.preventDefault();
138
+ if (hasVisibleFocus$()) {
139
+ void transition.api.toggle(true);
140
+ } else {
141
+ forceVisibleOnFocus$.set(true);
142
+ event.currentTarget?.focus?.();
143
+ forceVisibleOnFocus$.set(false);
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }))
149
+ ),
150
+ floatingDirective: mergeDirectives(
151
+ floating.directives.floatingDirective,
152
+ transition.directives.directive,
153
+ hasMouseInsideDirective,
154
+ directiveSubscribe(escDismiss$),
155
+ createAttributesDirective(() => ({
156
+ attributes: {
157
+ role: readable("tooltip"),
158
+ id: id$
159
+ },
160
+ events: {
161
+ mousedown: (event) => {
162
+ if (hasVisibleFocus$() && debouncedHasMouseInside$() && !event.defaultPrevented) {
163
+ visible$.skipNextSourceValue("hasVisibleFocus", false);
164
+ }
165
+ }
166
+ }
167
+ }))
168
+ )
169
+ }
170
+ };
171
+ }
172
+ );
173
+ export {
174
+ createTooltip as c,
175
+ defaultPlacement as d,
176
+ tooltipPlacementValidator as t
177
+ };