diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-04-05 23:01:32 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-04-05 23:01:32 +0200 |
| commit | 57568e61c22c41c073f4db59992735387e8372fe (patch) | |
| tree | f07d95abb248c110393d9870e7ab12864369b3f0 /src/components/atoms/loaders | |
| parent | 0c1d12c7f951db56e501145bd73071480273340a (diff) | |
chore: add a ProgressBar component
Diffstat (limited to 'src/components/atoms/loaders')
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; |
