I am trying to use PayPal's Glamorous CSS-in-JS library in a boilerplate project I'm building which also leverages TypeScript.
Glamorous allows you to add props to an element like-so:
const Section = glamorous.section([
{
...styles
},
({size}: any){
if(size === 'big') return {fontSize: '48px';}
else if(size === 'small') return {fontSize: '12px';}
},
({alignment}: any){
if(alignment === 'left') return {textAlign: 'left'}
else if(alignment === 'right') return {textAlign: 'right'}
}
]);
So that you can then use the element in JSX like this:
<Section size="big"></Section>
I have a number of props like this that I would like to add to all of my Glamorous-generated elements. So, I've created a helper function that looks like this:
export const special = (glam: any, styles: object[]): GBPComp =>{
return glam([styles as CSSStyleDeclaration[], specialProps]);
};
Where specialProps
represents a function (like the one above) that adds the various props to my array of style declarations.
I intend to use it like this:
const Section = special(glamorous.section, [
{
...styles
}
]);
I then want all of the props provided by specialProps
to be typed for my JSX usage. So, I've tried to create my GBPComp
type like this:
export type GBPComp = React.StatelessComponent<CSSProperties&ExtraGlamorousProps&React.HTMLProps<HTMLElement>&{
layout?: string,
width?: string
}>;
The issue arises with the fact that not all of the elements returned will necessarily have a property of React.HTMLProps<HTMLElement>
. They may be HTMLAnchorElement
or HTMLTableElement
, etc.
How might I be able to generate my GBPComp
type dynmically, such that it adds those props (i.e. layout
and width
) to all returned types? Such that the following will work properly within TypeScript:
const Section = special(glamorous.section, [
{
...styles
}
]);
const Anchor = special(glamorous.a, [
{
...styles
}
]);
<a href="#" layout="someString">This is an Anchor</a>
<section layout="someString">This is a Section</section>
If you do not want
React.HTMLProps<HTMLElement>
for every elements, instead of hardcodingReact.HTMLProps<HTMLElement>
, you could use generics for yourGBPComp
like soAnd
special()
also acceptsExtraProps
as generics and pass toGBPComp
like soNow you can assign
React.HTMLProps<HTMLAnchorElement>
props to yourAnchor