Skip to content

Commit 31029c9

Browse files
committed
docs: add avatar docs
1 parent 14f28db commit 31029c9

File tree

22 files changed

+391
-38
lines changed

22 files changed

+391
-38
lines changed

.changeset/popular-boats-kneel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@zag-js/avatar": patch
3+
---
4+
5+
Fix avatar machine transition when in loaded state and src is removed.

.prettierignore

-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@ coverage
44
.next
55
build
66
*.hbs
7-
website/data/**/*.mdx

.xstate/avatar.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ const fetchMachine = createMachine({
5252
}
5353
},
5454
loaded: {
55-
activities: ["trackSrcChange"]
55+
activities: ["trackSrcChange"],
56+
on: {
57+
"IMG.ERROR": {
58+
target: "error",
59+
actions: ["invokeOnError"]
60+
}
61+
}
5662
}
5763
}
5864
}, {

packages/docs/api.json

+69-21
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,42 @@
7171
}
7272
}
7373
},
74+
"avatar": {
75+
"api": {
76+
"isLoaded": {
77+
"type": "boolean",
78+
"description": "Whether the image is loaded."
79+
},
80+
"showFallback": {
81+
"type": "boolean",
82+
"description": "Whether the fallback is shown."
83+
},
84+
"setSrc": {
85+
"type": "(src: string) => void",
86+
"description": "Function to set new src."
87+
},
88+
"setLoaded": {
89+
"type": "() => void",
90+
"description": "Function to set loaded state."
91+
},
92+
"setError": {
93+
"type": "() => void",
94+
"description": "Function to set error state."
95+
}
96+
},
97+
"context": {
98+
"id": {
99+
"type": "string",
100+
"description": "The unique identifier of the machine.",
101+
"defaultValue": null
102+
},
103+
"getRootNode": {
104+
"type": "() => Node | ShadowRoot | Document",
105+
"description": "A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.",
106+
"defaultValue": null
107+
}
108+
}
109+
},
74110
"carousel": {
75111
"api": {
76112
"index": {
@@ -130,7 +166,7 @@
130166
"defaultValue": null
131167
},
132168
"getRootNode": {
133-
"type": "() => Node | ShadowRoot | Document",
169+
"type": "() => Node | Document | ShadowRoot",
134170
"description": "A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.",
135171
"defaultValue": null
136172
},
@@ -201,6 +237,10 @@
201237
"setChecked": {
202238
"type": "(checked: CheckedState) => void",
203239
"description": "Function to set the checked state of the checkbox"
240+
},
241+
"toggleChecked": {
242+
"type": "() => void",
243+
"description": "Function to toggle the checked state of the checkbox"
204244
}
205245
},
206246
"context": {
@@ -565,6 +605,10 @@
565605
"type": "DateView",
566606
"description": "The current view of the date picker"
567607
},
608+
"matchView": {
609+
"type": "typeof matchView",
610+
"description": "Matcher for the current view of the date picker"
611+
},
568612
"getDaysInWeek": {
569613
"type": "(weekIndex: number, from?: DateValue[]",
570614
"description": "Returns an array of days in the week index counted from the provided start date, or the first visible date if not given."
@@ -654,15 +698,23 @@
654698
"description": "The visible range of dates."
655699
},
656700
"getYears": {
657-
"type": "(props?: { columns?: number; }) => number[][]",
701+
"type": "() => { label: string; value: number; }[]",
702+
"description": "Returns the months of the year"
703+
},
704+
"getYearsGrid": {
705+
"type": "(props?: { columns?: number; }) => { label: string; value: number; }[][]",
658706
"description": "Returns the years of the decade based on the columns.\nRepresented as an array of arrays of years."
659707
},
660708
"getDecade": {
661709
"type": "() => { start: number; end: number; }",
662710
"description": "Returns the start and end years of the decade."
663711
},
664712
"getMonths": {
665-
"type": "(props?: { columns?: number; format?: \"short\" | \"long\"; }) => string[][]",
713+
"type": "(props?: { format?: \"short\" | \"long\"; }) => { label: string; value: number; }[]",
714+
"description": "Returns the months of the year"
715+
},
716+
"getMonthsGrid": {
717+
"type": "(props?: { columns?: number; format?: \"short\" | \"long\"; }) => { label: string; value: number; }[][]",
666718
"description": "Returns the months of the year based on the columns.\nRepresented as an array of arrays of months."
667719
},
668720
"format": {
@@ -1906,6 +1958,11 @@
19061958
"type": "boolean",
19071959
"description": "Whether text selection should be enabled on the pressable element.",
19081960
"defaultValue": null
1961+
},
1962+
"longPressDelay": {
1963+
"type": "number",
1964+
"description": "The amount of time (in milliseconds) to wait before firing the `onLongPress` event.",
1965+
"defaultValue": null
19091966
}
19101967
}
19111968
},
@@ -2604,17 +2661,13 @@
26042661
"type": "{ min: number; max: number; }",
26052662
"description": "The bounds of the currently dragged splitter handle."
26062663
},
2607-
"collapse": {
2664+
"setToMinSize": {
26082665
"type": "(id: PanelId) => void",
2609-
"description": "Function to collapse a panel."
2666+
"description": "Function to set a panel to its minimum size."
26102667
},
2611-
"expand": {
2668+
"setToMaxSize": {
26122669
"type": "(id: PanelId) => void",
2613-
"description": "Function to expand a panel."
2614-
},
2615-
"toggle": {
2616-
"type": "(id: PanelId) => void",
2617-
"description": "Function to toggle a panel between collapsed and expanded."
2670+
"description": "Function to set a panel to its maximum size."
26182671
},
26192672
"setSize": {
26202673
"type": "(id: PanelId, size: number) => void",
@@ -2687,13 +2740,13 @@
26872740
"type": "boolean",
26882741
"description": "Whether the checkbox is focused"
26892742
},
2690-
"isReadOnly": {
2691-
"type": "boolean",
2692-
"description": "Whether the checkbox is readonly"
2693-
},
26942743
"setChecked": {
2695-
"type": "(value: boolean) => void",
2744+
"type": "(checked: boolean) => void",
26962745
"description": "Function to set the checked state of the switch."
2746+
},
2747+
"toggleChecked": {
2748+
"type": "() => void",
2749+
"description": "Function to toggle the checked state of the checkbox"
26972750
}
26982751
},
26992752
"context": {
@@ -2771,11 +2824,6 @@
27712824
"type": "string | number",
27722825
"description": "The value of switch input. Useful for form submission.",
27732826
"defaultValue": "\"on\""
2774-
},
2775-
"aria-label": {
2776-
"type": "string",
2777-
"description": "Defines the string that labels the switch element.",
2778-
"defaultValue": null
27792827
}
27802828
}
27812829
},

