A light-weight, fast, and easy-to-use context api for Sinuous.
There are two ways to consume sinuous-context
Run the following inside your project directory:
npm install sinuous-context
Put this into your HTML:
<script src="https://unpkg.com/sinuous-context/dist/min.js"></script>
Be sure you place it below your Sinuous CDN, like this:
<script src="https://unpkg.com/sinuous/dist/all.js"></script>
<script src="https://unpkg.com/sinuous-context/dist/min.js"></script>
This places a sinuousContext
property on the window
object.
There are 3 exports from sinuous-context.
context
: a context of context provider style componentContext
: an alias ofcontext
for those who prefer capitalized component namesgetContext
: a function that returns the context available at the call site's place in the component hierarchy
context
(and Context
) take any arbitrary parameter name and value. Sinuous observables or computed may be passed as values, as can any non-reactive value (strings, numbers, objects, arrays, functions).
For example:
import { context } from "sinuous-context";
function someComponent() {
...
return html`
<${context}
foo=${someFunc}
bar=${someObservable}
baz=${someString}
>
<${someOtherComponent} />
<div>
<${andAnotherComponent} />
</div>
<//>
`;
}
This part is straightforward. Pass a key to getContext
to get a particular value, or pass nothing to get all context available at that part of the tree:
import { getContext } from 'sinuous-context';
function someOtherComponent() {
let fooFunc = getContext('foo'); // someFunc
let barObservable = getContext('bar'); // someObservable
fooFunc();
return html`<p>${barObservable}</p>`;
}
function andAnotherComponent() {
let allContext = getContext();
console.log(allContext);
// { foo: someFunc, bar: someObservable, baz: someString }
return html`...`;
}
As anyone who has used context apis in frameworks like React or Svelte will know, a context api should provide a form a dynamic scope or hierarchical shadowing. sinuous-context does this. For example:
import { html } from 'sinuous';
import { context, getContext } from 'sinuous-context';
export function outerComponent() {
return html`
<${context} a=${10} b=${2}>
<${nested} /> // 20
<${context} b=${4.5}> <${nested} /> // 45 <//>
<//>
`;
}
function nested() {
let allContext = getContext();
return html`<div>${allContext.a * allContext.b}</div>`;
}
If using JSX views with Sinuous, a context
(or Context
) component cannot be at the root of your app. A call to context
returns an update function (like an observable), not a dom node. It must be wrapped in some dom element, like so:
let App = () => {
return (
<div>
<Context>
<Component1 />
<Component2 />
</Context>
</div>
);
};
document.getElementById('app').append(App());
If context
(or Context
) is the only direct child component of a call to html
, html
will return a DocumentFragment
. This should generally pose no issues.
- Author of Sinuous
- The principal code of sinuous-context is taken directly from this codesandbox by Wesley Luyten. The only real changes to this code that sinuous-context brings are changes to the api. As such, this package is hugely indebted to him.