diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-09-27 17:38:23 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-10-24 12:25:00 +0200 |
| commit | 7255d25f6834a208c0ed44636356cc260f6ab6ba (patch) | |
| tree | 88016a958190f766a3ac0ab4b77f4732e17502e8 /src/components/atoms/heading/heading.tsx | |
| parent | ba793e043e4d8515b1a9ea490ee2c5f92b1fd6c2 (diff) | |
refactor(components): rewrite Heading component
* remove `alignment` and `withMargin` props (consumer should handle
that)
* move styles to Sass placeholders to avoid repeats with headings
coming from WordPress
* refactor some other components that depend on Heading to avoid ESlint
errors
Diffstat (limited to 'src/components/atoms/heading/heading.tsx')
| -rw-r--r-- | src/components/atoms/heading/heading.tsx | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/components/atoms/heading/heading.tsx b/src/components/atoms/heading/heading.tsx new file mode 100644 index 0000000..6cdb578 --- /dev/null +++ b/src/components/atoms/heading/heading.tsx @@ -0,0 +1,57 @@ +import { + type ForwardedRef, + forwardRef, + type ForwardRefRenderFunction, + type HTMLAttributes, + type ReactNode, +} from 'react'; +import styles from './heading.module.scss'; + +// eslint-disable-next-line @typescript-eslint/no-magic-numbers +export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6; + +export type HeadingProps = HTMLAttributes<HTMLHeadingElement> & { + /** + * The heading body. + */ + children: ReactNode; + /** + * Use an heading element or only its styles. + * + * @default false + */ + isFake?: boolean; + /** + * HTML heading level. + */ + level: HeadingLevel; +}; + +const HeadingWithRef: ForwardRefRenderFunction< + HTMLHeadingElement | HTMLParagraphElement, + HeadingProps +> = ( + { children, className = '', isFake = false, level, ...props }, + ref: ForwardedRef<HTMLHeadingElement | HTMLParagraphElement> +) => { + const HeadingTag = `h${level}` as const; + const levelClass = styles[`heading--${level}`]; + const headingClass = `${levelClass} ${className}`; + + return isFake ? ( + <p {...props} className={headingClass} ref={ref}> + {children} + </p> + ) : ( + <HeadingTag {...props} className={headingClass} ref={ref}> + {children} + </HeadingTag> + ); +}; + +/** + * Heading component. + * + * Render an HTML heading element or a paragraph with heading styles. + */ +export const Heading = forwardRef(HeadingWithRef); |
