Description
Description
Hello,
Thank you for your contribution to this wonderful library. You can see the bug in the reproduction link. Bellow is an explanation with the problem and a fix.
The issue is in the src/styled-system/jsx/factory.js
file with this line:
let { as: Element = __base__, ...elementProps } = props
If as
is a string, for example, h1
it will call:
return createElement(Element, {
ref,
...elementProps,
className: classes(),
})
And will create an h1
with the classes and styles from the component. The problem is that __base__
is a react component. In our case comp B
which renders comp A
. They will be ignored and the as
value will be used.
To fix it, I've changed the code to be the following in factory.js
:
import { createElement, forwardRef } from 'react'
import { getDisplayName } from './factory-helper.js'
import { css, cx } from '../css/index.js'
function createStyledFn(Dynamic) {
const __base__ = Dynamic.__base__ || Dynamic
return function styledFn(template) {
const styles = css.raw(template)
const StyledComponent = /* @__PURE__ */ forwardRef(function StyledComponent(
props,
ref,
) {
let { as: Element = __base__, ...elementProps } = props
if (typeof __base__ !== 'string') {
Element = __base__
}
function classes() {
return cx(css(__base__.__styles__, styles), elementProps.className)
}
return createElement(Element, {
ref,
...elementProps,
as: props.as,
className: classes(),
})
})
const name = getDisplayName(__base__)
StyledComponent.displayName = `styled.${name}`
StyledComponent.__styles__ = styles
StyledComponent.__base__ = __base__
return StyledComponent
}
}
function createJsxFactory() {
const cache = new Map()
return new Proxy(createStyledFn, {
apply(_, __, args) {
return createStyledFn(...args)
},
get(_, el) {
if (!cache.has(el)) {
cache.set(el, createStyledFn(el))
}
return cache.get(el)
},
})
}
export const styled = /* @__PURE__ */ createJsxFactory()
This way the styles are kept from the other components and the as
thingy also works.
Link to Reproduction
https://stackblitz.com/edit/vitejs-vite-enjwupkj?file=src%2FApp.tsx
Steps to reproduce
- Use template literal syntax
- Create at least 2 components like this: A = styled.span
some styles
and B = styled(A)other styles
- Use the last styled component with the as prop: fdfd
- The styles from comp A are not applied
JS Framework
No response
Panda CSS Version
0.48.0
Browser
No response
Operating System
- macOS
- Windows
- Linux
Additional Information
No response