-
-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
34 changed files
with
2,336 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
packages/bits-ui/src/lib/bits/navigation-menu/components/navigation-menu-content.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<script lang="ts"> | ||
import { useId } from "$lib/internal/useId.svelte.js"; | ||
import { box } from "svelte-toolbelt"; | ||
import type { ContentProps } from "../index.js"; | ||
import { useNavigationMenuContent } from "../navigation-menu.svelte.js"; | ||
import { mergeProps } from "$lib/internal/mergeProps.js"; | ||
import Portal from "$lib/bits/utilities/portal/portal.svelte"; | ||
import { PresenceLayer } from "$lib/bits/utilities/presence-layer/index.js"; | ||
import DismissableLayer from "$lib/bits/utilities/dismissable-layer/dismissable-layer.svelte"; | ||
import EscapeLayer from "$lib/bits/utilities/escape-layer/escape-layer.svelte"; | ||
import Mounted from "$lib/bits/utilities/mounted.svelte"; | ||
let { | ||
asChild, | ||
children: contentChildren, | ||
child, | ||
ref = $bindable(null), | ||
id = useId(), | ||
forceMount = false, | ||
...restProps | ||
}: ContentProps = $props(); | ||
let isMounted = $state(false); | ||
const contentState = useNavigationMenuContent({ | ||
id: box.with(() => id), | ||
ref: box.with( | ||
() => ref, | ||
(v) => { | ||
ref = v; | ||
} | ||
), | ||
forceMount: box.with(() => forceMount), | ||
isMounted: box.with(() => isMounted), | ||
}); | ||
const mergedProps = $derived(mergeProps(restProps, contentState.props)); | ||
const portalDisabled = $derived(!Boolean(contentState.menu.viewportNode)); | ||
</script> | ||
|
||
<Portal to={contentState.menu.viewportNode ?? undefined} disabled={portalDisabled}> | ||
<PresenceLayer {id} present={contentState.isPresent}> | ||
{#snippet presence({ present })} | ||
<EscapeLayer | ||
enabled={contentState.isPresent} | ||
onEscapeKeydown={(e) => contentState.onEscapeKeydown(e)} | ||
> | ||
<DismissableLayer | ||
enabled={contentState.isPresent} | ||
{id} | ||
onInteractOutside={contentState.onInteractOutside} | ||
onFocusOutside={contentState.onFocusOutside} | ||
> | ||
{#snippet children({ props: dismissableProps })} | ||
{#if asChild} | ||
<Mounted bind:isMounted /> | ||
{@render child?.({ props: mergeProps(dismissableProps, mergedProps) })} | ||
{:else} | ||
<Mounted bind:isMounted /> | ||
<div {...mergeProps(dismissableProps, mergedProps)}> | ||
{@render contentChildren?.()} | ||
</div> | ||
{/if} | ||
{/snippet} | ||
</DismissableLayer> | ||
</EscapeLayer> | ||
{/snippet} | ||
</PresenceLayer> | ||
</Portal> |
45 changes: 45 additions & 0 deletions
45
packages/bits-ui/src/lib/bits/navigation-menu/components/navigation-menu-indicator.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<script lang="ts"> | ||
import { mergeProps } from "$lib/internal/mergeProps.js"; | ||
import { useId } from "$lib/internal/useId.svelte.js"; | ||
import { box } from "svelte-toolbelt"; | ||
import type { IndicatorProps } from "../index.js"; | ||
import { useNavigationMenuIndicator } from "../navigation-menu.svelte.js"; | ||
import PresenceLayer from "$lib/bits/utilities/presence-layer/presence-layer.svelte"; | ||
import Portal from "$lib/bits/utilities/portal/portal.svelte"; | ||
let { | ||
id = useId(), | ||
ref = $bindable(null), | ||
asChild, | ||
children, | ||
child, | ||
forceMount = false, | ||
...restProps | ||
}: IndicatorProps = $props(); | ||
const indicatorState = useNavigationMenuIndicator({ | ||
id: box.with(() => id), | ||
ref: box.with( | ||
() => ref, | ||
(v) => (ref = v) | ||
), | ||
}); | ||
const mergedProps = $derived(mergeProps(restProps, indicatorState.props)); | ||
</script> | ||
|
||
{#if indicatorState.menu.indicatorTrackNode} | ||
<Portal to={indicatorState.menu.indicatorTrackNode}> | ||
<PresenceLayer {id} present={forceMount || indicatorState.isVisible}> | ||
{#snippet presence()} | ||
{#if asChild} | ||
{@render child?.({ props: mergedProps })} | ||
{:else} | ||
<div {...mergedProps}> | ||
{@render children?.()} | ||
</div> | ||
{/if} | ||
{/snippet} | ||
</PresenceLayer> | ||
</Portal> | ||
{/if} |
32 changes: 32 additions & 0 deletions
32
packages/bits-ui/src/lib/bits/navigation-menu/components/navigation-menu-item.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<script lang="ts"> | ||
import { box } from "svelte-toolbelt"; | ||
import type { ItemProps } from "../index.js"; | ||
import { useNavigationMenuItem } from "../navigation-menu.svelte.js"; | ||
import { useId } from "$lib/internal/useId.svelte.js"; | ||
import { mergeProps } from "$lib/internal/mergeProps.js"; | ||
let { | ||
id = useId(), | ||
value = useId(), | ||
asChild, | ||
child, | ||
children, | ||
ref = $bindable(), | ||
...restProps | ||
}: ItemProps = $props(); | ||
const itemState = useNavigationMenuItem({ | ||
id: box.with(() => id), | ||
value: box.with(() => value), | ||
}); | ||
const mergedProps = $derived(mergeProps(restProps, itemState.props)); | ||
</script> | ||
|
||
{#if asChild} | ||
{@render child?.({ props: mergedProps })} | ||
{:else} | ||
<li {...mergedProps} bind:this={ref}> | ||
{@render children?.()} | ||
</li> | ||
{/if} |
35 changes: 35 additions & 0 deletions
35
packages/bits-ui/src/lib/bits/navigation-menu/components/navigation-menu-link.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<script lang="ts"> | ||
import { noop } from "$lib/internal/callbacks.js"; | ||
import { useId } from "$lib/internal/useId.svelte.js"; | ||
import { box } from "svelte-toolbelt"; | ||
import type { LinkProps } from "../index.js"; | ||
import { useNavigationMenuLink } from "../navigation-menu.svelte.js"; | ||
import { mergeProps } from "$lib/internal/mergeProps.js"; | ||
let { | ||
id = useId(), | ||
ref = $bindable(), | ||
asChild, | ||
child, | ||
children, | ||
active = false, | ||
onSelect = noop, | ||
...restProps | ||
}: LinkProps = $props(); | ||
const linkState = useNavigationMenuLink({ | ||
id: box.with(() => id), | ||
active: box.with(() => active), | ||
onSelect: box.with(() => onSelect), | ||
}); | ||
const mergedProps = $derived(mergeProps(restProps, linkState.props)); | ||
</script> | ||
|
||
{#if asChild} | ||
{@render child?.({ props: mergedProps })} | ||
{:else} | ||
<a {...mergedProps} bind:this={ref}> | ||
{@render children?.()} | ||
</a> | ||
{/if} |
38 changes: 38 additions & 0 deletions
38
packages/bits-ui/src/lib/bits/navigation-menu/components/navigation-menu-list.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<script lang="ts"> | ||
import { box } from "svelte-toolbelt"; | ||
import type { ListProps } from "../index.js"; | ||
import { useNavigationMenuList } from "../navigation-menu.svelte.js"; | ||
import { useId } from "$lib/internal/useId.svelte.js"; | ||
import { mergeProps } from "$lib/internal/mergeProps.js"; | ||
let { | ||
id = useId(), | ||
asChild, | ||
children, | ||
child, | ||
ref = $bindable(null), | ||
...restProps | ||
}: ListProps = $props(); | ||
const listState = useNavigationMenuList({ | ||
id: box.with(() => id), | ||
ref: box.with( | ||
() => ref, | ||
(v) => (ref = v) | ||
), | ||
indicatorTrackRef: box(null), | ||
}); | ||
const mergedProps = $derived(mergeProps(restProps, listState.props)); | ||
const indicatorTrackProps = $derived(mergeProps(listState.indicatorTrackProps, {})); | ||
</script> | ||
|
||
<div {...indicatorTrackProps}> | ||
{#if asChild} | ||
{@render child?.({ props: mergedProps })} | ||
{:else} | ||
<ul {...mergedProps}> | ||
{@render children?.()} | ||
</ul> | ||
{/if} | ||
</div> |
48 changes: 48 additions & 0 deletions
48
packages/bits-ui/src/lib/bits/navigation-menu/components/navigation-menu-sub.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<!-- <script lang="ts"> | ||
import { useId } from "$lib/internal/useId.svelte.js"; | ||
import { box } from "svelte-toolbelt"; | ||
import type { SubProps } from "../index.js"; | ||
import { useNavigationMenuSub } from "../navigation-menu.svelte.js"; | ||
import { noop } from "$lib/internal/callbacks.js"; | ||
import { mergeProps } from "$lib/internal/mergeProps.js"; | ||
let { | ||
id = useId(), | ||
asChild, | ||
children, | ||
child, | ||
ref = $bindable(null), | ||
value = $bindable(""), | ||
orientation = "horizontal", | ||
onValueChange = noop, | ||
...restProps | ||
}: SubProps = $props(); | ||
const subState = useNavigationMenuSub({ | ||
id: box.with(() => id), | ||
orientation: box.with(() => orientation), | ||
ref: box.with( | ||
() => ref, | ||
(v) => (ref = v) | ||
), | ||
value: box.with( | ||
() => value, | ||
(v) => { | ||
if (v !== value) { | ||
value = v; | ||
onValueChange(v); | ||
} | ||
} | ||
), | ||
}); | ||
const mergedProps = $derived(mergeProps(restProps, subState.props)); | ||
</script> | ||
{#if asChild} | ||
{@render child?.({ props: mergedProps })} | ||
{:else} | ||
<div {...mergedProps}> | ||
{@render children?.()} | ||
</div> | ||
{/if} --> |
49 changes: 49 additions & 0 deletions
49
packages/bits-ui/src/lib/bits/navigation-menu/components/navigation-menu-trigger.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<script lang="ts"> | ||
import { box } from "svelte-toolbelt"; | ||
import type { TriggerProps } from "../index.js"; | ||
import { useNavigationMenuTrigger } from "../navigation-menu.svelte.js"; | ||
import { useId } from "$lib/internal/useId.svelte.js"; | ||
import { mergeProps } from "$lib/internal/mergeProps.js"; | ||
import VisuallyHidden from "$lib/bits/utilities/visually-hidden/visually-hidden.svelte"; | ||
import Mounted from "$lib/bits/utilities/mounted.svelte"; | ||
let { | ||
id = useId(), | ||
disabled = false, | ||
asChild, | ||
children, | ||
child, | ||
ref = $bindable(null), | ||
...restProps | ||
}: TriggerProps = $props(); | ||
let focusProxyMounted = $state(false); | ||
const triggerState = useNavigationMenuTrigger({ | ||
id: box.with(() => id), | ||
disabled: box.with(() => disabled), | ||
ref: box.with( | ||
() => ref, | ||
(v) => (ref = v) | ||
), | ||
focusProxyMounted: box.with(() => focusProxyMounted), | ||
}); | ||
const mergedProps = $derived(mergeProps(restProps, triggerState.props)); | ||
</script> | ||
|
||
{#if asChild} | ||
{@render child?.({ props: mergedProps })} | ||
{:else} | ||
<button {...mergedProps}> | ||
{@render children?.()} | ||
</button> | ||
{/if} | ||
|
||
{#if triggerState.open} | ||
<Mounted bind:isMounted={focusProxyMounted} /> | ||
<VisuallyHidden {...triggerState.visuallyHiddenProps} /> | ||
{#if triggerState.menu.viewportNode} | ||
<span aria-owns={triggerState.item.contentNode?.id ?? undefined}></span> | ||
{/if} | ||
{/if} |
Oops, something went wrong.