timepiece/node_modules/lit-html/node/development/directives/class-map.js

94 lines
3.4 KiB
JavaScript
Raw Normal View History

2024-05-14 14:54:12 +00:00
import { noChange } from '../lit-html.js';
import { directive, Directive, PartType } from '../directive.js';
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
class ClassMapDirective extends Directive {
constructor(partInfo) {
var _a;
super(partInfo);
if (partInfo.type !== PartType.ATTRIBUTE ||
partInfo.name !== 'class' ||
((_a = partInfo.strings) === null || _a === void 0 ? void 0 : _a.length) > 2) {
throw new Error('`classMap()` can only be used in the `class` attribute ' +
'and must be the only part in the attribute.');
}
}
render(classInfo) {
// Add spaces to ensure separation from static classes
return (' ' +
Object.keys(classInfo)
.filter((key) => classInfo[key])
.join(' ') +
' ');
}
update(part, [classInfo]) {
var _a, _b;
// Remember dynamic classes on the first render
if (this._previousClasses === undefined) {
this._previousClasses = new Set();
if (part.strings !== undefined) {
this._staticClasses = new Set(part.strings
.join(' ')
.split(/\s/)
.filter((s) => s !== ''));
}
for (const name in classInfo) {
if (classInfo[name] && !((_a = this._staticClasses) === null || _a === void 0 ? void 0 : _a.has(name))) {
this._previousClasses.add(name);
}
}
return this.render(classInfo);
}
const classList = part.element.classList;
// Remove old classes that no longer apply
// We use forEach() instead of for-of so that we don't require down-level
// iteration.
this._previousClasses.forEach((name) => {
if (!(name in classInfo)) {
classList.remove(name);
this._previousClasses.delete(name);
}
});
// Add or remove classes based on their classMap value
for (const name in classInfo) {
// We explicitly want a loose truthy check of `value` because it seems
// more convenient that '' and 0 are skipped.
const value = !!classInfo[name];
if (value !== this._previousClasses.has(name) &&
!((_b = this._staticClasses) === null || _b === void 0 ? void 0 : _b.has(name))) {
if (value) {
classList.add(name);
this._previousClasses.add(name);
}
else {
classList.remove(name);
this._previousClasses.delete(name);
}
}
}
return noChange;
}
}
/**
* A directive that applies dynamic CSS classes.
*
* This must be used in the `class` attribute and must be the only part used in
* the attribute. It takes each property in the `classInfo` argument and adds
* the property name to the element's `classList` if the property value is
* truthy; if the property value is falsey, the property name is removed from
* the element's `class`.
*
* For example `{foo: bar}` applies the class `foo` if the value of `bar` is
* truthy.
*
* @param classInfo
*/
const classMap = directive(ClassMapDirective);
export { classMap };
//# sourceMappingURL=class-map.js.map