From a92af6c3f83b06a2b90bc9068c2e3615404346e2 Mon Sep 17 00:00:00 2001 From: anatolzak <53095479+anatolzak@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:36:32 +0300 Subject: [PATCH 1/7] remove derived #attrs --- .../lib/bits/accordion/accordion.svelte.ts | 67 +++++++++---------- .../src/lib/bits/avatar/avatar.svelte.ts | 43 ++++++------ .../src/lib/bits/checkbox/checkbox.svelte.ts | 52 +++++++------- .../bits/collapsible/collapsible.svelte.ts | 54 +++++++-------- .../src/lib/bits/progress/progress.svelte.ts | 26 ++++--- .../bits/radio-group/radio-group.svelte.ts | 40 +++++------ 6 files changed, 130 insertions(+), 152 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts index eb8561ee3..3db048a7b 100644 --- a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts +++ b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts @@ -32,10 +32,6 @@ class AccordionBaseState { id = undefined as unknown as ReadonlyBox; node = boxedState(null); disabled: ReadonlyBox; - #attrs = $derived({ - id: this.id.value, - "data-accordion-root": "", - } as const); constructor(props: AccordionBaseStateProps) { this.id = props.id; @@ -52,7 +48,10 @@ class AccordionBaseState { } get props() { - return this.#attrs; + return { + id: this.id.value, + "data-accordion-root": "", + } as const; } } @@ -125,11 +124,6 @@ export class AccordionItemState { root = undefined as unknown as AccordionState; isSelected = $derived(this.root.includesItem(this.value)); isDisabled = $derived(this.disabled.value || this.root.disabled.value); - #attrs = $derived({ - "data-accordion-item": "", - "data-state": getDataOpenClosed(this.isSelected), - "data-disabled": getDataDisabled(this.isDisabled), - } as const); constructor(props: AccordionItemStateProps) { this.#value = props.value; @@ -146,7 +140,11 @@ export class AccordionItemState { } get props() { - return this.#attrs; + return { + "data-accordion-item": "", + "data-state": getDataOpenClosed(this.isSelected), + "data-disabled": getDataDisabled(this.isDisabled), + } as const; } createTrigger(props: AccordionTriggerStateProps) { @@ -184,16 +182,6 @@ class AccordionTriggerState { #isDisabled = $derived( this.#disabled.value || this.#itemState.disabled.value || this.#root.disabled.value ); - #attrs = $derived({ - id: this.#id.value, - disabled: this.#isDisabled, - "aria-expanded": getAriaExpanded(this.#itemState.isSelected), - "aria-disabled": getAriaDisabled(this.#isDisabled), - "data-disabled": getDataDisabled(this.#isDisabled), - "data-value": this.#itemState.value, - "data-state": getDataOpenClosed(this.#itemState.isSelected), - "data-accordion-trigger": "", - } as const); constructor(props: AccordionTriggerStateProps, itemState: AccordionItemState) { this.#disabled = props.disabled; @@ -241,10 +229,18 @@ class AccordionTriggerState { get props() { return { - ...this.#attrs, + id: this.#id.value, + disabled: this.#isDisabled, + "aria-expanded": getAriaExpanded(this.#itemState.isSelected), + "aria-disabled": getAriaDisabled(this.#isDisabled), + "data-disabled": getDataDisabled(this.#isDisabled), + "data-value": this.#itemState.value, + "data-state": getDataOpenClosed(this.#itemState.isSelected), + "data-accordion-trigger": "", + // onclick: this.#onclick, onkeydown: this.#onkeydown, - }; + } as const; } } @@ -269,18 +265,6 @@ class AccordionContentState { #forceMount = undefined as unknown as ReadonlyBox; present = $derived(this.#forceMount.value || this.item.isSelected); #styleProp = undefined as unknown as ReadonlyBox; - #attrs = $derived({ - id: this.#id.value, - "data-state": getDataOpenClosed(this.item.isSelected), - "data-disabled": getDataDisabled(this.item.isDisabled), - "data-value": this.item.value, - "data-accordion-content": "", - style: styleToString({ - ...this.#styleProp.value, - "--bits-accordion-content-height": `${this.#height.value}px`, - "--bits-accordion-content-width": `${this.#width.value}px`, - }), - } as const); constructor(props: AccordionContentStateProps, item: AccordionItemState) { this.item = item; @@ -334,7 +318,18 @@ class AccordionContentState { } get props() { - return this.#attrs; + return { + id: this.#id.value, + "data-state": getDataOpenClosed(this.item.isSelected), + "data-disabled": getDataDisabled(this.item.isDisabled), + "data-value": this.item.value, + "data-accordion-content": "", + style: styleToString({ + ...this.#styleProp.value, + "--bits-accordion-content-height": `${this.#height.value}px`, + "--bits-accordion-content-width": `${this.#width.value}px`, + }), + } as const; } } diff --git a/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts b/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts index 054d29135..f8f71652f 100644 --- a/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts +++ b/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts @@ -26,11 +26,6 @@ class AvatarRootState { delayMs: ReadonlyBox; loadingStatus = undefined as unknown as Box; styleProp = undefined as unknown as ReadonlyBox; - #attrs = $derived({ - "data-avatar-root": "", - "data-status": this.loadingStatus.value, - style: styleToString(this.styleProp.value), - } as const); constructor(props: AvatarRootStateProps) { this.delayMs = props.delayMs; @@ -67,7 +62,11 @@ class AvatarRootState { } get props() { - return this.#attrs; + return { + "data-avatar-root": "", + "data-status": this.loadingStatus.value, + style: styleToString(this.styleProp.value), + } as const; } } @@ -83,14 +82,6 @@ type AvatarImageStateProps = ReadonlyBoxedValues<{ class AvatarImageState { root = undefined as unknown as AvatarRootState; styleProp = undefined as unknown as ReadonlyBox; - #attrs = $derived({ - style: styleToString({ - ...this.styleProp.value, - display: this.root.loadingStatus.value === "loaded" ? "block" : "none", - }), - "data-avatar-image": "", - src: this.root.src.value, - } as const); constructor(props: AvatarImageStateProps, root: AvatarRootState) { this.root = root; @@ -99,7 +90,14 @@ class AvatarImageState { } get props() { - return this.#attrs; + return { + style: styleToString({ + ...this.styleProp.value, + display: this.root.loadingStatus.value === "loaded" ? "block" : "none", + }), + "data-avatar-image": "", + src: this.root.src.value, + } as const; } } @@ -114,13 +112,6 @@ type AvatarFallbackStateProps = ReadonlyBoxedValues<{ class AvatarFallbackState { root = undefined as unknown as AvatarRootState; styleProp = undefined as unknown as ReadonlyBox; - #attrs = $derived({ - style: styleToString({ - ...this.styleProp.value, - display: this.root.loadingStatus.value === "loaded" ? "none" : "block", - }), - "data-avatar-fallback": "", - } as const); constructor(props: AvatarFallbackStateProps, root: AvatarRootState) { this.styleProp = props.style; @@ -128,7 +119,13 @@ class AvatarFallbackState { } get props() { - return this.#attrs; + return { + style: styleToString({ + ...this.styleProp.value, + display: this.root.loadingStatus.value === "loaded" ? "none" : "block", + }), + "data-avatar-fallback": "", + } as const; } } diff --git a/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts b/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts index a99ce0bde..61017959c 100644 --- a/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts +++ b/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts @@ -42,16 +42,6 @@ class CheckboxRootState { value: ReadonlyBox; #onclickProp = boxedState(readonlyBox(() => () => {})); #onkeydownProp = boxedState(readonlyBox(() => () => {})); - #attrs = $derived({ - "data-disabled": getDataDisabled(this.disabled.value), - "data-state": getCheckboxDataState(this.checked.value), - role: "checkbox", - type: "button", - "aria-checked": getAriaChecked(this.checked.value), - "aria-required": getAriaRequired(this.required.value), - "data-checkbox-root": "", - disabled: this.disabled.value, - } as const); constructor(props: CheckboxRootStateProps) { this.checked = props.checked; @@ -86,10 +76,18 @@ class CheckboxRootState { get props() { return { - ...this.#attrs, + "data-disabled": getDataDisabled(this.disabled.value), + "data-state": getCheckboxDataState(this.checked.value), + role: "checkbox", + type: "button", + "aria-checked": getAriaChecked(this.checked.value), + "aria-required": getAriaRequired(this.required.value), + "data-checkbox-root": "", + disabled: this.disabled.value, + // onclick: this.#onclick, onkeydown: this.#onkeydown, - }; + } as const; } } @@ -99,18 +97,17 @@ class CheckboxRootState { class CheckboxIndicatorState { root = undefined as unknown as CheckboxRootState; - #attrs = $derived({ - "data-disabled": getDataDisabled(this.root.disabled.value), - "data-state": getCheckboxDataState(this.root.checked.value), - "data-checkbox-indicator": "", - }); constructor(root: CheckboxRootState) { this.root = root; } get props() { - return this.#attrs; + return { + "data-disabled": getDataDisabled(this.root.disabled.value), + "data-state": getCheckboxDataState(this.root.checked.value), + "data-checkbox-indicator": "", + } as const; } } @@ -120,15 +117,6 @@ class CheckboxIndicatorState { class CheckboxInputState { root = undefined as unknown as CheckboxRootState; - #attrs = $derived({ - type: "checkbox", - checked: this.root.checked.value === true, - disabled: this.root.disabled.value, - required: this.root.required.value, - name: this.root.name.value, - value: this.root.value.value, - "data-checkbox-input": "", - }); shouldRender = $derived(this.root.name.value !== undefined); constructor(root: CheckboxRootState) { @@ -136,7 +124,15 @@ class CheckboxInputState { } get props() { - return this.#attrs; + return { + type: "checkbox", + checked: this.root.checked.value === true, + disabled: this.root.disabled.value, + required: this.root.required.value, + name: this.root.name.value, + value: this.root.value.value, + "data-checkbox-input": "", + } as const; } } diff --git a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts index 525885451..c3bc8a58f 100644 --- a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts +++ b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts @@ -27,11 +27,6 @@ type CollapsibleRootStateProps = BoxedValues<{ class CollapsibleRootState { open = undefined as unknown as Box; disabled = undefined as unknown as ReadonlyBox; - #attrs = $derived({ - "data-state": getDataOpenClosed(this.open.value), - "data-disabled": getDataDisabled(this.disabled.value), - "data-collapsible-root": "", - } as const); contentId = readonlyBoxedState(generateId()); constructor(props: CollapsibleRootStateProps) { @@ -40,7 +35,11 @@ class CollapsibleRootState { } get props() { - return this.#attrs; + return { + "data-state": getDataOpenClosed(this.open.value), + "data-disabled": getDataDisabled(this.disabled.value), + "data-collapsible-root": "", + } as const; } toggleOpen() { @@ -72,17 +71,6 @@ class CollapsibleContentState { #height = $state(0); #forceMount = undefined as unknown as ReadonlyBox; present = $derived(this.#forceMount.value || this.root.open.value); - #attrs = $derived({ - id: this.root.contentId.value, - "data-state": getDataOpenClosed(this.root.open.value), - "data-disabled": getDataDisabled(this.root.disabled.value), - "data-collapsible-content": "", - style: styleToString({ - ...this.#styleProp.value, - "--bits-collapsible-content-height": this.#height ? `${this.#height}px` : undefined, - "--bits-collapsible-content-width": this.#width ? `${this.#width}px` : undefined, - }), - } as const); constructor(props: CollapsibleContentStateProps, root: CollapsibleRootState) { this.root = root; @@ -136,7 +124,17 @@ class CollapsibleContentState { } get props() { - return this.#attrs; + return { + id: this.root.contentId.value, + "data-state": getDataOpenClosed(this.root.open.value), + "data-disabled": getDataDisabled(this.root.disabled.value), + "data-collapsible-content": "", + style: styleToString({ + ...this.#styleProp.value, + "--bits-collapsible-content-height": this.#height ? `${this.#height}px` : undefined, + "--bits-collapsible-content-width": this.#width ? `${this.#width}px` : undefined, + }), + } as const; } } @@ -147,15 +145,6 @@ type CollapsibleTriggerStateProps = ReadonlyBoxedValues<{ class CollapsibleTriggerState { #root = undefined as unknown as CollapsibleRootState; #onclickProp = boxedState(readonlyBox(() => () => {})); - #attrs = $derived({ - type: "button", - "aria-controls": this.#root.contentId.value, - "aria-expanded": getAriaExpanded(this.#root.open.value), - "data-state": getDataOpenClosed(this.#root.open.value), - "data-disabled": getDataDisabled(this.#root.disabled.value), - disabled: this.#root.disabled.value, - "data-collapsible-trigger": "", - } as const); constructor(props: CollapsibleTriggerStateProps, root: CollapsibleRootState) { this.#root = root; @@ -168,9 +157,16 @@ class CollapsibleTriggerState { get props() { return { - ...this.#attrs, + type: "button", + "aria-controls": this.#root.contentId.value, + "aria-expanded": getAriaExpanded(this.#root.open.value), + "data-state": getDataOpenClosed(this.#root.open.value), + "data-disabled": getDataDisabled(this.#root.disabled.value), + disabled: this.#root.disabled.value, + "data-collapsible-trigger": "", + // onclick: this.#onclick, - }; + } as const; } } diff --git a/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts b/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts index d968bc95f..2e92d2a01 100644 --- a/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts +++ b/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts @@ -9,26 +9,24 @@ class ProgressRootState { #value = undefined as unknown as ProgressRootStateProps["value"]; #max = undefined as unknown as ProgressRootStateProps["max"]; - #attrs = $derived({ - role: "meter", - value: this.#value.value, - max: this.#max.value, - "aria-valuemin": 0, - "aria-valuemax": this.#max.value, - "aria-valuenow": this.#value.value, - "data-value": this.#value.value, - "data-state": getProgressDataState(this.#value.value, this.#max.value), - "data-max": this.#max.value, - "data-bits-progress-root": "", - } as const); - constructor(props: ProgressRootStateProps) { this.#value = props.value; this.#max = props.max; } get props() { - return this.#attrs; + return { + role: "meter", + value: this.#value.value, + max: this.#max.value, + "aria-valuemin": 0, + "aria-valuemax": this.#max.value, + "aria-valuenow": this.#value.value, + "data-value": this.#value.value, + "data-state": getProgressDataState(this.#value.value, this.#max.value), + "data-max": this.#max.value, + "data-bits-progress-root": "", + } as const; } } diff --git a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts index 9e1bf6371..0c4f65648 100644 --- a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts +++ b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts @@ -33,13 +33,6 @@ class RadioGroupRootState { orientation = undefined as unknown as RadioGroupRootStateProps["orientation"]; name = undefined as unknown as RadioGroupRootStateProps["name"]; value = undefined as unknown as RadioGroupRootStateProps["value"]; - #attrs = $derived({ - role: "radiogroup", - "aria-required": getAriaRequired(this.required.value), - "data-disabled": getDataDisabled(this.disabled.value), - "data-orientation": this.orientation.value, - "data-bits-radio-group": "", - } as const); constructor(props: RadioGroupRootStateProps) { this.id = props.id; @@ -80,7 +73,13 @@ class RadioGroupRootState { } get props() { - return this.#attrs; + return { + role: "radiogroup", + "aria-required": getAriaRequired(this.required.value), + "data-disabled": getDataDisabled(this.disabled.value), + "data-orientation": this.orientation.value, + "data-bits-radio-group": "", + } as const; } } @@ -107,18 +106,6 @@ class RadioGroupItemState { #onclickProp = boxedState(readonlyBox(() => () => {})); #onkeydownProp = boxedState(readonlyBox(() => () => {})); - #attrs = $derived({ - disabled: this.#isDisabled ? true : undefined, - "data-value": this.#value.value, - "data-orientation": this.#root.orientation.value, - "data-disabled": getDataDisabled(this.#isDisabled), - "data-state": this.#isChecked ? "checked" : "unchecked", - "aria-checked": getAriaChecked(this.#isChecked), - "data-bits-radio-group-item": "", - type: "button", - role: "radio", - } as const); - constructor(props: RadioGroupItemStateProps, root: RadioGroupRootState) { this.#disabled = props.disabled; this.#value = props.value; @@ -184,10 +171,19 @@ class RadioGroupItemState { get props() { return { - ...this.#attrs, + disabled: this.#isDisabled ? true : undefined, + "data-value": this.#value.value, + "data-orientation": this.#root.orientation.value, + "data-disabled": getDataDisabled(this.#isDisabled), + "data-state": this.#isChecked ? "checked" : "unchecked", + "aria-checked": getAriaChecked(this.#isChecked), + "data-bits-radio-group-item": "", + type: "button", + role: "radio", + // onclick, onkeydown, - }; + } as const; } } From 6fe12ea64216738bea505a7ba729cc444e8e394e Mon Sep 17 00:00:00 2001 From: anatolzak <53095479+anatolzak@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:37:24 +0300 Subject: [PATCH 2/7] remove unused imports --- packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts | 2 +- packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts | 2 +- packages/bits-ui/src/lib/bits/progress/progress.svelte.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts index 3db048a7b..4ed4917e7 100644 --- a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts +++ b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts @@ -1,4 +1,4 @@ -import { getContext, setContext, tick, untrack } from "svelte"; +import { getContext, setContext } from "svelte"; import { type Box, type BoxedValues, diff --git a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts index c3bc8a58f..cd72d6447 100644 --- a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts +++ b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts @@ -1,4 +1,4 @@ -import { getContext, onMount, setContext, tick } from "svelte"; +import { getContext, setContext } from "svelte"; import { getAriaExpanded, getDataDisabled, getDataOpenClosed } from "$lib/internal/attrs.js"; import { type Box, diff --git a/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts b/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts index 2e92d2a01..7ff45d201 100644 --- a/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts +++ b/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts @@ -1,4 +1,4 @@ -import type { BoxedValues, ReadonlyBoxedValues } from "$lib/internal/box.svelte.js"; +import type { ReadonlyBoxedValues } from "$lib/internal/box.svelte.js"; type ProgressRootStateProps = ReadonlyBoxedValues<{ value: number | null; From 31f7aa345a0267eb30560c4ab84158dec20eac47 Mon Sep 17 00:00:00 2001 From: anatolzak <53095479+anatolzak@users.noreply.github.com> Date: Wed, 17 Apr 2024 12:41:40 +0300 Subject: [PATCH 3/7] use getters instead of derived state to avoid initializing properties as undefined on the prototype --- .../lib/bits/accordion/accordion.svelte.ts | 46 +++++++++++-------- .../src/lib/bits/avatar/avatar.svelte.ts | 13 +++--- .../src/lib/bits/checkbox/checkbox.svelte.ts | 15 +++--- .../bits/collapsible/collapsible.svelte.ts | 19 ++++---- .../src/lib/bits/progress/progress.svelte.ts | 4 +- .../bits/radio-group/radio-group.svelte.ts | 32 +++++++------ 6 files changed, 75 insertions(+), 54 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts index 4ed4917e7..897829ca3 100644 --- a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts +++ b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts @@ -29,7 +29,7 @@ type AccordionBaseStateProps = ReadonlyBoxedValues<{ }>; class AccordionBaseState { - id = undefined as unknown as ReadonlyBox; + id: ReadonlyBox; node = boxedState(null); disabled: ReadonlyBox; @@ -120,10 +120,8 @@ type AccordionItemStateProps = ReadonlyBoxedValues<{ export class AccordionItemState { #value: ReadonlyBox; - disabled = undefined as unknown as ReadonlyBox; - root = undefined as unknown as AccordionState; - isSelected = $derived(this.root.includesItem(this.value)); - isDisabled = $derived(this.disabled.value || this.root.disabled.value); + disabled: ReadonlyBox; + root: AccordionState; constructor(props: AccordionItemStateProps) { this.#value = props.value; @@ -135,6 +133,14 @@ export class AccordionItemState { return this.#value.value; } + get isSelected() { + return this.root.includesItem(this.value); + } + + get isDisabled() { + return this.disabled.value || this.root.disabled.value; + } + updateValue() { this.root.toggleItem(this.value); } @@ -168,21 +174,16 @@ type AccordionTriggerStateProps = ReadonlyBoxedValues<{ }>; class AccordionTriggerState { - #disabled = undefined as unknown as ReadonlyBox; - #id = undefined as unknown as ReadonlyBox; + #disabled: ReadonlyBox; + #id: ReadonlyBox; #node = boxedState(null); - #root = undefined as unknown as AccordionState; - #itemState = undefined as unknown as AccordionItemState; + #root: AccordionState; + #itemState: AccordionItemState; #onclickProp = boxedState(readonlyBox(() => () => {})); #onkeydownProp = boxedState( readonlyBox(() => () => {}) ); - // Disabled if the trigger itself, the item it belongs to, or the root is disabled - #isDisabled = $derived( - this.#disabled.value || this.#itemState.disabled.value || this.#root.disabled.value - ); - constructor(props: AccordionTriggerStateProps, itemState: AccordionItemState) { this.#disabled = props.disabled; this.#itemState = itemState; @@ -194,6 +195,10 @@ class AccordionTriggerState { useNodeById(this.#id, this.#node); } + get #isDisabled() { + return this.#disabled.value || this.#itemState.disabled.value || this.#root.disabled.value; + } + #onclick = composeHandlers(this.#onclickProp, () => { if (this.#isDisabled) return; this.#itemState.updateValue(); @@ -255,16 +260,15 @@ type AccordionContentStateProps = ReadonlyBoxedValues<{ }>; class AccordionContentState { - item = undefined as unknown as AccordionItemState; + item: AccordionItemState; node = boxedState(null); - #id = undefined as unknown as ReadonlyBox; + #id: ReadonlyBox; #originalStyles: { transitionDuration: string; animationName: string } | undefined = undefined; #isMountAnimationPrevented = false; #width = boxedState(0); #height = boxedState(0); - #forceMount = undefined as unknown as ReadonlyBox; - present = $derived(this.#forceMount.value || this.item.isSelected); - #styleProp = undefined as unknown as ReadonlyBox; + #forceMount: ReadonlyBox; + #styleProp: ReadonlyBox; constructor(props: AccordionContentStateProps, item: AccordionItemState) { this.item = item; @@ -317,6 +321,10 @@ class AccordionContentState { }); } + get present() { + return this.#forceMount.value || this.item.isSelected; + } + get props() { return { id: this.#id.value, diff --git a/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts b/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts index f8f71652f..4b114c1c3 100644 --- a/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts +++ b/packages/bits-ui/src/lib/bits/avatar/avatar.svelte.ts @@ -24,12 +24,13 @@ type AvatarImageSrc = string | null | undefined; class AvatarRootState { src = readonlyBox(() => null); delayMs: ReadonlyBox; - loadingStatus = undefined as unknown as Box; - styleProp = undefined as unknown as ReadonlyBox; + loadingStatus: Box; + styleProp: ReadonlyBox; constructor(props: AvatarRootStateProps) { this.delayMs = props.delayMs; this.loadingStatus = props.loadingStatus; + this.styleProp = props.style; $effect.pre(() => { if (!this.src.value) return; @@ -80,8 +81,8 @@ type AvatarImageStateProps = ReadonlyBoxedValues<{ }>; class AvatarImageState { - root = undefined as unknown as AvatarRootState; - styleProp = undefined as unknown as ReadonlyBox; + root: AvatarRootState; + styleProp: ReadonlyBox; constructor(props: AvatarImageStateProps, root: AvatarRootState) { this.root = root; @@ -110,8 +111,8 @@ type AvatarFallbackStateProps = ReadonlyBoxedValues<{ }>; class AvatarFallbackState { - root = undefined as unknown as AvatarRootState; - styleProp = undefined as unknown as ReadonlyBox; + root: AvatarRootState; + styleProp: ReadonlyBox; constructor(props: AvatarFallbackStateProps, root: AvatarRootState) { this.styleProp = props.style; diff --git a/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts b/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts index 61017959c..6521b44f4 100644 --- a/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts +++ b/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts @@ -35,9 +35,9 @@ function getCheckboxDataState(checked: boolean | "indeterminate") { } class CheckboxRootState { - checked = undefined as unknown as Box; - disabled = undefined as unknown as ReadonlyBox; - required = undefined as unknown as ReadonlyBox; + checked: Box; + disabled: ReadonlyBox; + required: ReadonlyBox; name: ReadonlyBox; value: ReadonlyBox; #onclickProp = boxedState(readonlyBox(() => () => {})); @@ -96,7 +96,7 @@ class CheckboxRootState { */ class CheckboxIndicatorState { - root = undefined as unknown as CheckboxRootState; + root: CheckboxRootState; constructor(root: CheckboxRootState) { this.root = root; @@ -116,13 +116,16 @@ class CheckboxIndicatorState { */ class CheckboxInputState { - root = undefined as unknown as CheckboxRootState; - shouldRender = $derived(this.root.name.value !== undefined); + root: CheckboxRootState; constructor(root: CheckboxRootState) { this.root = root; } + get shouldRender() { + return this.root.name.value !== undefined; + } + get props() { return { type: "checkbox", diff --git a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts index cd72d6447..56bfebd0a 100644 --- a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts +++ b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts @@ -25,8 +25,8 @@ type CollapsibleRootStateProps = BoxedValues<{ }>; class CollapsibleRootState { - open = undefined as unknown as Box; - disabled = undefined as unknown as ReadonlyBox; + open: Box; + disabled: ReadonlyBox; contentId = readonlyBoxedState(generateId()); constructor(props: CollapsibleRootStateProps) { @@ -62,15 +62,14 @@ type CollapsibleContentStateProps = ReadonlyBoxedValues<{ }>; class CollapsibleContentState { - root = undefined as unknown as CollapsibleRootState; - #originalStyles: { transitionDuration: string; animationName: string } | undefined = undefined; - #styleProp = undefined as unknown as ReadonlyBox; + root: CollapsibleRootState; + #originalStyles: { transitionDuration: string; animationName: string } | undefined; + #styleProp: ReadonlyBox; node = boxedState(null); #isMountAnimationPrevented = $state(false); #width = $state(0); #height = $state(0); - #forceMount = undefined as unknown as ReadonlyBox; - present = $derived(this.#forceMount.value || this.root.open.value); + #forceMount: ReadonlyBox; constructor(props: CollapsibleContentStateProps, root: CollapsibleRootState) { this.root = root; @@ -123,6 +122,10 @@ class CollapsibleContentState { }); } + get present() { + return this.#forceMount.value || this.root.open.value; + } + get props() { return { id: this.root.contentId.value, @@ -143,7 +146,7 @@ type CollapsibleTriggerStateProps = ReadonlyBoxedValues<{ }>; class CollapsibleTriggerState { - #root = undefined as unknown as CollapsibleRootState; + #root: CollapsibleRootState; #onclickProp = boxedState(readonlyBox(() => () => {})); constructor(props: CollapsibleTriggerStateProps, root: CollapsibleRootState) { diff --git a/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts b/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts index 7ff45d201..1b86628d8 100644 --- a/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts +++ b/packages/bits-ui/src/lib/bits/progress/progress.svelte.ts @@ -6,8 +6,8 @@ type ProgressRootStateProps = ReadonlyBoxedValues<{ }>; class ProgressRootState { - #value = undefined as unknown as ProgressRootStateProps["value"]; - #max = undefined as unknown as ProgressRootStateProps["max"]; + #value: ProgressRootStateProps["value"]; + #max: ProgressRootStateProps["max"]; constructor(props: ProgressRootStateProps) { this.#value = props.value; diff --git a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts index 0c4f65648..f807a5850 100644 --- a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts +++ b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts @@ -25,14 +25,14 @@ type RadioGroupRootStateProps = ReadonlyBoxedValues<{ BoxedValues<{ value: string }>; class RadioGroupRootState { - id = undefined as unknown as RadioGroupRootStateProps["id"]; + id: RadioGroupRootStateProps["id"]; node = boxedState(null); - disabled = undefined as unknown as RadioGroupRootStateProps["disabled"]; - required = undefined as unknown as RadioGroupRootStateProps["required"]; - loop = undefined as unknown as RadioGroupRootStateProps["loop"]; - orientation = undefined as unknown as RadioGroupRootStateProps["orientation"]; - name = undefined as unknown as RadioGroupRootStateProps["name"]; - value = undefined as unknown as RadioGroupRootStateProps["value"]; + disabled: RadioGroupRootStateProps["disabled"]; + required: RadioGroupRootStateProps["required"]; + loop: RadioGroupRootStateProps["loop"]; + orientation: RadioGroupRootStateProps["orientation"]; + name: RadioGroupRootStateProps["name"]; + value: RadioGroupRootStateProps["value"]; constructor(props: RadioGroupRootStateProps) { this.id = props.id; @@ -96,13 +96,11 @@ type RadioGroupItemStateProps = ReadonlyBoxedValues<{ }>; class RadioGroupItemState { - #id = undefined as unknown as RadioGroupItemStateProps["id"]; + #id: RadioGroupItemStateProps["id"]; #node = boxedState(null); - #root = undefined as unknown as RadioGroupRootState; - #disabled = undefined as unknown as RadioGroupItemStateProps["disabled"]; - #value = undefined as unknown as RadioGroupItemStateProps["value"]; - #isDisabled = $derived(this.#disabled.value || this.#root.disabled.value); - #isChecked = $derived(this.#root.isChecked(this.#value.value)); + #root: RadioGroupRootState; + #disabled: RadioGroupItemStateProps["disabled"]; + #value: RadioGroupItemStateProps["value"]; #onclickProp = boxedState(readonlyBox(() => () => {})); #onkeydownProp = boxedState(readonlyBox(() => () => {})); @@ -169,6 +167,14 @@ class RadioGroupItemState { } }); + get #isDisabled() { + return this.#disabled.value || this.#root.disabled.value; + } + + get #isChecked() { + return this.#root.isChecked(this.#value.value); + } + get props() { return { disabled: this.#isDisabled ? true : undefined, From c83b8ef6de5aea40912eab1aeea26cf7cfd01b8c Mon Sep 17 00:00:00 2001 From: anatolzak <53095479+anatolzak@users.noreply.github.com> Date: Wed, 17 Apr 2024 13:31:43 +0300 Subject: [PATCH 4/7] simplify composing event handlers --- .../lib/bits/accordion/accordion.svelte.ts | 22 +++++++++---------- .../src/lib/bits/checkbox/checkbox.svelte.ts | 20 ++++++++--------- .../bits/collapsible/collapsible.svelte.ts | 10 ++++----- .../src/lib/bits/label/label.svelte.ts | 12 +++++----- .../bits/radio-group/radio-group.svelte.ts | 19 +++++++++------- packages/bits-ui/src/lib/internal/events.ts | 6 ++--- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts index 897829ca3..c0f914a0e 100644 --- a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts +++ b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts @@ -179,18 +179,16 @@ class AccordionTriggerState { #node = boxedState(null); #root: AccordionState; #itemState: AccordionItemState; - #onclickProp = boxedState(readonlyBox(() => () => {})); - #onkeydownProp = boxedState( - readonlyBox(() => () => {}) - ); + #composedClick: EventCallback; + #composedKeydown: EventCallback; constructor(props: AccordionTriggerStateProps, itemState: AccordionItemState) { this.#disabled = props.disabled; this.#itemState = itemState; this.#root = itemState.root; - this.#onclickProp.value = props.onclick; - this.#onkeydownProp.value = props.onkeydown; this.#id = props.id; + this.#composedClick = composeHandlers(props.onclick, this.#onclick); + this.#composedKeydown = composeHandlers(props.onkeydown, this.#onkeydown); useNodeById(this.#id, this.#node); } @@ -199,12 +197,12 @@ class AccordionTriggerState { return this.#disabled.value || this.#itemState.disabled.value || this.#root.disabled.value; } - #onclick = composeHandlers(this.#onclickProp, () => { + #onclick = () => { if (this.#isDisabled) return; this.#itemState.updateValue(); - }); + }; - #onkeydown = composeHandlers(this.#onkeydownProp, (e: KeyboardEvent) => { + #onkeydown = (e: KeyboardEvent) => { const handledKeys = [kbd.ARROW_DOWN, kbd.ARROW_UP, kbd.HOME, kbd.END, kbd.SPACE, kbd.ENTER]; if (this.#isDisabled || !handledKeys.includes(e.key)) return; @@ -230,7 +228,7 @@ class AccordionTriggerState { }; candidateItems[keyToIndex[e.key]!]?.focus(); - }); + }; get props() { return { @@ -243,8 +241,8 @@ class AccordionTriggerState { "data-state": getDataOpenClosed(this.#itemState.isSelected), "data-accordion-trigger": "", // - onclick: this.#onclick, - onkeydown: this.#onkeydown, + onclick: this.#composedClick, + onkeydown: this.#composedKeydown, } as const; } } diff --git a/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts b/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts index 6521b44f4..6ad8d9cc4 100644 --- a/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts +++ b/packages/bits-ui/src/lib/bits/checkbox/checkbox.svelte.ts @@ -40,8 +40,8 @@ class CheckboxRootState { required: ReadonlyBox; name: ReadonlyBox; value: ReadonlyBox; - #onclickProp = boxedState(readonlyBox(() => () => {})); - #onkeydownProp = boxedState(readonlyBox(() => () => {})); + #composedClick: EventCallback; + #composedKeydown: EventCallback; constructor(props: CheckboxRootStateProps) { this.checked = props.checked; @@ -49,22 +49,22 @@ class CheckboxRootState { this.required = props.required; this.name = props.name; this.value = props.value; - this.#onclickProp.value = props.onclick; - this.#onkeydownProp.value = props.onkeydown; + this.#composedClick = composeHandlers(props.onclick, this.#onclick); + this.#composedKeydown = composeHandlers(props.onkeydown, this.#onkeydown); } - #onkeydown = composeHandlers(this.#onkeydownProp, (e) => { + #onkeydown = (e: KeyboardEvent) => { if (e.key === kbd.ENTER) e.preventDefault(); - }); + }; - #onclick = composeHandlers(this.#onclickProp, () => { + #onclick = () => { if (this.disabled.value) return; if (this.checked.value === "indeterminate") { this.checked.value = true; return; } this.checked.value = !this.checked.value; - }); + }; createIndicator() { return new CheckboxIndicatorState(this); @@ -85,8 +85,8 @@ class CheckboxRootState { "data-checkbox-root": "", disabled: this.disabled.value, // - onclick: this.#onclick, - onkeydown: this.#onkeydown, + onclick: this.#composedClick, + onkeydown: this.#composedKeydown, } as const; } } diff --git a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts index 56bfebd0a..c8889f240 100644 --- a/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts +++ b/packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts @@ -147,16 +147,16 @@ type CollapsibleTriggerStateProps = ReadonlyBoxedValues<{ class CollapsibleTriggerState { #root: CollapsibleRootState; - #onclickProp = boxedState(readonlyBox(() => () => {})); + #composedClick: EventCallback; constructor(props: CollapsibleTriggerStateProps, root: CollapsibleRootState) { this.#root = root; - this.#onclickProp.value = props.onclick; + this.#composedClick = composeHandlers(props.onclick, this.#onclick); } - #onclick = composeHandlers(this.#onclickProp, () => { + #onclick = () => { this.#root.toggleOpen(); - }); + }; get props() { return { @@ -168,7 +168,7 @@ class CollapsibleTriggerState { disabled: this.#root.disabled.value, "data-collapsible-trigger": "", // - onclick: this.#onclick, + onclick: this.#composedClick, } as const; } } diff --git a/packages/bits-ui/src/lib/bits/label/label.svelte.ts b/packages/bits-ui/src/lib/bits/label/label.svelte.ts index bc6c74057..1c1c1083b 100644 --- a/packages/bits-ui/src/lib/bits/label/label.svelte.ts +++ b/packages/bits-ui/src/lib/bits/label/label.svelte.ts @@ -1,4 +1,4 @@ -import { type ReadonlyBoxedValues, boxedState, readonlyBox } from "$lib/internal/box.svelte.js"; +import type { ReadonlyBoxedValues } from "$lib/internal/box.svelte.js"; import { type EventCallback, composeHandlers } from "$lib/internal/events.js"; type LabelRootStateProps = ReadonlyBoxedValues<{ @@ -6,19 +6,19 @@ type LabelRootStateProps = ReadonlyBoxedValues<{ }>; class LabelRootState { - #onmousedownProp = boxedState(readonlyBox(() => () => {})); + #composedMousedown: EventCallback; constructor(props: LabelRootStateProps) { - this.#onmousedownProp.value = props.onmousedown; + this.#composedMousedown = composeHandlers(props.onmousedown, this.#onmousedown); } - #onmousedown = composeHandlers(this.#onmousedownProp, (e) => { + #onmousedown = (e: MouseEvent) => { if (e.detail > 1) e.preventDefault(); - }); + }; get props() { return { - onmousedown: this.#onmousedown, + onmousedown: this.#composedMousedown, }; } } diff --git a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts index f807a5850..931009d59 100644 --- a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts +++ b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts @@ -101,8 +101,8 @@ class RadioGroupItemState { #root: RadioGroupRootState; #disabled: RadioGroupItemStateProps["disabled"]; #value: RadioGroupItemStateProps["value"]; - #onclickProp = boxedState(readonlyBox(() => () => {})); - #onkeydownProp = boxedState(readonlyBox(() => () => {})); + #composedClick: EventCallback; + #composedKeydown: EventCallback; constructor(props: RadioGroupItemStateProps, root: RadioGroupRootState) { this.#disabled = props.disabled; @@ -110,14 +110,17 @@ class RadioGroupItemState { this.#root = root; this.#id = props.id; + this.#composedClick = composeHandlers(props.onclick, this.#onclick); + this.#composedKeydown = composeHandlers(props.onkeydown, this.#onkeydown); + useNodeById(this.#id, this.#node); } - onclick = composeHandlers(this.#onclickProp, () => { + #onclick = () => { this.#root.selectValue(this.#value.value); - }); + }; - onkeydown = composeHandlers(this.#onkeydownProp, (e) => { + #onkeydown = (e: KeyboardEvent) => { if (!this.#root.node.value || !this.#node.value) return; const items = this.#root.getRadioItemNodes(); if (!items.length) return; @@ -165,7 +168,7 @@ class RadioGroupItemState { itemToFocus.focus(); this.#root.selectValue(itemToFocus.dataset.value as string); } - }); + }; get #isDisabled() { return this.#disabled.value || this.#root.disabled.value; @@ -187,8 +190,8 @@ class RadioGroupItemState { type: "button", role: "radio", // - onclick, - onkeydown, + onclick: this.#composedClick, + onkeydown: this.#composedKeydown, } as const; } } diff --git a/packages/bits-ui/src/lib/internal/events.ts b/packages/bits-ui/src/lib/internal/events.ts index ca4402ee8..c80e75444 100644 --- a/packages/bits-ui/src/lib/internal/events.ts +++ b/packages/bits-ui/src/lib/internal/events.ts @@ -1,5 +1,5 @@ import { createEventDispatcher } from "svelte"; -import type { Box, ReadonlyBox } from "./box.svelte.js"; +import type { ReadonlyBox } from "./box.svelte.js"; type MeltEvent = { detail: { @@ -41,7 +41,7 @@ export type EventCallback ) => void; export function composeHandlers( - ...handlers: Array | Box>> | undefined> + ...handlers: Array | ReadonlyBox> | undefined> ): (e: E & { currentTarget: EventTarget & T }) => void { return function (this: T, e: E & { currentTarget: EventTarget & T }) { for (const handler of handlers) { @@ -49,7 +49,7 @@ export function composeHandlers Date: Wed, 17 Apr 2024 13:42:20 +0300 Subject: [PATCH 5/7] accordion: use store instead of box where possible --- .../src/lib/bits/accordion/accordion.svelte.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts index c0f914a0e..d6c911297 100644 --- a/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts +++ b/packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts @@ -263,8 +263,8 @@ class AccordionContentState { #id: ReadonlyBox; #originalStyles: { transitionDuration: string; animationName: string } | undefined = undefined; #isMountAnimationPrevented = false; - #width = boxedState(0); - #height = boxedState(0); + #width = $state(0); + #height = $state(0); #forceMount: ReadonlyBox; #styleProp: ReadonlyBox; @@ -306,8 +306,8 @@ class AccordionContentState { node.style.animationName = "none"; const rect = node.getBoundingClientRect(); - this.#height.value = rect.height; - this.#width.value = rect.width; + this.#height = rect.height; + this.#width = rect.width; // unblock any animations/transitions that were originally set if not the initial render if (!this.#isMountAnimationPrevented) { @@ -332,8 +332,8 @@ class AccordionContentState { "data-accordion-content": "", style: styleToString({ ...this.#styleProp.value, - "--bits-accordion-content-height": `${this.#height.value}px`, - "--bits-accordion-content-width": `${this.#width.value}px`, + "--bits-accordion-content-height": `${this.#height}px`, + "--bits-accordion-content-width": `${this.#width}px`, }), } as const; } From 2a438b42ec82b0a1a5f38d9eeeebe33f73cd0bf4 Mon Sep 17 00:00:00 2001 From: anatolzak <53095479+anatolzak@users.noreply.github.com> Date: Wed, 17 Apr 2024 13:59:43 +0300 Subject: [PATCH 6/7] radio group: slice code in half :) --- .../bits/radio-group/radio-group.svelte.ts | 48 ++++++------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts index 931009d59..702a5b656 100644 --- a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts +++ b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts @@ -130,44 +130,26 @@ class RadioGroupItemState { const dir = getElemDirection(this.#root.node.value); const { nextKey, prevKey } = getDirectionalKeys(dir, this.#root.orientation.value); - let itemToFocus: HTMLElement | undefined; const loop = this.#root.loop.value; - const keyMap = { - [nextKey]: () => { - e.preventDefault(); - const nextIndex = currentIndex + 1; - if (nextIndex >= items.length && loop) { - itemToFocus = items[0]; - } else { - itemToFocus = items[nextIndex]; - } - }, - [prevKey]: () => { - e.preventDefault(); - const prevIndex = currentIndex - 1; - if (prevIndex < 0 && loop) { - itemToFocus = items[items.length - 1]; - } else { - itemToFocus = items[prevIndex]; - } - }, - [kbd.HOME]: () => { - e.preventDefault(); - itemToFocus = items[0]; - }, - [kbd.END]: () => { - e.preventDefault(); - itemToFocus = items[items.length - 1]; - }, + const keyToIndex = { + [nextKey]: currentIndex + 1, + [prevKey]: currentIndex - 1, + [kbd.HOME]: 0, + [kbd.END]: items.length - 1, }; - keyMap[e.key]?.(); + let itemIndex = keyToIndex[e.key]; + if (itemIndex === undefined) return; + e.preventDefault(); - if (itemToFocus) { - itemToFocus.focus(); - this.#root.selectValue(itemToFocus.dataset.value as string); - } + if (itemIndex < 0 && loop) itemIndex = items.length - 1; + else if (itemIndex === items.length && loop) itemIndex = 0; + + const itemToFocus = items[itemIndex]; + if (!itemToFocus) return; + itemToFocus.focus(); + this.#root.selectValue(itemToFocus.dataset.value as string); }; get #isDisabled() { From 1fad00203eba92c23b41aeea5c71e728fc0de443 Mon Sep 17 00:00:00 2001 From: anatolzak <53095479+anatolzak@users.noreply.github.com> Date: Wed, 17 Apr 2024 14:00:10 +0300 Subject: [PATCH 7/7] remove unused import --- packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts index 702a5b656..6df279181 100644 --- a/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts +++ b/packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts @@ -4,7 +4,6 @@ import { type BoxedValues, type ReadonlyBoxedValues, boxedState, - readonlyBox, } from "$lib/internal/box.svelte.js"; import { useNodeById } from "$lib/internal/elements.svelte.js"; import { type EventCallback, composeHandlers } from "$lib/internal/events.js";