Skip to content

Commit dc6f9e6

Browse files
committed
feat: added avatar example with reactive controller
1 parent 1268ab7 commit dc6f9e6

File tree

5 files changed

+107
-1
lines changed

5 files changed

+107
-1
lines changed

examples/lit-ts/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ <h1>Lit + Zag</h1>
1111

1212
<a href="pages/accordion.html">Accordion</a>
1313
<a href="pages/avatar.html">Avatar</a>
14+
<a href="pages/avatar-controller.html">Avatar with Controller</a>
1415
<a href="pages/popover.html">Popover</a>
1516
<a href="pages/checkbox.html">Checkbox</a>
1617
<a href="pages/combobox.html">Combobox</a>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<link rel="stylesheet" href="/layout.css" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<title>Vite + TS</title>
9+
</head>
10+
<body style="padding: 40px">
11+
<h1>Avatar Element with Reactive Controller</h1>
12+
13+
<avatar-ctrl-element></avatar-ctrl-element>
14+
15+
<script type="module" src="./../src/avatar2.ts"></script>
16+
</body>
17+
</html>

examples/lit-ts/src/avatar2.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { spread } from "@open-wc/lit-helpers"
2+
import * as avatar from "@zag-js/avatar"
3+
import style from "@zag-js/shared/src/css/avatar.css?inline"
4+
import { html, LitElement, unsafeCSS } from "lit"
5+
import { customElement } from "lit/decorators.js"
6+
import { createId } from "./lib/create-id"
7+
import { ZagController } from "./zag-controller"
8+
9+
@customElement("avatar-ctrl-element")
10+
export class Avatar extends LitElement {
11+
zag: ZagController<avatar.Api, avatar.Machine>
12+
13+
constructor() {
14+
super()
15+
this.zag = new ZagController(this, avatar.connect, avatar.machine, {
16+
id: createId(),
17+
onStatusChange: (details) => {
18+
console.log("Avatar status changed:", details.status, details)
19+
},
20+
})
21+
}
22+
23+
static styles = unsafeCSS(style)
24+
25+
override render() {
26+
return html`<div ${spread(this.zag.api.getRootProps())} class="avatar">
27+
<span ${spread(this.zag.api.getFallbackProps())} class="avatar-fallback">PA</span>
28+
<img
29+
${spread(this.zag.api.getImageProps())}
30+
class="avatar-image"
31+
alt="Naruto"
32+
referrerpolicy="no-referrer"
33+
src="https://static.wikia.nocookie.net/naruto/images/d/d6/Naruto_Part_I.png/revision/latest/top-crop/width/200/height/150?cb=20210223094656"
34+
/>
35+
</div>`
36+
}
37+
}
38+
39+
declare global {
40+
interface HTMLElementTagNameMap {
41+
"avatar-ctrl-element": Avatar
42+
}
43+
}

examples/lit-ts/src/component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export abstract class Component<Api> extends LitElement implements ComponentInte
2424
override connectedCallback(): void {
2525
super.connectedCallback()
2626

27-
this.machine.subscribe((service) => {
27+
this.machine.subscribe(() => {
2828
this.api = this.initApi()
2929
this.requestUpdate()
3030
})
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { Machine, MachineSchema, Service } from "@zag-js/core"
2+
import type { NormalizeProps } from "@zag-js/types"
3+
import type { ReactiveController, ReactiveControllerHost } from "lit"
4+
import { normalizeProps, VanillaMachine } from "./lib"
5+
import { createId } from "./lib/create-id"
6+
7+
export class ZagController<Api, T extends MachineSchema> implements ReactiveController {
8+
host: ReactiveControllerHost
9+
10+
private id = createId()
11+
private connect: (service: Service<any>, normalize: NormalizeProps<any>) => Api
12+
13+
machine: VanillaMachine<any>
14+
api: Api
15+
16+
constructor(
17+
host: ReactiveControllerHost,
18+
connect: (service: Service<T>, normalize: NormalizeProps<any>) => Api,
19+
machine: Machine<T>,
20+
userProps: Partial<T["props"]> = {},
21+
) {
22+
// Store a reference to the host
23+
this.host = host
24+
// Register for lifecycle updates
25+
host.addController(this)
26+
27+
this.connect = connect
28+
29+
this.machine = new VanillaMachine(machine, { ...userProps, id: this.id })
30+
this.api = this.connect(this.machine.service, normalizeProps)
31+
}
32+
33+
hostConnected() {
34+
// Start the machine when the host is connected
35+
this.machine.subscribe(() => {
36+
this.api = this.connect(this.machine.service, normalizeProps)
37+
this.host.requestUpdate()
38+
})
39+
this.machine.start()
40+
}
41+
hostDisconnected() {
42+
// Stop the machine when the host is disconnected
43+
this.machine.stop()
44+
}
45+
}

0 commit comments

Comments
 (0)