Skip to content

Commit 3b14a11

Browse files
committed
v2.0.0 🎉
1 parent 9f78e25 commit 3b14a11

15 files changed

Lines changed: 177 additions & 76 deletions

‎dist/van-element.browser.js‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎dist/van-element.js‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎dist/van-element.umd.cjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
(function(s,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("vanjs-core")):typeof define=="function"&&define.amd?define(["exports","vanjs-core"],i):(s=typeof globalThis<"u"?globalThis:s||self,i(s.vanE={},s.van))})(this,function(s,i){"use strict";function o(r,c,n={mode:"open"}){window.customElements.define(r,class extends HTMLElement{constructor(){super(),this.attrs=[]}setAttribute(t,e){super.setAttribute(t,e),this.attrs[t]&&(this.attrs[t].val=e)}connectedCallback(){let t;i.add(n?this.attachShadow(n):this,c({attr:(e,h)=>{var d;return(d=this.attrs)[e]??(d[e]=i.state(this.getAttribute(e)??h))},mount:e=>t=e,$this:this,children:n?i.tags.slot():[...this.childNodes]})),this.dismount=t==null?void 0:t()}disconnectedCallback(){var t;(t=this.dismount)==null||t.call(this)}})}s.define=o,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
1+
(function(s,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("vanjs-core")):typeof define=="function"&&define.amd?define(["exports","vanjs-core"],i):(s=typeof globalThis<"u"?globalThis:s||self,i(s.vanE={},s.van))})(this,function(s,i){"use strict";function c(f,h,a={mode:"open"}){window.customElements.define(f,class extends HTMLElement{constructor(){super(),this.a=[]}setAttribute(e,t){super.setAttribute(e,t),this.a[e]&&(this.a[e].val=t)}connectedCallback(){let e;i.add(a?this.attachShadow(a):this,h({attr:(t,n)=>{var d;return(d=this.a)[t]??(d[t]=i.state(this.getAttribute(t)??n))},mount:t=>{let n=e;e=()=>{let d=n==null?void 0:n(),o=t();return()=>{d==null||d(),o==null||o()}}},$this:this})),this.d=e==null?void 0:e()}disconnectedCallback(){var e;(e=this.d)==null||e.call(this)}})}s.define=c,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});

‎docs/components.ts‎

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import van, { State } from "vanjs-core";
22
import { define } from "../src/van-element";
33

4-
const { button, div, h2, i, input, p, pre, slot, span, style } = van.tags;
4+
const { button, dialog, div, h2, i, input, p, pre, slot, span, style } =
5+
van.tags;
56

67
// Tutorial
78

@@ -275,3 +276,50 @@ define("adopted-style", ({ $this }) => {
275276
return p(slot());
276277
});
277278
// #endregion adoptedStyle
279+
280+
// EXAMPLES
281+
282+
// #region confirmationModal
283+
define("confirmation-modal", ({ attr, $this }) => {
284+
const confirmLabel = attr("confirm");
285+
const cancelLabel = attr("cancel", "Close");
286+
const onConfirm = () => {
287+
modal.close();
288+
$this.dispatchEvent(new Event("submit"));
289+
};
290+
const modal = dialog(
291+
div({ class: "mainContent" }, slot()),
292+
div(
293+
{ class: "actions" },
294+
button({ onclick: () => modal.close() }, cancelLabel),
295+
() => confirmLabel.val && button({ onclick: onConfirm }, confirmLabel.val)
296+
)
297+
);
298+
return [
299+
slot({ name: "trigger", onclick: () => modal.showModal() }),
300+
modal,
301+
// Some styles
302+
style(`
303+
dialog{
304+
padding: 2rem;
305+
}
306+
dialog::backdrop{
307+
backdrop-filter:blur(5px);
308+
}
309+
.mainContent{
310+
text-align: center;
311+
}
312+
.actions{
313+
display: flex;
314+
justify-content: space-around;
315+
}
316+
button{
317+
border:1px solid;
318+
font: inherit;
319+
padding: .5rem 1rem;
320+
background: transparent;
321+
cursor: pointer;
322+
}`),
323+
];
324+
});
325+
// #endregion confirmationModal

‎docs/examples.md‎

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,71 @@
22

33
::: info
44

5-
This page is under construction. In the meantime, visit this [showcase on CodePen](https://codepen.io/atmos4/pen/ZEPEvvB).
6-
7-
The plan is to port all or part of the showcase in here instead.
5+
This page is under construction.
86

97
**Contributions are most welcomed! 🙂**
108

11-
::::
9+
:::
10+
11+
This page will focus on showing more practical examples that reflect real world problems that can find a solution with Van Elements.
12+
13+
These examples were written with the following philosophy:
14+
15+
- most problems involving reactive UIs can be solved with VanJS
16+
- custom elements are a good fit for hydrating reactive logic into the DOM
17+
18+
::: tip
19+
20+
Shadow DOM can be useful for isolating specific styles. Parts that need to be exposed can just live in the slots.
21+
22+
If it gets in the way, just disable it. It is not as big of a deal as you might think.
23+
24+
:::
25+
26+
## 1. Reusable confirmation modal
27+
28+
This example illustrates how to create a self-contained confirmation modal. It uses a few techniques:
29+
30+
- **slots** to populate a custom trigger
31+
- a custom `submit` event that allows to intercept actions from outside the component
32+
- Shadow DOM isolation
33+
34+
<confirmation-modal cancel="No" confirm="Yes" onsubmit="alert('Confirmed')">
35+
<button slot="trigger" style="margin:1rem;padding:.8rem;border:1px solid var(--vp-c-text-1)">Click to confirm</button>
36+
<h3 style="margin:0">Please confirm</h3>
37+
<p>Are you sure you want to do this?</p>
38+
</confirmation-modal>
39+
40+
::: details Code
41+
<<< @/components.ts#confirmationModal {javascript}
42+
:::
43+
44+
```html
45+
<confirmation-modal cancel="No" confirm="Yes" onsubmit="alert('Confirmed')">
46+
<button slot="trigger">Click to confirm</button>
47+
<h3>Confirmation</h3>
48+
<p>Are you sure you want to do this?</p>
49+
</confirmation-modal>
50+
```
51+
52+
Now, thanks to the power of custom element reusability, we can reuse that confirmation modal anywhere, with custom text and actions.
53+
54+
<confirmation-modal>
55+
<button slot="trigger" style="margin:1rem;padding:.8rem;border:1px solid var(--vp-c-text-1)">Open tip 💡</button>
56+
<b>Tip of the day</b>
57+
<p>Eat vegetables to stay healthy</p>
58+
</confirmation-modal>
59+
60+
```html
61+
<confirmation-modal>
62+
<button slot="trigger">Open tip 💡</button>
63+
<b>Tip of the day</b>
64+
<p>Eat vegetables to stay healthy</p>
65+
</confirmation-modal>
66+
```
67+
68+
## 2. Normal VanJS code
69+
70+
Van Element is just a way to hydrate VanJS. So you could simply take your VanJS code and bind it to a custom element tag, and Van Element will put it in the DOM for you!
71+
72+
As an example, let's shamefully take

‎docs/intro/tutorial.md‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ My first Van Element: <hello-world></hello-world>
2323
My first Van Element: <hello-world>Hello world</hello-world>
2424
</fieldset>
2525

26-
## Slots and children
26+
## Slots
2727

28-
The first property you can use inside Van Elements is `children`. Under the hood, it's actually a `slot` tag!
28+
Let's add children to our Van element. We can use the `slot` for this.
2929

3030
```js
31-
define("hello-world", ({ children }) =>
32-
span({ style: "color:red;font-size:20px" }, children /* or slot() */)
31+
const { span, slot } = van.tags;
32+
33+
define("hello-world", () =>
34+
span({ style: "color:red;font-size:20px" }, slot())
3335
);
3436
```
3537

@@ -53,15 +55,15 @@ It would be nice if we can change `color` and `font-size` from outside the Van E
5355
Meet the first property provided by Van Element: `attr()`. It takes an attribute name and an optional default value and returns a VanJS `State` object.
5456

5557
```js
56-
define("hello-world", ({ attr, children }) => {
58+
define("hello-world", ({ attr }) => {
5759
const color = attr(
5860
"color", // name of the attribute
5961
"red" // default value (optional)
6062
);
6163
const size = attr("size", 20);
6264
return span(
6365
{ style: () => `color:${color.val};font-size:${size.val}` },
64-
children
66+
slot()
6567
);
6668
});
6769
```

‎docs/learn/overview.md‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ The core `define` method can take up to 3 arguments:
99
- `options` (_optional_)
1010
Extra [Shadow DOM options](./shadow-options).
1111

12-
The provided VanJS method will be provided with 4 properties:
12+
The provided VanJS method will be provided with some properties:
1313

1414
- `attr()`
1515
Method to [retrieve the value of a given attribute](./attributes).
1616
- `mount()`
1717
Lifecycle hook to [register `mount` and `dismount` callbacks](./lifecycle).
1818
- `$this`
1919
Refers to the instance of the Van Element.
20-
- `children`
21-
Child nodes of the custom element.

‎docs/learn/shadow-options.md‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,23 @@ define(
2626
Things that will **stop working**:
2727

2828
- DOM and style isolation
29-
- named slots
29+
- slots
3030

3131
Everything else **will work the exact same**, including:
3232

33-
- `$this`, `mount`, `attr` and `children`
33+
- `$this`, `mount`, `attr`
3434
- all VanJS logic
3535
- hydration and reusability
3636

37-
Additionally, you can use the `children` prop as a replacement for the default `slot` (similar to React).
38-
3937
## Shadow DOM or not?
4038

4139
**You can safely disable the Shadow DOM if:**
4240

4341
- All you want is easy hydration
4442
- Isolation gets in the way
45-
- You don't need named slots
43+
- You don't need slots
4644

4745
**You _should not_ disable it if:**
4846

4947
- You are building isolated components (component library, design system)
50-
- You need named slots for more complex logic
48+
- You need slots for composition

‎docs/learn/slots.md‎

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
11
# Slots
22

3-
Slots are like children in VanJS, but for Web Components.
4-
5-
::: tip
3+
::: info
64

7-
You can also use the `children` property.
8-
9-
- When using Shadow DOM, it will be an `HTMLSlotElement`.
10-
- With Shadow DOM disabled, it will be the custom element's `childNodes` and will behave the same way!
5+
You can only used slots if the Shadow DOM is enabled.
116

127
:::
138

14-
::: code-group
15-
16-
<<< @/components.ts#slots {javascript} [slot]
9+
Slots are like children in VanJS, but for Web Components.
1710

18-
```javascript [children]
19-
define("slot-demo", ({ children }) => p("Hello ", children));
20-
```
21-
22-
:::
11+
<<< @/components.ts#slots {javascript}
2312

2413
```html
2514
<slot-demo><strong>Robert</strong> and <i>Marie</i></slot-demo>
@@ -51,12 +40,4 @@ Slots can have names, which allows you to customize many different places in the
5140
</slot-names>
5241
</fieldset>
5342

54-
::: info Note
55-
56-
This feature is only available when using the Shadow DOM.
57-
58-
A polyfill could be built to support named slots without the Shadow DOM, if you are interested feel free to post an issue or submit a PR! 🫡
59-
60-
:::
61-
6243
You will find more examples in the [Examples](../examples) section.

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "vanjs-element",
33
"author": "Atmos4",
44
"license": "MIT",
5-
"version": "1.0.0",
5+
"version": "2.0.0",
66
"type": "module",
77
"description": "Web components with VanJS",
88
"files": [

0 commit comments

Comments
 (0)