@primer/react
Version:
An implementation of GitHub's Primer Design System using React
107 lines (103 loc) • 4.69 kB
JavaScript
import React, { forwardRef } from 'react';
import styled, { keyframes } from 'styled-components';
import { width } from 'styled-system';
import { get } from '../constants.js';
import sx from '../sx.js';
import { toggleStyledComponent } from '../internal/utils/toggleStyledComponent.js';
import { clsx } from 'clsx';
import classes from './ProgressBar.module.css.js';
import '../FeatureFlags/FeatureFlags.js';
import { useFeatureFlag } from '../FeatureFlags/useFeatureFlag.js';
import '../FeatureFlags/DefaultFeatureFlags.js';
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
const shimmer = keyframes(["from{mask-position:200%;}to{mask-position:0%;}"]);
const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_ga';
const ProgressItem = toggleStyledComponent(CSS_MODULES_FEATURE_FLAG, 'span', styled.span.withConfig({
displayName: "ProgressBar__ProgressItem",
componentId: "sc-1jz8j7n-0"
})(["width:", ";background-color:", ";@media (prefers-reduced-motion:no-preference){&[data-animated='true']{mask-image:linear-gradient(75deg,#000 30%,rgba(0,0,0,0.65) 80%);mask-size:200%;animation:", ";animation-duration:1s;animation-iteration-count:infinite;}}", ";"], props => props.progress ? `${props.progress}%` : 0, props => get(`colors.${props.bg || 'success.emphasis'}`), shimmer, sx));
const sizeMap = {
small: '5px',
large: '10px',
default: '8px'
};
const ProgressContainer = toggleStyledComponent(CSS_MODULES_FEATURE_FLAG, 'span', styled.span.withConfig({
displayName: "ProgressBar__ProgressContainer",
componentId: "sc-1jz8j7n-1"
})(["display:", ";overflow:hidden;background-color:", ";border-radius:", ";height:", ";gap:2px;", " ", ";"], props => props.inline ? 'inline-flex' : 'flex', get('colors.border.default'), get('radii.1'), props => sizeMap[props.barSize || 'default'], width, sx));
const Item = /*#__PURE__*/forwardRef(({
progress,
'aria-label': ariaLabel,
'aria-valuenow': ariaValueNow,
'aria-valuetext': ariaValueText,
className,
...rest
}, forwardRef) => {
const progressAsNumber = typeof progress === 'string' ? parseInt(progress, 10) : progress;
const ariaAttributes = {
'aria-valuenow': ariaValueNow !== null && ariaValueNow !== undefined ? ariaValueNow : progressAsNumber !== undefined && progressAsNumber >= 0 ? Math.round(progressAsNumber) : 0,
'aria-valuemin': 0,
'aria-valuemax': 100,
'aria-valuetext': ariaValueText
};
const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG);
const progressBarWidth = '--progress-width';
const progressBarBg = '--progress-bg';
const styles = {};
const bgType = rest.bg && rest.bg.split('.');
styles[progressBarWidth] = progress ? `${progress}%` : '0%';
styles[progressBarBg] = bgType && `var(--bgColor-${bgType[0]}-${bgType[1]})` || 'var(--bgColor-success-emphasis)';
return /*#__PURE__*/React.createElement(ProgressItem, _extends({
className: clsx(className, {
[classes.ProgressBarItem]: enabled
})
}, rest, {
role: "progressbar",
"aria-label": ariaLabel,
ref: forwardRef,
progress: progress,
style: enabled ? styles : undefined
}, ariaAttributes));
});
Item.displayName = 'ProgressBar.Item';
const ProgressBar = /*#__PURE__*/forwardRef(({
animated,
progress,
bg = 'success.emphasis',
barSize = 'default',
children,
'aria-label': ariaLabel,
'aria-valuenow': ariaValueNow,
'aria-valuetext': ariaValueText,
className,
...rest
}, forwardRef) => {
if (children && progress) {
throw new Error('You should pass `progress` or children, not both.');
}
// Get the number of non-empty nodes passed as children, this will exclude
// booleans, null, and undefined
const validChildren = React.Children.toArray(children).length;
const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG);
const cssModulesProps = !enabled ? {
barSize
} : {
'data-progress-display': rest.inline ? 'inline' : 'block',
'data-progress-bar-size': barSize
};
return /*#__PURE__*/React.createElement(ProgressContainer, _extends({
ref: forwardRef,
className: clsx(className, {
[classes.ProgressBarContainer]: enabled
})
}, cssModulesProps, rest), validChildren ? children : /*#__PURE__*/React.createElement(Item, {
"data-animated": animated,
progress: progress,
"aria-label": ariaLabel,
"aria-valuenow": ariaValueNow,
"aria-valuetext": ariaValueText,
bg: bg
}));
});
ProgressBar.displayName = 'ProgressBar';
export { Item, ProgressBar };