package.dist.index.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of avatar Show documentation
Show all versions of avatar Show documentation
Core logic for the avatar widget implemented as a state machine
The newest version!
'use strict';
var anatomy$1 = require('@zag-js/anatomy');
var domQuery = require('@zag-js/dom-query');
var core = require('@zag-js/core');
var utils = require('@zag-js/utils');
var types = require('@zag-js/types');
// src/avatar.anatomy.ts
var anatomy = anatomy$1.createAnatomy("avatar").parts("root", "image", "fallback");
var parts = anatomy.build();
var dom = domQuery.createScope({
getRootId: (ctx) => ctx.ids?.root ?? `avatar:${ctx.id}`,
getImageId: (ctx) => ctx.ids?.image ?? `avatar:${ctx.id}:image`,
getFallbackId: (ctx) => ctx.ids?.fallback ?? `avatar:${ctx.id}:fallback`,
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
getImageEl: (ctx) => dom.getById(ctx, dom.getImageId(ctx))
});
// src/avatar.connect.ts
function connect(state, send, normalize) {
const loaded = state.matches("loaded");
return {
loaded,
setSrc(src) {
send({ type: "SRC.SET", src });
},
setLoaded() {
send({ type: "IMG.LOADED", src: "api" });
},
setError() {
send({ type: "IMG.ERROR", src: "api" });
},
getRootProps() {
return normalize.element({
...parts.root.attrs,
dir: state.context.dir,
id: dom.getRootId(state.context)
});
},
getImageProps() {
return normalize.img({
...parts.image.attrs,
hidden: !loaded,
dir: state.context.dir,
id: dom.getImageId(state.context),
"data-state": loaded ? "visible" : "hidden",
onLoad() {
send({ type: "IMG.LOADED", src: "element" });
},
onError() {
send({ type: "IMG.ERROR", src: "element" });
}
});
},
getFallbackProps() {
return normalize.element({
...parts.fallback.attrs,
dir: state.context.dir,
id: dom.getFallbackId(state.context),
hidden: loaded,
"data-state": loaded ? "hidden" : "visible"
});
}
};
}
function machine(userContext) {
const ctx = utils.compact(userContext);
return core.createMachine(
{
id: "avatar",
initial: "loading",
activities: ["trackImageRemoval"],
context: ctx,
on: {
"SRC.CHANGE": {
target: "loading"
},
"IMG.UNMOUNT": {
target: "error"
}
},
states: {
loading: {
activities: ["trackSrcChange"],
entry: ["checkImageStatus"],
on: {
"IMG.LOADED": {
target: "loaded",
actions: ["invokeOnLoad"]
},
"IMG.ERROR": {
target: "error",
actions: ["invokeOnError"]
}
}
},
error: {
activities: ["trackSrcChange"],
on: {
"IMG.LOADED": {
target: "loaded",
actions: ["invokeOnLoad"]
}
}
},
loaded: {
activities: ["trackSrcChange"],
on: {
"IMG.ERROR": {
target: "error",
actions: ["invokeOnError"]
}
}
}
}
},
{
activities: {
trackSrcChange(ctx2, _evt, { send }) {
const imageEl = dom.getImageEl(ctx2);
return domQuery.observeAttributes(imageEl, {
attributes: ["src", "srcset"],
callback() {
send({ type: "SRC.CHANGE" });
}
});
},
trackImageRemoval(ctx2, _evt, { send }) {
const rootEl = dom.getRootEl(ctx2);
return domQuery.observeChildren(rootEl, {
callback(records) {
const removedNodes = Array.from(records[0].removedNodes);
const removed = removedNodes.find(
(node) => node.nodeType === Node.ELEMENT_NODE && node.matches("[data-scope=avatar][data-part=image]")
);
if (removed) {
send({ type: "IMG.UNMOUNT" });
}
}
});
}
},
actions: {
invokeOnLoad(ctx2) {
ctx2.onStatusChange?.({ status: "loaded" });
},
invokeOnError(ctx2) {
ctx2.onStatusChange?.({ status: "error" });
},
checkImageStatus(ctx2, _evt, { send }) {
const imageEl = dom.getImageEl(ctx2);
if (imageEl?.complete) {
const type = hasLoaded(imageEl) ? "IMG.LOADED" : "IMG.ERROR";
send({ type, src: "ssr" });
}
}
}
}
);
}
function hasLoaded(image) {
return image.complete && image.naturalWidth !== 0 && image.naturalHeight !== 0;
}
var props = types.createProps()(["dir", "id", "ids", "onStatusChange", "getRootNode"]);
var splitProps = utils.createSplitProps(props);
exports.anatomy = anatomy;
exports.connect = connect;
exports.machine = machine;
exports.props = props;
exports.splitProps = splitProps;
© 2015 - 2025 Weber Informatics LLC | Privacy Policy