stoop 0.5.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/api/styled.d.ts +13 -3
- package/dist/create-stoop.d.ts +1 -1
- package/dist/types/index.d.ts +279 -39
- package/package.json +2 -9
- package/dist/types/react-polymorphic-types.d.ts +0 -24
package/README.md
CHANGED
|
@@ -62,6 +62,7 @@ const Button = styled("button", {
|
|
|
62
62
|
- **Multiple themes** with built-in Provider
|
|
63
63
|
- **Utility functions** for custom CSS transformations
|
|
64
64
|
- **Zero runtime overhead** for theme switching
|
|
65
|
+
- **Zero dependencies** - only React peer dependency
|
|
65
66
|
|
|
66
67
|
## Documentation
|
|
67
68
|
|
package/dist/api/styled.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and CSS prop merging. Supports component targeting via selector references.
|
|
5
5
|
*/
|
|
6
6
|
import { forwardRef, type Context } from "react";
|
|
7
|
-
import type { CSS,
|
|
7
|
+
import type { CSS, StyledComponentProps, StyledComponentRef, StylableElement, Theme, ThemeContextValue, ThemeScale, UtilityFunction, Variants } from "../types";
|
|
8
8
|
/**
|
|
9
9
|
* Creates a styled component reference for selector targeting.
|
|
10
10
|
*
|
|
@@ -25,10 +25,20 @@ export declare function createStyledComponentRef(className: string): StyledCompo
|
|
|
25
25
|
* @returns Styled component factory function
|
|
26
26
|
*/
|
|
27
27
|
export declare function createStyledFunction(defaultTheme: Theme, prefix?: string, media?: Record<string, string>, utils?: Record<string, UtilityFunction>, themeMap?: Record<string, ThemeScale>, themeContext?: Context<ThemeContextValue | null>): {
|
|
28
|
-
<DefaultElement extends StylableElement, BaseStyles extends
|
|
28
|
+
<DefaultElement extends StylableElement, BaseStyles extends CSS & {
|
|
29
|
+
variants: {
|
|
30
|
+
[Name in string]: {
|
|
31
|
+
[Pair in string]: CSS;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}>(defaultElement: DefaultElement, baseStyles: BaseStyles): ReturnType<typeof forwardRef<unknown, StyledComponentProps<DefaultElement, BaseStyles extends {
|
|
35
|
+
variants: infer V;
|
|
36
|
+
} ? (V extends Variants ? V : {}) : {}>>> & {
|
|
29
37
|
selector: StyledComponentRef;
|
|
30
38
|
};
|
|
31
|
-
<DefaultElement extends StylableElement>(defaultElement: DefaultElement, baseStyles?: CSS
|
|
39
|
+
<DefaultElement extends StylableElement>(defaultElement: DefaultElement, baseStyles?: CSS & {
|
|
40
|
+
variants?: never;
|
|
41
|
+
}): ReturnType<typeof forwardRef<unknown, StyledComponentProps<DefaultElement, {}>>> & {
|
|
32
42
|
selector: StyledComponentRef;
|
|
33
43
|
};
|
|
34
44
|
};
|
package/dist/create-stoop.d.ts
CHANGED
|
@@ -32,5 +32,5 @@ export declare function createStoopBase(config: StoopConfig): {
|
|
|
32
32
|
* @param config - Configuration object containing theme, media queries, utilities, and optional prefix/themeMap
|
|
33
33
|
* @returns StoopInstance with all API functions
|
|
34
34
|
*/
|
|
35
|
-
export type { CSS,
|
|
35
|
+
export type { CSS, ComponentProps, DefaultTheme, StoopConfig, StoopInstance, Theme, ThemeScale, UtilityFunction, } from "./types";
|
|
36
36
|
export declare function createStoop(config: StoopConfig): StoopInstance;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,45 +2,169 @@
|
|
|
2
2
|
* Core TypeScript type definitions for Stoop.
|
|
3
3
|
* Defines CSS objects, themes, variants, styled components, and instance types.
|
|
4
4
|
*/
|
|
5
|
-
import type { ComponentType, ElementType, JSX, ReactNode } from "react";
|
|
6
|
-
|
|
5
|
+
import type { ComponentType, ElementType, JSX, ReactNode, ForwardRefExoticComponent, ComponentPropsWithRef, ReactElement } from "react";
|
|
6
|
+
/**
|
|
7
|
+
* Remove index signatures from a type, leaving only known properties.
|
|
8
|
+
* Useful for better autocomplete and type inference.
|
|
9
|
+
* Inspired by Stitches' RemoveIndex utility.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* type MyType = { foo: string; bar: number; [key: string]: unknown };
|
|
14
|
+
* type Clean = RemoveIndexSignature<MyType>; // { foo: string; bar: number }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export type RemoveIndexSignature<T> = {
|
|
18
|
+
[K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Widen literal types to their base types for more flexible prop types.
|
|
22
|
+
* Allows both literal values and their base types.
|
|
23
|
+
* Inspired by Stitches' Widen utility.
|
|
24
|
+
*
|
|
25
|
+
* **Note:** Currently unused in Stoop - we enforce strict literal types in variants.
|
|
26
|
+
* Available for future use if more flexible prop types are desired.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* type Strict = "sm" | "lg"; // Only accepts "sm" | "lg"
|
|
31
|
+
* type BoolWiden = Widen<"true" | "false">; // boolean | "true" | "false"
|
|
32
|
+
* type NumWiden = Widen<"1" | "2">; // number | "1" | "2"
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export type Widen<T> = T extends "true" ? boolean | T : T extends "false" ? boolean | T : T extends `${number}` ? number | T : T;
|
|
36
|
+
/**
|
|
37
|
+
* Narrowed string type for better type inference in unions.
|
|
38
|
+
* The intersection with Record<never, never> makes it distinct from plain string.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* type Props = { variant: "sm" | "lg" | NarrowString };
|
|
43
|
+
* // Autocomplete shows "sm" | "lg" but also accepts any string
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export type NarrowString = string & Record<never, never>;
|
|
47
|
+
/**
|
|
48
|
+
* Returns a string with the given prefix followed by the given values.
|
|
49
|
+
* Used to generate token names like "$primary" from theme keys.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* type Tokens = Prefixed<"$", "primary" | "secondary">; // "$primary" | "$secondary"
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export type Prefixed<K extends string, T> = `${K}${Extract<T, boolean | number | string>}`;
|
|
57
|
+
/**
|
|
58
|
+
* Generates valid token names for a theme scale.
|
|
59
|
+
* Creates a union of "$tokenName" strings from the keys of a theme scale.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* type Theme = { colors: { primary: string; secondary: string } };
|
|
64
|
+
* type ColorTokens = TokenByScaleName<"colors", Theme>; // "$primary" | "$secondary"
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export type TokenByScaleName<ScaleName extends string, Theme extends DefaultTheme> = ScaleName extends keyof Theme ? Theme[ScaleName] extends Record<string, ThemeScaleValue> ? Prefixed<"$", keyof Theme[ScaleName]> : never : never;
|
|
68
|
+
/**
|
|
69
|
+
* Generates valid token names for a CSS property based on themeMap.
|
|
70
|
+
* Maps the property to a theme scale, then generates tokens for that scale.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* type Theme = { colors: { primary: string } };
|
|
75
|
+
* type ThemeMap = { color: "colors" };
|
|
76
|
+
* type ColorTokens = TokenByPropertyName<"color", Theme, ThemeMap>; // "$primary"
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export type TokenByPropertyName<PropertyName extends string, Theme extends DefaultTheme, ThemeMap extends Record<string, ThemeScale>> = PropertyName extends keyof ThemeMap ? TokenByScaleName<ThemeMap[PropertyName], Theme> : never;
|
|
80
|
+
/**
|
|
81
|
+
* Generates all valid tokens from all theme scales.
|
|
82
|
+
* Creates a union of all "$tokenName" strings from all scales in the theme.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* type Theme = { colors: { primary: string }; space: { small: string } };
|
|
87
|
+
* type AllTokens = AllThemeTokens<Theme>; // "$primary" | "$small"
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export type AllThemeTokens<Theme extends DefaultTheme> = {
|
|
91
|
+
[K in keyof Theme]: K extends ThemeScale ? Theme[K] extends Record<string, ThemeScaleValue> ? Prefixed<"$", keyof Theme[K]> : never : never;
|
|
92
|
+
}[keyof Theme];
|
|
7
93
|
export type CSSPropertyValue = string | number;
|
|
8
94
|
export interface StyledComponentRef {
|
|
9
95
|
readonly __stoopClassName: string;
|
|
10
96
|
readonly __isStoopStyled: true;
|
|
11
97
|
toString(): string;
|
|
12
98
|
}
|
|
13
|
-
|
|
14
|
-
|
|
99
|
+
/**
|
|
100
|
+
* CSS style object interface.
|
|
101
|
+
* Supports nested selectors, media queries, variants, and CSS property values.
|
|
102
|
+
*
|
|
103
|
+
* Property values can be:
|
|
104
|
+
* - Primitives: string | number
|
|
105
|
+
* - Theme tokens: "$tokenName" strings validated against the theme
|
|
106
|
+
* - Nested CSS objects: for pseudo-selectors, media queries, nested selectors
|
|
107
|
+
* - Variants: variant configuration object
|
|
108
|
+
* - Arrays: for multiple values (e.g., multiple box-shadows, transforms)
|
|
109
|
+
* - undefined: for optional properties
|
|
110
|
+
*
|
|
111
|
+
* **Note on `unknown[]`:** Intentionally permissive to support various CSS patterns:
|
|
112
|
+
* - Multiple transforms: `["translateX(10px)", "rotate(45deg)"]`
|
|
113
|
+
* - Multiple box-shadows: `["0 0 10px rgba(0,0,0,0.1)", "inset 0 0 5px white"]`
|
|
114
|
+
* - Vendor prefix values: `["-webkit-line-clamp", "3"]`
|
|
115
|
+
*
|
|
116
|
+
* **Theme Token Validation:**
|
|
117
|
+
* When Theme and ThemeMap are provided, CSS property values are validated:
|
|
118
|
+
* - Known properties accept valid theme tokens (e.g., `color: "$primary"`)
|
|
119
|
+
* - Unknown properties still accept any string (for flexibility)
|
|
120
|
+
* - Tokens are validated against the theme scales via ThemeMap
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* const stoop = createStoop({
|
|
125
|
+
* theme: { colors: { primary: "#000" } },
|
|
126
|
+
* themeMap: { color: "colors" }
|
|
127
|
+
* });
|
|
128
|
+
* // color: "$primary" ✅ (valid token)
|
|
129
|
+
* // color: "$invalid" ❌ (TypeScript error)
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export interface CSS<Theme extends DefaultTheme = DefaultTheme, ThemeMap extends Record<string, ThemeScale> = Record<string, ThemeScale>> {
|
|
133
|
+
[property: string]: CSSPropertyValue | (AllThemeTokens<Theme> extends never ? never : AllThemeTokens<Theme>) | CSS<Theme, ThemeMap> | Variants<Theme, ThemeMap> | unknown[] | undefined;
|
|
15
134
|
}
|
|
16
135
|
/**
|
|
17
136
|
* Variants type definition.
|
|
18
|
-
* Uses
|
|
137
|
+
* Uses mapped type to preserve literal types instead of Record which widens them.
|
|
19
138
|
* This allows variant values like "primary" | "secondary" to be preserved as literal types
|
|
20
139
|
* rather than being widened to string.
|
|
21
140
|
*/
|
|
22
|
-
export type Variants = Record<string, Record<string,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
141
|
+
export type Variants<Theme extends DefaultTheme = DefaultTheme, ThemeMap extends Record<string, ThemeScale> = Record<string, ThemeScale>> = {
|
|
142
|
+
[variantName: string]: {
|
|
143
|
+
[variantValue: string]: CSS<Theme, ThemeMap>;
|
|
144
|
+
};
|
|
145
|
+
};
|
|
26
146
|
export type HTMLElements = keyof JSX.IntrinsicElements;
|
|
27
147
|
export type StylableElement = HTMLElements | ElementType;
|
|
28
|
-
export interface StyledBaseProps {
|
|
29
|
-
css?: CSS
|
|
148
|
+
export interface StyledBaseProps<Theme extends DefaultTheme = DefaultTheme, ThemeMap extends Record<string, ThemeScale> = Record<string, ThemeScale>> {
|
|
149
|
+
css?: CSS<Theme, ThemeMap>;
|
|
30
150
|
}
|
|
31
151
|
/**
|
|
32
152
|
* CSS object that includes variants configuration.
|
|
33
153
|
* Used for styled component definitions that combine base styles with variants.
|
|
34
|
-
*
|
|
35
|
-
* when variants are defined inline. This prevents TypeScript from widening literal types.
|
|
154
|
+
* Made generic to preserve exact variant literal types from the input.
|
|
36
155
|
* We exclude variants from the CSS index signature to make it distinct.
|
|
37
156
|
*/
|
|
38
|
-
export type CSSWithVariants = {
|
|
39
|
-
[K in keyof CSS as K extends "variants" ? never : K]: CSS[K];
|
|
157
|
+
export type CSSWithVariants<Theme extends DefaultTheme = DefaultTheme, ThemeMap extends Record<string, ThemeScale> = Record<string, ThemeScale>, V extends Variants<Theme, ThemeMap> = Variants<Theme, ThemeMap>> = {
|
|
158
|
+
[K in keyof CSS<Theme, ThemeMap> as K extends "variants" ? never : K]: CSS<Theme, ThemeMap>[K];
|
|
40
159
|
} & {
|
|
41
|
-
variants:
|
|
160
|
+
variants: V;
|
|
42
161
|
};
|
|
43
|
-
export type UtilityFunction = (value: CSSPropertyValue | CSS | undefined) => CSS
|
|
162
|
+
export type UtilityFunction<Theme extends DefaultTheme = DefaultTheme, ThemeMap extends Record<string, ThemeScale> = Record<string, ThemeScale>> = (value: CSSPropertyValue | CSS<Theme, ThemeMap> | undefined) => CSS<Theme, ThemeMap>;
|
|
163
|
+
/**
|
|
164
|
+
* Theme scale value type - restricts values to primitives.
|
|
165
|
+
* Ensures theme tokens are serializable and valid CSS values.
|
|
166
|
+
*/
|
|
167
|
+
export type ThemeScaleValue = string | number;
|
|
44
168
|
/**
|
|
45
169
|
* Theme scale type - represents valid keys from DefaultTheme.
|
|
46
170
|
* Used for type-safe theme scale references throughout the codebase.
|
|
@@ -50,21 +174,22 @@ export type ThemeScale = keyof DefaultTheme;
|
|
|
50
174
|
* Theme interface - strictly enforces only these 13 approved scales.
|
|
51
175
|
* Custom theme scales are NOT allowed.
|
|
52
176
|
* Media queries are also supported as part of the theme.
|
|
177
|
+
* All scale values must be strings or numbers (primitives only).
|
|
53
178
|
*/
|
|
54
179
|
export interface DefaultTheme {
|
|
55
|
-
colors?: Record<string,
|
|
56
|
-
opacities?: Record<string,
|
|
57
|
-
space?: Record<string,
|
|
58
|
-
radii?: Record<string,
|
|
59
|
-
sizes?: Record<string,
|
|
60
|
-
fonts?: Record<string,
|
|
61
|
-
fontWeights?: Record<string,
|
|
62
|
-
fontSizes?: Record<string,
|
|
63
|
-
lineHeights?: Record<string,
|
|
64
|
-
letterSpacings?: Record<string,
|
|
65
|
-
shadows?: Record<string,
|
|
66
|
-
zIndices?: Record<string,
|
|
67
|
-
transitions?: Record<string,
|
|
180
|
+
colors?: Record<string, ThemeScaleValue>;
|
|
181
|
+
opacities?: Record<string, ThemeScaleValue>;
|
|
182
|
+
space?: Record<string, ThemeScaleValue>;
|
|
183
|
+
radii?: Record<string, ThemeScaleValue>;
|
|
184
|
+
sizes?: Record<string, ThemeScaleValue>;
|
|
185
|
+
fonts?: Record<string, ThemeScaleValue>;
|
|
186
|
+
fontWeights?: Record<string, ThemeScaleValue>;
|
|
187
|
+
fontSizes?: Record<string, ThemeScaleValue>;
|
|
188
|
+
lineHeights?: Record<string, ThemeScaleValue>;
|
|
189
|
+
letterSpacings?: Record<string, ThemeScaleValue>;
|
|
190
|
+
shadows?: Record<string, ThemeScaleValue>;
|
|
191
|
+
zIndices?: Record<string, ThemeScaleValue>;
|
|
192
|
+
transitions?: Record<string, ThemeScaleValue>;
|
|
68
193
|
media?: Record<string, string>;
|
|
69
194
|
}
|
|
70
195
|
/**
|
|
@@ -81,18 +206,66 @@ export interface StoopConfig {
|
|
|
81
206
|
themeMap?: Record<string, ThemeScale>;
|
|
82
207
|
globalCss?: CSS;
|
|
83
208
|
}
|
|
84
|
-
export type VariantKeys<T extends Variants> = keyof T;
|
|
85
209
|
/**
|
|
86
210
|
* Extract the keys from a variant object, preserving literal types.
|
|
87
211
|
* Special handling for boolean variants: if keys are exactly "true" and "false",
|
|
88
212
|
* convert to boolean type. Otherwise, use keyof to preserve literal types.
|
|
213
|
+
*
|
|
214
|
+
* **STRICT MODE:** Unlike Stitches, we do NOT widen to allow any string/number.
|
|
215
|
+
* Only the exact keys defined in the variant are allowed.
|
|
216
|
+
*
|
|
217
|
+
* @see VariantPropsFromConfig - Uses this to build variant props
|
|
218
|
+
* @see Widen - Alternative approach used by Stitches (more permissive)
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* type BoolVariant = { true: CSS; false: CSS };
|
|
223
|
+
* type BoolKeys = ExtractVariantKeys<BoolVariant>; // boolean
|
|
224
|
+
*
|
|
225
|
+
* type SizeVariant = { sm: CSS; lg: CSS };
|
|
226
|
+
* type SizeKeys = ExtractVariantKeys<SizeVariant>; // "sm" | "lg"
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
type ExtractVariantKeys<T, Theme extends DefaultTheme = DefaultTheme, ThemeMap extends Record<string, ThemeScale> = Record<string, ThemeScale>> = T extends Record<string, CSS<Theme, ThemeMap>> ? keyof T extends "true" | "false" ? boolean : keyof T : never;
|
|
230
|
+
/**
|
|
231
|
+
* Converts variant configuration to prop types.
|
|
232
|
+
* All variant props are optional and use exact literal types from the config.
|
|
233
|
+
*
|
|
234
|
+
* @see ExtractVariantKeys - Internal utility used for key extraction
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```ts
|
|
238
|
+
* type Config = {
|
|
239
|
+
* size: { sm: CSS; lg: CSS };
|
|
240
|
+
* color: { primary: CSS; secondary: CSS };
|
|
241
|
+
* disabled: { true: CSS; false: CSS };
|
|
242
|
+
* };
|
|
243
|
+
* type Props = VariantPropsFromConfig<Config>;
|
|
244
|
+
* // Result: {
|
|
245
|
+
* // size?: "sm" | "lg";
|
|
246
|
+
* // color?: "primary" | "secondary";
|
|
247
|
+
* // disabled?: boolean;
|
|
248
|
+
* // }
|
|
249
|
+
* ```
|
|
89
250
|
*/
|
|
90
|
-
type ExtractVariantKeys<T> = T extends Record<string, CSS> ? keyof T extends "true" | "false" ? boolean : keyof T extends "false" | "true" ? boolean : keyof T : never;
|
|
91
251
|
export type VariantPropsFromConfig<T extends Variants> = {
|
|
92
|
-
[K in
|
|
252
|
+
[K in keyof T]?: ExtractVariantKeys<T[K]>;
|
|
93
253
|
};
|
|
94
|
-
|
|
95
|
-
|
|
254
|
+
/**
|
|
255
|
+
* Base props that all styled components have.
|
|
256
|
+
* Includes className, css prop, and variant props.
|
|
257
|
+
*/
|
|
258
|
+
type StyledOwnProps<VariantsConfig extends Variants> = StyledBaseProps & VariantPropsFromConfig<VariantsConfig>;
|
|
259
|
+
/**
|
|
260
|
+
* Merge utility that properly combines types.
|
|
261
|
+
* Omits conflicting keys from T and adds all of U.
|
|
262
|
+
*/
|
|
263
|
+
type Merge<T, U> = Omit<T, keyof U> & U;
|
|
264
|
+
/**
|
|
265
|
+
* Props for a styled component without the `as` prop polymorphism.
|
|
266
|
+
* Just the base element props + our styled props.
|
|
267
|
+
*/
|
|
268
|
+
export type StyledComponentProps<DefaultElement extends ElementType, VariantsConfig extends Variants = {}> = Merge<DefaultElement extends keyof JSX.IntrinsicElements | ComponentType<any> ? ComponentPropsWithRef<DefaultElement> : {}, StyledOwnProps<VariantsConfig>>;
|
|
96
269
|
export interface ThemeContextValue {
|
|
97
270
|
theme: Theme;
|
|
98
271
|
themeName?: string;
|
|
@@ -207,17 +380,58 @@ export interface AutoPreloadResult {
|
|
|
207
380
|
}
|
|
208
381
|
/**
|
|
209
382
|
* Styled component type - the return type of styled()
|
|
383
|
+
*
|
|
384
|
+
* Note: We use ComponentType for maximum compatibility with React's type system.
|
|
385
|
+
* This ensures styled components work seamlessly with React.ComponentProps,
|
|
386
|
+
* forwardRef, and other React utilities without additional type gymnastics.
|
|
387
|
+
*/
|
|
388
|
+
/**
|
|
389
|
+
* Styled component type with proper polymorphic support.
|
|
390
|
+
* Based on Stitches' approach: uses ForwardRefExoticComponent + call signature overloads
|
|
391
|
+
* to preserve strict variant types without permissive index signatures.
|
|
392
|
+
*
|
|
393
|
+
* This provides:
|
|
394
|
+
* - Strict variant type checking (no extra variant values accepted)
|
|
395
|
+
* - Support for `as` prop to change the underlying element
|
|
396
|
+
* - Proper ref forwarding for both default and `as` elements
|
|
210
397
|
*/
|
|
211
|
-
export
|
|
398
|
+
export interface StyledComponent<DefaultElement extends ElementType, VariantsConfig extends Variants = {}> extends ForwardRefExoticComponent<StyledComponentProps<DefaultElement, VariantsConfig>> {
|
|
399
|
+
/**
|
|
400
|
+
* Call signature without `as` prop - uses default element
|
|
401
|
+
*/
|
|
402
|
+
(props: StyledComponentProps<DefaultElement, VariantsConfig> & {
|
|
403
|
+
as?: never;
|
|
404
|
+
}): ReactElement | null;
|
|
405
|
+
/**
|
|
406
|
+
* Call signature with `as` prop - changes element type
|
|
407
|
+
* Note: ref type is intentionally permissive to avoid conflicts when
|
|
408
|
+
* using refs from hooks that may not match the exact element type.
|
|
409
|
+
*/
|
|
410
|
+
<As extends ElementType = DefaultElement>(props: Merge<As extends keyof JSX.IntrinsicElements | ComponentType<unknown> ? Omit<ComponentPropsWithRef<As>, "ref"> & {
|
|
411
|
+
ref?: unknown;
|
|
412
|
+
} : {}, StyledOwnProps<VariantsConfig> & {
|
|
413
|
+
as?: As;
|
|
414
|
+
}>): ReactElement | null;
|
|
212
415
|
selector: StyledComponentRef;
|
|
213
|
-
}
|
|
416
|
+
}
|
|
214
417
|
/**
|
|
215
418
|
* Styled function type - the main styled() function signature
|
|
216
419
|
* Variants must be embedded in the baseStyles object, matching Stitches API.
|
|
420
|
+
* Overloads are ordered to prefer the variants overload when variants are present.
|
|
217
421
|
*/
|
|
218
422
|
export interface StyledFunction {
|
|
219
|
-
<DefaultElement extends StylableElement, BaseStyles extends
|
|
220
|
-
|
|
423
|
+
<DefaultElement extends StylableElement, BaseStyles extends CSS & {
|
|
424
|
+
variants: {
|
|
425
|
+
[Name in string]: {
|
|
426
|
+
[Pair in string]: CSS;
|
|
427
|
+
};
|
|
428
|
+
};
|
|
429
|
+
}>(defaultElement: DefaultElement, baseStyles: BaseStyles): StyledComponent<DefaultElement, BaseStyles extends {
|
|
430
|
+
variants: infer V;
|
|
431
|
+
} ? (V extends Variants ? V : {}) : {}>;
|
|
432
|
+
<DefaultElement extends StylableElement>(defaultElement: DefaultElement, baseStyles?: CSS & {
|
|
433
|
+
variants?: never;
|
|
434
|
+
}): StyledComponent<DefaultElement, {}>;
|
|
221
435
|
}
|
|
222
436
|
export interface GetCssTextOptions {
|
|
223
437
|
theme?: Theme;
|
|
@@ -297,4 +511,30 @@ export interface StoopInstance {
|
|
|
297
511
|
*/
|
|
298
512
|
useTheme: () => ThemeManagementContextValue;
|
|
299
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Returns the properties, attributes, and children expected by a component.
|
|
516
|
+
* Use this to extract prop types from styled components.
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```ts
|
|
520
|
+
* const Button = styled('button', { ... });
|
|
521
|
+
* type ButtonProps = ComponentProps<typeof Button>;
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
export type ComponentProps<Component> = Component extends (...args: any[]) => any ? Parameters<Component>[0] : never;
|
|
525
|
+
/**
|
|
526
|
+
* Returns a type that extracts only the variant props from a styled component.
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```ts
|
|
530
|
+
* const Button = styled('button', {
|
|
531
|
+
* variants: { size: { sm: {}, lg: {} } }
|
|
532
|
+
* });
|
|
533
|
+
* type ButtonVariants = VariantProps<typeof Button>;
|
|
534
|
+
* // Result: { size?: "sm" | "lg" }
|
|
535
|
+
* ```
|
|
536
|
+
*/
|
|
537
|
+
export type VariantProps<Component extends {
|
|
538
|
+
selector: any;
|
|
539
|
+
}> = Component extends StyledComponent<any, infer V> ? VariantPropsFromConfig<V> : never;
|
|
300
540
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stoop",
|
|
3
3
|
"description": "CSS-in-JS library with type inference, theme creation, and variants support.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"author": "Jackson Dolman <mail@dolmios.com>",
|
|
6
6
|
"main": "./dist/create-stoop.js",
|
|
7
7
|
"types": "./dist/create-stoop.d.ts",
|
|
@@ -13,17 +13,11 @@
|
|
|
13
13
|
"url": "https://github.com/dolmios/stoop/issues"
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://github.com/dolmios/stoop#readme",
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"react-polymorphic-types": "^2.0.0"
|
|
18
|
-
},
|
|
19
16
|
"devDependencies": {
|
|
20
|
-
"@stitches/stringify": "^1.2.8",
|
|
21
17
|
"@types/node": "^25.0.3",
|
|
22
18
|
"@types/react": "^19.2.7",
|
|
23
19
|
"@types/react-dom": "^19.2.3",
|
|
24
20
|
"bun-types": "^1.3.5",
|
|
25
|
-
"style-object-to-css-string": "^1.1.3",
|
|
26
|
-
"to-css": "^1.2.1",
|
|
27
21
|
"typescript": "^5.9.3"
|
|
28
22
|
},
|
|
29
23
|
"exports": {
|
|
@@ -90,8 +84,7 @@
|
|
|
90
84
|
],
|
|
91
85
|
"license": "MIT",
|
|
92
86
|
"peerDependencies": {
|
|
93
|
-
"react": ">=16.8.0"
|
|
94
|
-
"react-dom": ">=16.8.0"
|
|
87
|
+
"react": ">=16.8.0"
|
|
95
88
|
},
|
|
96
89
|
"scripts": {
|
|
97
90
|
"build": "bun run build.ts",
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type declaration for react-polymorphic-types to work around package.json exports issue.
|
|
3
|
-
* Properly extends native element props while preserving custom variant props.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
declare module "react-polymorphic-types" {
|
|
7
|
-
import type { ElementType, ComponentPropsWithRef, ComponentPropsWithoutRef } from "react";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Polymorphic props with ref support.
|
|
11
|
-
* Extends native element props while preserving custom props (like variants).
|
|
12
|
-
* Variant props take precedence over native props with the same name.
|
|
13
|
-
*/
|
|
14
|
-
export type PolymorphicPropsWithRef<OwnProps, DefaultElement extends ElementType> = OwnProps &
|
|
15
|
-
Omit<ComponentPropsWithRef<DefaultElement>, keyof OwnProps>;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Polymorphic props without ref support.
|
|
19
|
-
* Extends native element props while preserving custom props (like variants).
|
|
20
|
-
* Variant props take precedence over native props with the same name.
|
|
21
|
-
*/
|
|
22
|
-
export type PolymorphicPropsWithoutRef<OwnProps, DefaultElement extends ElementType> = OwnProps &
|
|
23
|
-
Omit<ComponentPropsWithoutRef<DefaultElement>, keyof OwnProps>;
|
|
24
|
-
}
|