ui-ingredients
Version:
Headless component library for Svelte powered by zag
69 lines (68 loc) • 2.34 kB
JavaScript
import { getDocument, getWindow } from '@zag-js/dom-query';
import { getEnvironmentContext } from '../environment-provider/enviroment-provider-context.svelte.js';
import { getLocaleContext } from '../locale-provider/locale-provider-context.svelte.js';
import { parts } from './alert-anatomy.js';
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`,
indicator: props.ids?.indicator ?? `alert:${id}:indicator`,
});
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,
};
}
function getIndicatorProps() {
return {
id: ids.indicator,
dir: locale?.dir,
'aria-hidden': true,
...parts.indicator.attrs,
};
}
return {
getRootProps,
getTitleProps,
getDescriptionProps,
getIndicatorProps,
};
}