bits-ui 2.14.0 → 2.14.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/bits/accordion/accordion.svelte.d.ts +5 -1
- package/dist/bits/accordion/accordion.svelte.js +21 -2
- package/dist/bits/accordion/components/accordion-content.svelte +12 -24
- package/dist/bits/alert-dialog/components/alert-dialog-content.svelte +50 -62
- package/dist/bits/collapsible/collapsible.svelte.d.ts +4 -1
- package/dist/bits/collapsible/collapsible.svelte.js +15 -2
- package/dist/bits/collapsible/components/collapsible-content.svelte +12 -24
- package/dist/bits/context-menu/components/context-menu-content-static.svelte +2 -0
- package/dist/bits/context-menu/components/context-menu-content.svelte +2 -0
- package/dist/bits/date-field/date-field.svelte.js +5 -3
- package/dist/bits/dialog/components/dialog-content.svelte +44 -57
- package/dist/bits/dialog/components/dialog-overlay.svelte +9 -12
- package/dist/bits/dialog/dialog.svelte.d.ts +6 -0
- package/dist/bits/dialog/dialog.svelte.js +17 -3
- package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte +2 -0
- package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +2 -0
- package/dist/bits/link-preview/components/link-preview-content-static.svelte +2 -0
- 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 +6 -2
- package/dist/bits/menu/components/menu-content-static.svelte +2 -0
- package/dist/bits/menu/components/menu-content.svelte +2 -0
- package/dist/bits/menu/components/menu-sub-content-static.svelte +2 -0
- package/dist/bits/menu/components/menu-sub-content.svelte +2 -0
- package/dist/bits/menu/menu.svelte.d.ts +3 -0
- package/dist/bits/menu/menu.svelte.js +6 -2
- package/dist/bits/popover/components/popover-content-static.svelte +2 -0
- package/dist/bits/popover/components/popover-content.svelte +2 -0
- package/dist/bits/popover/components/popover-overlay.svelte +9 -12
- package/dist/bits/popover/popover.svelte.d.ts +6 -0
- package/dist/bits/popover/popover.svelte.js +16 -3
- package/dist/bits/select/components/select-content-static.svelte +2 -0
- package/dist/bits/select/components/select-content.svelte +2 -0
- package/dist/bits/select/select.svelte.d.ts +3 -0
- package/dist/bits/select/select.svelte.js +6 -2
- package/dist/bits/tooltip/components/tooltip-content-static.svelte +2 -0
- package/dist/bits/tooltip/components/tooltip-content.svelte +2 -0
- package/dist/bits/tooltip/tooltip.svelte.d.ts +3 -0
- package/dist/bits/tooltip/tooltip.svelte.js +6 -2
- package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte +1 -1
- package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte.d.ts +1 -1
- package/dist/bits/utilities/popper-layer/popper-layer.svelte +43 -45
- package/dist/bits/utilities/popper-layer/types.d.ts +4 -0
- package/dist/internal/animations-complete.js +7 -15
- package/dist/internal/date-time/field/helpers.js +3 -1
- package/dist/internal/date-time/field/time-helpers.js +4 -1
- package/dist/internal/presence-manager.svelte.d.ts +14 -0
- package/dist/internal/presence-manager.svelte.js +34 -0
- package/dist/internal/should-enable-focus-trap.d.ts +1 -2
- package/dist/internal/should-enable-focus-trap.js +2 -2
- package/package.json +2 -2
- package/dist/internal/open-change-complete.d.ts +0 -13
- package/dist/internal/open-change-complete.js +0 -24
|
@@ -5,7 +5,7 @@ import { isElement, isFocusVisible } from "../../internal/is.js";
|
|
|
5
5
|
import { createBitsAttrs, boolToEmptyStrOrUndef } from "../../internal/attrs.js";
|
|
6
6
|
import { TimeoutFn } from "../../internal/timeout-fn.js";
|
|
7
7
|
import { GraceArea } from "../../internal/grace-area.svelte.js";
|
|
8
|
-
import {
|
|
8
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
9
9
|
export const tooltipAttrs = createBitsAttrs({
|
|
10
10
|
component: "tooltip",
|
|
11
11
|
parts: ["content", "trigger"],
|
|
@@ -72,6 +72,7 @@ export class TooltipRootState {
|
|
|
72
72
|
ignoreNonKeyboardFocus = $derived.by(() => this.opts.ignoreNonKeyboardFocus.current ??
|
|
73
73
|
this.provider.opts.ignoreNonKeyboardFocus.current);
|
|
74
74
|
contentNode = $state(null);
|
|
75
|
+
contentPresence;
|
|
75
76
|
triggerNode = $state(null);
|
|
76
77
|
#wasOpenDelayed = $state(false);
|
|
77
78
|
#timerFn;
|
|
@@ -87,7 +88,7 @@ export class TooltipRootState {
|
|
|
87
88
|
this.#wasOpenDelayed = true;
|
|
88
89
|
this.opts.open.current = true;
|
|
89
90
|
}, this.delayDuration ?? 0);
|
|
90
|
-
new
|
|
91
|
+
this.contentPresence = new PresenceManager({
|
|
91
92
|
open: this.opts.open,
|
|
92
93
|
ref: boxWith(() => this.contentNode),
|
|
93
94
|
onComplete: () => {
|
|
@@ -294,6 +295,9 @@ export class TooltipContentState {
|
|
|
294
295
|
onCloseAutoFocus = (e) => {
|
|
295
296
|
e.preventDefault();
|
|
296
297
|
};
|
|
298
|
+
get shouldRender() {
|
|
299
|
+
return this.root.contentPresence.shouldRender;
|
|
300
|
+
}
|
|
297
301
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
298
302
|
props = $derived.by(() => ({
|
|
299
303
|
id: this.opts.id.current,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PopperLayerImplProps } from "./types.js";
|
|
2
|
-
type $$ComponentProps = Omit<PopperLayerImplProps, "open" | "children"> & {
|
|
2
|
+
type $$ComponentProps = Omit<PopperLayerImplProps, "open" | "children" | "shouldRender"> & {
|
|
3
3
|
enabled: boolean;
|
|
4
4
|
};
|
|
5
5
|
declare const PopperLayerInner: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { PopperLayerImplProps } from "./types.js";
|
|
3
3
|
import PopperLayerInner from "./popper-layer-inner.svelte";
|
|
4
|
-
import PresenceLayer from "../presence-layer/presence-layer.svelte";
|
|
5
4
|
|
|
6
5
|
let {
|
|
7
6
|
popper,
|
|
@@ -40,51 +39,50 @@
|
|
|
40
39
|
customAnchor = null,
|
|
41
40
|
isStatic = false,
|
|
42
41
|
ref,
|
|
42
|
+
shouldRender,
|
|
43
43
|
...restProps
|
|
44
44
|
}: PopperLayerImplProps = $props();
|
|
45
45
|
</script>
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{/snippet}
|
|
90
|
-
</PresenceLayer>
|
|
47
|
+
{#if shouldRender}
|
|
48
|
+
<PopperLayerInner
|
|
49
|
+
{popper}
|
|
50
|
+
{onEscapeKeydown}
|
|
51
|
+
{escapeKeydownBehavior}
|
|
52
|
+
{preventOverflowTextSelection}
|
|
53
|
+
{id}
|
|
54
|
+
{onPointerDown}
|
|
55
|
+
{onPointerUp}
|
|
56
|
+
{side}
|
|
57
|
+
{sideOffset}
|
|
58
|
+
{align}
|
|
59
|
+
{alignOffset}
|
|
60
|
+
{arrowPadding}
|
|
61
|
+
{avoidCollisions}
|
|
62
|
+
{collisionBoundary}
|
|
63
|
+
{collisionPadding}
|
|
64
|
+
{sticky}
|
|
65
|
+
{hideWhenDetached}
|
|
66
|
+
{updatePositionStrategy}
|
|
67
|
+
{strategy}
|
|
68
|
+
{dir}
|
|
69
|
+
{preventScroll}
|
|
70
|
+
{wrapperId}
|
|
71
|
+
{style}
|
|
72
|
+
{onPlaced}
|
|
73
|
+
{customAnchor}
|
|
74
|
+
{isStatic}
|
|
75
|
+
enabled={open}
|
|
76
|
+
{onInteractOutside}
|
|
77
|
+
{onCloseAutoFocus}
|
|
78
|
+
{onOpenAutoFocus}
|
|
79
|
+
{interactOutsideBehavior}
|
|
80
|
+
{loop}
|
|
81
|
+
{trapFocus}
|
|
82
|
+
{isValidEvent}
|
|
83
|
+
{onFocusOutside}
|
|
84
|
+
forceMount={false}
|
|
85
|
+
{ref}
|
|
86
|
+
{...restProps}
|
|
87
|
+
/>
|
|
88
|
+
{/if}
|
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
import { afterTick, onDestroyEffect } from "svelte-toolbelt";
|
|
2
2
|
export class AnimationsComplete {
|
|
3
3
|
#opts;
|
|
4
|
-
#currentFrame =
|
|
5
|
-
#isRunning = false;
|
|
4
|
+
#currentFrame = null;
|
|
6
5
|
constructor(opts) {
|
|
7
6
|
this.#opts = opts;
|
|
8
7
|
onDestroyEffect(() => this.#cleanup());
|
|
9
8
|
}
|
|
10
9
|
#cleanup() {
|
|
11
|
-
if (this.#currentFrame)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.#isRunning = false;
|
|
10
|
+
if (!this.#currentFrame)
|
|
11
|
+
return;
|
|
12
|
+
window.cancelAnimationFrame(this.#currentFrame);
|
|
13
|
+
this.#currentFrame = null;
|
|
16
14
|
}
|
|
17
15
|
run(fn) {
|
|
18
|
-
//
|
|
19
|
-
if (this.#isRunning)
|
|
20
|
-
return;
|
|
16
|
+
// if already running, cleanup and restart
|
|
21
17
|
this.#cleanup();
|
|
22
|
-
this.#isRunning = true;
|
|
23
18
|
const node = this.#opts.ref.current;
|
|
24
|
-
if (!node)
|
|
25
|
-
this.#isRunning = false;
|
|
19
|
+
if (!node)
|
|
26
20
|
return;
|
|
27
|
-
}
|
|
28
21
|
if (typeof node.getAnimations !== "function") {
|
|
29
22
|
this.#executeCallback(fn);
|
|
30
23
|
return;
|
|
@@ -43,7 +36,6 @@ export class AnimationsComplete {
|
|
|
43
36
|
#executeCallback(fn) {
|
|
44
37
|
const execute = () => {
|
|
45
38
|
fn();
|
|
46
|
-
this.#isRunning = false;
|
|
47
39
|
};
|
|
48
40
|
if (this.#opts.afterTick) {
|
|
49
41
|
afterTick(execute);
|
|
@@ -60,7 +60,9 @@ function createContentObj(props) {
|
|
|
60
60
|
* If we're operating in a 12 hour clock and the part is an hour, we handle
|
|
61
61
|
* the conversion to 12 hour format with 2 digit hours and leading zeros here.
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
const is12HourMode = props.hourCycle === 12 ||
|
|
64
|
+
(props.hourCycle === undefined && getDefaultHourCycle(locale) === 12);
|
|
65
|
+
if (part === "hour" && is12HourMode) {
|
|
64
66
|
/**
|
|
65
67
|
* If the value is over 12, we convert to 12 hour format and add leading
|
|
66
68
|
* zeroes if the value is less than 10.
|
|
@@ -6,6 +6,7 @@ import { styleToString } from "svelte-toolbelt";
|
|
|
6
6
|
import { useId } from "../../use-id.js";
|
|
7
7
|
import { getPlaceholder } from "../placeholders.js";
|
|
8
8
|
import { isZonedDateTime } from "../utils.js";
|
|
9
|
+
import { getDefaultHourCycle } from "./helpers.js";
|
|
9
10
|
export function initializeSegmentValues() {
|
|
10
11
|
const initialParts = EDITABLE_TIME_SEGMENT_PARTS.map((part) => {
|
|
11
12
|
if (part === "dayPeriod") {
|
|
@@ -50,7 +51,9 @@ function createTimeContentObj(props) {
|
|
|
50
51
|
* If we're operating in a 12 hour clock and the part is an hour, we handle
|
|
51
52
|
* the conversion to 12 hour format with 2 digit hours and leading zeros here.
|
|
52
53
|
*/
|
|
53
|
-
|
|
54
|
+
const is12HourMode = props.hourCycle === 12 ||
|
|
55
|
+
(props.hourCycle === undefined && getDefaultHourCycle(locale) === 12);
|
|
56
|
+
if (part === "hour" && is12HourMode) {
|
|
54
57
|
/**
|
|
55
58
|
* If the value is over 12, we convert to 12 hour format and add leading
|
|
56
59
|
* zeroes if the value is less than 10.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReadableBoxedValues } from "svelte-toolbelt";
|
|
2
|
+
interface PresenceManagerOpts extends ReadableBoxedValues<{
|
|
3
|
+
open: boolean;
|
|
4
|
+
ref: HTMLElement | null;
|
|
5
|
+
}> {
|
|
6
|
+
onComplete?: () => void;
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class PresenceManager {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(opts: PresenceManagerOpts);
|
|
12
|
+
get shouldRender(): boolean;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { watch } from "runed";
|
|
2
|
+
import { AnimationsComplete } from "./animations-complete.js";
|
|
3
|
+
export class PresenceManager {
|
|
4
|
+
#opts;
|
|
5
|
+
#enabled;
|
|
6
|
+
#afterAnimations;
|
|
7
|
+
#shouldRender = $state(false);
|
|
8
|
+
constructor(opts) {
|
|
9
|
+
this.#opts = opts;
|
|
10
|
+
this.#shouldRender = opts.open.current;
|
|
11
|
+
this.#enabled = opts.enabled ?? true;
|
|
12
|
+
this.#afterAnimations = new AnimationsComplete({
|
|
13
|
+
ref: this.#opts.ref,
|
|
14
|
+
afterTick: this.#opts.open,
|
|
15
|
+
});
|
|
16
|
+
watch(() => this.#opts.open.current, (isOpen) => {
|
|
17
|
+
if (isOpen)
|
|
18
|
+
this.#shouldRender = true;
|
|
19
|
+
if (!this.#enabled)
|
|
20
|
+
return;
|
|
21
|
+
this.#afterAnimations.run(() => {
|
|
22
|
+
if (isOpen === this.#opts.open.current) {
|
|
23
|
+
if (!this.#opts.open.current) {
|
|
24
|
+
this.#shouldRender = false;
|
|
25
|
+
}
|
|
26
|
+
this.#opts.onComplete?.();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
get shouldRender() {
|
|
32
|
+
return this.#shouldRender;
|
|
33
|
+
}
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bits-ui",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "github:huntabyte/bits-ui",
|
|
6
6
|
"funding": "https://github.com/sponsors/huntabyte",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"csstype": "^3.1.3",
|
|
29
29
|
"jsdom": "^24.1.3",
|
|
30
30
|
"publint": "^0.2.12",
|
|
31
|
-
"svelte": "
|
|
31
|
+
"svelte": "5.38.1",
|
|
32
32
|
"svelte-check": "^4.3.1",
|
|
33
33
|
"typescript": "^5.9.2",
|
|
34
34
|
"vite": "^7.1.5",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ReadableBoxedValues } from "svelte-toolbelt";
|
|
2
|
-
interface OpenChangeCompleteOpts extends ReadableBoxedValues<{
|
|
3
|
-
open: boolean;
|
|
4
|
-
ref: HTMLElement | null;
|
|
5
|
-
}> {
|
|
6
|
-
onComplete: () => void;
|
|
7
|
-
enabled?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export declare class OpenChangeComplete {
|
|
10
|
-
#private;
|
|
11
|
-
constructor(opts: OpenChangeCompleteOpts);
|
|
12
|
-
}
|
|
13
|
-
export {};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { watch } from "runed";
|
|
2
|
-
import { AnimationsComplete } from "./animations-complete.js";
|
|
3
|
-
export class OpenChangeComplete {
|
|
4
|
-
#opts;
|
|
5
|
-
#enabled;
|
|
6
|
-
#afterAnimations;
|
|
7
|
-
constructor(opts) {
|
|
8
|
-
this.#opts = opts;
|
|
9
|
-
this.#enabled = opts.enabled ?? true;
|
|
10
|
-
this.#afterAnimations = new AnimationsComplete({
|
|
11
|
-
ref: this.#opts.ref,
|
|
12
|
-
afterTick: this.#opts.open,
|
|
13
|
-
});
|
|
14
|
-
watch([() => this.#opts.open.current], ([open]) => {
|
|
15
|
-
if (!this.#enabled)
|
|
16
|
-
return;
|
|
17
|
-
this.#afterAnimations.run(() => {
|
|
18
|
-
if (open === this.#opts.open.current) {
|
|
19
|
-
this.#opts.onComplete();
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|