diff --git a/packages/styled-components/package.json b/packages/styled-components/package.json index 196c2af4..c062078e 100644 --- a/packages/styled-components/package.json +++ b/packages/styled-components/package.json @@ -38,9 +38,10 @@ "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { - "styled-components": "^4.0.0 || ^5.0.0" + "styled-components": "^6.1.11" }, "dependencies": { + "@emotion/is-prop-valid": "^1.2.2", "@xstyled/core": "^3.8.1", "@xstyled/system": "^3.8.1", "@xstyled/util": "^3.7.0" diff --git a/packages/styled-components/src/breakpoints.ts b/packages/styled-components/src/breakpoints.ts index 742d64ec..844d2215 100644 --- a/packages/styled-components/src/breakpoints.ts +++ b/packages/styled-components/src/breakpoints.ts @@ -5,7 +5,7 @@ import { useThemeDown, } from '@xstyled/core' import { Screens } from '@xstyled/system' -import { useTheme } from './theme' +import { useTheme } from 'styled-components' export { useViewportWidth } from '@xstyled/core' diff --git a/packages/styled-components/src/create.ts b/packages/styled-components/src/create.ts index 8afa9644..9a255ed7 100644 --- a/packages/styled-components/src/create.ts +++ b/packages/styled-components/src/create.ts @@ -1,11 +1,11 @@ import { StyleGenerator } from '@xstyled/system' -import { createCssFunction, XCSSFunction } from './createCssFunction' -import { createX, X } from './createX' -import { createStyled, XStyled } from './createStyled' import { - createCreateGlobalStyle, XCreateGlobalStyle, + createCreateGlobalStyle, } from './createCreateGlobalStyle' +import { XCSSFunction, createCssFunction } from './createCssFunction' +import { XStyled, createStyled } from './createStyled' +import { X, createX } from './createX' export interface XStyledSet { css: XCSSFunction @@ -18,9 +18,9 @@ export const createCss = ( generator: TGen, ): XStyledSet => { return { - css: createCssFunction(generator), - x: createX(generator), - styled: createStyled(generator), - createGlobalStyle: createCreateGlobalStyle(generator), + css: createCssFunction(generator), + x: createX(generator), + styled: createStyled(generator), + createGlobalStyle: createCreateGlobalStyle(generator), } } diff --git a/packages/styled-components/src/createCreateGlobalStyle.ts b/packages/styled-components/src/createCreateGlobalStyle.ts index 9bb7b53d..c113edcc 100644 --- a/packages/styled-components/src/createCreateGlobalStyle.ts +++ b/packages/styled-components/src/createCreateGlobalStyle.ts @@ -7,12 +7,10 @@ export type XCreateGlobalStyle = typeof scCreateGlobalStyle export const createCreateGlobalStyle = ( generator: TGen, ): XCreateGlobalStyle => { - const css = createCssFunction(generator) - return (( - ...args: Parameters - ): ReturnType => - scCreateGlobalStyle([ - // @ts-ignore - css(...args), - ])) as XCreateGlobalStyle + const css = createCssFunction(generator) + return ( + ...args: Parameters> + ) => + // @ts-expect-error + scCreateGlobalStyle([css(...args)]) } diff --git a/packages/styled-components/src/createCssFunction.ts b/packages/styled-components/src/createCssFunction.ts index 9ddb8c38..afc2b341 100644 --- a/packages/styled-components/src/createCssFunction.ts +++ b/packages/styled-components/src/createCssFunction.ts @@ -1,22 +1,19 @@ /* eslint-disable no-continue, no-loop-func, no-cond-assign */ -import { - css as scCss, - FlattenSimpleInterpolation, - ThemedCssFunction, -} from 'styled-components' -import { StyleGenerator, Theme } from '@xstyled/system' -import { flattenStrings } from '@xstyled/util' import { createTransform } from '@xstyled/core' +import { StyleGenerator } from '@xstyled/system' +import { flattenStrings } from '@xstyled/util' +import { css as scCss } from 'styled-components' -export type XCSSFunction = ThemedCssFunction +export type XCSSFunction = typeof scCss export const createCssFunction = ( generator: TGen, ): XCSSFunction => { const transform = createTransform(generator) - return ((...args: Parameters) => { - const scCssArgs = scCss(...args) + + return (...args: Parameters) => { + const scCssArgs = scCss(...args) const flattenedArgs = flattenStrings(scCssArgs as any[]) - return flattenedArgs.map(transform) as FlattenSimpleInterpolation - }) as XCSSFunction + return flattenedArgs.map(transform) as ReturnType> + } } diff --git a/packages/styled-components/src/createGlobalStyle.test.tsx b/packages/styled-components/src/createGlobalStyle.test.tsx index d886f625..c0b9ffe5 100644 --- a/packages/styled-components/src/createGlobalStyle.test.tsx +++ b/packages/styled-components/src/createGlobalStyle.test.tsx @@ -16,7 +16,7 @@ describe('#createGlobalStyle', () => { const GlobalStyle = createGlobalStyle` .margin { margin: 2; - } + } ` const { container } = render( <> diff --git a/packages/styled-components/src/createStyled.ts b/packages/styled-components/src/createStyled.ts index 7faad9b5..6e1fd16e 100644 --- a/packages/styled-components/src/createStyled.ts +++ b/packages/styled-components/src/createStyled.ts @@ -1,56 +1,52 @@ /* eslint-disable no-continue, no-loop-func, no-cond-assign */ -import type { ElementType } from 'react' +import isPropValid from '@emotion/is-prop-valid' import { BoxElements } from '@xstyled/core' +import { StyleGenerator, StyleGeneratorProps } from '@xstyled/system' import { string } from '@xstyled/util' -import { StyleGenerator, StyleGeneratorProps, Theme } from '@xstyled/system' import { - StyledConfig, - ThemedBaseStyledInterface, - ThemedStyledFunction, + FastOmit, + LibraryStyled, + ShouldForwardProp, + Styled, + StyledInstance, + StyledOptions, + WebTarget, } from 'styled-components' +import { XCSSFunction, createCssFunction } from './createCssFunction' import { scStyled } from './scStyled' -import { createCssFunction, XCSSFunction } from './createCssFunction' -const getCreateStyle = ( - baseCreateStyle: ThemedStyledFunction, +const getCreateStyle = ( + baseCreateStyle: StyledInstance<'web', any, any>, css: XCSSFunction, - generator?: StyleGenerator, -) => { + generator?: TGen, +): ReturnType>> => { const createStyle = (...args: Parameters) => - // @ts-ignore baseCreateStyle`${css(...args)}${generator}` createStyle.attrs = (attrs: Parameters[0]) => - getCreateStyle(baseCreateStyle.attrs(attrs), css, generator) - createStyle.withConfig = (config: StyledConfig) => - getCreateStyle(baseCreateStyle.withConfig(config), css, generator) + getCreateStyle(baseCreateStyle.attrs(attrs), css, generator) + createStyle.withConfig = (config: StyledOptions<'web', any>) => + getCreateStyle(baseCreateStyle.withConfig(config), css, generator) + // @ts-expect-error return createStyle } type BoxStyledTags = { - [Key in keyof BoxElements]: ThemedStyledFunction< + [Key in keyof BoxElements]: StyledInstance< + 'web', BoxElements[Key], - Theme, - TProps + FastOmit & TProps > } export interface XStyled - extends ThemedBaseStyledInterface, + extends Styled, BoxStyledTags> {} const createShouldForwardProp = ( generator: StyleGenerator, -): (( - prop: string | number | symbol, - defaultValidatorFn: (prop: string | number | symbol) => boolean, - elementToBeCreated?: ElementType, -) => boolean) => { +): ShouldForwardProp<'web'> => { const propSet = new Set(generator.meta.props) - return ( - prop: string | number | symbol, - defaultValidatorFn: (prop: string | number | symbol) => boolean, - elementToBeCreated?: ElementType, - ) => { + return (prop: string, elementToBeCreated?: WebTarget) => { if (string(prop) && propSet.has(prop)) { return false } @@ -61,7 +57,7 @@ const createShouldForwardProp = ( // This means that HTML elements could get unwanted props, but ultimately // this is a bug in the caller, because why are they passing unwanted // props? - return defaultValidatorFn(prop) + return isPropValid(prop) } return true } @@ -71,14 +67,14 @@ export const createBaseStyled = ( css: XCSSFunction, generator?: TGen, ): XStyled => { - const config = generator + const config: StyledOptions<'web', any> = generator ? { shouldForwardProp: createShouldForwardProp(generator), } : {} - return ((component: Parameters[0]) => { + return ((component: Target) => { const baseStyled = scStyled(component) - return getCreateStyle( + return getCreateStyle( config ? baseStyled.withConfig(config) : baseStyled, css, generator, @@ -86,18 +82,21 @@ export const createBaseStyled = ( }) as XStyled } +type JSXElementKeys = BoxElements[keyof BoxElements] + export const createStyled = ( generator: TGen, ): XStyled => { - const css = createCssFunction(generator) - const styled = createBaseStyled(css) - const xstyled = createBaseStyled(css, generator) + const css = createCssFunction(generator) + const styled = createBaseStyled(css) + const xstyled = createBaseStyled(css, generator) styled.box = xstyled('div') - Object.keys(scStyled).forEach((key) => { - // @ts-ignore + ;(Object.keys(scStyled) as JSXElementKeys[]).forEach((key) => { + // @ts-expect-error styled[key] = styled(key) - // @ts-ignore + // @ts-expect-error styled[`${key}Box`] = xstyled(key) }) + return styled } diff --git a/packages/styled-components/src/createX.ts b/packages/styled-components/src/createX.ts index 5c0c298f..103df928 100644 --- a/packages/styled-components/src/createX.ts +++ b/packages/styled-components/src/createX.ts @@ -1,33 +1,33 @@ /* eslint-disable no-continue, no-loop-func, no-cond-assign */ -import { StyledComponent, DefaultTheme } from 'styled-components' -import { scStyled } from './scStyled' import { StyleGenerator, StyleGeneratorProps } from '@xstyled/system' -import { createBaseStyled } from './createStyled' +import { + FastOmit, + SupportedHTMLElements, + IStyledComponent, +} from 'styled-components' import { createCssFunction } from './createCssFunction' - -type JSXElementKeys = keyof JSX.IntrinsicElements - -type SafeIntrinsicElement = ( - props: Omit, -) => React.ReactElement +import { createBaseStyled } from './createStyled' +import { scStyled } from './scStyled' export type X = { - [Key in JSXElementKeys]: StyledComponent< - SafeIntrinsicElement, - DefaultTheme, - StyleGeneratorProps, - 'color' + [Key in SupportedHTMLElements]: IStyledComponent< + 'web', + FastOmit> & + StyleGeneratorProps > } export const createX = ( generator: TGen, ): X => { - const xstyled = createBaseStyled(createCssFunction(generator), generator) + const xstyled = createBaseStyled( + createCssFunction(generator), + generator, + ) const x = {} as X Object.keys(scStyled).forEach((tag) => { - // @ts-ignore - x[tag] = xstyled(tag)`` + // @ts-expect-error + x[tag] = xstyled(tag)({}) }) return x } diff --git a/packages/styled-components/src/scStyled.ts b/packages/styled-components/src/scStyled.ts index d969f3cc..9aad87df 100644 --- a/packages/styled-components/src/scStyled.ts +++ b/packages/styled-components/src/scStyled.ts @@ -1,6 +1,6 @@ -import styled from 'styled-components' +import styled, { Styled } from 'styled-components' // Provide interop since `styled-components` does not work out of the box with ESM export const scStyled = - // @ts-ignore - typeof styled === 'function' ? styled : styled.default + // @ts-expect-error + (typeof styled === 'function' ? styled : styled.default) as Styled diff --git a/packages/styled-components/src/styled.test.tsx b/packages/styled-components/src/styled.test.tsx index af4eedc9..8f739a68 100644 --- a/packages/styled-components/src/styled.test.tsx +++ b/packages/styled-components/src/styled.test.tsx @@ -38,11 +38,9 @@ describe('#styled', () => { }) it('works with render props', () => { - const Foo = ({ - children, - }: { + const Foo: React.FC<{ children: ({ content }: { content: string }) => React.ReactNode - }) =>
{children({ content: 'Hello World' })}
+ }> = ({ children }) =>
{children({ content: 'Hello World' })}
const StyledFoo = styled(Foo)`` diff --git a/packages/styled-components/src/theme.ts b/packages/styled-components/src/theme.ts index 3ed8f62a..fed2f1a8 100644 --- a/packages/styled-components/src/theme.ts +++ b/packages/styled-components/src/theme.ts @@ -1,11 +1,8 @@ -import { useContext, ContextType } from 'react' -import { ThemeContext } from 'styled-components' import { createUseGetter } from '@xstyled/core' import { th } from '@xstyled/system' +import { useTheme } from 'styled-components' -export const useTheme = (): ContextType => { - return useContext(ThemeContext) -} +export { useTheme } export const useTh = createUseGetter(th, useTheme) diff --git a/packages/styled-components/src/x.test.tsx b/packages/styled-components/src/x.test.tsx index f8bce9a1..4ab43fbd 100644 --- a/packages/styled-components/src/x.test.tsx +++ b/packages/styled-components/src/x.test.tsx @@ -17,7 +17,7 @@ describe('#x', () => { const { container } = render() expect(container.firstChild).toHaveStyle(` margin: 2px; - padding: 1px; + padding: 1px; `) }) @@ -26,7 +26,7 @@ describe('#x', () => { expect(container.firstChild!.nodeName).toBe('A') expect(container.firstChild).toHaveStyle(` margin: 2px; - padding: 1px; + padding: 1px; `) }) @@ -39,7 +39,7 @@ describe('#x', () => { expect(container.firstChild!.nodeName).toBe('A') expect(container.firstChild).toHaveStyle(` margin: 2px; - padding: 1px; + padding: 1px; `) }) @@ -54,7 +54,7 @@ describe('#x', () => { expect(container.firstChild!.nodeName).toBe('A') expect(container.firstChild).toHaveStyle(` margin: 8px; - padding: 4px; + padding: 4px; `) })