menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

styled-components

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress!

Channels
Team

TS: Accept `as` prop in a wrapper component to send in to styled-component

June 18, 2021 at 12:54pm

TS: Accept `as` prop in a wrapper component to send in to styled-component

June 18, 2021 at 12:54pm
I am wondering how I can reuse the as prop TypeScript type in this wrapper component:
import React from 'react';
import styled from 'styled-components';
import theme, { ColorValue } from 'theme';
import { MarginProps } from 'utils/style';
const FONT_SIZE = {
displayTitle: 40,
primaryHeading: 34,
secondaryHeading: 28,
leadText: 20,
paragraph: 16,
paragraphSmall: 14,
xs: 12
};
const FONT_WEIGHT = {
regular: 400,
medium: 500,
semiBold: 600,
bold: 700
};
const SPACING = {
xxs: 4,
xs: 8,
s: 16,
m: 24,
l: 32,
xl: 40,
xxl: 48,
jumbo: 80
};
const PrimaryHeading = styled.h1`
font-size: ${FONT_SIZE.primaryHeading}px;
line-height: ${SPACING.xl}px;
letter-spacing: -0.4px;
font-weight: ${FONT_WEIGHT.regular};
`;
const SecondaryHeading = styled.h2`
font-size: ${FONT_SIZE.secondaryHeading}px;
line-height: ${SPACING.l}px;
letter-spacing: -0.4px;
font-weight: ${FONT_WEIGHT.regular};
`;
type TypographyProps = {
variant:
| 'primaryHeading'
| 'secondaryHeading'
children?: React.ReactNode;
color?: ColorValue;
as?: StyledComponentProps<>; // HERE: what is the type to use here? I want to accept an `as` prop to my `<Typography />` component.
} & MarginProps;
const components = {
primaryHeading: PrimaryHeading,
secondaryHeading: SecondaryHeading
};
const Typography = ({ variant, children, color, as }: TypographyProps) => {
const Comp = components[variant];
return (
<Comp color={color} {...(as ? { as } : {})}>
{children}
</Comp>
);
};
Typography.defaultProps = {
children: null,
color: theme.palette.black,
as: null
};
export default Typography;

June 18, 2021 at 5:41pm
While I don't know how to help you type as, I think you're basically trying to recreate https://styled-system.com/. Unless it is for learning purposes, I suggest you use that instead.

June 23, 2021 at 8:50am
Seems a bit overkill to introduce a new dependency just for this? So let's assume it is for learning purposes. I know in "easier" typings I can do SomeExternalType['aPropType']. This is not so easy when the types need generics and I have no idea what they should be.
I agree that adding another dependency shouldn't be done lightly and only after careful consideration.
However, in this case, I don't think that's an overkill. styled-system is looks (to me) very similar to what you're trying to achieve, only it is already used by many people, standardized and maintained. Why reinvent the wheel with another bespoke solution which future maintainers of your codebase will have to deal with?
BTW, personally, I don't even like the entire class of "styling as props" packages which to styled-system belongs. So it isn't a subjective recommendation of styled-system at all. It just seems to me like the technically correct solution to your requirements.
Edited