Skip to content

Commit eab309e

Browse files
Merge pull request #182 from enhance-dev/state-instanceid-context
State instanceid context
2 parents 867d28d + de194ee commit eab309e

5 files changed

Lines changed: 114 additions & 3 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
title: Context
3+
---
4+
5+
The context object enables passing state to child elements without needing to resort to passing attributes down through multiple elements.
6+
7+
## Set parent context
8+
9+
The context object is passed as a key on the state object. Add data to the context object and it will be available to child elements.
10+
11+
[Follow along by checking out the context demo from GitHub →](https://github.com/enhance-dev/context-demo)
12+
13+
Given this markup you can use the context object to pass state directly to a deeply nested child element. Consider the page structure in the example below:
14+
15+
<doc-code filename="app/pages/index.html">
16+
17+
```html
18+
<context-parent>
19+
<my-container>
20+
<my-container>
21+
<my-container>
22+
<context-heading></context-heading>
23+
</my-container>
24+
</my-container>
25+
</my-container>
26+
</context-parent>
27+
```
28+
29+
</doc-code>
30+
31+
32+
Add a heading key to the context object in the parent element:
33+
34+
<doc-code filename="app/pages/index.html">
35+
36+
```javascript
37+
export default function ContextParent({ html, state }) {
38+
const { context } = state
39+
context.heading = 'Heading set via context'
40+
return html`
41+
<style>
42+
:host {
43+
display: block;
44+
height: 100dvh;
45+
padding-top: 3rem;
46+
text-align: center;
47+
font-family: sans-serif;
48+
}
49+
</style>
50+
<slot></slot>
51+
`
52+
}
53+
```
54+
55+
</doc-code>
56+
57+
Render the heading passed via context in the deeply nested child element:
58+
<doc-code filenam="app/elements/context/heading.mjs">
59+
60+
```javascript
61+
export default function ContextHeading({ html, state }) {
62+
const { context } = state
63+
const { heading='Default heading' } = context
64+
return html`
65+
<style>
66+
:host > h1 {
67+
font-size: 1.5rem;
68+
}
69+
</style>
70+
<h1>${heading}</h1>
71+
`
72+
}
73+
```
74+
75+
</doc-code>
76+
77+

app/docs/md/elements/state/index.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ export default function MyElement ({ html, state }) {
3838

3939
</doc-code>
4040

41-
The state object contains two top level entries:
41+
The state object contains four top level keys:
4242

4343
- `attrs`, which contains all the key value pairs of attributes passed into your custom element’s instance
4444
- `store`, which contains the global state of your Enhance application
45+
- `instanceID`, which is a unique ID per instance of Custom Element
46+
- `context`, which is an Object that can be used to pass state to child elements to avoid prop drilling
4547

46-
These two different entries allow you to work with both basic and complex state in powerful ways without the need for complex abstractions or third party libraries.
48+
These keys allow you to work with both basic and complex state in powerful ways without the need for complex abstractions or third party libraries.
4749

4850
<doc-callout level="none" mark="✏️">
4951

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: Instance ID
3+
---
4+
5+
`instanceID` is a unique identifier that is generated per Custom Element instance. This enables you to differentiate between multiple instances of the same element on a page. It can also be useful when using a string based diffing library like [Morphdom](https://github.com/patrick-steele-idem/morphdom) which keys on unique identifiers to know when to update versus replace an element.
6+
7+
```javascript
8+
export default function MyCard({ html, state }) {
9+
const { attrs={}, instanceID='' } = state
10+
const { content='', heading='' } = attrs
11+
12+
return html`
13+
<figure id="figure-${instanceID}">
14+
<h2>${heading}</h2>
15+
<p>${content}</p>
16+
</figure>
17+
`
18+
}
19+
```
20+
21+
<doc-callout mark="ℹ️">
22+
Pro tip: As in the example above, prefix the id with the element name in order to use the id with multiple child elements.
23+
</doc-callout>

app/docs/nav-data.mjs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,15 @@ export const data = [
8282
path: '/docs/elements/state/',
8383
label: 'State',
8484
hasChildren: true,
85-
items: ['attributes', 'store'],
85+
items: [
86+
'attributes',
87+
'store',
88+
{
89+
slug: 'instance-id',
90+
label: 'Instance ID',
91+
},
92+
'context',
93+
],
8694
},
8795
],
8896
},

scripts/dictionary.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ lowercas(e|ed)
4848
MDN
4949
MDN's
5050
mixi(n|ns)
51+
Morphdom
5152
natively
5253
Netlify
5354
polyfills

0 commit comments

Comments
 (0)