@zag-js/avatar 0.47.0 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +15 -9
- package/dist/index.d.ts +15 -9
- package/dist/index.js +24 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -7
- package/src/avatar.connect.ts +6 -9
- package/src/avatar.dom.ts +3 -3
- package/src/avatar.machine.ts +15 -10
- package/src/avatar.props.ts +1 -1
- package/src/avatar.types.ts +14 -6
- package/src/index.ts +7 -1
package/dist/index.d.mts
CHANGED
|
@@ -5,14 +5,24 @@ import { StateMachine } from '@zag-js/core';
|
|
|
5
5
|
|
|
6
6
|
declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "image" | "fallback">;
|
|
7
7
|
|
|
8
|
+
type LoadStatus = "error" | "loaded";
|
|
8
9
|
interface StatusChangeDetails {
|
|
9
|
-
status:
|
|
10
|
+
status: LoadStatus;
|
|
10
11
|
}
|
|
12
|
+
type ElementIds = Partial<{
|
|
13
|
+
root: string;
|
|
14
|
+
image: string;
|
|
15
|
+
fallback: string;
|
|
16
|
+
}>;
|
|
11
17
|
interface PublicContext extends CommonProperties, DirectionProperty {
|
|
12
18
|
/**
|
|
13
19
|
* Functional called when the image loading status changes.
|
|
14
20
|
*/
|
|
15
21
|
onStatusChange?: (details: StatusChangeDetails) => void;
|
|
22
|
+
/**
|
|
23
|
+
* The ids of the elements in the avatar. Useful for composition.
|
|
24
|
+
*/
|
|
25
|
+
ids?: ElementIds;
|
|
16
26
|
}
|
|
17
27
|
interface PrivateContext {
|
|
18
28
|
}
|
|
@@ -29,11 +39,7 @@ interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
29
39
|
/**
|
|
30
40
|
* Whether the image is loaded.
|
|
31
41
|
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Whether the fallback is shown.
|
|
35
|
-
*/
|
|
36
|
-
showFallback: boolean;
|
|
42
|
+
loaded: boolean;
|
|
37
43
|
/**
|
|
38
44
|
* Function to set new src.
|
|
39
45
|
*/
|
|
@@ -55,7 +61,7 @@ declare function connect<T extends PropTypes>(state: State, send: Send, normaliz
|
|
|
55
61
|
|
|
56
62
|
declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
|
|
57
63
|
|
|
58
|
-
declare const props: ("dir" | "id" | "onStatusChange" | "getRootNode")[];
|
|
59
|
-
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "dir" | "id" | "onStatusChange" | "getRootNode">];
|
|
64
|
+
declare const props: ("dir" | "id" | "onStatusChange" | "ids" | "getRootNode")[];
|
|
65
|
+
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "dir" | "id" | "onStatusChange" | "ids" | "getRootNode">];
|
|
60
66
|
|
|
61
|
-
export { type MachineApi as Api, type UserDefinedContext as Context, type StatusChangeDetails, anatomy, connect, machine, props, splitProps };
|
|
67
|
+
export { type MachineApi as Api, type UserDefinedContext as Context, type ElementIds, type LoadStatus, type StatusChangeDetails, anatomy, connect, machine, props, splitProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,14 +5,24 @@ import { StateMachine } from '@zag-js/core';
|
|
|
5
5
|
|
|
6
6
|
declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "image" | "fallback">;
|
|
7
7
|
|
|
8
|
+
type LoadStatus = "error" | "loaded";
|
|
8
9
|
interface StatusChangeDetails {
|
|
9
|
-
status:
|
|
10
|
+
status: LoadStatus;
|
|
10
11
|
}
|
|
12
|
+
type ElementIds = Partial<{
|
|
13
|
+
root: string;
|
|
14
|
+
image: string;
|
|
15
|
+
fallback: string;
|
|
16
|
+
}>;
|
|
11
17
|
interface PublicContext extends CommonProperties, DirectionProperty {
|
|
12
18
|
/**
|
|
13
19
|
* Functional called when the image loading status changes.
|
|
14
20
|
*/
|
|
15
21
|
onStatusChange?: (details: StatusChangeDetails) => void;
|
|
22
|
+
/**
|
|
23
|
+
* The ids of the elements in the avatar. Useful for composition.
|
|
24
|
+
*/
|
|
25
|
+
ids?: ElementIds;
|
|
16
26
|
}
|
|
17
27
|
interface PrivateContext {
|
|
18
28
|
}
|
|
@@ -29,11 +39,7 @@ interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
29
39
|
/**
|
|
30
40
|
* Whether the image is loaded.
|
|
31
41
|
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Whether the fallback is shown.
|
|
35
|
-
*/
|
|
36
|
-
showFallback: boolean;
|
|
42
|
+
loaded: boolean;
|
|
37
43
|
/**
|
|
38
44
|
* Function to set new src.
|
|
39
45
|
*/
|
|
@@ -55,7 +61,7 @@ declare function connect<T extends PropTypes>(state: State, send: Send, normaliz
|
|
|
55
61
|
|
|
56
62
|
declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
|
|
57
63
|
|
|
58
|
-
declare const props: ("dir" | "id" | "onStatusChange" | "getRootNode")[];
|
|
59
|
-
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "dir" | "id" | "onStatusChange" | "getRootNode">];
|
|
64
|
+
declare const props: ("dir" | "id" | "onStatusChange" | "ids" | "getRootNode")[];
|
|
65
|
+
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "dir" | "id" | "onStatusChange" | "ids" | "getRootNode">];
|
|
60
66
|
|
|
61
|
-
export { type MachineApi as Api, type UserDefinedContext as Context, type StatusChangeDetails, anatomy, connect, machine, props, splitProps };
|
|
67
|
+
export { type MachineApi as Api, type UserDefinedContext as Context, type ElementIds, type LoadStatus, type StatusChangeDetails, anatomy, connect, machine, props, splitProps };
|
package/dist/index.js
CHANGED
|
@@ -36,20 +36,18 @@ var parts = anatomy.build();
|
|
|
36
36
|
// src/avatar.dom.ts
|
|
37
37
|
var import_dom_query = require("@zag-js/dom-query");
|
|
38
38
|
var dom = (0, import_dom_query.createScope)({
|
|
39
|
-
getRootId: (ctx) => `avatar:${ctx.id}`,
|
|
40
|
-
getImageId: (ctx) => `avatar:${ctx.id}:image`,
|
|
41
|
-
getFallbackId: (ctx) => `avatar:${ctx.id}:fallback`,
|
|
39
|
+
getRootId: (ctx) => ctx.ids?.root ?? `avatar:${ctx.id}`,
|
|
40
|
+
getImageId: (ctx) => ctx.ids?.image ?? `avatar:${ctx.id}:image`,
|
|
41
|
+
getFallbackId: (ctx) => ctx.ids?.fallback ?? `avatar:${ctx.id}:fallback`,
|
|
42
42
|
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
|
|
43
43
|
getImageEl: (ctx) => dom.getById(ctx, dom.getImageId(ctx))
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
// src/avatar.connect.ts
|
|
47
47
|
function connect(state, send, normalize) {
|
|
48
|
-
const
|
|
49
|
-
const showFallback = !isLoaded;
|
|
48
|
+
const loaded = state.matches("loaded");
|
|
50
49
|
return {
|
|
51
|
-
|
|
52
|
-
showFallback,
|
|
50
|
+
loaded,
|
|
53
51
|
setSrc(src) {
|
|
54
52
|
send({ type: "SRC.SET", src });
|
|
55
53
|
},
|
|
@@ -66,10 +64,10 @@ function connect(state, send, normalize) {
|
|
|
66
64
|
}),
|
|
67
65
|
imageProps: normalize.img({
|
|
68
66
|
...parts.image.attrs,
|
|
69
|
-
hidden: !
|
|
67
|
+
hidden: !loaded,
|
|
70
68
|
dir: state.context.dir,
|
|
71
69
|
id: dom.getImageId(state.context),
|
|
72
|
-
"data-state":
|
|
70
|
+
"data-state": loaded ? "visible" : "hidden",
|
|
73
71
|
onLoad() {
|
|
74
72
|
send({ type: "IMG.LOADED", src: "element" });
|
|
75
73
|
},
|
|
@@ -81,15 +79,15 @@ function connect(state, send, normalize) {
|
|
|
81
79
|
...parts.fallback.attrs,
|
|
82
80
|
dir: state.context.dir,
|
|
83
81
|
id: dom.getFallbackId(state.context),
|
|
84
|
-
hidden:
|
|
85
|
-
"data-state":
|
|
82
|
+
hidden: loaded,
|
|
83
|
+
"data-state": loaded ? "hidden" : "visible"
|
|
86
84
|
})
|
|
87
85
|
};
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
// src/avatar.machine.ts
|
|
91
89
|
var import_core = require("@zag-js/core");
|
|
92
|
-
var
|
|
90
|
+
var import_dom_query2 = require("@zag-js/dom-query");
|
|
93
91
|
var import_utils = require("@zag-js/utils");
|
|
94
92
|
function machine(userContext) {
|
|
95
93
|
const ctx = (0, import_utils.compact)(userContext);
|
|
@@ -145,18 +143,23 @@ function machine(userContext) {
|
|
|
145
143
|
{
|
|
146
144
|
activities: {
|
|
147
145
|
trackSrcChange(ctx2, _evt, { send }) {
|
|
148
|
-
const
|
|
149
|
-
return (0,
|
|
150
|
-
|
|
146
|
+
const imageEl = dom.getImageEl(ctx2);
|
|
147
|
+
return (0, import_dom_query2.observeAttributes)(imageEl, {
|
|
148
|
+
attributes: ["src", "srcset"],
|
|
149
|
+
callback() {
|
|
150
|
+
send({ type: "SRC.CHANGE" });
|
|
151
|
+
}
|
|
151
152
|
});
|
|
152
153
|
},
|
|
153
154
|
trackImageRemoval(ctx2, _evt, { send }) {
|
|
154
155
|
const rootEl = dom.getRootEl(ctx2);
|
|
155
|
-
return (0,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
return (0, import_dom_query2.observeChildren)(rootEl, {
|
|
157
|
+
callback(records) {
|
|
158
|
+
const removedNodes = Array.from(records[0].removedNodes);
|
|
159
|
+
const removed = removedNodes.find((node) => node.matches("[data-scope=avatar][data-part=image]"));
|
|
160
|
+
if (removed) {
|
|
161
|
+
send({ type: "IMG.UNMOUNT" });
|
|
162
|
+
}
|
|
160
163
|
}
|
|
161
164
|
});
|
|
162
165
|
}
|
|
@@ -183,7 +186,7 @@ function machine(userContext) {
|
|
|
183
186
|
// src/avatar.props.ts
|
|
184
187
|
var import_types = require("@zag-js/types");
|
|
185
188
|
var import_utils2 = require("@zag-js/utils");
|
|
186
|
-
var props = (0, import_types.createProps)()(["dir", "id", "onStatusChange", "getRootNode"]);
|
|
189
|
+
var props = (0, import_types.createProps)()(["dir", "id", "ids", "onStatusChange", "getRootNode"]);
|
|
187
190
|
var splitProps = (0, import_utils2.createSplitProps)(props);
|
|
188
191
|
// Annotate the CommonJS export names for ESM import in node:
|
|
189
192
|
0 && (module.exports = {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/avatar.anatomy.ts","../src/avatar.dom.ts","../src/avatar.connect.ts","../src/avatar.machine.ts","../src/avatar.props.ts"],"sourcesContent":["export { anatomy } from \"./avatar.anatomy\"\nexport { connect } from \"./avatar.connect\"\nexport { machine } from \"./avatar.machine\"\nexport * from \"./avatar.props\"\nexport type {
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/avatar.anatomy.ts","../src/avatar.dom.ts","../src/avatar.connect.ts","../src/avatar.machine.ts","../src/avatar.props.ts"],"sourcesContent":["export { anatomy } from \"./avatar.anatomy\"\nexport { connect } from \"./avatar.connect\"\nexport { machine } from \"./avatar.machine\"\nexport * from \"./avatar.props\"\nexport type {\n MachineApi as Api,\n UserDefinedContext as Context,\n ElementIds,\n LoadStatus,\n StatusChangeDetails,\n} from \"./avatar.types\"\n","import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"avatar\").parts(\"root\", \"image\", \"fallback\")\n\nexport const parts = anatomy.build()\n","import { createScope } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./avatar.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `avatar:${ctx.id}`,\n getImageId: (ctx: Ctx) => ctx.ids?.image ?? `avatar:${ctx.id}:image`,\n getFallbackId: (ctx: Ctx) => ctx.ids?.fallback ?? `avatar:${ctx.id}:fallback`,\n\n getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),\n getImageEl: (ctx: Ctx) => dom.getById<HTMLImageElement>(ctx, dom.getImageId(ctx)),\n})\n","import type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { parts } from \"./avatar.anatomy\"\nimport { dom } from \"./avatar.dom\"\nimport type { MachineApi, Send, State } from \"./avatar.types\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const loaded = state.matches(\"loaded\")\n return {\n loaded,\n setSrc(src) {\n send({ type: \"SRC.SET\", src })\n },\n setLoaded() {\n send({ type: \"IMG.LOADED\", src: \"api\" })\n },\n setError() {\n send({ type: \"IMG.ERROR\", src: \"api\" })\n },\n\n rootProps: normalize.element({\n ...parts.root.attrs,\n dir: state.context.dir,\n id: dom.getRootId(state.context),\n }),\n\n imageProps: normalize.img({\n ...parts.image.attrs,\n hidden: !loaded,\n dir: state.context.dir,\n id: dom.getImageId(state.context),\n \"data-state\": loaded ? \"visible\" : \"hidden\",\n onLoad() {\n send({ type: \"IMG.LOADED\", src: \"element\" })\n },\n onError() {\n send({ type: \"IMG.ERROR\", src: \"element\" })\n },\n }),\n\n fallbackProps: normalize.element({\n ...parts.fallback.attrs,\n dir: state.context.dir,\n id: dom.getFallbackId(state.context),\n hidden: loaded,\n \"data-state\": loaded ? \"hidden\" : \"visible\",\n }),\n }\n}\n","import { createMachine } from \"@zag-js/core\"\nimport { observeAttributes, observeChildren } from \"@zag-js/dom-query\"\nimport { compact } from \"@zag-js/utils\"\nimport { dom } from \"./avatar.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./avatar.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"avatar\",\n initial: \"loading\",\n activities: [\"trackImageRemoval\"],\n\n context: ctx,\n\n on: {\n \"SRC.CHANGE\": {\n target: \"loading\",\n },\n \"IMG.UNMOUNT\": {\n target: \"error\",\n },\n },\n\n states: {\n loading: {\n activities: [\"trackSrcChange\"],\n entry: [\"checkImgStatus\"],\n on: {\n \"IMG.LOADED\": {\n target: \"loaded\",\n actions: [\"invokeOnLoad\"],\n },\n \"IMG.ERROR\": {\n target: \"error\",\n actions: [\"invokeOnError\"],\n },\n },\n },\n error: {\n activities: [\"trackSrcChange\"],\n on: {\n \"IMG.LOADED\": {\n target: \"loaded\",\n actions: [\"invokeOnLoad\"],\n },\n },\n },\n loaded: {\n activities: [\"trackSrcChange\"],\n on: {\n \"IMG.ERROR\": {\n target: \"error\",\n actions: [\"invokeOnError\"],\n },\n },\n },\n },\n },\n {\n activities: {\n trackSrcChange(ctx, _evt, { send }) {\n const imageEl = dom.getImageEl(ctx)\n return observeAttributes(imageEl, {\n attributes: [\"src\", \"srcset\"],\n callback() {\n send({ type: \"SRC.CHANGE\" })\n },\n })\n },\n trackImageRemoval(ctx, _evt, { send }) {\n const rootEl = dom.getRootEl(ctx)\n return observeChildren(rootEl, {\n callback(records) {\n const removedNodes = Array.from(records[0].removedNodes) as HTMLElement[]\n const removed = removedNodes.find((node) => node.matches(\"[data-scope=avatar][data-part=image]\"))\n if (removed) {\n send({ type: \"IMG.UNMOUNT\" })\n }\n },\n })\n },\n },\n actions: {\n invokeOnLoad(ctx) {\n ctx.onStatusChange?.({ status: \"loaded\" })\n },\n invokeOnError(ctx) {\n ctx.onStatusChange?.({ status: \"error\" })\n },\n checkImgStatus(ctx, _evt, { send }) {\n const img = dom.getImageEl(ctx)\n if (img?.complete) {\n const type = img.currentSrc ? \"IMG.LOADED\" : \"IMG.ERROR\"\n send({ type, src: \"ssr\" })\n }\n },\n },\n },\n )\n}\n","import { createProps } from \"@zag-js/types\"\nimport { createSplitProps } from \"@zag-js/utils\"\nimport type { UserDefinedContext } from \"./avatar.types\"\n\nexport const props = createProps<UserDefinedContext>()([\"dir\", \"id\", \"ids\", \"onStatusChange\", \"getRootNode\"])\nexport const splitProps = createSplitProps<Partial<UserDefinedContext>>(props)\n"],"mappings":"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","names":["import_dom_query","ctx","import_utils"]}
|
package/dist/index.mjs
CHANGED
|
@@ -6,20 +6,18 @@ var parts = anatomy.build();
|
|
|
6
6
|
// src/avatar.dom.ts
|
|
7
7
|
import { createScope } from "@zag-js/dom-query";
|
|
8
8
|
var dom = createScope({
|
|
9
|
-
getRootId: (ctx) => `avatar:${ctx.id}`,
|
|
10
|
-
getImageId: (ctx) => `avatar:${ctx.id}:image`,
|
|
11
|
-
getFallbackId: (ctx) => `avatar:${ctx.id}:fallback`,
|
|
9
|
+
getRootId: (ctx) => ctx.ids?.root ?? `avatar:${ctx.id}`,
|
|
10
|
+
getImageId: (ctx) => ctx.ids?.image ?? `avatar:${ctx.id}:image`,
|
|
11
|
+
getFallbackId: (ctx) => ctx.ids?.fallback ?? `avatar:${ctx.id}:fallback`,
|
|
12
12
|
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
|
|
13
13
|
getImageEl: (ctx) => dom.getById(ctx, dom.getImageId(ctx))
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
// src/avatar.connect.ts
|
|
17
17
|
function connect(state, send, normalize) {
|
|
18
|
-
const
|
|
19
|
-
const showFallback = !isLoaded;
|
|
18
|
+
const loaded = state.matches("loaded");
|
|
20
19
|
return {
|
|
21
|
-
|
|
22
|
-
showFallback,
|
|
20
|
+
loaded,
|
|
23
21
|
setSrc(src) {
|
|
24
22
|
send({ type: "SRC.SET", src });
|
|
25
23
|
},
|
|
@@ -36,10 +34,10 @@ function connect(state, send, normalize) {
|
|
|
36
34
|
}),
|
|
37
35
|
imageProps: normalize.img({
|
|
38
36
|
...parts.image.attrs,
|
|
39
|
-
hidden: !
|
|
37
|
+
hidden: !loaded,
|
|
40
38
|
dir: state.context.dir,
|
|
41
39
|
id: dom.getImageId(state.context),
|
|
42
|
-
"data-state":
|
|
40
|
+
"data-state": loaded ? "visible" : "hidden",
|
|
43
41
|
onLoad() {
|
|
44
42
|
send({ type: "IMG.LOADED", src: "element" });
|
|
45
43
|
},
|
|
@@ -51,15 +49,15 @@ function connect(state, send, normalize) {
|
|
|
51
49
|
...parts.fallback.attrs,
|
|
52
50
|
dir: state.context.dir,
|
|
53
51
|
id: dom.getFallbackId(state.context),
|
|
54
|
-
hidden:
|
|
55
|
-
"data-state":
|
|
52
|
+
hidden: loaded,
|
|
53
|
+
"data-state": loaded ? "hidden" : "visible"
|
|
56
54
|
})
|
|
57
55
|
};
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
// src/avatar.machine.ts
|
|
61
59
|
import { createMachine } from "@zag-js/core";
|
|
62
|
-
import { observeAttributes, observeChildren } from "@zag-js/
|
|
60
|
+
import { observeAttributes, observeChildren } from "@zag-js/dom-query";
|
|
63
61
|
import { compact } from "@zag-js/utils";
|
|
64
62
|
function machine(userContext) {
|
|
65
63
|
const ctx = compact(userContext);
|
|
@@ -115,18 +113,23 @@ function machine(userContext) {
|
|
|
115
113
|
{
|
|
116
114
|
activities: {
|
|
117
115
|
trackSrcChange(ctx2, _evt, { send }) {
|
|
118
|
-
const
|
|
119
|
-
return observeAttributes(
|
|
120
|
-
|
|
116
|
+
const imageEl = dom.getImageEl(ctx2);
|
|
117
|
+
return observeAttributes(imageEl, {
|
|
118
|
+
attributes: ["src", "srcset"],
|
|
119
|
+
callback() {
|
|
120
|
+
send({ type: "SRC.CHANGE" });
|
|
121
|
+
}
|
|
121
122
|
});
|
|
122
123
|
},
|
|
123
124
|
trackImageRemoval(ctx2, _evt, { send }) {
|
|
124
125
|
const rootEl = dom.getRootEl(ctx2);
|
|
125
|
-
return observeChildren(rootEl,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
return observeChildren(rootEl, {
|
|
127
|
+
callback(records) {
|
|
128
|
+
const removedNodes = Array.from(records[0].removedNodes);
|
|
129
|
+
const removed = removedNodes.find((node) => node.matches("[data-scope=avatar][data-part=image]"));
|
|
130
|
+
if (removed) {
|
|
131
|
+
send({ type: "IMG.UNMOUNT" });
|
|
132
|
+
}
|
|
130
133
|
}
|
|
131
134
|
});
|
|
132
135
|
}
|
|
@@ -153,7 +156,7 @@ function machine(userContext) {
|
|
|
153
156
|
// src/avatar.props.ts
|
|
154
157
|
import { createProps } from "@zag-js/types";
|
|
155
158
|
import { createSplitProps } from "@zag-js/utils";
|
|
156
|
-
var props = createProps()(["dir", "id", "onStatusChange", "getRootNode"]);
|
|
159
|
+
var props = createProps()(["dir", "id", "ids", "onStatusChange", "getRootNode"]);
|
|
157
160
|
var splitProps = createSplitProps(props);
|
|
158
161
|
export {
|
|
159
162
|
anatomy,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/avatar.anatomy.ts","../src/avatar.dom.ts","../src/avatar.connect.ts","../src/avatar.machine.ts","../src/avatar.props.ts"],"sourcesContent":["import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"avatar\").parts(\"root\", \"image\", \"fallback\")\n\nexport const parts = anatomy.build()\n","import { createScope } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./avatar.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => `avatar:${ctx.id}`,\n getImageId: (ctx: Ctx) => `avatar:${ctx.id}:image`,\n getFallbackId: (ctx: Ctx) => `avatar:${ctx.id}:fallback`,\n\n getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),\n getImageEl: (ctx: Ctx) => dom.getById<HTMLImageElement>(ctx, dom.getImageId(ctx)),\n})\n","import type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { parts } from \"./avatar.anatomy\"\nimport { dom } from \"./avatar.dom\"\nimport type { MachineApi, Send, State } from \"./avatar.types\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const
|
|
1
|
+
{"version":3,"sources":["../src/avatar.anatomy.ts","../src/avatar.dom.ts","../src/avatar.connect.ts","../src/avatar.machine.ts","../src/avatar.props.ts"],"sourcesContent":["import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"avatar\").parts(\"root\", \"image\", \"fallback\")\n\nexport const parts = anatomy.build()\n","import { createScope } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./avatar.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `avatar:${ctx.id}`,\n getImageId: (ctx: Ctx) => ctx.ids?.image ?? `avatar:${ctx.id}:image`,\n getFallbackId: (ctx: Ctx) => ctx.ids?.fallback ?? `avatar:${ctx.id}:fallback`,\n\n getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),\n getImageEl: (ctx: Ctx) => dom.getById<HTMLImageElement>(ctx, dom.getImageId(ctx)),\n})\n","import type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { parts } from \"./avatar.anatomy\"\nimport { dom } from \"./avatar.dom\"\nimport type { MachineApi, Send, State } from \"./avatar.types\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const loaded = state.matches(\"loaded\")\n return {\n loaded,\n setSrc(src) {\n send({ type: \"SRC.SET\", src })\n },\n setLoaded() {\n send({ type: \"IMG.LOADED\", src: \"api\" })\n },\n setError() {\n send({ type: \"IMG.ERROR\", src: \"api\" })\n },\n\n rootProps: normalize.element({\n ...parts.root.attrs,\n dir: state.context.dir,\n id: dom.getRootId(state.context),\n }),\n\n imageProps: normalize.img({\n ...parts.image.attrs,\n hidden: !loaded,\n dir: state.context.dir,\n id: dom.getImageId(state.context),\n \"data-state\": loaded ? \"visible\" : \"hidden\",\n onLoad() {\n send({ type: \"IMG.LOADED\", src: \"element\" })\n },\n onError() {\n send({ type: \"IMG.ERROR\", src: \"element\" })\n },\n }),\n\n fallbackProps: normalize.element({\n ...parts.fallback.attrs,\n dir: state.context.dir,\n id: dom.getFallbackId(state.context),\n hidden: loaded,\n \"data-state\": loaded ? \"hidden\" : \"visible\",\n }),\n }\n}\n","import { createMachine } from \"@zag-js/core\"\nimport { observeAttributes, observeChildren } from \"@zag-js/dom-query\"\nimport { compact } from \"@zag-js/utils\"\nimport { dom } from \"./avatar.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./avatar.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"avatar\",\n initial: \"loading\",\n activities: [\"trackImageRemoval\"],\n\n context: ctx,\n\n on: {\n \"SRC.CHANGE\": {\n target: \"loading\",\n },\n \"IMG.UNMOUNT\": {\n target: \"error\",\n },\n },\n\n states: {\n loading: {\n activities: [\"trackSrcChange\"],\n entry: [\"checkImgStatus\"],\n on: {\n \"IMG.LOADED\": {\n target: \"loaded\",\n actions: [\"invokeOnLoad\"],\n },\n \"IMG.ERROR\": {\n target: \"error\",\n actions: [\"invokeOnError\"],\n },\n },\n },\n error: {\n activities: [\"trackSrcChange\"],\n on: {\n \"IMG.LOADED\": {\n target: \"loaded\",\n actions: [\"invokeOnLoad\"],\n },\n },\n },\n loaded: {\n activities: [\"trackSrcChange\"],\n on: {\n \"IMG.ERROR\": {\n target: \"error\",\n actions: [\"invokeOnError\"],\n },\n },\n },\n },\n },\n {\n activities: {\n trackSrcChange(ctx, _evt, { send }) {\n const imageEl = dom.getImageEl(ctx)\n return observeAttributes(imageEl, {\n attributes: [\"src\", \"srcset\"],\n callback() {\n send({ type: \"SRC.CHANGE\" })\n },\n })\n },\n trackImageRemoval(ctx, _evt, { send }) {\n const rootEl = dom.getRootEl(ctx)\n return observeChildren(rootEl, {\n callback(records) {\n const removedNodes = Array.from(records[0].removedNodes) as HTMLElement[]\n const removed = removedNodes.find((node) => node.matches(\"[data-scope=avatar][data-part=image]\"))\n if (removed) {\n send({ type: \"IMG.UNMOUNT\" })\n }\n },\n })\n },\n },\n actions: {\n invokeOnLoad(ctx) {\n ctx.onStatusChange?.({ status: \"loaded\" })\n },\n invokeOnError(ctx) {\n ctx.onStatusChange?.({ status: \"error\" })\n },\n checkImgStatus(ctx, _evt, { send }) {\n const img = dom.getImageEl(ctx)\n if (img?.complete) {\n const type = img.currentSrc ? \"IMG.LOADED\" : \"IMG.ERROR\"\n send({ type, src: \"ssr\" })\n }\n },\n },\n },\n )\n}\n","import { createProps } from \"@zag-js/types\"\nimport { createSplitProps } from \"@zag-js/utils\"\nimport type { UserDefinedContext } from \"./avatar.types\"\n\nexport const props = createProps<UserDefinedContext>()([\"dir\", \"id\", \"ids\", \"onStatusChange\", \"getRootNode\"])\nexport const splitProps = createSplitProps<Partial<UserDefinedContext>>(props)\n"],"mappings":"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","names":["ctx"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/avatar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "Core logic for the avatar widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -28,12 +28,11 @@
|
|
|
28
28
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@zag-js/anatomy": "0.
|
|
32
|
-
"@zag-js/
|
|
33
|
-
"@zag-js/
|
|
34
|
-
"@zag-js/
|
|
35
|
-
"@zag-js/
|
|
36
|
-
"@zag-js/types": "0.47.0"
|
|
31
|
+
"@zag-js/anatomy": "0.49.0",
|
|
32
|
+
"@zag-js/core": "0.49.0",
|
|
33
|
+
"@zag-js/dom-query": "0.49.0",
|
|
34
|
+
"@zag-js/utils": "0.49.0",
|
|
35
|
+
"@zag-js/types": "0.49.0"
|
|
37
36
|
},
|
|
38
37
|
"devDependencies": {
|
|
39
38
|
"clean-package": "2.2.0"
|
package/src/avatar.connect.ts
CHANGED
|
@@ -4,12 +4,9 @@ import { dom } from "./avatar.dom"
|
|
|
4
4
|
import type { MachineApi, Send, State } from "./avatar.types"
|
|
5
5
|
|
|
6
6
|
export function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {
|
|
7
|
-
const
|
|
8
|
-
const showFallback = !isLoaded
|
|
9
|
-
|
|
7
|
+
const loaded = state.matches("loaded")
|
|
10
8
|
return {
|
|
11
|
-
|
|
12
|
-
showFallback,
|
|
9
|
+
loaded,
|
|
13
10
|
setSrc(src) {
|
|
14
11
|
send({ type: "SRC.SET", src })
|
|
15
12
|
},
|
|
@@ -28,10 +25,10 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
|
|
|
28
25
|
|
|
29
26
|
imageProps: normalize.img({
|
|
30
27
|
...parts.image.attrs,
|
|
31
|
-
hidden: !
|
|
28
|
+
hidden: !loaded,
|
|
32
29
|
dir: state.context.dir,
|
|
33
30
|
id: dom.getImageId(state.context),
|
|
34
|
-
"data-state":
|
|
31
|
+
"data-state": loaded ? "visible" : "hidden",
|
|
35
32
|
onLoad() {
|
|
36
33
|
send({ type: "IMG.LOADED", src: "element" })
|
|
37
34
|
},
|
|
@@ -44,8 +41,8 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
|
|
|
44
41
|
...parts.fallback.attrs,
|
|
45
42
|
dir: state.context.dir,
|
|
46
43
|
id: dom.getFallbackId(state.context),
|
|
47
|
-
hidden:
|
|
48
|
-
"data-state":
|
|
44
|
+
hidden: loaded,
|
|
45
|
+
"data-state": loaded ? "hidden" : "visible",
|
|
49
46
|
}),
|
|
50
47
|
}
|
|
51
48
|
}
|
package/src/avatar.dom.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { createScope } from "@zag-js/dom-query"
|
|
|
2
2
|
import type { MachineContext as Ctx } from "./avatar.types"
|
|
3
3
|
|
|
4
4
|
export const dom = createScope({
|
|
5
|
-
getRootId: (ctx: Ctx) => `avatar:${ctx.id}`,
|
|
6
|
-
getImageId: (ctx: Ctx) => `avatar:${ctx.id}:image`,
|
|
7
|
-
getFallbackId: (ctx: Ctx) => `avatar:${ctx.id}:fallback`,
|
|
5
|
+
getRootId: (ctx: Ctx) => ctx.ids?.root ?? `avatar:${ctx.id}`,
|
|
6
|
+
getImageId: (ctx: Ctx) => ctx.ids?.image ?? `avatar:${ctx.id}:image`,
|
|
7
|
+
getFallbackId: (ctx: Ctx) => ctx.ids?.fallback ?? `avatar:${ctx.id}:fallback`,
|
|
8
8
|
|
|
9
9
|
getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),
|
|
10
10
|
getImageEl: (ctx: Ctx) => dom.getById<HTMLImageElement>(ctx, dom.getImageId(ctx)),
|
package/src/avatar.machine.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createMachine } from "@zag-js/core"
|
|
2
|
-
import { observeAttributes, observeChildren } from "@zag-js/
|
|
2
|
+
import { observeAttributes, observeChildren } from "@zag-js/dom-query"
|
|
3
3
|
import { compact } from "@zag-js/utils"
|
|
4
4
|
import { dom } from "./avatar.dom"
|
|
5
5
|
import type { MachineContext, MachineState, UserDefinedContext } from "./avatar.types"
|
|
@@ -61,19 +61,24 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
61
61
|
{
|
|
62
62
|
activities: {
|
|
63
63
|
trackSrcChange(ctx, _evt, { send }) {
|
|
64
|
-
const
|
|
65
|
-
return observeAttributes(
|
|
66
|
-
|
|
64
|
+
const imageEl = dom.getImageEl(ctx)
|
|
65
|
+
return observeAttributes(imageEl, {
|
|
66
|
+
attributes: ["src", "srcset"],
|
|
67
|
+
callback() {
|
|
68
|
+
send({ type: "SRC.CHANGE" })
|
|
69
|
+
},
|
|
67
70
|
})
|
|
68
71
|
},
|
|
69
72
|
trackImageRemoval(ctx, _evt, { send }) {
|
|
70
73
|
const rootEl = dom.getRootEl(ctx)
|
|
71
|
-
return observeChildren(rootEl,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
return observeChildren(rootEl, {
|
|
75
|
+
callback(records) {
|
|
76
|
+
const removedNodes = Array.from(records[0].removedNodes) as HTMLElement[]
|
|
77
|
+
const removed = removedNodes.find((node) => node.matches("[data-scope=avatar][data-part=image]"))
|
|
78
|
+
if (removed) {
|
|
79
|
+
send({ type: "IMG.UNMOUNT" })
|
|
80
|
+
}
|
|
81
|
+
},
|
|
77
82
|
})
|
|
78
83
|
},
|
|
79
84
|
},
|
package/src/avatar.props.ts
CHANGED
|
@@ -2,5 +2,5 @@ import { createProps } from "@zag-js/types"
|
|
|
2
2
|
import { createSplitProps } from "@zag-js/utils"
|
|
3
3
|
import type { UserDefinedContext } from "./avatar.types"
|
|
4
4
|
|
|
5
|
-
export const props = createProps<UserDefinedContext>()(["dir", "id", "onStatusChange", "getRootNode"])
|
|
5
|
+
export const props = createProps<UserDefinedContext>()(["dir", "id", "ids", "onStatusChange", "getRootNode"])
|
|
6
6
|
export const splitProps = createSplitProps<Partial<UserDefinedContext>>(props)
|
package/src/avatar.types.ts
CHANGED
|
@@ -5,10 +5,18 @@ import type { CommonProperties, DirectionProperty, PropTypes, RequiredBy } from
|
|
|
5
5
|
* Callback details
|
|
6
6
|
* -----------------------------------------------------------------------------*/
|
|
7
7
|
|
|
8
|
+
export type LoadStatus = "error" | "loaded"
|
|
9
|
+
|
|
8
10
|
export interface StatusChangeDetails {
|
|
9
|
-
status:
|
|
11
|
+
status: LoadStatus
|
|
10
12
|
}
|
|
11
13
|
|
|
14
|
+
export type ElementIds = Partial<{
|
|
15
|
+
root: string
|
|
16
|
+
image: string
|
|
17
|
+
fallback: string
|
|
18
|
+
}>
|
|
19
|
+
|
|
12
20
|
/* -----------------------------------------------------------------------------
|
|
13
21
|
* Machine context
|
|
14
22
|
* -----------------------------------------------------------------------------*/
|
|
@@ -18,6 +26,10 @@ interface PublicContext extends CommonProperties, DirectionProperty {
|
|
|
18
26
|
* Functional called when the image loading status changes.
|
|
19
27
|
*/
|
|
20
28
|
onStatusChange?: (details: StatusChangeDetails) => void
|
|
29
|
+
/**
|
|
30
|
+
* The ids of the elements in the avatar. Useful for composition.
|
|
31
|
+
*/
|
|
32
|
+
ids?: ElementIds
|
|
21
33
|
}
|
|
22
34
|
|
|
23
35
|
interface PrivateContext {}
|
|
@@ -44,11 +56,7 @@ export interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
44
56
|
/**
|
|
45
57
|
* Whether the image is loaded.
|
|
46
58
|
*/
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Whether the fallback is shown.
|
|
50
|
-
*/
|
|
51
|
-
showFallback: boolean
|
|
59
|
+
loaded: boolean
|
|
52
60
|
/**
|
|
53
61
|
* Function to set new src.
|
|
54
62
|
*/
|
package/src/index.ts
CHANGED
|
@@ -2,4 +2,10 @@ export { anatomy } from "./avatar.anatomy"
|
|
|
2
2
|
export { connect } from "./avatar.connect"
|
|
3
3
|
export { machine } from "./avatar.machine"
|
|
4
4
|
export * from "./avatar.props"
|
|
5
|
-
export type {
|
|
5
|
+
export type {
|
|
6
|
+
MachineApi as Api,
|
|
7
|
+
UserDefinedContext as Context,
|
|
8
|
+
ElementIds,
|
|
9
|
+
LoadStatus,
|
|
10
|
+
StatusChangeDetails,
|
|
11
|
+
} from "./avatar.types"
|