Skip to content

Commit

Permalink
next: initial floating stuff (#485)
Browse files Browse the repository at this point in the history
  • Loading branch information
huntabyte authored Apr 19, 2024
1 parent d97b8d6 commit 09d568c
Show file tree
Hide file tree
Showing 51 changed files with 1,434 additions and 487 deletions.
3 changes: 3 additions & 0 deletions packages/bits-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@testing-library/user-event": "^14.5.2",
"@types/jest-axe": "^3.5.9",
"@types/node": "^20.12.2",
"@types/resize-observer-browser": "^0.1.11",
"@types/testing-library__jest-dom": "^5.14.9",
"csstype": "^3.1.3",
"jest-axe": "^8.0.0",
Expand All @@ -54,6 +55,8 @@
"types": "./dist/index.d.ts",
"type": "module",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/dom": "^1.6.3",
"@internationalized/date": "^3.5.1",
"@melt-ui/svelte": "0.76.2",
"esm-env": "^1.0.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {
getDataOpenClosed,
kbd,
styleToString,
useNodeById,
verifyContextDeps,
} from "$lib/internal/index.js";
import type { StyleProperties } from "$lib/shared/index.js";
import { withTick } from "$lib/internal/with-tick.js";
import { useNodeById } from "$lib/internal/elements.svelte.js";
import { afterTick } from "$lib/internal/after-tick.js";

