Skip to content

Commit

Permalink
next: chores and cleanup (#576)
Browse files Browse the repository at this point in the history
  • Loading branch information
huntabyte authored Jun 17, 2024
1 parent d35f6ac commit b136913
Show file tree
Hide file tree
Showing 61 changed files with 910 additions and 399 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"build:packages": "pnpm -F \"./packages/**\" --parallel build",
"check": "pnpm build:packages && pnpm -r check",
"ci:publish": "pnpm build:packages && changeset publish",
"dev": "pnpm -r --parallel dev",
"dev": "pnpm -F \"./packages/**\" svelte-kit sync && pnpm -r --parallel dev",
"format": "prettier --write .",
"lint": "prettier --check . && eslint .",
"lint:fix": "eslint --fix .",
Expand Down
2 changes: 1 addition & 1 deletion packages/bits-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"vite": "^5.2.8",
"vitest": "^1.5.0"
"vitest": "^1.6.0"
},
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
99 changes: 75 additions & 24 deletions packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { WritableBox } from "svelte-toolbelt";
import {
type Box,
type ReadableBoxedValues,
Expand All @@ -10,7 +9,7 @@ import {
getDataOpenClosed,
getDataOrientation,
kbd,
useNodeById,
useRefById,
} from "$lib/internal/index.js";
import { type UseRovingFocusReturn, useRovingFocus } from "$lib/internal/useRovingFocus.svelte.js";
import type { Orientation } from "$lib/shared/index.js";
Expand All @@ -31,25 +30,33 @@ type AccordionBaseStateProps = ReadableBoxedValues<{
disabled: boolean;
orientation: Orientation;
loop: boolean;
ref: HTMLElement | null | undefined;
}>;
}> &
WritableBoxedValues<{
ref: HTMLElement | null;
}>;

