diff options
Diffstat (limited to 'src/components')
4 files changed, 177 insertions, 0 deletions
| diff --git a/src/components/atoms/loaders/progress-bar.module.scss b/src/components/atoms/loaders/progress-bar.module.scss new file mode 100644 index 0000000..166b7c4 --- /dev/null +++ b/src/components/atoms/loaders/progress-bar.module.scss @@ -0,0 +1,43 @@ +@use "@styles/abstracts/functions" as fun; + +.progress { +  width: max-content; +  margin: var(--spacing-sm) auto var(--spacing-md); +  text-align: center; + +  &__info { +    margin-bottom: var(--spacing-2xs); +    font-size: var(--font-size-sm); +  } + +  &__bar[value] { +    display: block; +    width: clamp(25ch, 20vw, 30ch); +    max-width: 100%; +    height: fun.convert-px(13); +    appearance: none; +    background: var(--color-bg-tertiary); +    border: fun.convert-px(1) solid var(--color-primary-darker); +    border-radius: 1em; +    box-shadow: inset 0 0 fun.convert-px(4) fun.convert-px(1) +      var(--color-shadow-light); + +    &::-webkit-progress-value { +      background-color: var(--color-primary-dark); +      border-radius: 1em; +    } + +    &::-moz-progress-bar { +      background-color: var(--color-primary-dark); +      border-radius: 1em; +    } + +    &::-webkit-progress-bar { +      background: var(--color-bg-tertiary); +      border: fun.convert-px(1) solid var(--color-primary-darker); +      border-radius: 1em; +      box-shadow: inset 0 0 fun.convert-px(4) fun.convert-px(1) +        var(--color-shadow-light); +    } +  } +} diff --git a/src/components/atoms/loaders/progress-bar.stories.tsx b/src/components/atoms/loaders/progress-bar.stories.tsx new file mode 100644 index 0000000..837a696 --- /dev/null +++ b/src/components/atoms/loaders/progress-bar.stories.tsx @@ -0,0 +1,70 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import ProgressBarComponent from './progress-bar'; + +export default { +  title: 'Atoms/Loaders', +  component: ProgressBarComponent, +  argTypes: { +    ariaLabel: { +      control: { +        type: 'string', +      }, +      description: 'An accessible name.', +      type: { +        name: 'string', +        required: false, +      }, +    }, +    current: { +      control: { +        type: 'number', +      }, +      description: 'The current value.', +      type: { +        name: 'number', +        required: true, +      }, +    }, +    info: { +      control: { +        type: 'text', +      }, +      description: 'An additional information to display.', +      type: { +        name: 'string', +        required: false, +      }, +    }, +    max: { +      control: { +        type: 'number', +      }, +      description: 'The maximal value.', +      type: { +        name: 'number', +        required: true, +      }, +    }, +    min: { +      control: { +        type: 'number', +      }, +      description: 'The minimal value.', +      type: { +        name: 'number', +        required: true, +      }, +    }, +  }, +} as ComponentMeta<typeof ProgressBarComponent>; + +const Template: ComponentStory<typeof ProgressBarComponent> = (args) => ( +  <ProgressBarComponent {...args} /> +); + +export const ProgressBar = Template.bind({}); +ProgressBar.args = { +  current: 10, +  min: 0, +  max: 50, +}; diff --git a/src/components/atoms/loaders/progress-bar.test.tsx b/src/components/atoms/loaders/progress-bar.test.tsx new file mode 100644 index 0000000..37a7364 --- /dev/null +++ b/src/components/atoms/loaders/progress-bar.test.tsx @@ -0,0 +1,9 @@ +import { render, screen } from '@test-utils'; +import ProgressBar from './progress-bar'; + +describe('ProgressBar', () => { +  it('renders a progress bar', () => { +    render(<ProgressBar min={0} max={50} current={10} />); +    expect(screen.getByRole('progressbar')).toBeInTheDocument(); +  }); +}); diff --git a/src/components/atoms/loaders/progress-bar.tsx b/src/components/atoms/loaders/progress-bar.tsx new file mode 100644 index 0000000..fa4e09d --- /dev/null +++ b/src/components/atoms/loaders/progress-bar.tsx @@ -0,0 +1,55 @@ +import { FC } from 'react'; +import styles from './progress-bar.module.scss'; + +export type ProgressBarProps = { +  /** +   * Accessible progress bar name. +   */ +  ariaLabel?: string; +  /** +   * Current value. +   */ +  current: number; +  /** +   * Additional information to display before progress bar. +   */ +  info?: string; +  /** +   * Minimal value. +   */ +  min: number; +  /** +   * Maximal value. +   */ +  max: number; +}; + +/** + * ProgressBar component + * + * Render a progress bar. + */ +const ProgressBar: FC<ProgressBarProps> = ({ +  ariaLabel, +  current, +  info, +  min, +  max, +}) => { +  return ( +    <div className={styles.progress}> +      {info && <div className={styles.progress__info}>{info}</div>} +      <progress +        className={styles.progress__bar} +        max={max} +        value={current} +        aria-valuemin={min} +        aria-valuemax={max} +        aria-valuenow={current} +        aria-label={ariaLabel} +      ></progress> +    </div> +  ); +}; + +export default ProgressBar; | 
