diff --git a/.changeset/eighty-llamas-refuse.md b/.changeset/eighty-llamas-refuse.md new file mode 100644 index 000000000..83a9a2bcc --- /dev/null +++ b/.changeset/eighty-llamas-refuse.md @@ -0,0 +1,5 @@ +--- +'@lion/ui': patch +--- + +[core] SlotMixin: allow rerenders of templates diff --git a/packages/ui/components/core/src/SlotMixin.js b/packages/ui/components/core/src/SlotMixin.js index cdc8c9448..d32488c0a 100644 --- a/packages/ui/components/core/src/SlotMixin.js +++ b/packages/ui/components/core/src/SlotMixin.js @@ -6,10 +6,103 @@ import { isTemplateResult } from 'lit/directive-helpers.js'; /** * @typedef {import('../types/SlotMixinTypes.js').SlotMixin} SlotMixin * @typedef {import('../types/SlotMixinTypes.js').SlotsMap} SlotsMap + * @typedef {import('../types/SlotMixinTypes.js').SlotFunctionResult} SlotFunctionResult + * @typedef {import('../types/SlotMixinTypes.js').SlotRerenderObject} SlotRerenderObject * @typedef {import('lit').LitElement} LitElement */ +const isRerenderConfig = (/** @type {SlotFunctionResult} */ o) => + !Array.isArray(o) && typeof o === 'object' && 'template' in o; + /** + * The SlotMixin is made for solving accessibility challenges that inherently come with the usage of shadow dom. + * Until [AOM](https://wicg.github.io/aom/explainer.html) is not in place yet, it is not possible to create relations between different shadow doms. + * The need for this can occur in the following situations: + * 1. a user defined slot + * For instance: + * ` + * + * `. + * + * The label here needs to be connected to the input element that may live in shadow dom. The input needs to have `aria-labelledby="label-id".` + * + * 2. an interplay of multiple nested web components + * For instance: + * ` + * + * + *
Group errror message
+ *
` + * In the case above, all inputs need to be able to refer the error message of their parent + * ` + * In a nutshell: SlotMixin helps you with everything related to rendering light dom (i.e. rendering to slots). + * So that you can build accessible ui components with ease, while delegating all edge cases to SlotMixin. + * Edge cases that it solves: + * - rendering light dom in context of scoped customElementRegistries: we respect the customElementRegistry bound to your ShadowRoot + * - the concept of rerendering based on property effects + * - easily render lit templates + * + * So what does the api look like? SlotMixin can be used like this: + * + * @example + * ```js + * class AccessibleControl extends SlotMixin(LitElement) { + * get slots() { + * return { + * ...super.slots, + * 'my-public-slot': () => document.createElement('input'), + * '_my-private-slot': () => html``; + * '' => () => html`
default slot
`, + * }; + * } + * } + * ``` + * + * ## Private and public slots + * Some elements provide a property/attribute api with a fallback to content projection as a means to provide more advanced html. + * For instance, a simple text label is provided like this: + * `` + * + * A more advanced label can be provided like this: + * ` + * + * ` + * + * In the property/attribute case, SlotMixin adds the `