packages/machines/avatar/src/avatar.machine.ts

+6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ export function machine(userContext: UserDefinedContext) {
4949
},
5050
loaded: {
5151
activities: ["trackSrcChange"],
52+
on: {
53+
"IMG.ERROR": {
54+
target: "error",
55+
actions: ["invokeOnError"],
56+
},
57+
},
5258
},
5359
},
5460
},

pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* eslint-disable @next/next/no-img-element */
2+
import { chakra } from "@chakra-ui/system"
3+
import { Center, Circle } from "@chakra-ui/layout"
4+
import * as avatar from "@zag-js/avatar"
5+
import { normalizeProps, useMachine } from "@zag-js/react"
6+
import { useId } from "react"
7+
8+
export function Avatar(props: { controls: { src: string; name: string } }) {
9+
const { src, name } = props.controls
10+
11+
const [state, send] = useMachine(avatar.machine({ id: useId() }))
12+
const api = avatar.connect(state, send, normalizeProps)
13+
14+
const initial = name
15+
.split(" ")
16+
.map((s) => s[0])
17+
.join("")
18+
19+
return (
20+
<>
21+
<main className="avatar">
22+
<Circle size="80px" overflow="hidden" {...api.rootProps}>
23+
<chakra.div
24+
width="80px"
25+
height="80px"
26+
fontSize="sm"
27+
lineHeight="1"
28+
fontWeight="semibold"
29+
color="white"
30+
bg="gray.500"
31+
{...api.fallbackProps}
32+
>
33+
<Center width="full" height="full">
34+
{initial}
35+
</Center>
36+
</chakra.div>
37+
<chakra.img
38+
width="80px"
39+
height="80px"
40+
objectFit="cover"
41+
borderRadius="9999px"
42+
alt={name}
43+
referrerPolicy="no-referrer"
44+
src={src}
45+
{...api.imageProps}
46+
/>
47+
</Circle>
48+
</main>
49+
</>
50+
)
51+
}

