UNPKG

1.87 kBJavaScriptView Raw
1import { isPrimitive, typeOf } from "./helpers.js"
2
3const pascalToKebab = (string) =>
4 string.replace(/[\w]([A-Z])/g, function (m) {
5 return m[0] + "-" + m[1].toLowerCase()
6 })
7
8const kebabToPascal = (string) =>
9 string.replace(/[\w]-([\w])/g, function (m) {
10 return m[0] + m[2].toUpperCase()
11 })
12
13const parseStyles = (value) => {
14 let type = typeof value
15
16 if (type === "string")
17 return value.split(";").reduce((o, value) => {
18 const [k, v] = value.split(":").map((v) => v.trim())
19 if (k) o[k] = v
20 return o
21 }, {})
22
23 if (type === "object") return value
24
25 return {}
26}
27
28const joinStyles = (value) =>
29 Object.entries(value)
30 .map(([k, v]) => `${k}: ${v};`)
31 .join(" ")
32
33const convertStyles = (o) =>
34 Object.keys(o).reduce((a, k) => {
35 a[pascalToKebab(k)] = o[k]
36 return a
37 }, {})
38
39export const applyAttribute = (node, name, value) => {
40 if (name === "style") {
41 value = joinStyles(
42 convertStyles({
43 ...parseStyles(node.getAttribute("style")),
44 ...parseStyles(value),
45 })
46 )
47 } else if (name === "class") {
48 switch (typeOf(value)) {
49 case "Array":
50 value = value.join(" ")
51 break
52 case "Object":
53 value = Object.keys(value)
54 .reduce((a, k) => {
55 if (value[k]) a.push(k)
56 return a
57 }, [])
58 .join(" ")
59 break
60 }
61 } else if (!isPrimitive(value)) {
62 return (node[kebabToPascal(name)] = value)
63 }
64
65 name = pascalToKebab(name)
66
67 if (typeof value === "boolean") {
68 if (name.startsWith("aria-")) {
69 value = "" + value
70 } else if (value) {
71 value = ""
72 }
73 }
74
75 let current = node.getAttribute(name)
76
77 if (value === current) return
78
79 if (typeof value === "string" || typeof value === "number") {
80 node.setAttribute(name, value)
81 } else {
82 node.removeAttribute(name)
83 }
84}