class AccordionBaseState {
id: AccordionBaseStateProps["id"];
node: WritableBox<HTMLElement | null>;
#id: AccordionBaseStateProps["id"];
#ref: AccordionBaseStateProps["ref"];
disabled: AccordionBaseStateProps["disabled"];
#loop: AccordionBaseStateProps["loop"];
orientation: AccordionBaseStateProps["orientation"];
rovingFocusGroup: UseRovingFocusReturn;

constructor(props: AccordionBaseStateProps) {
this.id = props.id;
this.#id = props.id;
this.disabled = props.disabled;
this.node = useNodeById(this.id);
this.#ref = props.ref;

useRefById({
id: props.id,
ref: this.#ref,
});

this.orientation = props.orientation;
this.#loop = props.loop;
this.rovingFocusGroup = useRovingFocus({
rootNodeId: this.id,
rootNodeId: this.#id,
candidateSelector: TRIGGER_ATTR,
loop: this.#loop,
orientation: this.orientation,
Expand All @@ -59,7 +66,7 @@ class AccordionBaseState {
props = $derived.by(
() =>
({
id: this.id.value,
id: this.#id.value,
"data-orientation": getDataOrientation(this.orientation.value),
"data-disabled": getDataDisabled(this.disabled.value),
[ROOT_ATTR]: "",
Expand Down Expand Up @@ -126,11 +133,16 @@ export class AccordionMultiState extends AccordionBaseState {
type AccordionItemStateProps = ReadableBoxedValues<{
value: string;
disabled: boolean;
id: string;
}> & {
rootState: AccordionState;
};
} & WritableBoxedValues<{
ref: HTMLElement | null;
}>;

export class AccordionItemState {
#id: AccordionItemStateProps["id"];
#ref: AccordionItemStateProps["ref"];
value: AccordionItemStateProps["value"];
disabled: AccordionItemStateProps["disabled"];
root: AccordionState;
Expand All @@ -141,6 +153,13 @@ export class AccordionItemState {
this.value = props.value;
this.disabled = props.disabled;
this.root = props.rootState;
this.#id = props.id;
this.#ref = props.ref;

useRefById({
id: this.#id,
ref: this.#ref,
});
}

updateValue() {
Expand All @@ -162,6 +181,7 @@ export class AccordionItemState {
props = $derived.by(
() =>
({
id: this.#id.value,
[ITEM_ATTR]: "",
"data-state": getDataOpenClosed(this.isSelected),
"data-disabled": getDataDisabled(this.isDisabled),
Expand All @@ -176,12 +196,15 @@ export class AccordionItemState {
type AccordionTriggerStateProps = ReadableBoxedValues<{
disabled: boolean;
id: string;
}>;
}> &
WritableBoxedValues<{
ref: HTMLElement | null;
}>;

class AccordionTriggerState {
#ref: AccordionTriggerStateProps["ref"];
#disabled: AccordionTriggerStateProps["disabled"];
#id: AccordionTriggerStateProps["id"];
#node: Box<HTMLElement | null>;
#root: AccordionState;
#itemState: AccordionItemState;
#isDisabled = $derived.by(
Expand All @@ -193,8 +216,12 @@ class AccordionTriggerState {
this.#itemState = itemState;
this.#root = itemState.root;
this.#id = props.id;
this.#ref = props.ref;

this.#node = useNodeById(this.#id);
useRefById({
id: props.id,
ref: this.#ref,
});
}

#onclick = () => {
Expand All @@ -209,7 +236,7 @@ class AccordionTriggerState {
return;
}

this.#root.rovingFocusGroup.handleKeydown(this.#node.value, e);
this.#root.rovingFocusGroup.handleKeydown(this.#ref.value, e);
};

props = $derived.by(
Expand Down Expand Up @@ -238,11 +265,14 @@ class AccordionTriggerState {
type AccordionContentStateProps = ReadableBoxedValues<{
forceMount: boolean;
id: string;
}>;
}> &
WritableBoxedValues<{
ref: HTMLElement | null;
}>;

class AccordionContentState {
item: AccordionItemState;
node: WritableBox<HTMLElement | null>;
#ref: AccordionContentStateProps["ref"];
#id: AccordionContentStateProps["id"];
#originalStyles: { transitionDuration: string; animationName: string } | undefined = undefined;
#isMountAnimationPrevented = false;
Expand All @@ -257,8 +287,12 @@ class AccordionContentState {
this.#forceMount = props.forceMount;
this.#isMountAnimationPrevented = this.item.isSelected;
this.#id = props.id;
this.#ref = props.ref;

this.node = useNodeById(this.#id);
useRefById({
id: this.#id,
ref: this.#ref,
});

$effect.pre(() => {
const rAF = requestAnimationFrame(() => {
Expand All @@ -273,11 +307,11 @@ class AccordionContentState {
$effect(() => {
// eslint-disable-next-line no-unused-expressions
this.present;
const node = this.node.value;
const node = this.#ref.value;
if (!node) return;

afterTick(() => {
if (!this.node) return;
if (!this.#ref.value) return;
// get the dimensions of the element
this.#originalStyles = this.#originalStyles || {
transitionDuration: node.style.transitionDuration,
Expand Down Expand Up @@ -320,19 +354,34 @@ class AccordionContentState {

type AccordionHeaderStateProps = ReadableBoxedValues<{
level: 1 | 2 | 3 | 4 | 5 | 6;
}>;
id: string;
}> &
WritableBoxedValues<{
ref: HTMLElement | null;
}>;

class AccordionHeaderState {
#item: AccordionItemState;
#id: AccordionHeaderStateProps["id"];
#ref: AccordionHeaderStateProps["ref"];
#level: AccordionHeaderStateProps["level"];
#item: AccordionItemState;
constructor(props: AccordionHeaderStateProps, item: AccordionItemState) {
this.#level = props.level;
this.#id = props.id;
this.#ref = props.ref;

useRefById({
id: this.#id,
ref: this.#ref,
});

this.#item = item;
}

props = $derived.by(
() =>
({
id: this.#id.value,
role: "heading",
"aria-level": this.#level.value,
"data-heading-level": this.#level.value,
Expand All @@ -357,8 +406,10 @@ type InitAccordionProps = {
disabled: boolean;
orientation: Orientation;
loop: boolean;
ref: HTMLElement | null | undefined;
}>;
}> &
WritableBoxedValues<{
ref: HTMLElement | null;
}>;

const [setAccordionRootContext, getAccordionRootContext] =
createContext<AccordionState>("Accordion.Root");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
let {
child,
asChild,
ref = $bindable(),
ref = $bindable(null),
id = useId(),
forceMount = false,
children,
Expand All @@ -18,6 +18,10 @@
const contentState = useAccordionContent({
forceMount: box.with(() => forceMount),
id: box.with(() => id),
ref: box.with(
() => ref,
(v) => (ref = v)
),
});
</script>

Expand All @@ -31,7 +35,7 @@
props: mergedProps,
})}
{:else}
<div {...mergedProps} bind:this={ref}>
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@
import type { AccordionHeaderProps } from "../types.js";
import { useAccordionHeader } from "../accordion.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
import { useId } from "$lib/internal/useId.svelte.js";
let {
id = useId(),
asChild,
level = 2,
children,
child,
ref = $bindable(),
ref = $bindable(null),
...restProps
}: AccordionHeaderProps = $props();
const headerState = useAccordionHeader({
id: box.with(() => id),
level: box.with(() => level),
ref: box.with(
() => ref,
(v) => (ref = v)
),
});
const mergedProps = $derived(mergeProps(restProps, headerState.props));
Expand All @@ -23,7 +30,7 @@
{#if asChild}
{@render child?.({ props: mergedProps })}
{:else}
<div {...mergedProps} bind:this={ref}>
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@
import type { AccordionItemProps } from "../types.js";
import { useAccordionItem } from "../accordion.svelte.js";
import { mergeProps } from "$lib/internal/mergeProps.js";
import { useId } from "$lib/internal/useId.svelte.js";
let {
id = useId(),
asChild,
disabled = false,
value,
children,
child,
ref = $bindable(),
ref = $bindable(null),
...restProps
}: AccordionItemProps = $props();
const itemState = useAccordionItem({
value: box.with(() => value),
disabled: box.with(() => disabled),
id: box.with(() => id),
ref: box.with(
() => ref,
(v) => (ref = v)
),
});
const mergedProps = $derived(mergeProps(restProps, itemState.props));
Expand All @@ -25,7 +32,7 @@
{#if asChild}
{@render child?.({ props: mergedProps })}
{:else}
<div {...mergedProps} bind:this={ref}>
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let {
disabled = false,
asChild,
ref = $bindable(),
ref = $bindable(null),
id = useId(),
children,
child,
Expand All @@ -17,6 +17,10 @@
const triggerState = useAccordionTrigger({
disabled: box.with(() => disabled),
id: box.with(() => id),
ref: box.with(
() => ref,
(v) => (ref = v)
),
});
const mergedProps = $derived(mergeProps(restProps, triggerState.props));
Expand All @@ -25,7 +29,7 @@
{#if asChild}
{@render child?.({ props: mergedProps })}
{:else}
<button bind:this={ref} type="button" {...mergedProps}>
<button type="button" {...mergedProps}>
{@render children?.()}
</button>
{/if}
Loading

0 comments on commit b136913

Please sign in to comment.