diff --git a/.changeset/light-tomatoes-trade.md b/.changeset/light-tomatoes-trade.md new file mode 100644 index 0000000000..918a534891 --- /dev/null +++ b/.changeset/light-tomatoes-trade.md @@ -0,0 +1,5 @@ +--- +"@zag-js/svelte": patch +--- + +Fix style merging in svelte `mergeProps` diff --git a/packages/frameworks/svelte/src/index.ts b/packages/frameworks/svelte/src/index.ts index 22a1662eb8..396eddcb6c 100644 --- a/packages/frameworks/svelte/src/index.ts +++ b/packages/frameworks/svelte/src/index.ts @@ -1,4 +1,4 @@ -export { mergeProps } from "@zag-js/core" +export { mergeProps } from "./merge-props" export type { ContextFrom, EventFrom, StateFrom } from "@zag-js/core" export { normalizeProps } from "./normalize-props.js" export type { PropTypes } from "./normalize-props.js" diff --git a/packages/frameworks/svelte/src/merge-props.ts b/packages/frameworks/svelte/src/merge-props.ts new file mode 100644 index 0000000000..97e1a20c0e --- /dev/null +++ b/packages/frameworks/svelte/src/merge-props.ts @@ -0,0 +1,34 @@ +import { mergeProps as zagMergeProps } from "@zag-js/core" + +const CSS_REGEX = /((?:--)?(?:\w+-?)+)\s*:\s*([^;]*)/g + +type CSSObject = Record + +const serialize = (style: string): CSSObject => { + const res: Record = {} + let match: RegExpExecArray | null + while ((match = CSS_REGEX.exec(style))) { + res[match[1]!] = match[2]! + } + return res +} + +const css = (style: CSSObject | string | undefined): string => { + if (typeof style === "string") style = serialize(style) + + const mergedString = Object.entries(style as CSSObject) + .map(([key, value]) => `${key}: ${value}`) + .join("; ") + + return mergedString +} + +export function mergeProps(...args: Record[]) { + const merged = zagMergeProps(...args) + + if ("style" in merged) { + merged.style = css(merged.style) + } + + return merged +}