feature: element-based API
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 条评论