bits-ui 1.0.0-next.90 → 1.0.0-next.92

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.
Files changed (50) hide show
  1. package/dist/bits/alert-dialog/components/alert-dialog-content.svelte +8 -5
  2. package/dist/bits/command/command.svelte.d.ts +0 -1
  3. package/dist/bits/command/command.svelte.js +50 -61
  4. package/dist/bits/command/components/command.svelte +3 -2
  5. package/dist/bits/command/compute-command-score.d.ts +26 -0
  6. package/dist/bits/command/{command-score.js → compute-command-score.js} +47 -15
  7. package/dist/bits/command/index.d.ts +1 -0
  8. package/dist/bits/command/index.js +1 -0
  9. package/dist/bits/command/types.d.ts +2 -1
  10. package/dist/bits/dialog/components/dialog-content.svelte +8 -5
  11. package/dist/bits/index.d.ts +1 -1
  12. package/dist/bits/index.js +1 -1
  13. package/dist/bits/menubar/components/menubar-content-static.svelte +9 -0
  14. package/dist/bits/menubar/components/menubar-content.svelte +9 -0
  15. package/dist/bits/menubar/menubar.svelte.d.ts +7 -3
  16. package/dist/bits/menubar/menubar.svelte.js +10 -2
  17. package/dist/bits/navigation-menu/components/navigation-menu-content-impl.svelte +90 -0
  18. package/dist/bits/navigation-menu/components/navigation-menu-content-impl.svelte.d.ts +13 -0
  19. package/dist/bits/navigation-menu/components/navigation-menu-content.svelte +18 -57
  20. package/dist/bits/navigation-menu/components/navigation-menu-content.svelte.d.ts +1 -1
  21. package/dist/bits/navigation-menu/components/navigation-menu-indicator-impl.svelte +32 -0
  22. package/dist/bits/navigation-menu/components/navigation-menu-indicator-impl.svelte.d.ts +4 -0
  23. package/dist/bits/navigation-menu/components/navigation-menu-indicator.svelte +7 -19
  24. package/dist/bits/navigation-menu/components/navigation-menu-list.svelte +10 -8
  25. package/dist/bits/navigation-menu/components/navigation-menu-sub.svelte +44 -0
  26. package/dist/bits/navigation-menu/components/navigation-menu-sub.svelte.d.ts +4 -0
  27. package/dist/bits/navigation-menu/components/navigation-menu-trigger.svelte +3 -3
  28. package/dist/bits/navigation-menu/components/navigation-menu-viewport.svelte +3 -3
  29. package/dist/bits/navigation-menu/exports.d.ts +2 -1
  30. package/dist/bits/navigation-menu/exports.js +1 -0
  31. package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +209 -201
  32. package/dist/bits/navigation-menu/navigation-menu.svelte.js +572 -621
  33. package/dist/bits/navigation-menu/types.d.ts +18 -2
  34. package/dist/bits/select/select.svelte.d.ts +2 -2
  35. package/dist/bits/select/select.svelte.js +27 -8
  36. package/dist/bits/utilities/dismissible-layer/use-dismissable-layer.svelte.js +1 -1
  37. package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.js +2 -2
  38. package/dist/bits/utilities/popper-layer/popper-layer.svelte +2 -2
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/internal/events.d.ts +1 -1
  42. package/dist/internal/events.js +2 -2
  43. package/dist/internal/previous-with-init.svelte.d.ts +11 -0
  44. package/dist/internal/previous-with-init.svelte.js +21 -0
  45. package/dist/internal/tabbable.d.ts +1 -0
  46. package/dist/internal/tabbable.js +1 -1
  47. package/dist/internal/use-arrow-navigation.d.ts +0 -1
  48. package/dist/internal/use-arrow-navigation.js +2 -2
  49. package/package.json +1 -1
  50. package/dist/bits/command/command-score.d.ts +0 -1
