diff options
Diffstat (limited to 'src/components/atoms')
| -rw-r--r-- | src/components/atoms/layout/copyright.module.scss | 32 | ||||
| -rw-r--r-- | src/components/atoms/layout/copyright.stories.tsx | 55 | ||||
| -rw-r--r-- | src/components/atoms/layout/copyright.test.tsx | 32 | ||||
| -rw-r--r-- | src/components/atoms/layout/copyright.tsx | 59 | 
4 files changed, 178 insertions, 0 deletions
| diff --git a/src/components/atoms/layout/copyright.module.scss b/src/components/atoms/layout/copyright.module.scss new file mode 100644 index 0000000..a0e5347 --- /dev/null +++ b/src/components/atoms/layout/copyright.module.scss @@ -0,0 +1,32 @@ +@use "@styles/abstracts/functions" as fun; +@use "@styles/abstracts/mixins" as mix; + +.wrapper { +  --icon-size: #{fun.convert-px(70)}; + +  display: flex; +  flex-flow: row wrap; +  align-items: center; +  place-content: center; +  gap: var(--spacing-2xs); +  margin: 0; +  font-family: var(--font-family-secondary); +  font-size: var(--font-size-md); +  text-align: center; + +  @include mix.media("screen") { +    @include mix.dimensions("sm") { +      text-align: left; +    } +  } +} + +.owner { +  flex: 1 0 100%; + +  @include mix.media("screen") { +    @include mix.dimensions("sm") { +      flex: initial; +    } +  } +} diff --git a/src/components/atoms/layout/copyright.stories.tsx b/src/components/atoms/layout/copyright.stories.tsx new file mode 100644 index 0000000..3b315fa --- /dev/null +++ b/src/components/atoms/layout/copyright.stories.tsx @@ -0,0 +1,55 @@ +import CCBySA from '@components/atoms/icons/cc-by-sa'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import { IntlProvider } from 'react-intl'; +import CopyrightComponent from './copyright'; + +export default { +  title: 'Atoms/Layout', +  component: CopyrightComponent, +  argTypes: { +    dates: { +      description: 'The copyright dates.', +      type: { +        name: 'object', +        required: true, +        value: {}, +      }, +    }, +    icon: { +      control: { +        type: null, +      }, +      description: 'The copyright icon.', +      type: { +        name: 'string', +        required: true, +      }, +    }, +    owner: { +      control: { +        type: 'text', +      }, +      description: 'The copyright owner', +      type: { +        name: 'string', +        required: true, +      }, +    }, +  }, +} as ComponentMeta<typeof CopyrightComponent>; + +const Template: ComponentStory<typeof CopyrightComponent> = (args) => ( +  <IntlProvider locale="en"> +    <CopyrightComponent {...args} /> +  </IntlProvider> +); + +export const Copyright = Template.bind({}); +Copyright.args = { +  dates: { +    start: '2012', +    end: '2022', +  }, +  icon: <CCBySA />, +  owner: 'Your name', +}; diff --git a/src/components/atoms/layout/copyright.test.tsx b/src/components/atoms/layout/copyright.test.tsx new file mode 100644 index 0000000..6bfe612 --- /dev/null +++ b/src/components/atoms/layout/copyright.test.tsx @@ -0,0 +1,32 @@ +import CCBySA from '@components/atoms/icons/cc-by-sa'; +import { render, screen } from '@test-utils'; +import Copyright from './copyright'; + +const dates = { +  start: '2012', +  end: '2022', +}; +const icon = <CCBySA />; +const owner = 'Your name'; + +describe('Copyright', () => { +  it('renders the copyright owner', () => { +    render(<Copyright dates={dates} icon={icon} owner={owner} />); +    expect(screen.getByText(owner)).toBeInTheDocument(); +  }); + +  it('renders the copyright start date', () => { +    render(<Copyright dates={dates} icon={icon} owner={owner} />); +    expect(screen.getByText(dates.start)).toBeInTheDocument(); +  }); + +  it('renders the copyright end date', () => { +    render(<Copyright dates={dates} icon={icon} owner={owner} />); +    expect(screen.getByText(dates.end)).toBeInTheDocument(); +  }); + +  it('renders the copyright icon', () => { +    render(<Copyright dates={dates} icon={icon} owner={owner} />); +    expect(screen.getByTitle('CC BY SA')).toBeInTheDocument(); +  }); +}); diff --git a/src/components/atoms/layout/copyright.tsx b/src/components/atoms/layout/copyright.tsx new file mode 100644 index 0000000..76252ee --- /dev/null +++ b/src/components/atoms/layout/copyright.tsx @@ -0,0 +1,59 @@ +import { ReactNode, VFC } from 'react'; +import styles from './copyright.module.scss'; + +export type CopyrightDates = { +  /** +   * The copyright start year. +   */ +  start: string; +  /** +   * The copyright end year. +   */ +  end?: string; +}; + +export type CopyrightProps = { +  /** +   * The copyright owner. +   */ +  owner: string; +  /** +   * The copyright dates. +   */ +  dates: CopyrightDates; +  /** +   * The copyright icon. +   */ +  icon: ReactNode; +}; + +/** + * Copyright component + * + * Renders a copyright information (owner, dates, license icon). + */ +const Copyright: VFC<CopyrightProps> = ({ owner, dates, icon }) => { +  const getFormattedDate = (date: string) => { +    const datetime = new Date(date).toISOString(); + +    return <time dateTime={datetime}>{date}</time>; +  }; + +  return ( +    <div className={styles.wrapper}> +      <span className={styles.owner}>{owner}</span> +      {icon} +      {getFormattedDate(dates.start)} +      {dates.end ? ( +        <> +          <span>-</span> +          {getFormattedDate(dates.end)} +        </> +      ) : ( +        '' +      )} +    </div> +  ); +}; + +export default Copyright; | 
