ui-ingredients
Version:
Headless component library for Svelte powered by zag
60 lines (59 loc) • 2.1 kB
JavaScript
import { getDocument, getWindow } from '@zag-js/dom-query';
import { getEnvironmentContext } from '../EnvironmentProvider/EnvironmentProviderContext.svelte.js';
import { getLocaleContext } from '../LocaleProvider/LocaleProviderContext.svelte.js';
import { anatomy } from './Alert.anatomy.js';
const parts = anatomy.build();
export function createAlert(props) {
const locale = getLocaleContext();
const environment = getEnvironmentContext();
const id = $derived(props().id);
const ids = $derived({
root: props().ids?.root ?? `alert:${id}`,
title: props().ids?.title ?? `alert:${id}:title`,
description: props().ids?.description ?? `alert:${id}:description`,
});
let hasTitle = $state(false);
let hasDescription = $state(false);
$effect(() => {
const rootNode = environment?.().getRootNode() ?? document;
const doc = getDocument(rootNode);
const win = getWindow(rootNode);
function handler() {
hasTitle = doc.getElementById(ids.title) !== null;
hasDescription = doc.getElementById(ids.description) !== null;
}
handler();
const observer = new win.MutationObserver(handler);
observer.observe(rootNode, { childList: true, subtree: true });
return () => observer.disconnect();
});
function getRootProps() {
return {
id: ids.root,
dir: locale?.().dir,
role: 'alert',
'aria-labelledby': hasTitle ? ids.title : undefined,
'aria-describedby': hasDescription ? ids.description : undefined,
...parts.root.attrs,
};
}
function getTitleProps() {
return {
id: ids.title,
dir: locale?.().dir,
...parts.title.attrs,
};
}
function getDescriptionProps() {
return {
id: ids.description,
dir: locale?.().dir,
...parts.description.attrs,
};
}
return () => ({
getRootProps,
getTitleProps,
getDescriptionProps,
});
}