@@ -0,0 +1,90 @@
1
+ <script lang="ts">
2
+ import { box, mergeProps } from "svelte-toolbelt";
3
+ import { untrack, type Snippet } from "svelte";
4
+ import type { NavigationMenuContentProps } from "../types.js";
5
+ import {
6
+ NavigationMenuItemContext,
7
+ NavigationMenuItemState,
8
+ useNavigationMenuContentImpl,
9
+ } from "../navigation-menu.svelte.js";
10
+ import { noop } from "../../../internal/noop.js";
11
+ import { useId } from "../../../internal/use-id.js";
12
+ import DismissibleLayer from "../../utilities/dismissible-layer/dismissible-layer.svelte";
13
+ import EscapeLayer from "../../utilities/escape-layer/escape-layer.svelte";
14
+
15
+ let {
16
+ ref = $bindable(null),
17
+ id = useId(),
18
+ child: childProp,
19
+ children: childrenProp,
20
+ onInteractOutside = noop,
21
+ onFocusOutside = noop,
22
+ onEscapeKeydown = noop,
23
+ escapeKeydownBehavior = "close",
24
+ interactOutsideBehavior = "close",
25
+ itemState,
26
+ onRefChange,
27
+ ...restProps
28
+ }: Omit<NavigationMenuContentProps, "child"> & {
29
+ itemState?: NavigationMenuItemState;
30
+ onRefChange?: (ref: HTMLElement | null) => void;
31
+ child?: Snippet<[{ props: Record<string, unknown> }]>;
32
+ } = $props();
33
+
34
+ const contentImplState = useNavigationMenuContentImpl(
35
+ {
36
+ id: box.with(() => id),
37
+ ref: box.with(
38
+ () => ref,
39
+ (v) => {
40
+ ref = v;
41
+ untrack(() => onRefChange?.(v));
42
+ }
43
+ ),
44
+ },
45
+ itemState
46
+ );
47
+
48
+ if (itemState) {
49
+ NavigationMenuItemContext.set(itemState);
50
+ }
51
+
52
+ const mergedProps = $derived(mergeProps(restProps, contentImplState.props));
53
+ </script>
54
+
55
+ <DismissibleLayer
56
+ {id}
57
+ enabled={true}
58
+ onInteractOutside={(e) => {
59
+ onInteractOutside(e);
60
+ if (e.defaultPrevented) return;
61
+ contentImplState.onInteractOutside(e);
62
+ }}
63
+ onFocusOutside={(e) => {
64
+ onFocusOutside(e);
65
+ if (e.defaultPrevented) return;
66
+ contentImplState.onFocusOutside(e);
67
+ }}
68
+ {interactOutsideBehavior}
69
+ >
70
+ {#snippet children({ props: dismissibleProps })}
71
+ <EscapeLayer
72
+ enabled={true}
73
+ onEscapeKeydown={(e) => {
74
+ onEscapeKeydown(e);
75
+ if (e.defaultPrevented) return;
76
+ contentImplState.onEscapeKeydown(e);
77
+ }}
78
+ {escapeKeydownBehavior}
79
+ >
80
+ {@const finalProps = mergeProps(mergedProps, dismissibleProps)}
81
+ {#if childProp}
82
+ {@render childProp({ props: finalProps })}
83
+ {:else}
84
+ <div {...finalProps}>
85
+ {@render childrenProp?.()}
86
+ </div>
87
+ {/if}
88
+ </EscapeLayer>
89
+ {/snippet}
90
+ </DismissibleLayer>
@@ -0,0 +1,13 @@
1
+ import { type Snippet } from "svelte";
2
+ import type { NavigationMenuContentProps } from "../types.js";
3
+ import { NavigationMenuItemState } from "../navigation-menu.svelte.js";
4
+ type $$ComponentProps = Omit<NavigationMenuContentProps, "child"> & {
5
+ itemState?: NavigationMenuItemState;
6
+ onRefChange?: (ref: HTMLElement | null) => void;
7
+ child?: Snippet<[{
8
+ props: Record<string, unknown>;
9
+ }]>;
10
+ };
11
+ declare const NavigationMenuContentImpl: import("svelte").Component<$$ComponentProps, {}, "ref">;
12
+ type NavigationMenuContentImpl = ReturnType<typeof NavigationMenuContentImpl>;
13
+ export default NavigationMenuContentImpl;
@@ -1,82 +1,43 @@
1
1
  <script lang="ts">
2
2
  import { box, mergeProps } from "svelte-toolbelt";
3
- import type { NavigationMenuContentProps } from "../types.js";
4
3
  import { useNavigationMenuContent } from "../navigation-menu.svelte.js";
4
+ import NavigationMenuContentImpl from "./navigation-menu-content-impl.svelte";
5
5
  import { useId } from "../../../internal/use-id.js";
6
+ import type { NavigationMenuContentProps } from "../../../types.js";
6
7
  import Portal from "../../utilities/portal/portal.svelte";
7
8
  import PresenceLayer from "../../utilities/presence-layer/presence-layer.svelte";
8
- import DismissibleLayer from "../../utilities/dismissible-layer/dismissible-layer.svelte";
9
- import EscapeLayer from "../../utilities/escape-layer/escape-layer.svelte";
10
9
  import Mounted from "../../utilities/mounted.svelte";
11
10
 
12
11
  let {
13
- children: contentChildren,
14
- child,
15
12
  ref = $bindable(null),
16
13
  id = useId(),
14
+ children,
15
+ child,
17
16
  forceMount = false,
18
- onEscapeKeydown,
19
- onInteractOutside,
20
- onFocusOutside,
21
17
  ...restProps
22
18
  }: NavigationMenuContentProps = $props();
23
19
 
24
- let isMounted = $state(false);
25
-
26
20
  const contentState = useNavigationMenuContent({
27
21
  id: box.with(() => id),
28
22
  ref: box.with(
29
23
  () => ref,
30
- (v) => {
31
- ref = v;
32
- }
24
+ (v) => (ref = v)
33
25
  ),
34
- forceMount: box.with(() => forceMount),
35
- isMounted: box.with(() => isMounted),
36
26
  });
37
27
 
38
28
  const mergedProps = $derived(mergeProps(restProps, contentState.props));
39
- const portalDisabled = $derived(!contentState.menu.viewportNode);
40
29
  </script>
41
30
 
42
- <Portal to={contentState.menu.viewportNode ?? undefined} disabled={portalDisabled}>
43
- <PresenceLayer {id} present={contentState.isPresent}>
44
- {#snippet presence()}
45
- <EscapeLayer
46
- enabled={contentState.isPresent}
47
- onEscapeKeydown={(e) => {
48
- onEscapeKeydown?.(e);
49
- if (e.defaultPrevented) return;
50
- contentState.onEscapeKeydown(e);
51
- }}
52
- >
53
- <DismissibleLayer
54
- enabled={contentState.isPresent}
55
- {id}
56
- onInteractOutside={(e) => {
57
- onInteractOutside?.(e);
58
- if (e.defaultPrevented) return;
59
- contentState.onInteractOutside(e);
60
- }}
61
- onFocusOutside={(e) => {
62
- onFocusOutside?.(e);
63
- if (e.defaultPrevented) return;
64
- contentState.onFocusOutside(e);
65
- }}
66
- >
67
- {#snippet children({ props: dismissibleProps })}
68
- {#if child}
69
- <Mounted bind:mounted={isMounted} />
70
- {@render child({ props: mergeProps(dismissibleProps, mergedProps) })}
71
- {:else}
72
- <Mounted bind:mounted={isMounted} />
73
- <div {...mergeProps(dismissibleProps, mergedProps)}>
74
- {@render contentChildren?.()}
75
- </div>
76
- {/if}
77
- {/snippet}
78
- </DismissibleLayer>
79
- </EscapeLayer>
80
- {/snippet}
81
- </PresenceLayer>
82
- </Portal>
31
+ {#if contentState.context.viewportRef.current}
32
+ <Portal to={contentState.context.viewportRef.current}>
33
+ <PresenceLayer
34
+ {id}
35
+ present={forceMount || contentState.open || contentState.isLastActiveValue}
36
+ >
37
+ {#snippet presence()}
38
+ <NavigationMenuContentImpl {...mergedProps} {children} {child} />
39
+ <Mounted bind:mounted={contentState.mounted} />
40
+ {/snippet}
41
+ </PresenceLayer>
42
+ </Portal>
43
+ {/if}
@@ -1,4 +1,4 @@
1
- import type { NavigationMenuContentProps } from "../types.js";
1
+ import type { NavigationMenuContentProps } from "../../../types.js";
2
2
  declare const NavigationMenuContent: import("svelte").Component<NavigationMenuContentProps, {}, "ref">;
3
3
  type NavigationMenuContent = ReturnType<typeof NavigationMenuContent>;
4
4
  export default NavigationMenuContent;
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import { box, mergeProps } from "svelte-toolbelt";
3
+ import type { NavigationMenuIndicatorProps } from "../types.js";
4
+ import { useNavigationMenuIndicatorImpl } from "../navigation-menu.svelte.js";
5
+ import { useId } from "../../../internal/use-id.js";
6
+
7
+ let {
8
+ id = useId(),
9
+ ref = $bindable(null),
10
+ children,
11
+ child,
12
+ ...restProps
13
+ }: NavigationMenuIndicatorProps = $props();
14
+
15
+ const indicatorState = useNavigationMenuIndicatorImpl({
16
+ id: box.with(() => id),
17
+ ref: box.with(
18
+ () => ref,
19
+ (v) => (ref = v)
20
+ ),
21
+ });
22
+
23
+ const mergedProps = $derived(mergeProps(restProps, indicatorState.props));
24
+ </script>
25
+
26
+ {#if child}
27
+ {@render child({ props: mergedProps })}
28
+ {:else}
29
+ <div {...mergedProps}>
30
+ {@render children?.()}
31
+ </div>
32
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { NavigationMenuIndicatorProps } from "../types.js";
2
+ declare const NavigationMenuIndicatorImpl: import("svelte").Component<NavigationMenuIndicatorProps, {}, "ref">;
3
+ type NavigationMenuIndicatorImpl = ReturnType<typeof NavigationMenuIndicatorImpl>;
4
+ export default NavigationMenuIndicatorImpl;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
- import { box, mergeProps } from "svelte-toolbelt";
2
+ import { mergeProps } from "svelte-toolbelt";
3
3
  import type { NavigationMenuIndicatorProps } from "../types.js";
4
4
  import { useNavigationMenuIndicator } from "../navigation-menu.svelte.js";
5
+ import NavigationMenuIndicatorImpl from "./navigation-menu-indicator-impl.svelte";
5
6
  import { useId } from "../../../internal/use-id.js";
6
7
  import PresenceLayer from "../../utilities/presence-layer/presence-layer.svelte";
7
8
  import Portal from "../../utilities/portal/portal.svelte";
@@ -15,28 +16,15 @@
15
16
  ...restProps
16
17
  }: NavigationMenuIndicatorProps = $props();
17
18
 
18
- const indicatorState = useNavigationMenuIndicator({
19
- id: box.with(() => id),
20
- ref: box.with(
21
- () => ref,
22
- (v) => (ref = v)
23
- ),
24
- });
25
-
26
- const mergedProps = $derived(mergeProps(restProps, indicatorState.props));
19
+ const indicatorState = useNavigationMenuIndicator();
20
+ const mergedProps = $derived(mergeProps(restProps));
27
21
  </script>
28
22
 
29
- {#if indicatorState.menu.indicatorTrackNode}
30
- <Portal to={indicatorState.menu.indicatorTrackNode}>
23
+ {#if indicatorState.context.indicatorTrackRef.current}
24
+ <Portal to={indicatorState.context.indicatorTrackRef.current}>
31
25
  <PresenceLayer {id} present={forceMount || indicatorState.isVisible}>
32
26
  {#snippet presence()}
33
- {#if child}
34
- {@render child({ props: mergedProps })}
35
- {:else}
36
- <div {...mergedProps}>
37
- {@render children?.()}
38
- </div>
39
- {/if}
27
+ <NavigationMenuIndicatorImpl {...mergedProps} {children} {child} {id} bind:ref />
40
28
  {/snippet}
41
29
  </PresenceLayer>
42
30
  </Portal>
@@ -3,6 +3,7 @@
3
3
  import type { NavigationMenuListProps } from "../types.js";
4
4
  import { useNavigationMenuList } from "../navigation-menu.svelte.js";
5
5
  import { useId } from "../../../internal/use-id.js";
6
+ import Mounted from "../../utilities/mounted.svelte";
6
7
 
7
8
  let {
8
9
  id = useId(),
@@ -18,19 +19,20 @@
18
19
  () => ref,
19
20
  (v) => (ref = v)
20
21
  ),
21
- indicatorTrackRef: box(null),
22
22
  });
23
23
 
24
24
  const mergedProps = $derived(mergeProps(restProps, listState.props));
25
- const indicatorTrackProps = $derived(mergeProps(listState.indicatorTrackProps, {}));
25
+ const wrapperProps = $derived(mergeProps(listState.wrapperProps));
26
26
  </script>
27
27
 
28
- <div {...indicatorTrackProps}>
29
- {#if child}
30
- {@render child({ props: mergedProps })}
31
- {:else}
28
+ {#if child}
29
+ {@render child({ props: mergedProps, wrapperProps })}
30
+ <Mounted bind:mounted={listState.wrapperMounted} />
31
+ {:else}
32
+ <div {...wrapperProps}>
32
33
  <ul {...mergedProps}>
33
34
  {@render children?.()}
34
35
  </ul>
35
- {/if}
36
- </div>
36
+ </div>
37
+ <Mounted bind:mounted={listState.wrapperMounted} />
38
+ {/if}
@@ -0,0 +1,44 @@
1
+ <script lang="ts">
2
+ import { box, mergeProps } from "svelte-toolbelt";
3
+ import type { NavigationMenuSubProps } from "../types.js";
4
+ import { useNavigationMenuSub } from "../navigation-menu.svelte.js";
5
+ import { useId } from "../../../internal/use-id.js";
6
+ import { noop } from "../../../internal/noop.js";
7
+
8
+ let {
9
+ child,
10
+ children,
11
+ id = useId(),
12
+ ref = $bindable(null),
13
+ value = $bindable(""),
14
+ onValueChange = noop,
15
+ orientation = "horizontal",
16
+ ...restProps
17
+ }: NavigationMenuSubProps = $props();
18
+
19
+ const rootState = useNavigationMenuSub({
20
+ id: box.with(() => id),
21
+ value: box.with(
22
+ () => value,
23
+ (v) => {
24
+ value = v;
25
+ onValueChange(v);
26
+ }
27
+ ),
28
+ orientation: box.with(() => orientation),
29
+ ref: box.with(
30
+ () => ref,
31
+ (v) => (ref = v)
32
+ ),
33
+ });
34
+
35
+ const mergedProps = $derived(mergeProps(restProps, rootState.props));
36
+ </script>
37
+
38
+ {#if child}
39
+ {@render child({ props: mergedProps })}
40
+ {:else}
41
+ <div {...mergedProps}>
42
+ {@render children?.()}
43
+ </div>
44
+ {/if}
@@ -0,0 +1,4 @@
1
+ import type { NavigationMenuSubProps } from "../types.js";
2
+ declare const NavigationMenuSub: import("svelte").Component<NavigationMenuSubProps, {}, "value" | "ref">;
3
+ type NavigationMenuSub = ReturnType<typeof NavigationMenuSub>;
4
+ export default NavigationMenuSub;
@@ -36,9 +36,9 @@
36
36
  {/if}
37
37
 
38
38
  {#if triggerState.open}
39
+ <VisuallyHidden {...triggerState.focusProxyProps} />
39
40
  <Mounted bind:mounted={triggerState.focusProxyMounted} />
40
- <VisuallyHidden {...triggerState.visuallyHiddenProps} />
41
- {#if triggerState.menu.viewportNode}
42
- <span aria-owns={triggerState.item.contentNode?.id ?? undefined}></span>
41
+ {#if triggerState.context.viewportRef.current}
42
+ <span aria-owns={triggerState.itemContext.contentId ?? undefined}></span>
43
43
  {/if}
44
44
  {/if}
@@ -1,16 +1,16 @@
1
1
  <script lang="ts">
2
- import { box, mergeProps } from "svelte-toolbelt";
3
2
  import type { NavigationMenuViewportProps } from "../types.js";
4
3
  import { useNavigationMenuViewport } from "../navigation-menu.svelte.js";
5
4
  import { useId } from "../../../internal/use-id.js";
6
5
  import PresenceLayer from "../../utilities/presence-layer/presence-layer.svelte";
6
+ import { box, mergeProps } from "svelte-toolbelt";
7
7
 
8
8
  let {
9
9
  id = useId(),
10
10
  ref = $bindable(null),
11
- children,
12
- child,
13
11
  forceMount = false,
12
+ child,
13
+ children,
14
14
  ...restProps
15
15
  }: NavigationMenuViewportProps = $props();
16
16
 
@@ -6,4 +6,5 @@ export { default as Link } from "./components/navigation-menu-link.svelte";
6
6
  export { default as List } from "./components/navigation-menu-list.svelte";
7
7
  export { default as Trigger } from "./components/navigation-menu-trigger.svelte";
8
8
  export { default as Viewport } from "./components/navigation-menu-viewport.svelte";
9
- export type { NavigationMenuRootProps as RootProps, NavigationMenuItemProps as ItemProps, NavigationMenuListProps as ListProps, NavigationMenuTriggerProps as TriggerProps, NavigationMenuViewportProps as ViewportProps, NavigationMenuIndicatorProps as IndicatorProps, NavigationMenuContentProps as ContentProps, NavigationMenuLinkProps as LinkProps, } from "./types.js";
9
+ export { default as Sub } from "./components/navigation-menu-sub.svelte";
10
+ export type { NavigationMenuRootProps as RootProps, NavigationMenuItemProps as ItemProps, NavigationMenuListProps as ListProps, NavigationMenuTriggerProps as TriggerProps, NavigationMenuViewportProps as ViewportProps, NavigationMenuIndicatorProps as IndicatorProps, NavigationMenuContentProps as ContentProps, NavigationMenuLinkProps as LinkProps, NavigationMenuSubProps as SubProps, } from "./types.js";
@@ -6,3 +6,4 @@ export { default as Link } from "./components/navigation-menu-link.svelte";
6
6
  export { default as List } from "./components/navigation-menu-list.svelte";
7
7
  export { default as Trigger } from "./components/navigation-menu-trigger.svelte";
8
8
  export { default as Viewport } from "./components/navigation-menu-viewport.svelte";
9
+ export { default as Sub } from "./components/navigation-menu-sub.svelte";