import * as React from 'react'; import {accessibleHide, createComponent} from '@workday/canvas-kit-react/common'; import {createStencil, handleCsProp, keyframes} from '@workday/canvas-kit-styling'; import {SkeletonHeader} from './parts/SkeletonHeader'; import {SkeletonShape} from './parts/SkeletonShape'; import {SkeletonText} from './parts/SkeletonText'; export interface SkeletonProps { /** * For accessibility reasons, `aria-label` is transformed into a text representation * (visually hidden, but announced by screen readers) of the loader. * * IMPORTANT: Since we take over the use of `aria-label` here, the attribute * does not get applied to the container element. We anticipate that this will change * in a future major version. * @default 'Loading' */ 'aria-label'?: string; children?: React.ReactNode; } const fade = keyframes({ from: {opacity: 0.4}, to: {opacity: 1}, }); export const skeletonStencil = createStencil({ base: () => ({ animation: `${fade} 0.8s linear infinite alternate`, position: 'relative', overflow: 'hidden', height: '100%', width: '100%', '& [data-part="skeleton-accessible-hide"]': { ...accessibleHide, }, }), }); /** * Skeleton subcomponents **must** be wrapped by the `Skeleton` container component. * * ```tsx * * * * * ``` * * `Skeleton` places its children in a container element with `aria-hidden` set to `true` and * announces itself using a visually hidden element. */ export const Skeleton = createComponent('div')({ displayName: 'Skeleton', Component: ( {children, 'aria-label': loadingAriaLabel = 'Loading', ...elemProps}: SkeletonProps, ref, Element ) => (
{loadingAriaLabel}
{children}
), subComponents: { /** * `Skeleton.Header` renders a placeholder for header content such as headings. */ Header: SkeletonHeader, /** * `Skeleton.Text` renders a placeholder for text content such as paragraphs. Each placeholder * line has a width of `100%` and a fixed height of `21px`, with the last line having a width of * `60%` if there are multiple lines. */ Text: SkeletonText, /** * `Skeleton.Shape` renders a placeholder for graphic elements such as icons, avatars and small * images. Set the `height`, `width`, and `borderRadius` props of the `Skeleton.Shape` to create * various rectangular and circular shapes. */ Shape: SkeletonShape, }, });