Last active
April 2, 2025 05:15
-
-
Save denilsonsa/4fc1a7bbdf6cfdbd31fe10d22f8e29d1 to your computer and use it in GitHub Desktop.
Mixing Lit v1 and Lit v2/v3 html and css templates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// lit-transition.js | |
// Provides some functions/objects that work on both Lit v1 and Lit v2/v3. | |
// This code is based on this proof-of-concept: https://codepen.io/denilsonsa/pen/dPyWZbY | |
// How to use this code? Use this: | |
// import { multicss as css, multihtml as html, multinothing as nothing } from './lit-transition.js'; | |
// Instead of Lit's own css, html and nothing functions/objects. | |
//////////////////////////////////////////////////////////// | |
import { css as css2, CSSResult as CSSResult2, html as html2 } from 'ing-web/core.js'; | |
/* eslint-disable prefer-rest-params */ | |
// Old-style (Lit v1 and lit-element v2) CSSResult is checked by `instanceof`. | |
// New-style (Lit v2/v3 and lit-element v4) CSSResult is checked by the presence of '_$cssResult$'. | |
// We can build a mixed CSSResult object by making it pass the checks from both versions. | |
// This mixed object works inside `css` from both and new versions. | |
// Returns a CSS template that is compatible with both Lit v1 and Lit v3. | |
export function multicss(strings, ...values) { | |
for (let i = 0; i < values.length; i++) { | |
// If this value is a new-style instance `_$cssResult$`, | |
// but not an old-style instance... | |
if (values[i]._$cssResult$ && !(values[i] instanceof CSSResult2)) { | |
// Change its prototype to the old-style prototype, | |
// while keeping the `_$cssResult$` attribute. | |
Object.setPrototypeOf(values[i], CSSResult2.prototype); | |
} | |
} | |
// Create a new mixed-style object, and return it. | |
const ret = css2.apply(this, [strings, ...values]); | |
ret._$cssResult$ = true; | |
return ret; | |
} | |
// `nothing` is a sentinel object which is checked using `===`. | |
// Since each version has a different object instance representing `nothing`, they will never be equal. | |
// The lit-html code checks against that sentinel and calls `.clear()`. | |
// The same code also calls `.clear()` if the value is an iterable. | |
// Thus, an empty iterable should behave just like `nothing`. | |
// (Should have the same behavior only in the context of element contents/children; | |
// the behavior is certainly different when used in attributes and properties.) | |
export const multinothing = []; | |
// Returns an HTML template that is compatible with both Lit v1 and Lit v3. | |
// | |
// Works for simple HTML templates. | |
// More complex ones may or may not work, depending on how deep they are, and | |
// if they have a mix of plain `html` templates from different versions. | |
export function multihtml() { | |
const ret = html2.apply(this, arguments); | |
ret._$litType$ = 1; // 1 for html, 2 for svg, 3 for MathML | |
return ret; | |
} | |
// A similar approach could be implemented for @lion Validators, | |
// in case someone needs to support multiple @lion/ui versions. | |
// https://github.com/ing-bank/lion/tree/master/packages/ui/components/form-core/src/validate | |
// | |
// The old ValidateMixin.js was checking `v instanceof Validator`, | |
// but the new code in their master branch checks for `validatorCtor['_$isValidator$']`. | |
// | |
// This new check is not yet available in @lion/form-core 0.18.3, but that version is several years old. | |
// This new check is available in @lion/ui 0.8.5 or later. | |
// | |
// https://github.com/ing-bank/lion/commit/9b92fa216eed801f981c24b0708513f571998103 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment