Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next: menu #522

Merged
merged 46 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
9afc663
init tooltip
huntabyte Apr 26, 2024
7fd25ff
grace area
huntabyte Apr 28, 2024
60d0c6f
tooltip root
huntabyte Apr 28, 2024
0524056
more
huntabyte Apr 28, 2024
dc54680
annoyed
huntabyte Apr 28, 2024
74b2d5c
fix: tooltip & grace area (#521)
anatolzak Apr 28, 2024
1d3e183
more
huntabyte Apr 28, 2024
c9d302d
cleanup
huntabyte Apr 28, 2024
74c14a1
maybe
huntabyte Apr 28, 2024
9d7ca4e
menu stuff
huntabyte Apr 29, 2024
13ec4ee
more menu stuff
huntabyte Apr 29, 2024
d2ee896
more
huntabyte Apr 29, 2024
8e3a476
more menu work
huntabyte Apr 29, 2024
bd401ab
more
huntabyte Apr 29, 2024
e04c95b
urg
huntabyte Apr 29, 2024
02c6e3b
somewhere
huntabyte Apr 29, 2024
830e5a3
cleanup
huntabyte Apr 29, 2024
a1d2cf2
finally
huntabyte May 2, 2024
acb31dd
that was painful
huntabyte May 2, 2024
55b893a
more
huntabyte May 2, 2024
1edad19
sub stuff
huntabyte May 2, 2024
b84131a
cleanup
huntabyte May 3, 2024
d9ade42
solid progress, lots to cleanup still
huntabyte May 3, 2024
e320e82
meh
huntabyte May 3, 2024
dc35f5a
improvements
huntabyte May 3, 2024
6d42238
more better
huntabyte May 3, 2024
dde080b
improvements
huntabyte May 3, 2024
ebbf711
autofocus first item when using keyboard
huntabyte May 5, 2024
a197395
more progress
huntabyte May 5, 2024
1fd551f
menu arrow
huntabyte May 5, 2024
79533af
handle select
huntabyte May 5, 2024
6db7209
more menu stuff
huntabyte May 10, 2024
ad9c70f
cleanup pointerdown events
huntabyte May 10, 2024
96854d8
remove logs
huntabyte May 10, 2024
52ebf5a
menu checkbox item
huntabyte May 10, 2024
679b154
menu radio group progress
huntabyte May 11, 2024
b3e5683
menu radio group check
huntabyte May 11, 2024
b1f6cf6
closer closer closer
huntabyte May 11, 2024
4ea3399
some context menu progress
huntabyte May 11, 2024
af44145
context trigger
huntabyte May 14, 2024
4af624e
context trigger
huntabyte May 14, 2024
3f598d5
menu work
huntabyte May 29, 2024
c1db03e
more
huntabyte May 29, 2024
9ab468c
passing all previous dropdown menu tests
huntabyte May 30, 2024
334218a
dialog passing all tests
huntabyte May 30, 2024
4731665
Merge branch 'next' into next-menu
huntabyte May 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"tabWidth": 4,
"singleQuote": false,
"trailingComma": "es5",
"semi": true,
"printWidth": 100,
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
"overrides": [
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.2",
"prettier-plugin-tailwindcss": "0.5.13",
"svelte": "5.0.0-next.115",
"svelte": "5.0.0-next.139",
"svelte-eslint-parser": "^0.34.1",
"wrangler": "^3.44.0"
},
Expand Down
7 changes: 4 additions & 3 deletions packages/bits-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"jsdom": "^24.0.0",
"publint": "^0.2.7",
"resize-observer-polyfill": "^1.5.1",
"svelte": "5.0.0-next.115",
"svelte": "5.0.0-next.139",
"svelte-check": "^3.6.9",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
Expand All @@ -63,10 +63,11 @@
"clsx": "^2.1.0",
"esm-env": "^1.0.0",
"nanoid": "^5.0.5",
"runed": "^0.4.1",
"runed": "^0.5.0",
"scule": "^1.3.0",
"style-object-to-css-string": "^1.1.3",
"style-to-object": "^1.0.6"
"style-to-object": "^1.0.6",
"svelte-toolbelt": "^0.0.2"
},
"peerDependencies": {
"svelte": "^5.0.0"
Expand Down
4 changes: 2 additions & 2 deletions packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { WritableBox } from "runed";
import type { WritableBox } from "svelte-toolbelt";
import {
type Box,
type ReadableBoxedValues,
Expand Down Expand Up @@ -40,7 +40,7 @@ class AccordionBaseState {
disabled = undefined as unknown as AccordionBaseStateProps["disabled"];
#loop = undefined as unknown as AccordionBaseStateProps["loop"];
orientation = undefined as unknown as AccordionBaseStateProps["orientation"];
rovingFocusGroup = undefined as unknown as UseRovingFocusReturn;
rovingFocusGroup: UseRovingFocusReturn;

constructor(props: AccordionBaseStateProps) {
this.id = props.id;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import { useAccordionContent } from "../accordion.svelte.js";
import type { AccordionContentProps } from "../types.js";
import { PresenceLayer } from "$lib/bits/utilities/presence-layer/index.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import type { AccordionHeaderProps } from "../types.js";
import { useAccordionHeader } from "../accordion.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import type { AccordionItemProps } from "../types.js";
import { useAccordionItem } from "../accordion.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import type { AccordionTriggerProps } from "../types.js";
import { useAccordionTrigger } from "../accordion.svelte.js";
import { mergeProps, useId } from "$lib/internal/index.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { type WritableBox, box } from "runed";
import { type WritableBox, box } from "svelte-toolbelt";
import { useAccordionRoot } from "../accordion.svelte.js";
import type { RootProps } from "../index.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
Expand Down
2 changes: 1 addition & 1 deletion packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { untrack } from "svelte";
import type { ReadableBox, WritableBox } from "runed";
import type { ReadableBox, WritableBox } from "svelte-toolbelt";
import type { AvatarImageLoadingStatus } from "./types.js";
import { createContext } from "$lib/internal/createContext.js";
import type { ReadableBoxedValues } from "$lib/internal/box.svelte.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import type { ImageProps } from "../index.js";
import { useAvatarImage } from "../avatar.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import type { RootProps } from "../index.js";
import { useAvatarRoot } from "../avatar.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import type { RootProps } from "../index.js";
import { useCheckboxRoot } from "../checkbox.svelte.js";
import CheckboxInput from "./checkbox-input.svelte";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { box } from "runed";
import { box } from "svelte-toolbelt";
import {
type ReadableBoxedValues,
type WritableBoxedValues,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import { useCollapsibleContent } from "../collapsible.svelte.js";
import type { CollapsibleContentProps } from "../types.js";
import { PresenceLayer } from "$lib/bits/utilities/presence-layer/index.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { box } from "runed";
import { box } from "svelte-toolbelt";
import type { RootProps } from "../index.js";
import { useCollapsibleRoot } from "../collapsible.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,105 +1,88 @@
<script lang="ts">
import { melt } from "@melt-ui/svelte";
import { getCtx, updatePositioning } from "../ctx.js";
import type { ContentEvents, ContentProps } from "../index.js";
import type { Transition } from "$lib/internal/types.js";
import { createDispatcher } from "$lib/internal/events.js";
import { box } from "svelte-toolbelt";
import type { ContentProps } from "../index.js";
import { useMenuContent } from "$lib/bits/menu/menu.svelte.js";
import { useId } from "$lib/internal/useId.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
import { noop } from "$lib/internal/callbacks.js";
import PopperLayer from "$lib/bits/utilities/popper-layer/popper-layer.svelte";
import { isElement } from "$lib/internal/is.js";
import type { InteractOutsideEvent } from "$lib/bits/utilities/dismissable-layer/types.js";

type T = $$Generic<Transition>;
type In = $$Generic<Transition>;
type Out = $$Generic<Transition>;
type $$Props = ContentProps<T, In, Out>;
type $$Events = ContentEvents;
let {
id = useId(),
asChild,
child,
children,
el = $bindable(),
loop = true,
onInteractOutside = noop,
onEscapeKeydown = noop,
forceMount = false,
...restProps
}: ContentProps = $props();

export let transition: $$Props["transition"] = undefined;
export let transitionConfig: $$Props["transitionConfig"] = undefined;
export let inTransition: $$Props["inTransition"] = undefined;
export let inTransitionConfig: $$Props["inTransitionConfig"] = undefined;
export let outTransition: $$Props["outTransition"] = undefined;
export let outTransitionConfig: $$Props["outTransitionConfig"] = undefined;
export let asChild: $$Props["asChild"] = false;
export let id: $$Props["id"] = undefined;
export let alignOffset: $$Props["alignOffset"] = 0;
export let collisionPadding: $$Props["collisionPadding"] = 8;
export let avoidCollisions: $$Props["avoidCollisions"] = true;
export let collisionBoundary: $$Props["collisionBoundary"] = undefined;
export let fitViewport: $$Props["fitViewport"] = false;
export let strategy: $$Props["strategy"] = "absolute";
export let overlap: $$Props["overlap"] = false;
export let el: $$Props["el"] = undefined;

const {
elements: { menu },
states: { open },
ids,
getAttrs,
} = getCtx();

const dispatch = createDispatcher();
const attrs = getAttrs("content");
const state = useMenuContent({
id: box.with(() => id),
loop: box.with(() => loop),
});

$: if (id) {
ids.menu.set(id);
function handleInteractOutsideStart(e: InteractOutsideEvent) {
if (!isElement(e.target)) return;
if (e.target.id === state.parentMenu.triggerId.value) {
e.preventDefault();
return;
}
if (e.target.closest(`#${state.parentMenu.triggerId.value}`)) {
e.preventDefault();
}
}
$: builder = $menu;
$: Object.assign(builder, attrs);

$: updatePositioning({
alignOffset,
collisionPadding,
avoidCollisions,
collisionBoundary,
fitViewport,
strategy,
overlap,
});
const mergedProps = $derived(
mergeProps(restProps, state.props, {
onInteractOutsideStart: handleInteractOutsideStart,
style: {
outline: "none",
"--bits-context-menu-content-transform-origin":
"var(--bits-floating-transform-origin)",
"--bits-context-menu-content-available-width":
"var(--bits-floating-available-width)",
"--bits-context-menu-content-available-height":
"var(--bits-floating-available-height)",
"--bits-context-menu-trigger-width": "var(--bits-floating-anchor-width)",
"--bits-context-menu-trigger-height": "var(--bits-floating-anchor-height)",
},
})
);
</script>

{#if asChild && $open}
<slot {builder} />
{:else if transition && $open}
<div
bind:this={el}
transition:transition={transitionConfig}
use:melt={builder}
{...$$restProps}
on:m-keydown={dispatch}
>
<slot {builder} />
</div>
{:else if inTransition && outTransition && $open}
<div
bind:this={el}
in:inTransition={inTransitionConfig}
out:outTransition={outTransitionConfig}
use:melt={builder}
{...$$restProps}
on:m-keydown={dispatch}
>
<slot {builder} />
</div>
{:else if inTransition && $open}
<div
bind:this={el}
in:inTransition={inTransitionConfig}
use:melt={builder}
{...$$restProps}
on:m-keydown={dispatch}
>
<slot {builder} />
</div>
{:else if outTransition && $open}
<div
bind:this={el}
out:outTransition={outTransitionConfig}
use:melt={builder}
{...$$restProps}
on:m-keydown={dispatch}
>
<slot {builder} />
</div>
{:else if $open}
<div bind:this={el} use:melt={builder} {...$$restProps} on:m-keydown={dispatch}>
<slot {builder} />
</div>
{/if}
<PopperLayer
{...mergedProps}
side="right"
sideOffset={2}
align="start"
present={state.parentMenu.open.value || forceMount}
onInteractOutside={(e) => {
onInteractOutside(e);
if (e.defaultPrevented) return;
state.parentMenu.onClose();
}}
onEscapeKeydown={(e) => {
// TODO: users should be able to cancel this
onEscapeKeydown(e);
state.parentMenu.onClose();
}}
trapped
{loop}
>
{#snippet popper({ props })}
{@const finalProps = mergeProps(props, mergedProps)}
{#if asChild}
{@render child?.({ props: finalProps })}
{:else}
<div {...finalProps} bind:this={el}>
{@render children?.()}
</div>
{/if}
{/snippet}
</PopperLayer>
Loading
Loading