diff --git a/.changeset/fifty-stingrays-flash.md b/.changeset/fifty-stingrays-flash.md new file mode 100644 index 000000000..7cfa936fc --- /dev/null +++ b/.changeset/fifty-stingrays-flash.md @@ -0,0 +1,5 @@ +--- +"bits-ui": patch +--- + +fix: toolbar onValueChange firing diff --git a/packages/bits-ui/src/lib/bits/toolbar/components/toolbar-group.svelte b/packages/bits-ui/src/lib/bits/toolbar/components/toolbar-group.svelte index 3f61f6d20..56755dbd1 100644 --- a/packages/bits-ui/src/lib/bits/toolbar/components/toolbar-group.svelte +++ b/packages/bits-ui/src/lib/bits/toolbar/components/toolbar-group.svelte @@ -2,6 +2,7 @@ import { melt } from "@melt-ui/svelte"; import { setGroupCtx } from "../ctx.js"; import type { GroupProps } from "../index.js"; + import { arraysAreEqual } from "$lib/internal/arrays.js"; type T = $$Generic<"single" | "multiple">; type $$Props = GroupProps; @@ -24,8 +25,11 @@ defaultValue: value, onValueChange: (({ next }: { next: $$Props["value"] }) => { if (Array.isArray(next)) { - onValueChange?.(next); - value = next; + if (!Array.isArray(value) || !arraysAreEqual(value, next)) { + onValueChange?.(next); + value = next; + return next; + } return next; } @@ -39,7 +43,8 @@ const attrs = getAttrs("group"); - $: value !== undefined && localValue.set(value); + $: value !== undefined && + localValue.set(Array.isArray(value) ? ([...value] as $$Props["value"]) : (value as any)); $: updateOption("disabled", disabled); $: updateOption("type", type); diff --git a/packages/bits-ui/src/tests/toolbar/Toolbar.spec.ts b/packages/bits-ui/src/tests/toolbar/Toolbar.spec.ts index 26f3aaa98..26403abfe 100644 --- a/packages/bits-ui/src/tests/toolbar/Toolbar.spec.ts +++ b/packages/bits-ui/src/tests/toolbar/Toolbar.spec.ts @@ -205,9 +205,6 @@ describe("toolbar", () => { singleProps: { onValueChange: singleOnValueChange }, }); - expect(newMultipleValue).toStrictEqual(["bold"]); - expect(newSingleValue).toBe(undefined); - await user.click(groupMultipleItemStrikethrough); expect(newMultipleValue).toStrictEqual(["bold", "strikethrough"]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8305e378e..17f588af9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -130,6 +130,9 @@ importers: specifier: workspace:* version: link:../../packages/bits-ui devDependencies: + '@melt-ui/pp': + specifier: ^0.3.0 + version: 0.3.0(@melt-ui/svelte@0.76.2)(svelte@4.2.12) '@prettier/sync': specifier: 0.3.0 version: 0.3.0(prettier@3.2.5) @@ -752,10 +755,6 @@ packages: peerDependencies: '@effect-ts/otel-node': '*' peerDependenciesMeta: - '@effect-ts/core': - optional: true - '@effect-ts/otel': - optional: true '@effect-ts/otel-node': optional: true dependencies: diff --git a/sites/docs/package.json b/sites/docs/package.json index 219e4d7fb..d78a3ea71 100644 --- a/sites/docs/package.json +++ b/sites/docs/package.json @@ -15,6 +15,7 @@ "check": "pnpm build:content && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" }, "devDependencies": { + "@melt-ui/pp": "^0.3.0", "@prettier/sync": "0.3.0", "@sveltejs/adapter-cloudflare": "^4.2.0", "@sveltejs/kit": "^2.5.0", diff --git a/sites/docs/svelte.config.js b/sites/docs/svelte.config.js index 86657c83e..0bbca6cdd 100644 --- a/sites/docs/svelte.config.js +++ b/sites/docs/svelte.config.js @@ -3,6 +3,7 @@ import url from "node:url"; import adapter from "@sveltejs/adapter-cloudflare"; import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; import { mdsx } from "mdsx"; +import { preprocessMeltUI, sequence } from "@melt-ui/pp"; import { mdsxConfig } from "./mdsx.config.js"; const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); @@ -11,13 +12,16 @@ const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); const config = { preprocess: [ mdsx(mdsxConfig), - vitePreprocess({ - style: { - css: { - postcss: path.join(__dirname, "postcss.config.cjs"), + sequence([ + vitePreprocess({ + style: { + css: { + postcss: path.join(__dirname, "postcss.config.cjs"), + }, }, - }, - }), + }), + preprocessMeltUI(), + ]), ], extensions: [".svelte", ".md"],