-
-
Notifications
You must be signed in to change notification settings - Fork 273
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 stylesand 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