import { forwardRef } from 'react'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; import { px, rangeLimit, round } from '@gilbarbara/helpers'; import { StringOrNumber } from '@gilbarbara/types'; import { SetRequired } from 'type-fest'; import { getColorVariant, getTheme } from './modules/helpers'; import { baseStyles, getStyledOptions, isDarkMode, marginStyles } from './modules/system'; import { Paragraph } from './Paragraph'; import { ComponentProps, Shades, StyledProps, WithColor, WithMargin } from './types'; export interface ProgressBarKnownProps extends StyledProps, WithColor, WithMargin { /** @default light */ backgroundShade?: Shades; /** @default false */ hideText?: boolean; /** @default false */ large?: boolean; step: number; steps: number; /** @default 100% */ width?: StringOrNumber; } export type ProgressBarProps = ComponentProps; export const defaultProps = { backgroundShade: 'light', hideText: false, large: false, shade: 'mid', variant: 'primary', width: '100%', } satisfies Omit; export const StyledProgressBar = styled( 'div', getStyledOptions(), )>(props => { const { width } = props; const { grayLight } = getTheme(props); return css` ${baseStyles(props)}; color: ${isDarkMode(props) && grayLight}; width: ${px(width)}; ${marginStyles(props)}; `; }); const StyledProgressTrack = styled( 'div', getStyledOptions(), )>(props => { const { backgroundShade, large, shade, variant } = props; const { radius, variants } = getTheme(props); const { bg } = getColorVariant(variant, shade, variants); const height = large ? '8px' : '4px'; return css` background-color: ${variants.gray[backgroundShade].bg}; border-radius: ${large ? radius.xs : radius.xxs}; line-height: 1; height: ${height}; overflow: hidden; > div { background-color: ${bg}; height: ${height}; transition: width 0.4s; width: 0; } `; }); export const ProgressBar = forwardRef((props, ref) => { const { hideText, step, steps, ...rest } = { ...defaultProps, ...props }; const percentage = round(rangeLimit((step / steps) * 100)); const stepLimit = rangeLimit(step, 0, steps); return ( {!hideText && {`Step ${stepLimit} of ${steps}`}}
); }); ProgressBar.displayName = 'ProgressBar';