UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

117 lines (116 loc) 3.65 kB
"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