/** * @license * Copyright 2018 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ import { noChange } from '../lit-html.js'; import { directive, Directive, PartType, } from '../directive.js'; class StyleMapDirective extends Directive { constructor(partInfo) { var _a; super(partInfo); if (partInfo.type !== PartType.ATTRIBUTE || partInfo.name !== 'style' || ((_a = partInfo.strings) === null || _a === void 0 ? void 0 : _a.length) > 2) { throw new Error('The `styleMap` directive must be used in the `style` attribute ' + 'and must be the only part in the attribute.'); } } render(styleInfo) { return Object.keys(styleInfo).reduce((style, prop) => { const value = styleInfo[prop]; if (value == null) { return style; } // Convert property names from camel-case to dash-case, i.e.: // `backgroundColor` -> `background-color` // Vendor-prefixed names need an extra `-` appended to front: // `webkitAppearance` -> `-webkit-appearance` // Exception is any property name containing a dash, including // custom properties; we assume these are already dash-cased i.e.: // `--my-button-color` --> `--my-button-color` prop = prop .replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, '-$&') .toLowerCase(); return style + `${prop}:${value};`; }, ''); } update(part, [styleInfo]) { const { style } = part.element; if (this._previousStyleProperties === undefined) { this._previousStyleProperties = new Set(); for (const name in styleInfo) { this._previousStyleProperties.add(name); } return this.render(styleInfo); } // Remove old properties that no longer exist in styleInfo // We use forEach() instead of for-of so that re don't require down-level // iteration. this._previousStyleProperties.forEach((name) => { // If the name isn't in styleInfo or it's null/undefined if (styleInfo[name] == null) { this._previousStyleProperties.delete(name); if (name.includes('-')) { style.removeProperty(name); } else { // Note reset using empty string (vs null) as IE11 does not always // reset via null (https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style#setting_styles) // eslint-disable-next-line @typescript-eslint/no-explicit-any style[name] = ''; } } }); // Add or update properties for (const name in styleInfo) { const value = styleInfo[name]; if (value != null) { this._previousStyleProperties.add(name); if (name.includes('-')) { style.setProperty(name, value); } else { // eslint-disable-next-line @typescript-eslint/no-explicit-any style[name] = value; } } } return noChange; } } /** * A directive that applies CSS properties to an element. * * `styleMap` can only be used in the `style` attribute and must be the only * expression in the attribute. It takes the property names in the `styleInfo` * object and adds the property values as CSS properties. Property names with * dashes (`-`) are assumed to be valid CSS property names and set on the * element's style object using `setProperty()`. Names without dashes are * assumed to be camelCased JavaScript property names and set on the element's * style object using property assignment, allowing the style object to * translate JavaScript-style names to CSS property names. * * For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size': * '0'})` sets the `background-color`, `border-top` and `--size` properties. * * @param styleInfo */ export const styleMap = directive(StyleMapDirective); //# sourceMappingURL=style-map.js.map