diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/atoms/icons/plus-minus.module.scss | 39 | ||||
| -rw-r--r-- | src/components/atoms/icons/plus-minus.stories.tsx | 73 | ||||
| -rw-r--r-- | src/components/atoms/icons/plus-minus.test.tsx | 16 | ||||
| -rw-r--r-- | src/components/atoms/icons/plus-minus.tsx | 45 | 
4 files changed, 173 insertions, 0 deletions
| diff --git a/src/components/atoms/icons/plus-minus.module.scss b/src/components/atoms/icons/plus-minus.module.scss new file mode 100644 index 0000000..c54db33 --- /dev/null +++ b/src/components/atoms/icons/plus-minus.module.scss @@ -0,0 +1,39 @@ +@use "@styles/abstracts/functions" as fun; + +.icon { +  display: flex; +  place-content: center; +  place-items: center; +  width: var(--icon-size, #{fun.convert-px(30)}); +  height: var(--icon-size, #{fun.convert-px(30)}); +  position: relative; +  background: var(--color-bg); +  border: fun.convert-px(1) solid var(--color-primary); +  border-radius: fun.convert-px(3); +  color: var(--color-primary); + +  &::before, +  &::after { +    content: ""; +    position: absolute; +    background: var(--color-primary); +    transition: transform 0.4s ease-out 0s; +  } + +  &::after { +    height: fun.convert-px(3); +    width: 60%; +  } + +  &::before { +    height: 60%; +    width: fun.convert-px(3); +    transform: scaleY(1); +  } + +  &--minus { +    &::before { +      transform: scaleY(0); +    } +  } +} diff --git a/src/components/atoms/icons/plus-minus.stories.tsx b/src/components/atoms/icons/plus-minus.stories.tsx new file mode 100644 index 0000000..1b5086a --- /dev/null +++ b/src/components/atoms/icons/plus-minus.stories.tsx @@ -0,0 +1,73 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import PlusMinusIcon from './plus-minus'; + +export default { +  title: 'Atoms/Icons', +  component: PlusMinusIcon, +  args: { +    ariaHidden: true, +  }, +  argTypes: { +    additionalClasses: { +      control: { +        type: 'text', +      }, +      description: 'Set additional classes.', +      table: { +        category: 'Options', +      }, +      type: { +        name: 'string', +        required: false, +      }, +    }, +    ariaHidden: { +      control: { +        type: 'boolean', +      }, +      description: 'Should be hidden for accessibility.', +      table: { +        category: 'Options', +        defaultValue: { summary: true }, +      }, +      type: { +        name: 'boolean', +        required: false, +      }, +    }, +    ariaLabel: { +      control: { +        type: 'text', +      }, +      description: 'An accessible name.', +      table: { +        category: 'Options', +      }, +      type: { +        name: 'string', +        required: false, +      }, +    }, +    state: { +      control: { +        type: 'radio', +        options: ['plus', 'minus'], +      }, +      description: 'Which state should be displayed.', +      type: { +        name: 'enum', +        required: true, +        value: ['plus', 'minus'], +      }, +    }, +  }, +} as ComponentMeta<typeof PlusMinusIcon>; + +const Template: ComponentStory<typeof PlusMinusIcon> = (args) => ( +  <PlusMinusIcon {...args} /> +); + +export const PlusMinus = Template.bind({}); +PlusMinus.args = { +  state: 'plus', +}; diff --git a/src/components/atoms/icons/plus-minus.test.tsx b/src/components/atoms/icons/plus-minus.test.tsx new file mode 100644 index 0000000..96c2ad0 --- /dev/null +++ b/src/components/atoms/icons/plus-minus.test.tsx @@ -0,0 +1,16 @@ +import { render, screen } from '@test-utils'; +import PlusMinus from './plus-minus'; + +describe('PlusMinus', () => { +  it('renders a plus icon', () => { +    render(<PlusMinus state="plus" ariaHidden={false} ariaLabel="Plus icon" />); +    expect(screen.getByLabelText('Plus icon')).toHaveClass('icon--plus'); +  }); + +  it('renders a minus icon', () => { +    render( +      <PlusMinus state="minus" ariaHidden={false} ariaLabel="Minus icon" /> +    ); +    expect(screen.getByLabelText('Minus icon')).toHaveClass('icon--minus'); +  }); +}); diff --git a/src/components/atoms/icons/plus-minus.tsx b/src/components/atoms/icons/plus-minus.tsx new file mode 100644 index 0000000..1a6f7b0 --- /dev/null +++ b/src/components/atoms/icons/plus-minus.tsx @@ -0,0 +1,45 @@ +import { FC } from 'react'; +import styles from './plus-minus.module.scss'; + +type PlusMinusProps = { +  /** +   * Adds additional classes. +   */ +  additionalClasses?: string; +  /** +   * An accessible name. +   */ +  ariaLabel?: string; +  /** +   * Should be hidden for accessibility. Default: true. +   */ +  ariaHidden?: boolean; +  /** +   * Which state should be displayed. +   */ +  state: 'plus' | 'minus'; +}; + +/** + * PlusMinus component + * + * Render a plus or a minus icon. + */ +const PlusMinus: FC<PlusMinusProps> = ({ +  additionalClasses, +  ariaHidden = true, +  ariaLabel, +  state, +}) => { +  const stateClass = `icon--${state}`; + +  return ( +    <div +      className={`${styles.icon} ${styles[stateClass]} ${additionalClasses}`} +      aria-label={ariaLabel} +      aria-hidden={ariaHidden} +    ></div> +  ); +}; + +export default PlusMinus; | 
