UNPKG

@spaced-out/ui-design-system

Version:
1,061 lines (1,024 loc) 26.8 kB
// @flow strict import * as React from 'react'; import type {ColorTypes} from '../../types/typography'; import {TEXT_COLORS} from '../../types/typography'; import classify from '../../utils/classify'; import {escapeRegExp} from '../../utils/string'; import css from '../../styles/typography.module.css'; export type TextProps = { color?: ColorTypes, children?: React.Node, className?: string, highlightedTextClassName?: string, highlightString?: string | string[], caseSensitiveHighlighting?: boolean, highlightWithBackground?: boolean, ... }; export type HighlightTextProps = { text: string, highlight: string | string[], highlightClassName?: string, caseSensitiveHighlighting?: boolean, highlightWithBackground?: boolean, }; const HighlightText: React$AbstractComponent< HighlightTextProps, HTMLSpanElement, > = React.forwardRef<HighlightTextProps, HTMLSpanElement>( ( { text, highlight, highlightClassName, caseSensitiveHighlighting, highlightWithBackground, }: HighlightTextProps, ref, ) => { // Split text on highlight term, include term itself into parts, ignore case // Convert highlight to an array if it's not already const highlightArray = [].concat(highlight).filter((item) => item !== ''); const highlights = highlightArray.map(escapeRegExp).join('|'); const parts = text .split( new RegExp(`(${highlights})`, caseSensitiveHighlighting ? '' : 'gi'), ) .filter((part) => part !== ''); return ( <span ref={ref}> {parts.map((part, idx) => { const isHighlighted = highlightArray.some((highlightTerm) => caseSensitiveHighlighting ? escapeRegExp(part).includes(escapeRegExp(highlightTerm)) : escapeRegExp(part) .toLowerCase() .includes(escapeRegExp(highlightTerm).toLowerCase()), ); return isHighlighted ? ( <span // eslint-disable-next-line react/no-array-index-key key={idx} className={classify( css.highlightText, { [css.bgHighlighting]: highlightWithBackground, }, highlightClassName, )} > {part} </span> ) : ( part ); })} </span> ); }, ); export const JumboLarge: React$AbstractComponent<TextProps, HTMLSpanElement> = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.jumboLarge, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const JumboMedium: React$AbstractComponent<TextProps, HTMLSpanElement> = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.jumboMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const JumboSmall: React$AbstractComponent<TextProps, HTMLSpanElement> = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.jumboSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const TitleMedium: React$AbstractComponent< TextProps, HTMLHeadingElement, > = React.forwardRef<TextProps, HTMLHeadingElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <h1 {...props} className={classify(css.titleMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </h1> ), ); export const SubTitleLarge: React$AbstractComponent< TextProps, HTMLHeadingElement, > = React.forwardRef<TextProps, HTMLHeadingElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <h2 {...props} className={classify(css.subTitleLarge, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </h2> ), ); export const SubTitleMedium: React$AbstractComponent< TextProps, HTMLHeadingElement, > = React.forwardRef<TextProps, HTMLHeadingElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <h3 {...props} className={classify(css.subTitleMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </h3> ), ); export const SubTitleSmall: React$AbstractComponent< TextProps, HTMLHeadingElement, > = React.forwardRef<TextProps, HTMLHeadingElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <h4 {...props} className={classify(css.subTitleSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </h4> ), ); export const SubTitleExtraSmall: React$AbstractComponent< TextProps, HTMLHeadingElement, > = React.forwardRef<TextProps, HTMLHeadingElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <h5 {...props} className={classify(css.subTitleExtraSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </h5> ), ); export const ButtonTextMedium: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.buttonTextMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const ButtonTextSmall: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.buttonTextSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const MenuTextMedium: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.menuTextMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const MenuTextSmall: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.menuTextSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const ButtonTextExtraSmall: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.buttonTextExtraSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const ButtonTextMediumUnderline: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify( css.buttonTextMedium, css.underline, css[color], className, )} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const ButtonTextSmallUnderline: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify( css.buttonTextSmall, css.underline, css[color], className, )} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const ButtonTextExtraSmallUnderline: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify( css.buttonTextExtraSmall, css.underline, css[color], className, )} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const FormInputMedium: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.formInputMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const FormInputSmall: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.formInputSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const BodyLarge: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.bodyLarge, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const BodyMedium: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.bodyMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const BodySmall: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.bodySmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const BodyLargeBold: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.bodyLarge, css.bold, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const BodyMediumBold: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.bodyMedium, css.bold, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const BodySmallBold: React$AbstractComponent< TextProps, HTMLParagraphElement, > = React.forwardRef<TextProps, HTMLParagraphElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <p {...props} className={classify(css.bodySmall, css.bold, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </p> ), ); export const FormLabelMedium: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.formLabelMedium, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), ); export const FormLabelSmall: React$AbstractComponent< TextProps, HTMLSpanElement, > = React.forwardRef<TextProps, HTMLSpanElement>( ( { color = TEXT_COLORS.primary, children, className, highlightedTextClassName, highlightString, caseSensitiveHighlighting, highlightWithBackground, ...props }: TextProps, ref, ): React.Node => ( <span {...props} className={classify(css.formLabelSmall, css[color], className)} ref={ref} > {!!highlightString?.length && typeof children === 'string' ? ( <HighlightText text={children} highlight={highlightString} caseSensitiveHighlighting={caseSensitiveHighlighting} highlightClassName={highlightedTextClassName} highlightWithBackground={highlightWithBackground} /> ) : ( children )} </span> ), );