aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/atoms/headings
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/atoms/headings')
-rw-r--r--src/components/atoms/headings/heading.module.scss16
-rw-r--r--src/components/atoms/headings/heading.stories.tsx26
-rw-r--r--src/components/atoms/headings/heading.tsx58
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);