diff --git a/packages/dom-expressions/src/client.d.ts b/packages/dom-expressions/src/client.d.ts index 0c7c2507..4ae67b79 100644 --- a/packages/dom-expressions/src/client.d.ts +++ b/packages/dom-expressions/src/client.d.ts @@ -30,12 +30,16 @@ export function spread( export function assign(node: Element, props: any, isSVG?: Boolean, skipChildren?: Boolean): void; export function setAttribute(node: Element, name: string, value: string): void; export function setAttributeNS(node: Element, namespace: string, name: string, value: string): void; -export function addEventListener(node: Element, name: string, handler: () => void, delegate: boolean): void; -export function classList( +export function addEventListener( node: Element, - value: { [k: string]: boolean }, - prev?: { [k: string]: boolean } + name: string, + handler: () => void, + delegate: boolean ): void; +type ClassList = + | { [k: string]: boolean } + | (ClassList | string | number | boolean | null | undefined)[]; +export function classList(node: Element, value: ClassList, prev?: { [k: string]: boolean }): void; export function style( node: Element, value: { [k: string]: string }, diff --git a/packages/dom-expressions/src/client.js b/packages/dom-expressions/src/client.js index e52fdc77..d4eef5c9 100644 --- a/packages/dom-expressions/src/client.js +++ b/packages/dom-expressions/src/client.js @@ -84,8 +84,7 @@ export function addEventListener(node, name, handler, delegate) { } export function classList(node, value, prev = {}) { - const classKeys = Object.keys(value), - prevKeys = Object.keys(prev); + const prevKeys = Object.keys(prev); let i, len; for (i = 0, len = prevKeys.length; i < len; i++) { const key = prevKeys[i]; @@ -93,13 +92,28 @@ export function classList(node, value, prev = {}) { toggleClassKey(node, key, false); delete prev[key]; } - for (i = 0, len = classKeys.length; i < len; i++) { - const key = classKeys[i], - classValue = !!value[key]; - if (!key || key === "undefined" || prev[key] === classValue) continue; - toggleClassKey(node, key, classValue); - prev[key] = classValue; - } + (function setClasses(classes) { + if (classes instanceof Array) { + for (const key of classes) { + // classList setting classes for all numbers except for 0 may be + // unexpected behavior, you must explicity omit 0 using `n || false` + if (!key && key !== 0) continue; + if (typeof key === 'object') { // Both objects and arrays + setClasses(key); + continue; + } + toggleClassKey(node, key, true); + prev[key] = true; + } + } else if (typeof classes === 'object') { + for (const [key, enabled] of Object.entries(classes)) { + if (!enabled) continue; + toggleClassKey(node, key, true); + prev[key] = true + } + } + })(value); + return prev; }