ITADN

feature: element-based API

#25Opentrusktr 创建于 2024-08-03
T
trusktrcommented
For example, I think it would be easier to use context with *any* custom element system regardless of the authoring experience if users could use elements, because all authoring experiences standardize on HTML. As an example, `solid-element` allows writing custom elements with `function` instead of `class`, so it is impossible to apply a class mixin to a custom element written with `solid-element`. However, providing an element-based API would make context fully agnostic of element authoring patterns. Here's a code sample. This next piece of code is higher up in the tree in some ancestor custom element: ```jsx // Let's assume we're using JSX for templating, but the elements being used as custom elements, // and we're using a function-based custom element authoring library (f.e. solid-element, enhance, etc): customElement('higher-up-element', function () { return <context-provider name="foo-context" value={anyValue}> <any-other-element /> </context-provider> }) ``` Now here's the tree inside of `any-other-element`: ```jsx // Let's assume we're using JSX for templating, but the elements being used as custom elements. // Also for sake of example, this is function-based element f.e. solid-element, enhance, etc customElement('any-other-element', function () { const [fooContext, setFooContext] = createSignal(null) createEffect(() => { // re-runs any time the context changes because fooContext is reactive console.log('foo context', fooContext()) }) return <context-consumer name="foo-context" receive={value => setFooContext(value)}> <div>context value: {fooContext()}</div> </context-provider> }) ``` As we can see by the example, - the end user's ability to use context was not limited to class-based custom elements. - the pattern can even be used with custom elements in any other framework (React, Vue, Svelte, Solid, Angular, etc) whereas the class mixin format can't React example: ```jsx export function MyComponent() { // ... use hooks here ... const [fooContext, setFooContext] = useState(null) return <context-consumer name="foo-context" receive={value => setFooContext(value)}> <div>context value: {fooContext}</div> </context-provider> } ``` etc. Some custom element libraries may ship with their own set of context to make composition and mixing and matching of their features flexible, and regardless if we're in React/Vue/Svelte/etc we'd want to be able to configure and use that custom element library. For example, `foo-context` and `any-other-element` might both come from a library. A user would be able to configure the elements how they see fit: ```jsx // f.e. Preact code: return <context-provider name="foo-context" value={fooValue}> <any-other-element /> <any-other-element /> <any-other-element /> </context-provider> ``` vs ```jsx // f.e. Preact code: return ( <context-provider name="foo-context" value={fooValue1}> <any-other-element /> </context-provider> <context-provider name="foo-context" value={fooValue2}> <any-other-element /> </context-provider> <context-provider name="foo-context" value={fooValue3}> <any-other-element /> </context-provider> ) ``` A custom element library could also abstract it more, as needed, regardless of end user framework: ```vue <!-- f.e. Vue code: --> <template> <foo-context :value="fooValue1"> <any-other-element /> </foo-context> <foo-context :value="fooValue2"> <any-other-element /> <any-other-element /> </foo-context> </template> <script setup>...</script> ```
2 条评论