@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
117 lines (116 loc) • 3.65 kB
JavaScript
"use client";
import React from 'react';
import clsx from 'clsx';
import { extendExistingPropsWithContext, removeUndefinedProps, validateDOMAttributes } from "../../shared/component-helper.js";
import { LOCALE } from "../../shared/defaults.js";
import Space from "../space/Space.js";
import { applySpacing } from "../space/SpacingUtils.js";
import Context from "../../shared/Context.js";
import Provider from "../../shared/Provider.js";
import withComponentMarkers from "../../shared/helpers/withComponentMarkers.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const skeletonDefaultProps = {
show: null,
skeleton: null,
noAnimation: null,
figure: null,
ariaBusy: null,
ariaReady: null,
element: null,
className: null,
children: null
};
function Skeleton(props) {
const context = React.useContext(Context);
const [ariaLiveUpdate, setAriaLiveUpdate] = React.useState(null);
const ariaLiveUpdateTimeoutRef = React.useRef(null);
const prevShowRef = React.useRef(props.show);
const getProps = React.useCallback((propsToExtend = props, ctx = context) => {
return extendExistingPropsWithContext({
...skeletonDefaultProps,
...removeUndefinedProps({
...propsToExtend
})
}, skeletonDefaultProps, {
skeleton: ctx.Skeleton || ctx.skeleton,
noAnimation: ctx.skeletonNoAnimation
}, ctx.getTranslation(propsToExtend).Skeleton);
}, [props, context]);
const updateAriaLive = React.useCallback(() => {
clearTimeout(ariaLiveUpdateTimeoutRef.current);
ariaLiveUpdateTimeoutRef.current = setTimeout(() => {
const {
ariaBusy,
ariaReady
} = getProps();
let newString = null;
if (props.show) {
newString = ariaBusy;
} else {
newString = ariaReady;
}
if (newString) {
setAriaLiveUpdate(newString);
ariaLiveUpdateTimeoutRef.current = setTimeout(() => {
setAriaLiveUpdate(null);
}, 1e3);
}
}, 1e3);
}, [props.show, getProps]);
React.useEffect(() => {
if (prevShowRef.current !== props.show) {
updateAriaLive();
}
prevShowRef.current = props.show;
}, [props.show, updateAriaLive]);
React.useEffect(() => {
return () => {
clearTimeout(ariaLiveUpdateTimeoutRef.current);
};
}, []);
const extendedProps = getProps();
const {
show,
noAnimation,
figure,
skeleton,
ariaBusy,
ariaReady,
className,
children,
...attributes
} = extendedProps;
const showSkeleton = typeof show === 'boolean' || typeof show === 'string' ? show : skeleton;
const params = applySpacing(extendedProps, {
className: clsx(figure ? 'dnb-skeleton__figure' : 'dnb-skeleton__root', className, showSkeleton && 'dnb-skeleton', noAnimation && 'dnb-skeleton--no-animation'),
'aria-busy': showSkeleton,
'aria-label': showSkeleton ? ariaBusy : undefined,
lang: context.locale || LOCALE,
...attributes
});
validateDOMAttributes(props, params);
return _jsxs(Space, {
...params,
children: [figure ? showSkeleton ? typeof figure === 'function' ? figure() : figure : children : _jsx(Provider, {
skeleton: showSkeleton,
skeletonNoAnimation: noAnimation,
children: children
}), _jsx("span", {
className: "dnb-sr-only",
"aria-live": "assertive",
children: ariaLiveUpdate
})]
});
}
export default Skeleton;
function Exclude(props) {
return _jsx(Provider, {
...props,
skeleton: false
});
}
Skeleton.Exclude = Exclude;
withComponentMarkers(Skeleton, {
_supportsSpacingProps: true
});
//# sourceMappingURL=Skeleton.js.map