bits-ui 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bits/avatar/avatar.svelte.d.ts +2 -1
- package/dist/bits/avatar/avatar.svelte.js +5 -3
- package/dist/bits/calendar/calendar.svelte.d.ts +2 -0
- package/dist/bits/calendar/calendar.svelte.js +9 -4
- package/dist/bits/combobox/components/combobox-input.svelte +2 -2
- package/dist/bits/combobox/components/combobox.svelte +5 -0
- package/dist/bits/combobox/types.d.ts +18 -1
- package/dist/bits/date-field/date-field.svelte.d.ts +3 -1
- package/dist/bits/date-field/date-field.svelte.js +15 -6
- package/dist/bits/date-range-field/date-range-field.svelte.d.ts +2 -0
- package/dist/bits/date-range-field/date-range-field.svelte.js +4 -2
- package/dist/bits/link-preview/link-preview.svelte.d.ts +2 -0
- package/dist/bits/link-preview/link-preview.svelte.js +11 -6
- package/dist/bits/menu/menu.svelte.d.ts +2 -0
- package/dist/bits/menu/menu.svelte.js +15 -10
- package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +3 -1
- package/dist/bits/navigation-menu/navigation-menu.svelte.js +21 -11
- package/dist/bits/pin-input/pin-input.svelte.d.ts +4 -2
- package/dist/bits/pin-input/pin-input.svelte.js +17 -13
- package/dist/bits/pin-input/usePasswordManager.svelte.d.ts +3 -2
- package/dist/bits/pin-input/usePasswordManager.svelte.js +6 -5
- package/dist/bits/range-calendar/range-calendar.svelte.d.ts +2 -0
- package/dist/bits/range-calendar/range-calendar.svelte.js +9 -3
- package/dist/bits/scroll-area/scroll-area.svelte.d.ts +2 -0
- package/dist/bits/scroll-area/scroll-area.svelte.js +15 -12
- package/dist/bits/select/components/select.svelte +6 -0
- package/dist/bits/select/select.svelte.d.ts +5 -1
- package/dist/bits/select/select.svelte.js +34 -18
- package/dist/bits/time-field/time-field.svelte.d.ts +3 -1
- package/dist/bits/time-field/time-field.svelte.js +15 -6
- package/dist/bits/time-range-field/time-range-field.svelte.d.ts +2 -0
- package/dist/bits/time-range-field/time-range-field.svelte.js +4 -2
- package/dist/bits/tooltip/tooltip.svelte.d.ts +2 -0
- package/dist/bits/tooltip/tooltip.svelte.js +4 -2
- package/dist/bits/utilities/floating-layer/use-floating-layer.svelte.js +3 -2
- package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.js +14 -9
- package/dist/bits/utilities/portal/types.d.ts +1 -1
- package/dist/bits/utilities/text-selection-layer/use-text-selection-layer.svelte.d.ts +2 -0
- package/dist/bits/utilities/text-selection-layer/use-text-selection-layer.svelte.js +7 -7
- package/dist/internal/box-auto-reset.svelte.d.ts +7 -1
- package/dist/internal/box-auto-reset.svelte.js +11 -6
- package/dist/internal/date-time/announcer.d.ts +1 -1
- package/dist/internal/date-time/announcer.js +20 -20
- package/dist/internal/date-time/calendar-helpers.svelte.js +7 -5
- package/dist/internal/date-time/field/helpers.d.ts +8 -2
- package/dist/internal/date-time/field/helpers.js +8 -7
- package/dist/internal/date-time/field/time-helpers.d.ts +8 -2
- package/dist/internal/date-time/field/time-helpers.js +9 -9
- package/dist/internal/dom.d.ts +0 -1
- package/dist/internal/dom.js +0 -3
- package/dist/internal/focus.d.ts +2 -2
- package/dist/internal/focus.js +14 -9
- package/dist/internal/math.d.ts +0 -4
- package/dist/internal/math.js +0 -28
- package/dist/internal/tabbable.d.ts +0 -2
- package/dist/internal/tabbable.js +10 -14
- package/dist/internal/use-data-typeahead.svelte.d.ts +1 -0
- package/dist/internal/use-data-typeahead.svelte.js +4 -1
- package/dist/internal/use-dom-typeahead.svelte.d.ts +3 -1
- package/dist/internal/use-dom-typeahead.svelte.js +5 -2
- package/dist/internal/use-grace-area.svelte.js +9 -5
- package/package.json +2 -2
- package/dist/internal/dom-context.svelte.d.ts +0 -9
- package/dist/internal/dom-context.svelte.js +0 -26
- package/dist/internal/use-size.svelte.d.ts +0 -7
- package/dist/internal/use-size.svelte.js +0 -54
|
@@ -245,19 +245,19 @@ export function isFirstTimeSegment(id, fieldNode) {
|
|
|
245
245
|
* so it can be associated via `aria-describedby` and read by
|
|
246
246
|
* screen readers as the user interacts with the date field.
|
|
247
247
|
*/
|
|
248
|
-
export function setTimeDescription(
|
|
248
|
+
export function setTimeDescription(props) {
|
|
249
249
|
if (!isBrowser)
|
|
250
250
|
return;
|
|
251
|
-
const valueString = formatter.selectedTime(value);
|
|
252
|
-
const el =
|
|
251
|
+
const valueString = props.formatter.selectedTime(props.value);
|
|
252
|
+
const el = props.doc.getElementById(props.id);
|
|
253
253
|
if (!el) {
|
|
254
|
-
const div =
|
|
254
|
+
const div = props.doc.createElement("div");
|
|
255
255
|
div.style.cssText = styleToString({
|
|
256
256
|
display: "none",
|
|
257
257
|
});
|
|
258
|
-
div.id = id;
|
|
258
|
+
div.id = props.id;
|
|
259
259
|
div.innerText = `Selected Time: ${valueString}`;
|
|
260
|
-
|
|
260
|
+
props.doc.body.appendChild(div);
|
|
261
261
|
}
|
|
262
262
|
else {
|
|
263
263
|
el.innerText = `Selected Time: ${valueString}`;
|
|
@@ -268,13 +268,13 @@ export function setTimeDescription(id, formatter, value) {
|
|
|
268
268
|
* the provided ID. This function should be called when the
|
|
269
269
|
* date field is unmounted.
|
|
270
270
|
*/
|
|
271
|
-
export function removeTimeDescriptionElement(id) {
|
|
271
|
+
export function removeTimeDescriptionElement(id, doc) {
|
|
272
272
|
if (!isBrowser)
|
|
273
273
|
return;
|
|
274
|
-
const el =
|
|
274
|
+
const el = doc.getElementById(id);
|
|
275
275
|
if (!el)
|
|
276
276
|
return;
|
|
277
|
-
|
|
277
|
+
doc.body.removeChild(el);
|
|
278
278
|
}
|
|
279
279
|
export function convertTimeValueToDateValue(time) {
|
|
280
280
|
if (time instanceof Time) {
|
package/dist/internal/dom.d.ts
CHANGED
package/dist/internal/dom.js
CHANGED
package/dist/internal/focus.d.ts
CHANGED
|
@@ -20,9 +20,9 @@ export declare function focus(element?: FocusableTarget | null, { select }?: {
|
|
|
20
20
|
* Attempts to focus the first element in a list of candidates.
|
|
21
21
|
* Stops when focus is successful.
|
|
22
22
|
*/
|
|
23
|
-
export declare function focusFirst(candidates: HTMLElement[], { select }
|
|
23
|
+
export declare function focusFirst(candidates: HTMLElement[], { select }: {
|
|
24
24
|
select?: boolean | undefined;
|
|
25
|
-
}): true | undefined;
|
|
25
|
+
} | undefined, getActiveElement: () => HTMLElement | null): true | undefined;
|
|
26
26
|
/**
|
|
27
27
|
* Returns the first visible element in a list.
|
|
28
28
|
* NOTE: Only checks visibility up to the `container`.
|
package/dist/internal/focus.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getDocument, getWindow } from "svelte-toolbelt";
|
|
1
2
|
import { isBrowser, isElementHidden, isSelectableInput } from "./is.js";
|
|
2
3
|
/**
|
|
3
4
|
* Handles `initialFocus` prop behavior for the
|
|
@@ -20,12 +21,14 @@ export function handleCalendarInitialFocus(calendar) {
|
|
|
20
21
|
* A utility function that focuses an element without scrolling.
|
|
21
22
|
*/
|
|
22
23
|
export function focusWithoutScroll(element) {
|
|
24
|
+
const doc = getDocument(element);
|
|
25
|
+
const win = getWindow(element);
|
|
23
26
|
const scrollPosition = {
|
|
24
|
-
x:
|
|
25
|
-
y:
|
|
27
|
+
x: win.pageXOffset || doc.documentElement.scrollLeft,
|
|
28
|
+
y: win.pageYOffset || doc.documentElement.scrollTop,
|
|
26
29
|
};
|
|
27
30
|
element.focus();
|
|
28
|
-
|
|
31
|
+
win.scrollTo(scrollPosition.x, scrollPosition.y);
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
34
|
* A utility function that focuses an element.
|
|
@@ -33,9 +36,10 @@ export function focusWithoutScroll(element) {
|
|
|
33
36
|
export function focus(element, { select = false } = {}) {
|
|
34
37
|
if (!(element && element.focus))
|
|
35
38
|
return;
|
|
36
|
-
|
|
39
|
+
const doc = getDocument(element);
|
|
40
|
+
if (doc.activeElement === element)
|
|
37
41
|
return;
|
|
38
|
-
const previouslyFocusedElement =
|
|
42
|
+
const previouslyFocusedElement = doc.activeElement;
|
|
39
43
|
// prevent scroll on focus
|
|
40
44
|
element.focus({ preventScroll: true });
|
|
41
45
|
// only elect if its not the same element, it supports selection, and we need to select it
|
|
@@ -47,11 +51,11 @@ export function focus(element, { select = false } = {}) {
|
|
|
47
51
|
* Attempts to focus the first element in a list of candidates.
|
|
48
52
|
* Stops when focus is successful.
|
|
49
53
|
*/
|
|
50
|
-
export function focusFirst(candidates, { select = false } = {}) {
|
|
51
|
-
const previouslyFocusedElement =
|
|
54
|
+
export function focusFirst(candidates, { select = false } = {}, getActiveElement) {
|
|
55
|
+
const previouslyFocusedElement = getActiveElement();
|
|
52
56
|
for (const candidate of candidates) {
|
|
53
57
|
focus(candidate, { select });
|
|
54
|
-
if (
|
|
58
|
+
if (getActiveElement() !== previouslyFocusedElement)
|
|
55
59
|
return true;
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -78,7 +82,8 @@ export function findVisible(elements, container) {
|
|
|
78
82
|
*/
|
|
79
83
|
export function getTabbableCandidates(container) {
|
|
80
84
|
const nodes = [];
|
|
81
|
-
const
|
|
85
|
+
const doc = getDocument(container);
|
|
86
|
+
const walker = doc.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
82
87
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
88
|
acceptNode: (node) => {
|
|
84
89
|
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
package/dist/internal/math.d.ts
CHANGED
|
@@ -1,5 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* From https://github.com/melt-ui/melt-ui/blob/main/packages/svelte/src/lib/internal/math.ts
|
|
3
|
-
*/
|
|
4
|
-
export declare function snapValueToStep(value: number, min: number, max: number, step: number): number;
|
|
5
1
|
export declare function linearScale(domain: [number, number], range: [number, number], clamp?: boolean): (x: number) => number;
|
package/dist/internal/math.js
CHANGED
|
@@ -1,31 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* From https://github.com/melt-ui/melt-ui/blob/main/packages/svelte/src/lib/internal/math.ts
|
|
3
|
-
*/
|
|
4
|
-
export function snapValueToStep(value, min, max, step) {
|
|
5
|
-
const remainder = (value - (Number.isNaN(min) ? 0 : min)) % step;
|
|
6
|
-
let snappedValue = Math.abs(remainder) * 2 >= step
|
|
7
|
-
? value + Math.sign(remainder) * (step - Math.abs(remainder))
|
|
8
|
-
: value - remainder;
|
|
9
|
-
if (!Number.isNaN(min)) {
|
|
10
|
-
if (snappedValue < min) {
|
|
11
|
-
snappedValue = min;
|
|
12
|
-
}
|
|
13
|
-
else if (!Number.isNaN(max) && snappedValue > max) {
|
|
14
|
-
snappedValue = min + Math.floor((max - min) / step) * step;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
else if (!Number.isNaN(max) && snappedValue > max) {
|
|
18
|
-
snappedValue = Math.floor(max / step) * step;
|
|
19
|
-
}
|
|
20
|
-
const string = step.toString();
|
|
21
|
-
const index = string.indexOf(".");
|
|
22
|
-
const precision = index >= 0 ? string.length - index : 0;
|
|
23
|
-
if (precision > 0) {
|
|
24
|
-
const pow = 10 ** precision;
|
|
25
|
-
snappedValue = Math.round(snappedValue * pow) / pow;
|
|
26
|
-
}
|
|
27
|
-
return snappedValue;
|
|
28
|
-
}
|
|
29
1
|
export function linearScale(domain, range, clamp = true) {
|
|
30
2
|
const [d0, d1] = domain;
|
|
31
3
|
const [r0, r1] = range;
|
|
@@ -6,5 +6,3 @@ export declare function getTabbableIn(container: HTMLElement, direction: "next"
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function getTabbableFrom(currentNode: HTMLElement, direction: "next" | "prev"): import("tabbable").FocusableElement | undefined;
|
|
8
8
|
export declare function getTabbableFromFocusable(currentNode: HTMLElement, direction: "next" | "prev"): import("tabbable").FocusableElement;
|
|
9
|
-
export declare function getNextTabbable(): import("tabbable").FocusableElement | undefined;
|
|
10
|
-
export declare function getPreviousTabbable(): import("tabbable").FocusableElement | undefined;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { focusable, isFocusable, isTabbable, tabbable } from "tabbable";
|
|
2
|
-
import { activeElement
|
|
2
|
+
import { activeElement } from "./dom.js";
|
|
3
|
+
import { getDocument } from "svelte-toolbelt";
|
|
3
4
|
function getTabbableOptions() {
|
|
4
5
|
return {
|
|
5
6
|
getShadowRoot: true,
|
|
@@ -32,35 +33,30 @@ export function getTabbableFrom(currentNode, direction) {
|
|
|
32
33
|
if (!isTabbable(currentNode, getTabbableOptions())) {
|
|
33
34
|
return getTabbableFromFocusable(currentNode, direction);
|
|
34
35
|
}
|
|
35
|
-
const
|
|
36
|
+
const doc = getDocument(currentNode);
|
|
37
|
+
const allTabbable = tabbable(doc.body, getTabbableOptions());
|
|
36
38
|
if (direction === "prev")
|
|
37
39
|
allTabbable.reverse();
|
|
38
40
|
const activeIndex = allTabbable.indexOf(currentNode);
|
|
39
41
|
if (activeIndex === -1)
|
|
40
|
-
return
|
|
42
|
+
return doc.body;
|
|
41
43
|
const nextTabbableElements = allTabbable.slice(activeIndex + 1);
|
|
42
44
|
return nextTabbableElements[0];
|
|
43
45
|
}
|
|
44
46
|
export function getTabbableFromFocusable(currentNode, direction) {
|
|
47
|
+
const doc = getDocument(currentNode);
|
|
45
48
|
if (!isFocusable(currentNode, getTabbableOptions()))
|
|
46
|
-
return
|
|
49
|
+
return doc.body;
|
|
47
50
|
// find all focusable nodes, since some elements may be focusable but not tabbable
|
|
48
51
|
// such as context menu triggers
|
|
49
|
-
const allFocusable = focusable(
|
|
52
|
+
const allFocusable = focusable(doc.body, getTabbableOptions());
|
|
50
53
|
// find index of current node among focusable siblings
|
|
51
54
|
if (direction === "prev")
|
|
52
55
|
allFocusable.reverse();
|
|
53
56
|
const activeIndex = allFocusable.indexOf(currentNode);
|
|
54
57
|
if (activeIndex === -1)
|
|
55
|
-
return
|
|
58
|
+
return doc.body;
|
|
56
59
|
const nextFocusableElements = allFocusable.slice(activeIndex + 1);
|
|
57
60
|
// find the next focusable node that is also tabbable
|
|
58
|
-
return
|
|
59
|
-
document.body);
|
|
60
|
-
}
|
|
61
|
-
export function getNextTabbable() {
|
|
62
|
-
return getTabbableIn(document.body, "next");
|
|
63
|
-
}
|
|
64
|
-
export function getPreviousTabbable() {
|
|
65
|
-
return getTabbableIn(document.body, "prev");
|
|
61
|
+
return nextFocusableElements.find((node) => isTabbable(node, getTabbableOptions())) ?? doc.body;
|
|
66
62
|
}
|
|
@@ -5,6 +5,7 @@ type UseDataTypeaheadOpts = {
|
|
|
5
5
|
getCurrentItem: () => string;
|
|
6
6
|
candidateValues: Getter<string[]>;
|
|
7
7
|
enabled: boolean;
|
|
8
|
+
getWindow: () => Window & typeof globalThis;
|
|
8
9
|
};
|
|
9
10
|
export declare function useDataTypeahead(opts: UseDataTypeaheadOpts): {
|
|
10
11
|
search: import("svelte-toolbelt").WritableBox<string>;
|
|
@@ -2,7 +2,10 @@ import { getNextMatch } from "./arrays.js";
|
|
|
2
2
|
import { boxAutoReset } from "./box-auto-reset.svelte.js";
|
|
3
3
|
export function useDataTypeahead(opts) {
|
|
4
4
|
// Reset `search` 1 second after it was last updated
|
|
5
|
-
const search = boxAutoReset("",
|
|
5
|
+
const search = boxAutoReset("", {
|
|
6
|
+
afterMs: 1000,
|
|
7
|
+
getWindow: opts.getWindow,
|
|
8
|
+
});
|
|
6
9
|
const candidateValues = $derived(opts.candidateValues());
|
|
7
10
|
function handleTypeaheadSearch(key) {
|
|
8
11
|
if (!opts.enabled)
|
|
@@ -2,8 +2,10 @@ export type DOMTypeahead = ReturnType<typeof useDOMTypeahead>;
|
|
|
2
2
|
type UseDOMTypeaheadOpts = {
|
|
3
3
|
onMatch?: (item: HTMLElement) => void;
|
|
4
4
|
getCurrentItem?: () => HTMLElement | null;
|
|
5
|
+
getActiveElement: () => HTMLElement | null;
|
|
6
|
+
getWindow: () => Window & typeof globalThis;
|
|
5
7
|
};
|
|
6
|
-
export declare function useDOMTypeahead(opts
|
|
8
|
+
export declare function useDOMTypeahead(opts: UseDOMTypeaheadOpts): {
|
|
7
9
|
search: import("svelte-toolbelt").WritableBox<string>;
|
|
8
10
|
handleTypeaheadSearch: (key: string, candidates: HTMLElement[]) => HTMLElement | undefined;
|
|
9
11
|
resetTypeahead: () => void;
|
|
@@ -2,9 +2,12 @@ import { getNextMatch } from "./arrays.js";
|
|
|
2
2
|
import { boxAutoReset } from "./box-auto-reset.svelte.js";
|
|
3
3
|
export function useDOMTypeahead(opts) {
|
|
4
4
|
// Reset `search` 1 second after it was last updated
|
|
5
|
-
const search = boxAutoReset("",
|
|
5
|
+
const search = boxAutoReset("", {
|
|
6
|
+
afterMs: 1000,
|
|
7
|
+
getWindow: opts.getWindow,
|
|
8
|
+
});
|
|
6
9
|
const onMatch = opts?.onMatch ?? ((node) => node.focus());
|
|
7
|
-
const getCurrentItem = opts?.getCurrentItem ?? (() =>
|
|
10
|
+
const getCurrentItem = opts?.getCurrentItem ?? (() => opts?.getActiveElement());
|
|
8
11
|
function handleTypeaheadSearch(key, candidates) {
|
|
9
12
|
if (!candidates.length)
|
|
10
13
|
return;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { executeCallbacks } from "svelte-toolbelt";
|
|
1
|
+
import { executeCallbacks, getWindow } from "svelte-toolbelt";
|
|
2
2
|
import { on } from "svelte/events";
|
|
3
3
|
import { watch } from "runed";
|
|
4
4
|
import { boxAutoReset } from "./box-auto-reset.svelte.js";
|
|
5
5
|
import { isElement, isHTMLElement } from "./is.js";
|
|
6
6
|
export function useGraceArea(opts) {
|
|
7
7
|
const enabled = $derived(opts.enabled());
|
|
8
|
-
const isPointerInTransit = boxAutoReset(false,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const isPointerInTransit = boxAutoReset(false, {
|
|
9
|
+
afterMs: opts.transitTimeout ?? 300,
|
|
10
|
+
onChange: (value) => {
|
|
11
|
+
if (enabled) {
|
|
12
|
+
opts.setIsPointerInTransit?.(value);
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
getWindow: () => getWindow(opts.triggerNode()),
|
|
12
16
|
});
|
|
13
17
|
let pointerGraceArea = $state(null);
|
|
14
18
|
function handleRemoveGraceArea() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bits-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "github:huntabyte/bits-ui",
|
|
6
6
|
"funding": "https://github.com/sponsors/huntabyte",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"css.escape": "^1.5.1",
|
|
47
47
|
"esm-env": "^1.1.2",
|
|
48
48
|
"runed": "^0.28.0",
|
|
49
|
-
"svelte-toolbelt": "^0.
|
|
49
|
+
"svelte-toolbelt": "^0.9.1",
|
|
50
50
|
"tabbable": "^6.2.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Box } from "svelte-toolbelt";
|
|
2
|
-
export declare class DOMContext {
|
|
3
|
-
readonly element: Box<HTMLElement | null>;
|
|
4
|
-
readonly root: Document | ShadowRoot | null;
|
|
5
|
-
constructor(element: Box<HTMLElement | null>);
|
|
6
|
-
querySelector: (selector: string) => Element | null;
|
|
7
|
-
querySelectorAll: (selector: string) => NodeListOf<Element>;
|
|
8
|
-
getElementById: (id: string) => HTMLElement | null;
|
|
9
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export class DOMContext {
|
|
2
|
-
element;
|
|
3
|
-
root = $derived.by(() => {
|
|
4
|
-
if (!this.element.current)
|
|
5
|
-
return null;
|
|
6
|
-
return this.element.current.getRootNode();
|
|
7
|
-
});
|
|
8
|
-
constructor(element) {
|
|
9
|
-
this.element = element;
|
|
10
|
-
}
|
|
11
|
-
querySelector = (selector) => {
|
|
12
|
-
if (!this.root)
|
|
13
|
-
return null;
|
|
14
|
-
return this.root.querySelector(selector);
|
|
15
|
-
};
|
|
16
|
-
querySelectorAll = (selector) => {
|
|
17
|
-
if (!this.root)
|
|
18
|
-
return [];
|
|
19
|
-
return this.root.querySelectorAll(selector);
|
|
20
|
-
};
|
|
21
|
-
getElementById = (id) => {
|
|
22
|
-
if (!this.root)
|
|
23
|
-
return null;
|
|
24
|
-
return this.root.getElementById(id);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/// <reference types="resize-observer-browser" />
|
|
2
|
-
import { untrack } from "svelte";
|
|
3
|
-
import { afterTick } from "svelte-toolbelt";
|
|
4
|
-
export function useSize(node) {
|
|
5
|
-
let size = $state(undefined);
|
|
6
|
-
$effect(() => {
|
|
7
|
-
const currNode = node.current;
|
|
8
|
-
if (!currNode) {
|
|
9
|
-
size = undefined;
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
afterTick(() => {
|
|
13
|
-
if (!currNode)
|
|
14
|
-
return;
|
|
15
|
-
size = {
|
|
16
|
-
width: currNode.offsetWidth,
|
|
17
|
-
height: currNode.offsetHeight,
|
|
18
|
-
};
|
|
19
|
-
});
|
|
20
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
21
|
-
if (!Array.isArray(entries) || !entries.length)
|
|
22
|
-
return;
|
|
23
|
-
const entry = entries[0];
|
|
24
|
-
if (!entry)
|
|
25
|
-
return;
|
|
26
|
-
let width;
|
|
27
|
-
let height;
|
|
28
|
-
if ("borderBoxSize" in entry) {
|
|
29
|
-
const borderSizeEntry = entry.borderBoxSize;
|
|
30
|
-
const borderSize = Array.isArray(borderSizeEntry)
|
|
31
|
-
? borderSizeEntry[0]
|
|
32
|
-
: borderSizeEntry;
|
|
33
|
-
width = borderSize.inlineSize;
|
|
34
|
-
height = borderSize.blockSize;
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
width = currNode.offsetWidth;
|
|
38
|
-
height = currNode.offsetHeight;
|
|
39
|
-
}
|
|
40
|
-
untrack(() => (size = { width, height }));
|
|
41
|
-
});
|
|
42
|
-
resizeObserver.observe(currNode, { box: "border-box" });
|
|
43
|
-
return () => {
|
|
44
|
-
if (!currNode)
|
|
45
|
-
return;
|
|
46
|
-
resizeObserver.unobserve(currNode);
|
|
47
|
-
};
|
|
48
|
-
});
|
|
49
|
-
return {
|
|
50
|
-
get value() {
|
|
51
|
-
return size;
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
}
|