diff options
Diffstat (limited to 'src/components/atoms/headings')
| -rw-r--r-- | src/components/atoms/headings/heading.module.scss | 16 | ||||
| -rw-r--r-- | src/components/atoms/headings/heading.stories.tsx | 26 | ||||
| -rw-r--r-- | src/components/atoms/headings/heading.tsx | 58 | 
3 files changed, 86 insertions, 14 deletions
| diff --git a/src/components/atoms/headings/heading.module.scss b/src/components/atoms/headings/heading.module.scss index 8620f6f..a420bc1 100644 --- a/src/components/atoms/headings/heading.module.scss +++ b/src/components/atoms/headings/heading.module.scss @@ -6,11 +6,23 @@    letter-spacing: 0.01ex;    &--regular { -    margin: 0; +    margin-bottom: 0; +    margin-top: 0; +  } + +  &--left { +    text-align: left; +  } + +  &--center { +    width: fit-content; +    margin-left: auto; +    margin-right: auto;    }    &--margin { -    margin: 0 0 var(--spacing-sm); +    margin-top: 0; +    margin-bottom: var(--spacing-sm);      & + & {        margin-top: var(--spacing-md); diff --git a/src/components/atoms/headings/heading.stories.tsx b/src/components/atoms/headings/heading.stories.tsx index da5a718..0e3885d 100644 --- a/src/components/atoms/headings/heading.stories.tsx +++ b/src/components/atoms/headings/heading.stories.tsx @@ -8,10 +8,26 @@ export default {    title: 'Atoms/Typography/Headings',    component: Heading,    args: { +    alignment: 'left',      isFake: false,      withMargin: true,    },    argTypes: { +    alignment: { +      control: { +        type: 'select', +      }, +      description: 'The title alignment.', +      options: ['center', 'left'], +      table: { +        category: 'Options', +        defaultValue: { summary: 'left' }, +      }, +      type: { +        name: 'string', +        required: false, +      }, +    },      className: {        control: {          type: 'text', @@ -32,6 +48,16 @@ export default {          required: true,        },      }, +    id: { +      control: { +        type: 'text', +      }, +      description: 'An unique id.', +      type: { +        name: 'string', +        required: false, +      }, +    },      isFake: {        control: {          type: 'boolean', diff --git a/src/components/atoms/headings/heading.tsx b/src/components/atoms/headings/heading.tsx index c5bf4ca..e385249 100644 --- a/src/components/atoms/headings/heading.tsx +++ b/src/components/atoms/headings/heading.tsx @@ -1,10 +1,20 @@ -import { FC, ReactNode } from 'react'; +import { +  createElement, +  ForwardedRef, +  forwardRef, +  ForwardRefRenderFunction, +  ReactNode, +} from 'react';  import styles from './heading.module.scss';  export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;  export type HeadingProps = {    /** +   * The title alignment. Default: left; +   */ +  alignment?: 'center' | 'left'; +  /**     * The heading body.     */    children: ReactNode; @@ -30,31 +40,55 @@ export type HeadingProps = {    withMargin?: boolean;  }; +type TitleTagProps = Pick<HeadingProps, 'children' | 'className' | 'id'> & { +  tagName: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p'; +}; + +const TitleTag = forwardRef< +  HTMLHeadingElement | HTMLParagraphElement, +  TitleTagProps +>( +  ( +    { children, tagName, ...props }, +    ref: ForwardedRef<HTMLHeadingElement | HTMLParagraphElement> +  ) => { +    return createElement(tagName, { ...props, ref }, children); +  } +); +TitleTag.displayName = 'TitleTag'; +  /**   * Heading component.   *   * Render an HTML heading element or a paragraph with heading styles.   */ -const Heading: FC<HeadingProps> = ({ -  children, -  className, -  id, -  isFake = false, -  level, -  withMargin = true, -}) => { -  const TitleTag = isFake ? `p` : (`h${level}` as keyof JSX.IntrinsicElements); +const Heading: ForwardRefRenderFunction<HTMLDivElement, HeadingProps> = ( +  { +    alignment = 'left', +    children, +    className, +    id, +    isFake = false, +    level, +    withMargin = true, +  }, +  ref: ForwardedRef<HTMLHeadingElement | HTMLParagraphElement> +) => { +  const tagName = isFake ? 'p' : (`h${level}` as TitleTagProps['tagName']);    const levelClass = `heading--${level}`; +  const alignmentClass = `heading--${alignment}`;    const marginClass = withMargin ? 'heading--margin' : 'heading--regular';    return (      <TitleTag -      className={`${styles.heading} ${styles[levelClass]} ${styles[marginClass]} ${className}`} +      tagName={tagName} +      className={`${styles.heading} ${styles[levelClass]} ${styles[alignmentClass]} ${styles[marginClass]} ${className}`}        id={id} +      ref={ref}      >        {children}      </TitleTag>    );  }; -export default Heading; +export default forwardRef(Heading); | 
