Skip to content

Commit fbd8e16

Browse files
committed
Flat styled components
1 parent 895d193 commit fbd8e16

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

src/styled.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ interface AnyStyleProps {
7070
style?: UnknownStyles
7171
}
7272

73+
type StyledComponent = React.ForwardRefExoticComponent<Omit<React.PropsWithChildren<UnknownProps & AnyStyleProps & AsComponentProps>, "ref"> & React.RefAttributes<unknown>> & {
74+
isStyled?: boolean
75+
parsers: Parser[]
76+
attrs: InnerAttrs[]
77+
origin: AnyComponent
78+
}
79+
80+
const isStyledComponent = (component: AnyComponent): component is StyledComponent => !!(component as StyledComponent)?.isStyled
81+
7382
const methods = {
7483
style,
7584
maybeDynamic,
@@ -87,27 +96,36 @@ export function createStyled<Theme extends AnyTheme>() {
8796
throw new Error('It seems you forgot to add babel plugin.')
8897
}
8998
}
99+
parsers = isStyledComponent(Component) ? [...Component.parsers, ...parsers] : parsers
100+
attrs = isStyledComponent(Component) ? [...Component.attrs, ...attrs] : attrs
101+
const origin = isStyledComponent(Component) ? Component.origin : Component
90102
const { styles: fixedStyle, dynamic } = splitStyles(parsers)
91103

92104
// Component
93105
const StyledComponent = React.forwardRef((props: PropsWithChildren<UnknownProps & AnyStyleProps & AsComponentProps>, ref) => {
94106
const theme = useContext(ThemeContext)
95-
let propsWithTheme: Themed<UnknownProps, Theme> = Object.assign({}, props, { theme })
96-
propsWithTheme = buildPropsFromAttrs(propsWithTheme, attrs)
97107
let style: StyleProp<UnknownStyles> = fixedStyle
108+
let propsForElement: Themed<UnknownProps, Theme> = Object.assign({}, props, { theme })
109+
if (attrs.length > 0) {
110+
propsForElement = buildPropsFromAttrs(propsForElement, attrs)
111+
}
98112
if (dynamic.length > 0) {
99113
style = Object.assign({}, style)
100-
style = buildDynamicStyles(propsWithTheme, dynamic, style)
114+
style = buildDynamicStyles(propsForElement, dynamic, style)
101115
}
102116
if (props.style) {
103117
style = [style, props.style]
104118
}
105-
const parsedProps = Object.assign(propsWithTheme, { theme: props.theme, ref, style })
106-
const CastedComponent = (props.as ?? Component) as AnyComponent
119+
const parsedProps = Object.assign(propsForElement, { theme: props.theme, ref, style })
120+
const CastedComponent = (props.as ?? origin) as AnyComponent
107121
return createElement(CastedComponent, parsedProps)
108-
})
122+
}) as StyledComponent
109123

110124
StyledComponent.displayName = 'StyledComponent'
125+
StyledComponent.isStyled = true
126+
StyledComponent.parsers = parsers
127+
StyledComponent.attrs = attrs
128+
StyledComponent.origin = origin
111129

112130
return StyledComponent
113131
}

0 commit comments

Comments
 (0)