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); |
