diff --git a/CHANGELOG.md b/CHANGELOG.md index 4557438d..ce374112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Precise UI Changelog +## 2.1.17 + +- Make dynamically created Headline subcomponents static + ## 2.1.16 - Fix some typings for React 18 compatibility. diff --git a/package.json b/package.json index f6dd6f31..0fd826b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "precise-ui", - "version": "2.1.16", + "version": "2.1.17", "description": "Precise UI React component library powered by Styled Components.", "keywords": [ "react", diff --git a/src/components/Headline/Headline.test.tsx b/src/components/Headline/Headline.test.tsx index 956a4b0c..314fb70c 100644 --- a/src/components/Headline/Headline.test.tsx +++ b/src/components/Headline/Headline.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { mount, mount } from 'enzyme'; +import { mount } from 'enzyme'; import { Headline } from './'; import { light } from '../../themes'; diff --git a/src/components/Headline/index.tsx b/src/components/Headline/index.tsx index 7b5bc9a7..9b603e5c 100644 --- a/src/components/Headline/index.tsx +++ b/src/components/Headline/index.tsx @@ -6,12 +6,14 @@ import { getFontStyle } from '../../textStyles'; export type HeadlineSize = 'small' | 'medium'; +export type HeadlineLevel = keyof typeof styledHeadlines; + export interface HeadlineProps extends StandardProps { /** * Represent 5 levels of headings (1-5) * Default is 3 */ - level?: 1 | 2 | 3 | 4 | 5; + level?: HeadlineLevel; /** * When specified headline will have muted text color */ @@ -24,67 +26,55 @@ export interface HeadlineProps extends StandardProps { export interface StyledHeadlineProps { size: HeadlineSize; - level: number; + level: HeadlineLevel; theme?: any; subheader?: boolean; } -interface HeadlineCache { - [key: string]: any; -} - -const Headlines: HeadlineCache = {}; - -function getComponentName(level: number) { - return `h${level >= 1 && level <= 5 ? level : 3}`; -} - -function getHeadlineStyle(level: StyledHeadlineProps['level']) { - switch (level) { - case 1: - return getFontStyle({ size: 'xxxLarge', weight: 'light' }); - case 2: - return getFontStyle({ size: 'xxLarge', weight: 'light' }); - case 3: - return getFontStyle({ size: 'xLarge', weight: 'medium' }); - case 4: - return getFontStyle({ size: 'large', weight: 'regular' }); - case 5: - return getFontStyle({ size: 'medium', weight: 'medium' }); - default: - return ''; - } -} - -function getStyledHeadline(level: number) { - const component = getComponentName(level); - const Headline = Headlines[component]; - - if (!Headline) { - const NewHeadline = styled(component as 'h1')( - themed( - props => css` - ${getHeadlineStyle(props.level)} - - margin: 0; - padding: ${props.theme.headingsPadding || `0 ${distance.small} 0 0`}; - font-family: ${props.theme.fontFamily || 'inherit'}; - color: ${props.subheader ? props.theme.text5 : 'inherit'}; - `, - ), - ); - Headlines[component] = NewHeadline; - return NewHeadline; - } +/** + * A common style for all headline levels. + */ +const baseStyle = themed( + props => css` + margin: 0; + padding: ${props.theme.headingsPadding || `0 ${distance.small} 0 0`}; + font-family: ${props.theme.fontFamily || 'inherit'}; + color: ${props.subheader ? props.theme.text5 : 'inherit'}; + `, +); - return Headline; -} +/** + * A map of styled components for each headline level. + */ +const styledHeadlines = { + 1: styled.h1` + ${getFontStyle({ size: 'xxxLarge', weight: 'light' })} + ${baseStyle} + `, + 2: styled.h2` + ${getFontStyle({ size: 'xxLarge', weight: 'light' })} + ${baseStyle} + `, + 3: styled.h3` + ${getFontStyle({ size: 'xLarge', weight: 'medium' })} + ${baseStyle} + `, + 4: styled.h4` + ${getFontStyle({ size: 'large', weight: 'regular' })} + ${baseStyle} + `, + 5: styled.h5` + ${getFontStyle({ size: 'medium', weight: 'medium' })} + ${baseStyle} + `, +}; /** * Headline component with styles for all headline levels. */ export const Headline: React.SFC = ({ level = 3, children, ...rest }) => { - const StyledHeadline = getStyledHeadline(level); + const StyledHeadline = styledHeadlines[level] || styledHeadlines[3]; + return ( {children}