website/components/showcase.tsx

+22-12
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
1-
import { Checkbox } from "./machines/checkbox"
2-
import { Radio } from "./machines/radio"
1+
import { Combobox } from "components/machines/combobox"
2+
import { ContextMenu } from "components/machines/context-menu"
3+
import { HoverCard } from "components/machines/hover-card"
4+
import { NestedMenu } from "components/machines/nested-menu"
5+
import { Pagination } from "components/machines/pagination"
6+
import { Pressable } from "components/machines/pressable"
7+
import { Rating } from "components/machines/rating"
8+
import { SegmentedControl } from "components/machines/segmented-control"
9+
import { Switch } from "components/machines/switch"
310
import { Accordion } from "./machines/accordion"
11+
import { Avatar } from "./machines/avatar"
12+
import { Checkbox } from "./machines/checkbox"
413
import { Dialog } from "./machines/dialog"
514
import { Editable } from "./machines/editable"
615
import { Menu } from "./machines/menu"
716
import { NumberInput } from "./machines/number-input"
817
import { PinInput } from "./machines/pin-input"
918
import { Popover } from "./machines/popover"
19+
import { Radio } from "./machines/radio"
1020
import { RangeSlider } from "./machines/range-slider"
21+
import { Select } from "./machines/select"
1122
import { Slider } from "./machines/slider"
1223
import { Tabs } from "./machines/tabs"
1324
import { TagsInput } from "./machines/tags-input"
1425
import { ToastGroup } from "./machines/toast"
1526
import { Tooltip } from "./machines/tooltip"
1627
import { Playground } from "./playground"
17-
import { Rating } from "components/machines/rating"
18-
import { Pressable } from "components/machines/pressable"
19-
import { ContextMenu } from "components/machines/context-menu"
20-
import { NestedMenu } from "components/machines/nested-menu"
21-
import { HoverCard } from "components/machines/hover-card"
22-
import { Pagination } from "components/machines/pagination"
23-
import { Select } from "./machines/select"
24-
import { Combobox } from "components/machines/combobox"
25-
import { Switch } from "components/machines/switch"
26-
import { SegmentedControl } from "components/machines/segmented-control"
2728

2829
const components = {
2930
Dialog: () => (
@@ -278,6 +279,15 @@ const components = {
278279
}}
279280
/>
280281
),
282+
Avatar: () => (
283+
<Playground
284+
component={Avatar}
285+
defaultProps={{
286+
name: "Segun Adebayo",
287+
src: "https://static.wikia.nocookie.net/naruto/images/d/d6/Naruto_Part_I.png/revision/latest/scale-to-width-down/300?cb=20210223094656",
288+
}}
289+
/>
290+
),
281291
}
282292

283293
export function Showcase(props: { id: keyof typeof components }) {

website/data/components/accordion.mdx

+1-2
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ const [state, send] = useMachine(
159159
)
160160
```
161161

162-
163162
## Styling guide
164163

165164
Earlier, we mentioned that each accordion part has a `data-part` attribute added
@@ -207,4 +206,4 @@ on the item and content.
207206

208207
The accordion's `api` exposes the following methods and properties:
209208

210-
<ApiTable name="accordion" />
209+
<ApiTable name="accordion" />

0 commit comments

Comments
 (0)