bits-ui 1.0.0-next.44 → 1.0.0-next.46
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/bits/link-preview/components/link-preview-content.svelte +2 -0
- package/dist/bits/link-preview/link-preview.svelte.d.ts +3 -0
- package/dist/bits/link-preview/link-preview.svelte.js +17 -1
- package/dist/bits/slider/slider.svelte.d.ts +2 -1
- package/dist/bits/slider/slider.svelte.js +10 -3
- package/dist/internal/use-grace-area.svelte.d.ts +1 -1
- package/dist/internal/use-grace-area.svelte.js +8 -10
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import PopperLayer from "../../utilities/popper-layer/popper-layer.svelte";
|
|
7
7
|
import { getFloatingContentCSSVars } from "../../../internal/floating-svelte/floating-utils.svelte.js";
|
|
8
8
|
import PopperLayerForceMount from "../../utilities/popper-layer/popper-layer-force-mount.svelte";
|
|
9
|
+
import Mounted from "../../utilities/mounted.svelte";
|
|
9
10
|
|
|
10
11
|
let {
|
|
11
12
|
children,
|
|
@@ -112,6 +113,7 @@
|
|
|
112
113
|
{@render children?.()}
|
|
113
114
|
</div>
|
|
114
115
|
{/if}
|
|
116
|
+
<Mounted onMountedChange={(m) => (contentState.root.contentMounted = m)} />
|
|
115
117
|
{/snippet}
|
|
116
118
|
</PopperLayer>
|
|
117
119
|
{/if}
|
|
@@ -16,8 +16,10 @@ declare class LinkPreviewRootState {
|
|
|
16
16
|
timeout: number | null;
|
|
17
17
|
contentNode: HTMLElement | null;
|
|
18
18
|
contentId: string | undefined;
|
|
19
|
+
contentMounted: boolean;
|
|
19
20
|
triggerNode: HTMLElement | null;
|
|
20
21
|
isPointerInTransit: import("svelte-toolbelt").WritableBox<boolean>;
|
|
22
|
+
isOpening: boolean;
|
|
21
23
|
constructor(props: LinkPreviewRootStateProps);
|
|
22
24
|
clearTimeout: () => void;
|
|
23
25
|
handleOpen: () => void;
|
|
@@ -41,6 +43,7 @@ declare class LinkPreviewTriggerState {
|
|
|
41
43
|
currentTarget: HTMLElement;
|
|
42
44
|
}) => void;
|
|
43
45
|
readonly onblur: () => void;
|
|
46
|
+
readonly onpointerleave: (e: PointerEvent) => void;
|
|
44
47
|
};
|
|
45
48
|
}
|
|
46
49
|
type LinkPreviewContentStateProps = WithRefProps;
|
|
@@ -18,8 +18,10 @@ class LinkPreviewRootState {
|
|
|
18
18
|
timeout = null;
|
|
19
19
|
contentNode = $state(null);
|
|
20
20
|
contentId = $state(undefined);
|
|
21
|
+
contentMounted = $state(false);
|
|
21
22
|
triggerNode = $state(null);
|
|
22
23
|
isPointerInTransit = box(false);
|
|
24
|
+
isOpening = $state(false);
|
|
23
25
|
constructor(props) {
|
|
24
26
|
this.open = props.open;
|
|
25
27
|
this.openDelay = props.openDelay;
|
|
@@ -67,15 +69,21 @@ class LinkPreviewRootState {
|
|
|
67
69
|
this.clearTimeout();
|
|
68
70
|
if (this.open.current)
|
|
69
71
|
return;
|
|
72
|
+
this.isOpening = true;
|
|
70
73
|
this.timeout = window.setTimeout(() => {
|
|
71
|
-
this.
|
|
74
|
+
if (this.isOpening) {
|
|
75
|
+
this.open.current = true;
|
|
76
|
+
this.isOpening = false;
|
|
77
|
+
}
|
|
72
78
|
}, this.openDelay.current);
|
|
73
79
|
};
|
|
74
80
|
immediateClose = () => {
|
|
75
81
|
this.clearTimeout();
|
|
82
|
+
this.isOpening = false;
|
|
76
83
|
this.open.current = false;
|
|
77
84
|
};
|
|
78
85
|
handleClose = () => {
|
|
86
|
+
this.isOpening = false;
|
|
79
87
|
this.clearTimeout();
|
|
80
88
|
if (!this.isPointerDownOnContent && !this.hasSelection) {
|
|
81
89
|
this.timeout = window.setTimeout(() => {
|
|
@@ -105,6 +113,13 @@ class LinkPreviewTriggerState {
|
|
|
105
113
|
return;
|
|
106
114
|
this.#root.handleOpen();
|
|
107
115
|
};
|
|
116
|
+
#onpointerleave = (e) => {
|
|
117
|
+
if (isTouch(e))
|
|
118
|
+
return;
|
|
119
|
+
if (!this.#root.contentMounted) {
|
|
120
|
+
this.#root.immediateClose();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
108
123
|
#onfocus = (e) => {
|
|
109
124
|
if (!isFocusVisible(e.currentTarget))
|
|
110
125
|
return;
|
|
@@ -124,6 +139,7 @@ class LinkPreviewTriggerState {
|
|
|
124
139
|
onpointerenter: this.#onpointerenter,
|
|
125
140
|
onfocus: this.#onfocus,
|
|
126
141
|
onblur: this.#onblur,
|
|
142
|
+
onpointerleave: this.#onpointerleave,
|
|
127
143
|
}));
|
|
128
144
|
}
|
|
129
145
|
class LinkPreviewContentState {
|
|
@@ -18,6 +18,7 @@ type SliderRootStateProps = WithRefProps<ReadableBoxedValues<{
|
|
|
18
18
|
value: number[];
|
|
19
19
|
}>>;
|
|
20
20
|
declare class SliderRootState {
|
|
21
|
+
#private;
|
|
21
22
|
id: SliderRootStateProps["id"];
|
|
22
23
|
ref: SliderRootStateProps["ref"];
|
|
23
24
|
value: SliderRootStateProps["value"];
|
|
@@ -84,7 +85,7 @@ declare class SliderRootState {
|
|
|
84
85
|
readonly "data-orientation": "horizontal" | "vertical";
|
|
85
86
|
readonly "data-disabled": "" | undefined;
|
|
86
87
|
readonly style: {
|
|
87
|
-
readonly touchAction:
|
|
88
|
+
readonly touchAction: string | undefined;
|
|
88
89
|
};
|
|
89
90
|
readonly "data-slider-root": "";
|
|
90
91
|
};
|
|
@@ -125,7 +125,7 @@ class SliderRootState {
|
|
|
125
125
|
};
|
|
126
126
|
};
|
|
127
127
|
handlePointerMove = (e) => {
|
|
128
|
-
if (!this.isActive)
|
|
128
|
+
if (!this.isActive || this.disabled.current)
|
|
129
129
|
return;
|
|
130
130
|
e.preventDefault();
|
|
131
131
|
e.stopPropagation();
|
|
@@ -170,7 +170,7 @@ class SliderRootState {
|
|
|
170
170
|
}
|
|
171
171
|
};
|
|
172
172
|
handlePointerDown = (e) => {
|
|
173
|
-
if (e.button !== 0)
|
|
173
|
+
if (e.button !== 0 || this.disabled.current)
|
|
174
174
|
return;
|
|
175
175
|
const sliderNode = this.ref.current;
|
|
176
176
|
const closestThumb = this.getClosestThumb(e);
|
|
@@ -186,6 +186,8 @@ class SliderRootState {
|
|
|
186
186
|
this.handlePointerMove(e);
|
|
187
187
|
};
|
|
188
188
|
handlePointerUp = () => {
|
|
189
|
+
if (this.disabled.current)
|
|
190
|
+
return;
|
|
189
191
|
if (this.isActive) {
|
|
190
192
|
this.onValueCommit.current(untrack(() => this.value.current));
|
|
191
193
|
}
|
|
@@ -306,12 +308,17 @@ class SliderRootState {
|
|
|
306
308
|
ticks: this.ticksRenderArr,
|
|
307
309
|
thumbs: this.thumbsRenderArr,
|
|
308
310
|
}));
|
|
311
|
+
#touchAction = $derived.by(() => {
|
|
312
|
+
if (this.disabled.current)
|
|
313
|
+
return undefined;
|
|
314
|
+
return this.orientation.current === "horizontal" ? "pan-y" : "pan-x";
|
|
315
|
+
});
|
|
309
316
|
props = $derived.by(() => ({
|
|
310
317
|
id: this.id.current,
|
|
311
318
|
"data-orientation": getDataOrientation(this.orientation.current),
|
|
312
319
|
"data-disabled": getDataDisabled(this.disabled.current),
|
|
313
320
|
style: {
|
|
314
|
-
touchAction: this
|
|
321
|
+
touchAction: this.#touchAction,
|
|
315
322
|
},
|
|
316
323
|
[SLIDER_ROOT_ATTR]: "",
|
|
317
324
|
}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Getter } from "svelte-toolbelt";
|
|
2
|
-
export declare function useGraceArea(
|
|
2
|
+
export declare function useGraceArea(getTriggerNode: Getter<HTMLElement | null>, getContentNode: Getter<HTMLElement | null>): {
|
|
3
3
|
isPointerInTransit: import("svelte-toolbelt").WritableBox<boolean>;
|
|
4
4
|
onPointerExit: import("./create-event-hook.svelte.js").EventHookOn<void>;
|
|
5
5
|
};
|
|
@@ -3,8 +3,10 @@ import { boxAutoReset } from "./box-auto-reset.svelte.js";
|
|
|
3
3
|
import { createEventHook } from "./create-event-hook.svelte.js";
|
|
4
4
|
import { isElement, isHTMLElement } from "./is.js";
|
|
5
5
|
import { addEventListener } from "./events.js";
|
|
6
|
-
export function useGraceArea(
|
|
6
|
+
export function useGraceArea(getTriggerNode, getContentNode) {
|
|
7
7
|
const isPointerInTransit = boxAutoReset(false, 300);
|
|
8
|
+
const triggerNode = $derived(getTriggerNode());
|
|
9
|
+
const contentNode = $derived(getContentNode());
|
|
8
10
|
let pointerGraceArea = $state(null);
|
|
9
11
|
const pointerExit = createEventHook();
|
|
10
12
|
function handleRemoveGraceArea() {
|
|
@@ -24,17 +26,15 @@ export function useGraceArea(triggerNode, contentNode) {
|
|
|
24
26
|
isPointerInTransit.current = true;
|
|
25
27
|
}
|
|
26
28
|
$effect(() => {
|
|
27
|
-
|
|
28
|
-
const content = contentNode();
|
|
29
|
-
if (!trigger || !content)
|
|
29
|
+
if (!triggerNode || !contentNode)
|
|
30
30
|
return;
|
|
31
31
|
const handleTriggerLeave = (e) => {
|
|
32
|
-
handleCreateGraceArea(e,
|
|
32
|
+
handleCreateGraceArea(e, contentNode);
|
|
33
33
|
};
|
|
34
34
|
const handleContentLeave = (e) => {
|
|
35
|
-
handleCreateGraceArea(e,
|
|
35
|
+
handleCreateGraceArea(e, triggerNode);
|
|
36
36
|
};
|
|
37
|
-
const unsub = executeCallbacks(addEventListener(
|
|
37
|
+
const unsub = executeCallbacks(addEventListener(triggerNode, "pointerleave", handleTriggerLeave), addEventListener(contentNode, "pointerleave", handleContentLeave));
|
|
38
38
|
return unsub;
|
|
39
39
|
});
|
|
40
40
|
$effect(() => {
|
|
@@ -46,10 +46,8 @@ export function useGraceArea(triggerNode, contentNode) {
|
|
|
46
46
|
const target = e.target;
|
|
47
47
|
if (!isElement(target))
|
|
48
48
|
return;
|
|
49
|
-
const trigger = triggerNode();
|
|
50
|
-
const content = contentNode();
|
|
51
49
|
const pointerPosition = { x: e.clientX, y: e.clientY };
|
|
52
|
-
const hasEnteredTarget =
|
|
50
|
+
const hasEnteredTarget = triggerNode?.contains(target) || contentNode?.contains(target);
|
|
53
51
|
const isPointerOutsideGraceArea = !isPointInPolygon(pointerPosition, pointerGraceArea);
|
|
54
52
|
if (hasEnteredTarget) {
|
|
55
53
|
handleRemoveGraceArea();
|