Skip to content

Commit 3ce5483

Browse files
committed
feat: new docs for 4.42
1 parent 589c18f commit 3ce5483

File tree

114 files changed

+17932
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+17932
-5
lines changed

docs/components/api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Once all the metadata has been collected, all the decorators are removed from th
2525
- [@Listen()](./events.md#listen-decorator) listens for DOM events
2626
- [@AttrDeserialize()](./serialization-deserialization.md#the-attrdeserialize-decorator-attrdeserialize) declares a hook to translate a component's attribute string to its JS property
2727
- [@PropSerialize()](./serialization-deserialization.md#the-propserialize-decorator-propserialize) declares a hook that translates a component's JS property to its attribute string
28+
- [@AttachInternals()](./attach-internals.md) attaches ElementInternals to a component
2829

2930

3031
## Lifecycle hooks
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: Attach Internals
3+
sidebar_label: Attach Internals
4+
description: attach internals decorator
5+
slug: /attach-internals
6+
---
7+
8+
# Attach Internals Decorator
9+
10+
The `@AttachInternals` decorator is used to attach [ElementInternals](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals) to a Stencil component.
11+
This allows you to leverage features such as [Custom States](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet) and [Form Association](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals#form_association).
12+
13+
## Form Association
14+
15+
Read the dedicated guide on [Form Associated Components](./form-associated) and how to use `@AttachInternals` there.
16+
17+
## Custom States
18+
19+
You can use the `@AttachInternals` decorator to define [Custom States](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet) for your component.
20+
21+
```tsx
22+
import { Component, h, AttachInternals } from '@stencil/core';
23+
/**
24+
* My Element component
25+
*/
26+
@Component({
27+
tag: 'my-element',
28+
styleUrl: 'my-element.css',
29+
})
30+
export class MyElement {
31+
@AttachInternals({
32+
states: {
33+
/** A custom state for my element */
34+
'my-custom-state': true,
35+
/** Another custom state for my element */
36+
'another-state': false
37+
}
38+
}) internals: ElementInternals;
39+
render() {
40+
return <div>My Element</div>;
41+
}
42+
}
43+
```
44+
45+
In the example above, we define two custom states: `my-custom-state` and `another-state`.
46+
47+
The initial values of the custom states can be set via the `states` object and
48+
later on, you can update the states dynamically using the `internals.states` property. For example:
49+
50+
```tsx
51+
handleClick() {
52+
this.internals.states.add('another-state'); // to add a state
53+
this.internals.states.delete('my-custom-state'); // to remove a state
54+
}
55+
```
56+
57+
You or your element users can then use custom states in CSS like so:
58+
59+
```css
60+
/* Use them internally... */
61+
:host(:state(my-custom-state)) {
62+
background-color: yellow;
63+
}
64+
/* ... Or use them externally */
65+
my-element:state(another-state) {
66+
border: 2px solid red;
67+
}
68+
```

docs/components/templating-and-jsx.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,23 @@ export class AppHome {
468468

469469
In this example we are using `ref` to get a reference to our input `ref={(el) => this.textInput = el as HTMLInputElement}`. We can then use that ref to do things such as grab the value from the text input directly `this.textInput.value`.
470470

471+
## Explicitly setting attributes or properties
472+
473+
By default, Stencil tries to intelligently determine whether to set an attribute or (more commonly) a property on an element when using JSX.
474+
However, in some cases you may want to explicitly set one or the other. You can do this by using the `attr:` or `prop:` prefixes. For example:
475+
476+
```tsx
477+
<input attr:value="Hello" />
478+
```
479+
480+
will set the `value` attribute on the input element, while:
481+
482+
```tsx
483+
<input prop:value="Hello" />
484+
```
485+
486+
will explicitly set the `value` property on the input element.
487+
471488

472489
## Avoid Shared JSX Nodes
473490

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
title: Docs Custom Elements Manifest Output Target
3+
sidebar_label: CEM (docs-custom-elements-manifest)
4+
description: Custom Elements Manifest
5+
slug: /docs-custom-elements-manifest
6+
---
7+
8+
# Generating Documentation in Custom Elements Manifest (CEM) format
9+
10+
Since Stencil v4.42, Stencil supports automatically generating a [Custom Elements Manifest (CEM)](https://custom-elements-manifest.open-wc.org/)
11+
file in your project. The CEM format is a standardized JSON format for describing
12+
custom elements and is supported by a variety of tools in the web components ecosystem.
13+
14+
15+
```tsx title="stencil.config.ts"
16+
import { Config } from '@stencil/core';
17+
18+
export const config: Config = {
19+
outputTargets: [
20+
{
21+
type: 'docs-custom-elements-manifest',
22+
file: 'path/to/cem.json'
23+
}
24+
]
25+
};
26+
```
27+
28+
The JSON file output by Stencil conforms to the [CEM Schema interface](https://github.com/webcomponents/custom-elements-manifest/blob/main/schema.d.ts).
29+
30+
## Properties, Methods, Events, and Attributes
31+
32+
The CEM output target includes information about your components' properties,
33+
methods, events, and attributes based on the decorators you use in your Stencil
34+
components.
35+
36+
## CSS Properties
37+
38+
Stencil can document CSS variables if you annotate them with JSDoc-style
39+
comments in your CSS/SCSS files. If, for instance, you had a component with a
40+
CSS file like the following:
41+
42+
```css title="src/components/my-button/my-button.css"
43+
:host {
44+
/**
45+
* @prop --background: Background of the button
46+
* @prop --background-activated: Background of the button when activated
47+
* @prop --background-focused: Background of the button when focused
48+
*/
49+
--background: pink;
50+
--background-activated: aqua;
51+
--background-focused: fuchsia;
52+
}
53+
```
54+
55+
Then you'd get the following in the JSON output:
56+
57+
```json title="Example docs-custom-elements-manifest Output"
58+
[
59+
{
60+
"cssProperties": [
61+
{
62+
"name": "background",
63+
"description": "Background of the button"
64+
},
65+
{
66+
"name": "background-activated",
67+
"description": "Background of the button when activated"
68+
},
69+
{
70+
"name": "background-focused",
71+
"description": "Background of the button when focused"
72+
}
73+
]
74+
}
75+
]
76+
```
77+
78+
## Slots
79+
80+
If one of your Stencil components makes use of
81+
[slots](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot) for
82+
rendering children you can document them by using the `@slot` JSDoc tag in the
83+
component's comment.
84+
85+
For instance, if you had a `my-button` component with a slot you might document
86+
it like so:
87+
88+
```tsx title="src/components/my-button/my-button.tsx"
89+
import { Component, h } from '@stencil/core';
90+
91+
/**
92+
* @slot buttonContent - Slot for the content of the button
93+
*/
94+
@Component({
95+
tag: 'my-button',
96+
styleUrl: 'my-button.css',
97+
shadow: true,
98+
})
99+
export class MyButton {
100+
render() {
101+
return <button><slot name="buttonContent"></slot></button>
102+
}
103+
}
104+
```
105+
106+
This would show up in the generated JSON file like so:
107+
108+
```json
109+
"slots": [
110+
{
111+
"name": "buttonContent",
112+
"description": "Slot for the content of the button"
113+
}
114+
]
115+
```
116+
117+
:::caution
118+
Stencil does not check that the slots you document in a component's JSDoc
119+
comment using the `@slot` tag are actually present in the JSX returned by the
120+
component's `render` function.
121+
122+
It is up to you as the component author to ensure the `@slot` tags on a
123+
component are kept up to date.
124+
:::
125+
126+
## Custom States
127+
128+
You can document [Custom States](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet) for your components using the `@AttachInternals` decorator
129+
and JSDoc comments.
130+
131+
For example:
132+
133+
```tsx title="src/components/my-element/my-element.tsx"
134+
import { Component, h, AttachInternals } from '@stencil/core';
135+
/**
136+
* My Element component
137+
*/
138+
@Component({
139+
tag: 'my-element',
140+
styleUrl: 'my-element.css',
141+
shadow: true,
142+
})
143+
export class MyElement {
144+
@AttachInternals({
145+
states: {
146+
new: true,
147+
/** If this item is older than 6 months old. Use via `:state(archived)` */
148+
archived: false
149+
},
150+
}) internals!: ElementInternals;
151+
```
152+
153+
This would show up in the generated JSON file like so:
154+
155+
```json
156+
"customStates": [
157+
{
158+
"name": "new",
159+
"description": ""
160+
},
161+
{
162+
"name": "archived",
163+
"description": "If this item is older than 6 months old. Use via `:state(archived)"
164+
}
165+
]
166+
```
167+
168+
## Demos
169+
170+
You can save demos for a component in the `usage/` subdirectory within
171+
that component's directory. The content of these files will be added to the
172+
`demos` property of the generated JSON. This allows you to keep examples right
173+
next to the code, making it easy to include them in a documentation site or
174+
other downstream consumer(s) of your docs.
175+
176+
:::caution
177+
Stencil doesn't check that your demos are up-to-date! If you make any
178+
changes to your component's API you'll need to remember to update your demos
179+
manually.
180+
:::
181+
182+
If, for instance, you had a usage example like this:
183+
184+
````md title="src/components/my-button/usage/my-button-usage.md"
185+
# How to use `my-button`
186+
187+
A button is often a great help in adding interactivity to an app!
188+
189+
You could use it like this:
190+
191+
```html
192+
<my-button>My Button!</my-button>
193+
```
194+
````
195+
196+
197+
You'd get the following in the JSON output under the `"usage"` key:
198+
199+
```json
200+
"demos": [{
201+
"url": "my-button-usage.md",
202+
"description": "# How to use `my-button`\n\nA button is often a great help in adding interactivity to an app!\n\nYou could use it like this:\n\n```html\n<my-button>My Button!</my-button>\n```\n"
203+
}]
204+
```

docs/documentation-generation/docs-json.md

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ CSS file like the following:
101101
Then you'd get the following in the JSON output:
102102

103103
```json title="Example docs-json Output"
104-
[
104+
"styles": [
105105
{
106106
"name": "--background",
107107
"annotation": "prop",
@@ -184,10 +184,12 @@ export class MyButton {
184184
This would show up in the generated JSON file like so:
185185

186186
```json
187-
"slots": {
188-
"name": "buttonContent",
189-
"docs": "Slot for the content of the button"
190-
}
187+
"slots": [
188+
{
189+
"name": "buttonContent",
190+
"description": "Slot for the content of the button"
191+
}
192+
]
191193
```
192194

193195
:::caution
@@ -199,6 +201,49 @@ It is up to you as the component author to ensure the `@slot` tags on a
199201
component are kept up to date.
200202
:::
201203

204+
## Custom States
205+
206+
You can document [Custom States](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet) for your components using the `@AttachInternals` decorator
207+
and JSDoc comments.
208+
209+
For example:
210+
211+
```tsx title="src/components/my-element/my-element.tsx"
212+
import { Component, h, AttachInternals } from '@stencil/core';
213+
/**
214+
* My Element component
215+
*/
216+
@Component({
217+
tag: 'my-element',
218+
styleUrl: 'my-element.css',
219+
shadow: true,
220+
})
221+
export class MyElement {
222+
@AttachInternals({
223+
states: {
224+
new: true,
225+
/** If this item is older than 6 months old. Use via `:state(archived)` */
226+
archived: false
227+
},
228+
}) internals!: ElementInternals;
229+
```
230+
231+
This would show up in the generated JSON file like so:
232+
233+
```json
234+
"states": [
235+
{
236+
"name": "new",
237+
"initialValue": true,
238+
"description": ""
239+
},
240+
{
241+
"name": "archived",
242+
"initialValue": false,
243+
"description": "If this item is older than 6 months old. Use via `:state(archived)"
244+
}
245+
]
246+
```
202247
203248
## Usage
204249

0 commit comments

Comments
 (0)