Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support svelte 5.16.0 class value #2142

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 71 additions & 1 deletion packages/frameworks/svelte/src/merge-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,77 @@ const serialize = (style: string): CSSObject => {
return res
}

type ClassValue = ClassValue[] | Record<string, any> | string | number | bigint | null | boolean | undefined

const classValueToString = (mix: ClassValue) => {
let i: any
let j: any

let str = ""

if (typeof mix === "string" || typeof mix === "number") {
str += mix
} else if (typeof mix === "object") {
if (Array.isArray(mix)) {
const len = mix.length

for (i = 0; i < len; i++) {
if (mix[i]) {
if ((j = classValueToString(mix[i]))) {
str && (str += " ")
str += j
}
}
}
} else {
for (j in mix) {
if (mix![j]) {
str && (str += " ")
str += j
}
}
}
}

return str
}

const clsx = (...args: ClassValue[]) => {
let idx = 0
let tmp: ClassValue
let cls: string
let str = ""
let len = args.length

for (; idx < len; idx++) {
if ((tmp = args[idx])) {
if ((cls = classValueToString(tmp))) {
str && (str += " ")
str += cls
}
}
}

return str
}

export function mergeProps(...args: Record<string, any>[]) {
const merged = zagMergeProps(...args)
const copy = args.map((arg) => Object.assign({}, arg))
const classes: ClassValue[] = []

for (const arg of copy) {
if ("class" in arg) {
classes.push(arg.class)
delete arg.class
}

if ("className" in arg) {
classes.push(arg.className)
delete arg.className
}
}

const merged = zagMergeProps(...copy)

if ("style" in merged) {
if (typeof merged.style === "string") {
Expand All @@ -24,5 +93,6 @@ export function mergeProps(...args: Record<string, any>[]) {
merged.style = toStyleString(merged.style)
}

classes.length && (merged.class = clsx(...classes))
return merged
}
16 changes: 10 additions & 6 deletions packages/frameworks/svelte/tests/merge-props.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, it, expect, vi } from "vitest"
import { describe, expect, it, vi } from "vitest"
import { mergeProps } from "../src"

describe("mergeProps for Svelte", () => {
Expand All @@ -10,7 +10,7 @@ describe("mergeProps for Svelte", () => {
const props = mergeProps({ onClick, className, id })

expect(props.onClick).toBe(onClick)
expect(props.className).toBe(className)
expect(props.class).toBe(className)
expect(props.id).toBe(id)
})

Expand All @@ -29,14 +29,18 @@ describe("mergeProps for Svelte", () => {

it("combines css classes", () => {
const className1 = "primary"
const className2 = "hover"
const className3 = "focus"
const className2 = ["hover", { focus: true }, null, undefined]
const className3 = {
md: false,
lg: true,
xl: false,
}

const props = mergeProps({ class: className1 }, { class: className2 }, { class: className3 })
expect(props.class).toBe("primary hover focus")
expect(props.class).toBe("primary hover focus lg")

const props2 = mergeProps({ className: className1 }, { className: className2 }, { className: className3 })
expect(props2.className).toBe("primary hover focus")
expect(props2.class).toBe("primary hover focus lg")
})

it("combines styles", () => {
Expand Down