Компонент заголовка в стилизованной системе

Как я могу создать общий компонент заголовка, используя стилизованную систему и стилизованные компоненты?

Следующее работает, но все мои заголовки используют тег h1.

import css from "@styled-system/css"
import styled from "styled-components"
import { color, ColorProps, textAlign, TextAlignProps, variant } from "styled-system"

type Props = {
  level: 1 | 2 | 3 | 4 | 5 | 6
} & TextAlignProps &
  ColorProps

const Css = css({
  fontFamily: "heading",
  fontWeight: "heading",
})

const Variant = variant({
  prop: "level",
  variants: {
    1: {
      fontSize: 7,
      lineHeight: 7,
    },
    2: {
      fontSize: 6,
      lineHeight: 6,
    },
    3: {
      fontSize: 5,
      lineHeight: 5,
    },
    4: {
      fontSize: 4,
      lineHeight: 4,
    },
    5: {
      fontSize: 3,
      lineHeight: 3,
    },
    6: {
      fontSize: 2,
      lineHeight: 2,
    },
  },
})

const Heading = styled("h1")<Props>(Css, Variant, textAlign, color)

export default Heading

Я попытался создать компонент HeadingBase, например:

type Props = {
  level: 1 | 2 | 3 | 4 | 5 | 6,
  as: string | undefined
} & TextAlignProps &
  ColorProps

const HeadingBase = ({ level, as: Component = `h${level}`, ...props }: Props) => <Component {...props} />

const Heading = styled(HeadingBase)<Props>(Css, Variant, textAlign, color)

Но я получаю сообщение об ошибке на <Component {...props} />, потому что у него нет API для TextAlignProps и ColorProps.


person lolol    schedule 05.04.2021    source источник


Ответы (1)


Возможно, вы можете использовать as, чтобы при предоставлении варианта ключ as автоматически заменялся строкой варианта. Это может быть проще объяснить кодом, посмотрите.

const headingVariant = ({ fontSize }) => {
  let variantConfig = {
    h1: {
      fontSize: [7, 8], //28px 32px
    },
    h2: {
      fontSize: [6, 7], //24px 28px
    },
    h3: {
      fontSize: ['22px', 6], //22px 24px
    },
    h4: {
      fontSize: 5, //20px
    },
    h5: {
      fontSize: 4, //18px
    },
  };

  if (fontSize) {
    variantConfig = Object.keys(variantConfig).reduce((acc, currKey) => {
      acc[currKey] = {
        ...variantConfig[currKey],
        fontSize,
      };
      return acc;
    }, {});
  }
  return variant({
    prop: 'variant',
    variants: variantConfig,
  });
};

const Heading = styled(BaseText).attrs(
  ({ variant: hybridVariant, as: asOverride }) => ({
    as: asOverride ?? hybridVariant,
  })
)(
  ({ isBold, color }) =>
    css({
      fontFamily: `sofia-pro, Helvetica, Arial`,
      lineHeight: '130%',
      color: color || 'text',
      fontWeight: isBold ? 1 : 0,
      fontStyle: 'normal',
    }),
  headingVariant
);

Heading.propTypes = {
  isBold: PropTypes.bool,
  variant: PropTypes.string,
};

Heading.defaultProps = {
  isBold: true,
  variant: 'h2',
};

export default Heading;
person ParthianShotgun    schedule 05.04.2021