/**
* BASE
Expand Down Expand Up @@ -284,7 +284,7 @@ class AccordionContentState {
const node = this.node.value;
if (!node) return;

withTick(() => {
afterTick(() => {
if (!this.node) return;
// get the dimensions of the element
this.#originalStyles = this.#originalStyles || {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { getAccordionContentState } from "../accordion.svelte.js";
import type { AccordionContentProps } from "../types.js";
import Presence from "$lib/bits/utilities/presence.svelte";
import Presence from "$lib/bits/utilities/presence-layer/presence-layer.svelte";
import { readonlyBox } from "$lib/internal/box.svelte.js";
import { generateId } from "$lib/internal/id.js";
Expand All @@ -23,7 +23,7 @@
});
</script>

<Presence forceMount={true} present={content.present} node={content.node}>
<Presence forceMount={true} present={content.present} {id}>
{#snippet presence({ present })}
{@const mergedProps = {
...restProps,
Expand Down
22 changes: 12 additions & 10 deletions packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { getContext, setContext } from "svelte";
import { getAriaExpanded, getDataDisabled, getDataOpenClosed } from "$lib/internal/attrs.js";
import {
type Box,
type BoxedValues,
type EventCallback,
type ReadonlyBox,
type ReadonlyBoxedValues,
afterTick,
boxedState,
readonlyBox,
composeHandlers,
generateId,
getAriaExpanded,
getDataDisabled,
getDataOpenClosed,
readonlyBoxedState,
} from "$lib/internal/box.svelte.js";
import { generateId } from "$lib/internal/id.js";
import { styleToString } from "$lib/internal/style.js";
import { type EventCallback, composeHandlers } from "$lib/internal/events.js";
styleToString,
useNodeById,
verifyContextDeps,
} from "$lib/internal/index.js";
import type { StyleProperties } from "$lib/shared/index.js";
import { withTick } from "$lib/internal/with-tick.js";
import { useNodeById } from "$lib/internal/elements.svelte.js";
import { verifyContextDeps } from "$lib/internal/context.js";

type CollapsibleRootStateProps = BoxedValues<{
open: boolean;
Expand Down Expand Up @@ -105,7 +107,7 @@ class CollapsibleContentState {
const node = this.node.value;
if (!node) return;

withTick(() => {
afterTick(() => {
if (!this.node) return;
// get the dimensions of the element
this.#originalStyles = this.#originalStyles || {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { getCollapsibleContentState } from "../collapsible.svelte.js";
import type { CollapsibleContentProps } from "../types.js";
import Presence from "$lib/bits/utilities/presence.svelte";
import Presence from "$lib/bits/utilities/presence-layer/presence-layer.svelte";
import { generateId } from "$lib/internal/id.js";
import { readonlyBox } from "$lib/internal/box.svelte.js";
Expand All @@ -23,7 +23,7 @@
});
</script>

<Presence forceMount={true} present={content.present} node={content.node}>
<Presence forceMount={true} present={content.present} {id}>
{#snippet presence({ present })}
{@const mergedProps = {
...restProps,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +0,0 @@
<script lang="ts">
import { melt } from "@melt-ui/svelte";
import { setArrow } from "../ctx.js";
import type { ArrowProps } from "../index.js";
type $$Props = ArrowProps;
export let asChild: $$Props["asChild"] = false;
export let el: $$Props["el"] = undefined;
export let size = 8;
const {
elements: { arrow },
getAttrs,
} = setArrow(size);
const attrs = getAttrs("arrow");
$: builder = $arrow;
$: Object.assign(builder, attrs);
</script>

{#if asChild}
<slot {builder} />
{:else}
<div bind:this={el} use:melt={builder} {...$$restProps} />
{/if}
Original file line number Diff line number Diff line change
@@ -1,38 +0,0 @@
<script lang="ts">
import { melt } from "@melt-ui/svelte";
import { getCtx } from "../ctx.js";
import type { CloseEvents, CloseProps } from "../index.js";
import { createDispatcher } from "$lib/internal/events.js";
type $$Props = CloseProps;
type $$Events = CloseEvents;
export let asChild: $$Props["asChild"] = false;
export let el: $$Props["el"] = undefined;
const {
elements: { close },
getAttrs,
} = getCtx();
const dispatch = createDispatcher();
const attrs = getAttrs("close");
$: builder = $close;
$: Object.assign(builder, attrs);
</script>

{#if asChild}
<slot {builder} />
{:else}
<button
bind:this={el}
use:melt={builder}
type="button"
{...$$restProps}
on:m-click={dispatch}
on:m-keydown={dispatch}
>
<slot {builder} />
</button>
{/if}
Original file line number Diff line number Diff line change
@@ -1,99 +1,44 @@
<script lang="ts">
import { melt } from "@melt-ui/svelte";
import { getCtx, updatePositioning } from "../ctx.js";
import type { ContentProps } from "../index.js";
import type { Transition } from "$lib/internal/index.js";
type T = $$Generic<Transition>;
type In = $$Generic<Transition>;
type Out = $$Generic<Transition>;
type $$Props = ContentProps<T, In, Out>;
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 side: $$Props["side"] = "bottom";
export let align: $$Props["align"] = "center";
export let sideOffset: $$Props["sideOffset"] = 0;
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 sameWidth: $$Props["sameWidth"] = false;
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: { content },
states: { open },
ids,
getAttrs,
} = getCtx();
const attrs = getAttrs("content");
$: if (id) {
ids.content.set(id);
}
$: builder = $content;
$: Object.assign(builder, attrs);
$: if ($open) {
updatePositioning({
side,
align,
sideOffset,
alignOffset,
collisionPadding,
avoidCollisions,
collisionBoundary,
sameWidth,
fitViewport,
strategy,
overlap,
});
}
import { setPopoverContentState } from "../popover.svelte.js";
import { FloatingLayer, PresenceLayer } from "$lib/bits/utilities/index.js";
import { readonlyBox } from "$lib/internal/box.svelte.js";
import { generateId } from "$lib/internal/id.js";
let {
asChild,
child,
children,
el = $bindable(),
style = {},
id = generateId(),
forceMount = false,
...restProps
}: ContentProps = $props();
const state = setPopoverContentState({
id: readonlyBox(() => id),
});
</script>

{#if asChild && $open}
<slot {builder} />
{:else if transition && $open}
<div
bind:this={el}
transition:transition={transitionConfig}
use:melt={builder}
{...$$restProps}
>
<slot {builder} />
</div>
{:else if inTransition && outTransition && $open}
<div
bind:this={el}
in:inTransition={inTransitionConfig}
out:outTransition={outTransitionConfig}
use:melt={builder}
{...$$restProps}
>
<slot {builder} />
</div>
{:else if inTransition && $open}
<div bind:this={el} in:inTransition={inTransitionConfig} use:melt={builder} {...$$restProps}>
<slot {builder} />
</div>
{:else if outTransition && $open}
<div bind:this={el} out:outTransition={outTransitionConfig} use:melt={builder} {...$$restProps}>
<slot {builder} />
</div>
{:else if $open}
<div bind:this={el} use:melt={builder} {...$$restProps}>
<slot {builder} />
</div>
{/if}
<PresenceLayer.Root forceMount={true} present={state.root.open.value || forceMount} {id}>
{#snippet presence({ present })}
<FloatingLayer.Content {id} {style} {...restProps}>
{#snippet content({ props })}
{@const mergedProps = {
...state.props,
...props,
hidden: present.value ? undefined : true,
...restProps,
}}
{#if asChild}
{@render child?.({ props: mergedProps })}
{:else}
<div {...mergedProps} bind:this={el}>
{@render children?.()}
</div>
{/if}
{/snippet}
</FloatingLayer.Content>
{/snippet}
</PresenceLayer.Root>
Loading

0 comments on commit 09d568c

Please sign in to comment.