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