UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

107 lines (103 loc) 4.69 kB
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 };