From 74ab55e68ab82eb6faf0ed83341f1ae6a7239adc Mon Sep 17 00:00:00 2001 From: Gabriel Santerre <gab@100terres.com> Date: Mon, 3 Oct 2022 01:18:50 -0400 Subject: [PATCH] fix(types): restrict regular styles function call to one argument --- src/index.d.ts | 95 +++++++++++++++++++++++++--------------------- test/test.spec.tsx | 26 +++++++++++++ 2 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 500f710..678fd46 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,21 +1,41 @@ import { Properties as CSSProperties } from "csstype"; -import { JSX } from "solid-js"; +import { JSX, Component } from "solid-js"; + +// This type is only available in Solid 1.5 or later. +type ValidComponent = + | keyof JSX.IntrinsicElements + | Component<any> + | (string & {}); + export interface DefaultTheme {} export interface CSSAttribute extends CSSProperties { [key: string]: CSSAttribute | string | number | undefined; } +type StylesGenerator<P = {}> = + (props: P) => CSSAttribute | string; +type TagStyleGenerator<P = {}> = + (props: P) => number | string | undefined; +type TagArgs<P = {}> = Array<string | TagStyleGenerator<P>>; +type StylesArg<P = {}> = + | string + | CSSAttribute + | StylesGenerator<P> + | Array<CSSAttribute | StylesGenerator<P>>; +export declare function keyframes(styles: StylesArg): string; export declare function keyframes( - tag: TemplateStringsArray | string, - ...props: Array<string | number> + tag: TemplateStringsArray, + ...tagArgs: TagArgs ): string; export declare function extractCss(): string; +export declare function glob(styles: StylesArg): void; export declare function glob( - tag: CSSAttribute | TemplateStringsArray | string, - ...props: Array<string | number> + tag: TemplateStringsArray, + ...tagArgs: TagArgs ): void; +export declare function css(styles: StylesArg): string; export declare function css( - tag: CSSAttribute | TemplateStringsArray | string, - ...props: Array<string | number> + tag: TemplateStringsArray, + ...tagArgs: TagArgs ): string; export declare function shouldForwardProp( predicate: (x: string) => boolean @@ -31,46 +51,35 @@ export declare function ThemeProvider< } >(props: T): JSX.Element; export declare function useTheme(): DefaultTheme; -type Tagged<T> = <P>( - args_0: - | string - | TemplateStringsArray - | CSSAttribute - | (( - props: P & - T & { - theme?: DefaultTheme; - as?: string | number | symbol | undefined; - class?: any; - children?: any; - } - ) => string | CSSAttribute), - ...args_1: ( - | string - | number - | (( - props: P & - T & { - theme?: DefaultTheme; - as?: string | number | symbol | undefined; - class?: any; - children?: any; - } - ) => string | number | CSSAttribute | undefined) - )[] -) => ((props: P & T) => JSX.Element) & { - class: (props: P & T) => string; +export interface ThemeProp { + theme?: DefaultTheme; +} +interface AsProps { + as?: ValidComponent; +} +type StylesFn<T> = <P>( + styles: StylesArg<P & T & AsProps & ThemeProp>, +) => Component<P & T & AsProps> & { + class: (props: P & T & AsProps) => string; +}; +type TagFn<T> = <P>( + tag: TemplateStringsArray, + ...args: TagArgs<P & T & AsProps & ThemeProp>, +) => Component<P & T & AsProps> & { + class: (props: P & T & AsProps) => string; }; +type StylingFn<T> = StylesFn<T> & TagFn<T>; export interface Styled { <T extends keyof JSX.IntrinsicElements>( - tag: T | ((props: JSX.IntrinsicElements[T]) => JSX.Element) - ): Tagged<JSX.IntrinsicElements[T]>; - <T>(component: (props: T) => JSX.Element): Tagged<T>; + element: T | Component<JSX.IntrinsicElements[T]> + ): StylingFn<JSX.IntrinsicElements[T]>; + <T>(component: Component<T>): StylingFn<T>; } export declare const styled: Styled & { - [Tag in keyof JSX.IntrinsicElements]: Tagged<JSX.IntrinsicElements[Tag]>; + [element in keyof JSX.IntrinsicElements]: StylingFn<JSX.IntrinsicElements[element]>; }; export declare function createGlobalStyles( - tag: CSSAttribute | TemplateStringsArray | string, - ...props: Array<string | number | Function> -): Function; + tag: TemplateStringsArray, + ...tagArgs: TagArgs + ): () => null; +export declare function createGlobalStyles(styles: StylesArg): () => null; diff --git a/test/test.spec.tsx b/test/test.spec.tsx index 1e2b3f5..a065c0f 100644 --- a/test/test.spec.tsx +++ b/test/test.spec.tsx @@ -38,6 +38,32 @@ describe("Simple Styled", () => { }); }); + test("Creates component properly with styles function", () => { + const Div = styled("div")<{ bold: boolean; border: number; color: string }>(({ bold, border, color }) => ({ + color: "steelblue", + fontSize: "32px", + padding: "5px", + border: `${border}px solid ${color}`, + backgroundColor: "linen", + fontWeight: (bold ? "bold" : 100), + })); + + createRoot(() => { + const v = ( + <Div + aria-label="button" + onClick={() => {}} + class="test" + bold={true} + border={1} + color="whitesmoke" + > + Testera + </Div> + ); + }); + }); + test("Creates input properly", () => { const Input = styled("input")` width: 5em;