UNPKG

@carbon/react

Version:

React components for the Carbon Design System

97 lines (92 loc) 2.9 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js'; import PropTypes from 'prop-types'; import React, { useRef } from 'react'; import cx from 'classnames'; import { usePrefix } from '../../internal/usePrefix.js'; import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js'; const randoms = [0.973051493507435, 0.15334737213558558, 0.5671034553053769]; function getRandomInt(min, max, n) { return Math.floor(randoms[n % 3] * (max - min + 1)) + min; } const SkeletonText = ({ paragraph = false, lineCount = 3, width = '100%', heading = false, className = '', ...rest }) => { const prefix = usePrefix(); const skeletonTextClasses = cx({ [`${prefix}--skeleton__text`]: true, [`${prefix}--skeleton__heading`]: heading, [className]: className }); const widthNum = parseInt(width, 10); const widthPx = width.includes('px'); const widthPercent = width.includes('%'); let lineCountNumber = 1; if (paragraph) { lineCountNumber = lineCount; } const refs = useRef([]); useIsomorphicEffect(() => { refs.current.map((item, j) => { const randomPercentWidth = getRandomInt(0, 75, j) + 'px'; const randomPxWidth = getRandomInt(Math.max(widthNum - 75, 0), widthNum, j) + 'px'; if (item) { if (widthPercent && paragraph) { item.style.width = `calc(${width} - ${randomPercentWidth})`; } else if (widthPx && paragraph) { item.style.width = randomPxWidth; } else { item.style.width = width; } } }); }, [lineCountNumber, paragraph, refs, width, widthNum, widthPercent, widthPx]); const lines = []; for (let i = 0; i < lineCountNumber; i++) { lines.push(/*#__PURE__*/React.createElement("p", _extends({ className: skeletonTextClasses, key: i, ref: el => { refs.current = [...refs.current, el]; } }, rest))); } if (lineCountNumber !== 1) { return /*#__PURE__*/React.createElement("div", null, lines); } // eslint-disable-next-line react/jsx-no-useless-fragment return /*#__PURE__*/React.createElement(React.Fragment, null, lines); }; SkeletonText.propTypes = { /** * Specify an optional className to be applied to the container node */ className: PropTypes.string, /** * generates skeleton text at a larger size */ heading: PropTypes.bool, /** * the number of lines shown if paragraph is true */ lineCount: PropTypes.number, /** * will generate multiple lines of text */ paragraph: PropTypes.bool, /** * width (in px or %) of single line of text or max-width of paragraph lines */ width: PropTypes.string }; export { SkeletonText as default };