Control flow components for solid-js
npm install solid-ctrl-flow
Contexts of the provided Owner
tsx
const owner = ...;
return <>
...
>
`
$3
Eventually wraps its content into a template if a certain condition is met.
The following code
`tsx
const value = true;
return <>
{c()}}>
CONTENT
>
`
Is equivalent to this
`tsx
return <>
CONTENT
>
`
And if value was falsish, it would have been equivalent to this
`tsx
return <>CONTENT>
`
If you are NOT wrapping the content with a context provider you can set the recycled attribute to true in order to NOT run again the whole content each time its template gets added/removed, in this case the Owner of the content won't be child of the template one
`tsx
return <>
}>
{/ This won't be 2 /}
{useContext(ctx)}
>
`
$3
Allows you to not repeat the same condition across many Match components.
The following code
`tsx
const value = 1;
return <>
One
Two
Default
>
`
Is equivalent to this
`tsx
const value = 1;
return <>
One
Two
Default
>
`
$3
Friendlier version of the Portal.
Example:
`tsx
const e = new Extractor();
return <>
This text will be shown instead of e.Dest
>
`
If a Extractor.Dest has no Extractor.Source to render (Or it isn't inside a Extractor.Joint), it will render whatever you pass inside the children attribute
Componets from different Extractors don't "talk" to each other and there can be more than one source and destinations:
`tsx
const a = new Extractor(), b = new Extractor(), c = new Extractor()
function ProofThatItWorksCrossComponent() {
return <>
0
{/ Sources will be sorted by the "order" attribute before being rendered inside a destination /}
{/ The value defaults to 0 and doesn't need to be an integer /}
1
2
>
}
return <>
{/ No source /}
fb
3
{/ Double destination /}
4
5
{/ No destination /}
6
{/ Inner scope for the "c" extractor /}
7
8
>
`
The output of this code is 1, 5, ~~fb~~, 3, 1, 5, 4, 0, 2, 8, 7, 8.
You can detect the number of destinations available for a given extractor through Extractor.getDestCount()
`tsx
const e = new Extractor();
const [ g, s ] = createSignal(true);
return <>
{void untrack(() => {
// The function is undefined when we're not under an Extractor.Joint
console.log(e.getDestCount); //→ undefined
})}
{untrack(() => {
// The founction is returned by a getter that bounds it to the current context
const f = e.getDestCount!;
return <>
{untrack(() => {
// (This scope is not reactive, so it doesn't know about the destinations that will come up later)
console.log(f()); //→ 0
})}
{untrack(() => {
console.log(f()); //→ 1
})}
{/ This is reactive and will contain the number 2 or 3 depending on g() /}
{JSON.stringify(g())} - {f()}
{untrack(() => {
// Since f() is bound, it will return the destination count of ITS Extractor.Joint, not the closest one
console.log(f()); //→ 3
console.log(e.getDestCount!()); //→ 0
})}
>
})}
>
`
You can use Extractor.SameContextSource to automate the process of using a SameContext inside a Extractor.Source. When in doubt, use Extractor.SameContextSource instead of Extractor.Source
`tsx
const e = new Extractor(), ctx = createContext(1);
return <>
{/ This will contain "1" and "3" /}
{/ This will contain "2" and "3" /}
{useContext(ctx)}
{useContext(ctx)}
>
`
Utility
$3
Calls an Accessor maintaining its reactivity at 1 level
$3
Memoizes the properties of an object
$3
Like splitProps() but passes the every part except the last one to memoProps()`