classname-variants 1.3.3 → 1.4.1

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 CHANGED
@@ -1,20 +1,67 @@
1
- # classname-variants
1
+ # classname-variants 🌈
2
2
 
3
- Stitches-like [variant API](https://stitches.dev/docs/variants) for plain class names.
3
+ Library to create type-safe components that render their class name based on a set of variants.
4
4
 
5
- The library is framework-agnostic and can be used with any kind of CSS flavor.
5
+ ## Features
6
6
 
7
- It is especially useful though if used with [Tailwind](https://tailwindcss.com/) or [CSS Modules](https://github.com/css-modules/css-modules) in combination with React, as it provides some [dedicated helpers](#React) and even allows for a _styled-components_ like API, but with [class names instead of styles](#bonus-styled-components-but-with-class-names-)!
7
+ - ⚛ïļ Supports React, Preact and vanilla DOM
8
+ - ðŸ›Ąïļ Fully type-safe and excellent auto completion support
9
+ - ✅ Supports both optional and required variants
10
+ - ðŸŠķ Light-weight without any dependencies
8
11
 
9
- [![Edit classname-variants/react](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/classname-variants-react-3bzjl?fontsize=14&hidenavigation=1&theme=dark)
12
+ ![npm bundle size](https://img.shields.io/bundlephobia/minzip/classname-variants)
13
+
14
+ # Examples
15
+
16
+ Here is an example that uses React and Tailwind CSS:
17
+
18
+ ```tsx
19
+ import { styled } from "classname-variants/react";
20
+
21
+ const Button = styled("button", {
22
+ variants: {
23
+ size: {
24
+ small: "text-xs",
25
+ large: "text-lg",
26
+ },
27
+ primary: {
28
+ true: "bg-teal-500 text-white",
29
+ },
30
+ },
31
+ });
32
+
33
+ function UsageExample() {
34
+ return <Button primary size="large" />;
35
+ }
36
+ ```
10
37
 
11
- # Basics
38
+ [![Edit classname-variants/react](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/classname-variants-react-3bzjl?fontsize=14&hidenavigation=1&theme=dark)
12
39
 
13
- Let's assume we want to build a button component with Tailwind CSS that comes in different sizes and colors.
40
+ While the library has been designed with tools like Tailwind in mind, it can be also used with custom classes or CSS modules:
14
41
 
15
- It consists of some _base classes_ that are always present as well as some optional classes that need to be added depending on the desired _variants_.
42
+ ## Preact + CSS modules
16
43
 
17
44
  ```tsx
45
+ import { styled } from "classname-variants/preact";
46
+ import styles from "./styles.module.css";
47
+
48
+ const Button = styled("button", {
49
+ variants: {
50
+ size: {
51
+ small: styles.small,
52
+ large: styles.large,
53
+ },
54
+ },
55
+ });
56
+ ```
57
+
58
+ ## Vanilla DOM
59
+
60
+ The core of the library is completely framework-agnostic:
61
+
62
+ ```ts
63
+ import { variants } from "classname-variants";
64
+
18
65
  const button = variants({
19
66
  base: "rounded text-white",
20
67
  variants: {
@@ -22,50 +69,61 @@ const button = variants({
22
69
  brand: "bg-sky-500",
23
70
  accent: "bg-teal-500",
24
71
  },
25
- size: {
26
- small: "px-5 py-3 text-xs",
27
- large: "px-6 py-4 text-base",
28
- },
29
72
  },
30
73
  });
31
- ```
32
-
33
- The result is a function that expects an object which specifies what variants should be selected. When called, it returns a string containing the respective class names:
34
74
 
35
- ```ts
36
75
  document.write(`
37
- <button class="${button({
38
- color: "accent",
39
- size: "large",
40
- })}">
76
+ <button class="${button({ color: "accent" })}">
41
77
  Click Me!
42
78
  </button>
43
79
  `);
44
80
  ```
45
81
 
46
- # Advanced Usage
82
+ # API
47
83
 
48
- ## Boolean variants
84
+ ### Defining variants
49
85
 
50
- Variants can be of type `boolean` by using `"true"` as the key:
86
+ You can add any number of variants by using the `variants` key.
51
87
 
52
- ```tsx
53
- const button = variants({
54
- base: "text-white",
88
+ ```ts
89
+ {
90
+ variants: {
91
+ color: {
92
+ primary: "bg-teal",
93
+ secondary: "bg-indigo",
94
+ danger: "bg-red"
95
+ },
96
+ size: {
97
+ small: "text-sm",
98
+ medium: "text-md",
99
+ large: "text-lg",
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### Boolean variants
106
+
107
+ Variants can be typed as `boolean` by using `true` / `false` as key:
108
+
109
+ ```ts
110
+ {
55
111
  variants: {
56
- rounded: {
57
- true: "rounded-full",
112
+ primary: {
113
+ true: "bg-teal-500",
58
114
  },
59
115
  },
60
- });
116
+ }
61
117
  ```
62
118
 
63
- ## Compound variants
119
+ ```ts
120
+ <Button primary>Click Me!</Button>
121
+ ```
64
122
 
65
- The `compoundVariants` option can be used to apply class names based on a combination of other variants.
123
+ The `compoundVariants` option can be used to apply class names based on a combination of other variants:
66
124
 
67
- ```tsx
68
- const button = variants({
125
+ ```ts
126
+ {
69
127
  variants: {
70
128
  color: {
71
129
  neutral: "bg-gray-200",
@@ -84,128 +142,71 @@ const button = variants({
84
142
  className: "border-teal-500",
85
143
  },
86
144
  ],
87
- });
145
+ }
88
146
  ```
89
147
 
90
- ## Default variants
148
+ ### Default variants
91
149
 
92
- The `defaultVariants` option can be used to select a variant by default:
150
+ If you define a variant it becomes a required prop unless you specify a default (or the variant is boolean). You can use the `defaultVariants` property to specify defaults:
93
151
 
94
152
  ```ts
95
- const button = variants({
153
+ {
96
154
  variants: {
97
155
  color: {
98
- neutral: "bg-gray-200",
99
- accent: "bg-teal-400",
156
+ primary: "bg-teal-300",
157
+ secondary: "bg-teal-100"
100
158
  },
101
159
  },
102
160
  defaultVariants: {
103
- color: "neutral",
104
- },
105
- });
161
+ color: "secondary",
162
+ }
163
+ }
106
164
  ```
107
165
 
108
- # React
109
-
110
- The library contains utility functions that are useful for writing React components.
166
+ ### Base class
111
167
 
112
- It works much like `variants()` but instead of a class name string, the resulting function returns an object with props.
168
+ Use the `base` property to specify class names that should always be applied:
113
169
 
114
170
  ```ts
115
- import { variantProps } from "classname-variants/react";
116
-
117
- const buttonProps = variantProps({
118
- base: "rounded-md text-white",
171
+ {
172
+ base: "text-black rounded-full px-2",
119
173
  variants: {
120
- color: {
121
- brand: "bg-sky-500",
122
- accent: "bg-teal-500",
123
- },
124
- size: {
125
- small: "px-5 py-3 text-xs",
126
- large: "px-6 py-4 text-base",
127
- },
128
- rounded: {
129
- true: "rounded-full",
130
- },
131
- },
132
- defaultVariants: {
133
- color: "brand",
134
- },
135
- });
136
- ```
137
-
138
- This way a component's props (or part of them) can be directly spread into the target element. All variant-related props are used to construct the `className` property while all other props are passed through verbatim:
139
-
140
- ```tsx
141
- type Props = JSX.IntrinsicElements["button"] &
142
- VariantPropsOf<typeof buttonProps>;
143
-
144
- function Button(props: Props) {
145
- return <button {...buttonProps(props)} />;
146
- }
147
-
148
- function App() {
149
- return (
150
- <Button size="small" color="accent" onClick={console.log}>
151
- Click Me!
152
- </Button>
153
- );
174
+ // ...
175
+ }
154
176
  }
155
177
  ```
156
178
 
157
- # Bonus: styled-components, but for static CSS 💅
179
+ ### Components without variants
158
180
 
159
- Things can be taken even a step further, resulting in a _styled-components_ like way of defining reusable components. Under the hood, this does basically the same as the example above, but also handles _refs_ correctly:
181
+ Sometimes it can be useful to define styled components that
182
+ don't have any variants, which can be done like this:
160
183
 
161
- ```ts
162
- import { styled, tw } from "classname-variants/react";
184
+ ```tsx
185
+ import { styled } from "classname-variants/react";
163
186
 
164
- const Button = styled("button", {
165
- variants: {
166
- size: {
167
- small: tw`text-xs`,
168
- large: tw`text-base`,
169
- },
170
- },
171
- });
187
+ const Button = styled("button", "bg-transparent border p-2");
172
188
  ```
173
189
 
174
- Again, this is not limited to tailwind, so you could do the same with CSS modules:
190
+ ### Styling custom components
175
191
 
176
- ```ts
177
- import { styled } from "classname-variants/react";
178
- import styles from "./styles.module.css";
192
+ You can style any custom React/Preact component as long as they accept a `className` prop (or `class` in case of Preact).
179
193
 
180
- const Button = styled("button", {
194
+ ```tsx
195
+ function MyComponent(props) {
196
+ return <div {...props}>I'm a stylable custom component.</div>;
197
+ }
198
+
199
+ const MyStyledComponent = styled(MyComponent, {
200
+ base: "some-class",
181
201
  variants: {
182
- size: {
183
- small: styles.small,
184
- large: styles.large,
185
- },
202
+ // ...
186
203
  },
187
204
  });
188
205
  ```
189
206
 
190
- > [!TIP]
191
- > You can also style other custom React components as long as they accept a `className` prop.
192
-
193
- ## Styled components without variants
194
-
195
- You can also use the `styled` function to create styled components without any variants at all:
196
-
197
- ```ts
198
- import { styled } from "classname-variants/react";
199
-
200
- const Button = styled(
201
- "button",
202
- "border-none rounded px-3 font-sans bg-green-600 text-white hover:bg-green-500"
203
- );
204
- ```
205
-
206
- ## Polymorphic components with "as"
207
+ ### Polymorphic components with "as"
207
208
 
208
- If you want to keep all the variants you have defined for a component but want to render a different HTML tag or a different custom component, you can use the "as" prop to do so:
209
+ If you want to keep all the variants you have defined for a component but want to render a different HTML tag or a different custom component, you can use the `as` prop to do so:
209
210
 
210
211
  ```tsx
211
212
  import { styled } from "classname-variants/react";
@@ -215,17 +216,20 @@ const Button = styled("button", {
215
216
  //...
216
217
  },
217
218
  });
219
+ ```
218
220
 
219
- function App() {
220
- return (
221
- <div>
222
- <Button>I'm a button</Button>
223
- <Button as="a" href="/">
224
- I'm a link!
225
- </Button>
226
- </div>
227
- );
228
- }
221
+ The component can then be rendered as button or as anchor or even as custom component exposed by some router:
222
+
223
+ ```tsx
224
+ <>
225
+ <Button>I'm a button</Button>
226
+ <Button as="a" href="/">
227
+ I'm a link!
228
+ </Button>
229
+ <Button as={Link} to="/">
230
+ I'm a styled Link component
231
+ </Button>
232
+ </>
229
233
  ```
230
234
 
231
235
  # Tailwind IntelliSense
package/index.html CHANGED
@@ -10,7 +10,10 @@
10
10
  <script src="https://cdn.tailwindcss.com"></script>
11
11
  </head>
12
12
  <body>
13
- <div id="root"></div>
14
- <script type="module" src="./src/example.tsx"></script>
13
+ <h1>React</h1>
14
+ <div id="react-root"></div>
15
+ <h1>Preact</h1>
16
+ <div id="preact-root"></div>
17
+ <script type="module" src="./src/example/index.ts"></script>
15
18
  </body>
16
19
  </html>
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { createElement } from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import { render, h } from "preact";
4
+ import { ReactApp } from "./react";
5
+ import { PreactApp } from "./preact";
6
+ const root = createRoot(document.getElementById("react-root"));
7
+ root.render(createElement(ReactApp));
8
+ render(h(PreactApp, {}), document.getElementById("preact-root"));
@@ -0,0 +1,9 @@
1
+ /** @jsx h */
2
+ import { h } from "preact";
3
+ export declare const ExpectErrors: <As extends keyof h.JSX.IntrinsicElements | import("preact").ComponentType<any> = "div">(props: {
4
+ as?: As | undefined;
5
+ } & Omit<import("preact").ComponentProps<As>, "as" | "color"> & {
6
+ color: "neutral" | "accent";
7
+ } & {}) => import("preact").VNode<{}> | null;
8
+ export declare function WithErrors(): h.JSX.Element;
9
+ export declare function PreactApp(): h.JSX.Element;
@@ -0,0 +1,76 @@
1
+ /** @jsx h */
2
+ import { styled } from "../preact";
3
+ import { h } from "preact";
4
+ function CustomComponent({ title, ...props }) {
5
+ return h("div", { ...props }, title);
6
+ }
7
+ const Card = styled("div", "bg-white p-4 border-2 rounded-lg");
8
+ const TitleCard = styled(CustomComponent, "bg-white p-4 border-2 rounded-lg");
9
+ const Button = styled("button", {
10
+ base: "px-5 py-2 text-white disabled:bg-gray-400 disabled:text-gray-300",
11
+ variants: {
12
+ color: {
13
+ neutral: "bg-slate-500 hover:bg-slate-400",
14
+ accent: "bg-teal-500 hover:bg-teal-400",
15
+ },
16
+ size: {
17
+ small: "text-sm",
18
+ medium: "text-md",
19
+ },
20
+ outlined: {
21
+ true: "border-2",
22
+ },
23
+ rounded: {
24
+ true: "rounded-full",
25
+ false: "rounded-sm",
26
+ },
27
+ },
28
+ compoundVariants: [
29
+ {
30
+ variants: { color: "accent", outlined: true },
31
+ className: "border-teal-600",
32
+ },
33
+ ],
34
+ defaultVariants: {
35
+ color: "neutral",
36
+ },
37
+ });
38
+ export const ExpectErrors = styled("div", {
39
+ variants: {
40
+ color: {
41
+ neutral: "grey",
42
+ accent: "hotpink",
43
+ },
44
+ },
45
+ compoundVariants: [
46
+ {
47
+ //@ts-expect-error
48
+ variants: { outlined: true },
49
+ className: "",
50
+ },
51
+ ],
52
+ defaultVariants: {
53
+ //@ts-expect-error
54
+ outlined: true,
55
+ },
56
+ });
57
+ export function WithErrors() {
58
+ return (h("div", null,
59
+ h(Button, { foo: true, size: "medium" }, "unknown property"),
60
+ h(Card, { foo: true }, "Unknown property"),
61
+ h(Button, { size: "medium", color: "foo" }, "Invalid variant"),
62
+ h(Button, null, "Missing size")));
63
+ }
64
+ export function PreactApp() {
65
+ return (h("div", { className: "flex justify-center items-center pt-8 gap-4 flex-wrap" },
66
+ h(Button, { size: "medium", onClick: console.log }, "Accent"),
67
+ h(Button, { size: "medium", rounded: true }, "Neutral + Rounded"),
68
+ h(Button, { size: "medium", color: "accent", outlined: true }, "Accent + Outlined"),
69
+ h(Button, { size: "medium", color: "accent", disabled: true }, "Disabled"),
70
+ h(TitleCard, { title: "Hello" }),
71
+ h(Card, null,
72
+ h("h1", null, "Hello"),
73
+ h("p", null, "world")),
74
+ h(Card, { as: "a", href: "https://example.com" }, "Link"),
75
+ h(Card, { as: CustomComponent, title: "Test" })));
76
+ }
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export declare const ExpectErrors: <As extends React.ElementType<any> = "div">(props: {
3
+ as?: As | undefined;
4
+ } & Omit<React.ComponentProps<As>, "as" | "color"> & {
5
+ color: "neutral" | "accent";
6
+ } & {}) => React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
7
+ export declare function WithErrors(): JSX.Element;
8
+ export declare function ReactApp(): JSX.Element;
@@ -0,0 +1,76 @@
1
+ import React from "react";
2
+ import { styled } from "../react";
3
+ function CustomComponent({ title, ...props }) {
4
+ return React.createElement("div", { ...props }, title);
5
+ }
6
+ const Card = styled("div", "bg-white p-4 border-2 rounded-lg");
7
+ const TitleCard = styled(CustomComponent, "bg-white p-4 border-2 rounded-lg");
8
+ const Button = styled("button", {
9
+ base: "px-5 py-2 text-white disabled:bg-gray-400 disabled:text-gray-300",
10
+ variants: {
11
+ color: {
12
+ neutral: "bg-slate-500 hover:bg-slate-400",
13
+ accent: "bg-teal-500 hover:bg-teal-400",
14
+ },
15
+ size: {
16
+ small: "text-sm",
17
+ medium: "text-md",
18
+ },
19
+ outlined: {
20
+ true: "border-2",
21
+ },
22
+ rounded: {
23
+ true: "rounded-full",
24
+ false: "rounded-sm",
25
+ },
26
+ },
27
+ compoundVariants: [
28
+ {
29
+ variants: { color: "accent", outlined: true },
30
+ className: "border-teal-600",
31
+ },
32
+ ],
33
+ defaultVariants: {
34
+ color: "neutral",
35
+ },
36
+ });
37
+ export const ExpectErrors = styled("div", {
38
+ variants: {
39
+ color: {
40
+ neutral: "grey",
41
+ accent: "hotpink",
42
+ },
43
+ },
44
+ compoundVariants: [
45
+ {
46
+ //@ts-expect-error
47
+ variants: { outlined: true },
48
+ className: "",
49
+ },
50
+ ],
51
+ defaultVariants: {
52
+ //@ts-expect-error
53
+ outlined: true,
54
+ },
55
+ });
56
+ export function WithErrors() {
57
+ return (React.createElement("div", null,
58
+ React.createElement(Button, { foo: true, size: "medium" }, "unknown property"),
59
+ React.createElement(Card, { foo: true }, "Unknown property"),
60
+ React.createElement(Button, { size: "medium", color: "foo" }, "Invalid variant"),
61
+ React.createElement(Button, null, "Missing size"),
62
+ React.createElement(Card, { as: "b", href: "https://example.com" }, "B tags don't have a href attribute")));
63
+ }
64
+ export function ReactApp() {
65
+ return (React.createElement("div", { className: "flex justify-center items-center pt-8 gap-4 flex-wrap" },
66
+ React.createElement(Button, { size: "medium", onClick: console.log }, "Accent"),
67
+ React.createElement(Button, { size: "medium", rounded: true }, "Neutral + Rounded"),
68
+ React.createElement(Button, { size: "medium", color: "accent", outlined: true }, "Accent + Outlined"),
69
+ React.createElement(Button, { size: "medium", color: "accent", disabled: true }, "Disabled"),
70
+ React.createElement(TitleCard, { title: "Hello" }),
71
+ React.createElement(Card, null,
72
+ React.createElement("h1", null, "Hello"),
73
+ React.createElement("p", null, "world")),
74
+ React.createElement(Card, { as: "a", href: "https://example.com" }, "Link"),
75
+ React.createElement(Card, { as: CustomComponent, title: "Test" })));
76
+ }
@@ -0,0 +1,30 @@
1
+ import type { JSX, ComponentType, ComponentProps, VNode } from "preact";
2
+ type ElementType<P = any> = keyof JSX.IntrinsicElements | ComponentType<P>;
3
+ import { Variants, VariantsConfig, VariantOptions, Simplify } from "./index.js";
4
+ /**
5
+ * Utility type to infer the first argument of a variantProps function.
6
+ */
7
+ export type VariantPropsOf<T> = T extends (props: infer P) => any ? P : never;
8
+ /**
9
+ * Type for the variantProps() argument – consists of the VariantOptions and an optional className for chaining.
10
+ */
11
+ type VariantProps<C extends VariantsConfig<V>, V extends Variants = C["variants"]> = VariantOptions<C> & {
12
+ class?: string;
13
+ className?: string;
14
+ };
15
+ export declare function variantProps<C extends VariantsConfig<V>, V extends Variants = C["variants"]>(config: Simplify<C>): <P extends VariantProps<C, C["variants"]>>(props: P) => {
16
+ class: string;
17
+ } & Omit<P, keyof C["variants"]>;
18
+ type VariantsOf<T, V> = T extends VariantsConfig ? V : {};
19
+ type AsProps<T extends ElementType = ElementType> = {
20
+ as?: T;
21
+ };
22
+ type PolymorphicComponentProps<V, T extends ElementType> = AsProps<T> & Omit<ComponentProps<T>, "as" | keyof V> & V;
23
+ export declare function styled<T extends ElementType, C extends VariantsConfig<V>, V extends Variants = VariantsOf<C, C["variants"]>>(type: T, config: string | Simplify<C>): <As extends ElementType<any> = T>(props: PolymorphicComponentProps<VariantOptions<C, C["variants"]>, As>) => VNode | null;
24
+ /**
25
+ * No-op function to mark template literals as tailwind strings.
26
+ */
27
+ export declare const tw: (template: {
28
+ raw: readonly string[] | ArrayLike<string>;
29
+ }, ...substitutions: any[]) => string;
30
+ export {};
package/lib/preact.js ADDED
@@ -0,0 +1,33 @@
1
+ import { h } from "preact";
2
+ import { forwardRef } from "preact/compat";
3
+ import { variants, } from "./index.js";
4
+ export function variantProps(config) {
5
+ const variantClassName = variants(config);
6
+ return (props) => {
7
+ const result = {};
8
+ // Pass-through all unrelated props
9
+ for (let prop in props) {
10
+ if (config.variants && !(prop in config.variants)) {
11
+ result[prop] = props[prop];
12
+ }
13
+ }
14
+ // Add the optionally passed class/className prop for chaining
15
+ result.class = [variantClassName(props), props.class, props.className]
16
+ .filter(Boolean)
17
+ .join(" ");
18
+ return result;
19
+ };
20
+ }
21
+ export function styled(type, config) {
22
+ const styledProps = typeof config === "string"
23
+ ? variantProps({ base: config, variants: {} })
24
+ : variantProps(config);
25
+ const Component = forwardRef(({ as, ...props }, ref) => {
26
+ return h(as !== null && as !== void 0 ? as : type, { ...styledProps(props), ref });
27
+ });
28
+ return Component;
29
+ }
30
+ /**
31
+ * No-op function to mark template literals as tailwind strings.
32
+ */
33
+ export const tw = String.raw;
package/lib/react.d.ts CHANGED
@@ -17,16 +17,8 @@ type VariantsOf<T, V> = T extends VariantsConfig ? V : {};
17
17
  type AsProps<T extends ElementType = ElementType> = {
18
18
  as?: T;
19
19
  };
20
- type PolymorphicComponentProps<T extends ElementType> = AsProps<T> & Omit<ComponentProps<T>, "as">;
21
- export declare function styled<T extends ElementType, C extends VariantsConfig<V>, V extends Variants = VariantsOf<C, C["variants"]>>(type: T, config: string | Simplify<C>): <As extends ElementType<any> = T>(props: AsProps<As> & Omit<ComponentProps<As>, "as"> & (C["variants"] extends infer T_1 extends Variants ? { [K in keyof T_1 as K extends keyof (C["variants"] extends infer T_2 extends Variants ? { [K_1 in keyof T_2 as C["variants"][K_1] extends {
22
- true: any;
23
- } | {
24
- false: any;
25
- } ? K_1 : never]: C["variants"][K_1]; } : never) | keyof (C["variants"] extends infer T_3 extends Variants ? { [K_2 in keyof T_3 as K_2 extends keyof C["defaultVariants"] ? K_2 : never]: C["variants"][K_2]; } : never) ? never : K]: (C["variants"] extends infer T_4 extends Variants ? { [K_3 in keyof T_4]: keyof C["variants"][K_3] extends "true" | "false" ? boolean : keyof C["variants"][K_3]; } : never)[K]; } : never) & (C["variants"] extends infer T_5 extends Variants ? { [K_4 in keyof T_5 as K_4 extends keyof (C["variants"] extends infer T_2 extends Variants ? { [K_1 in keyof T_2 as C["variants"][K_1] extends {
26
- true: any;
27
- } | {
28
- false: any;
29
- } ? K_1 : never]: C["variants"][K_1]; } : never) | keyof (C["variants"] extends infer T_3 extends Variants ? { [K_2 in keyof T_3 as K_2 extends keyof C["defaultVariants"] ? K_2 : never]: C["variants"][K_2]; } : never) ? K_4 : never]?: (C["variants"] extends infer T_4 extends Variants ? { [K_3 in keyof T_4]: keyof C["variants"][K_3] extends "true" | "false" ? boolean : keyof C["variants"][K_3]; } : never)[K_4] | undefined; } : never)) => ReactElement | null;
20
+ type PolymorphicComponentProps<V, T extends ElementType> = AsProps<T> & Omit<ComponentProps<T>, "as" | keyof V> & V;
21
+ export declare function styled<T extends ElementType, C extends VariantsConfig<V>, V extends Variants = VariantsOf<C, C["variants"]>>(type: T, config: string | Simplify<C>): <As extends ElementType<any> = T>(props: PolymorphicComponentProps<VariantOptions<C, C["variants"]>, As>) => ReactElement | null;
30
22
  /**
31
23
  * No-op function to mark template literals as tailwind strings.
32
24
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "classname-variants",
3
- "version": "1.3.3",
3
+ "version": "1.4.1",
4
4
  "description": "Variant API for plain class names",
5
5
  "author": "Felix Gnass <fgnass@gmail.com>",
6
6
  "license": "MIT",
@@ -16,6 +16,10 @@
16
16
  "./react": {
17
17
  "import": "./lib/react.js",
18
18
  "type": "./lib/react.d.ts"
19
+ },
20
+ "./preact": {
21
+ "import": "./lib/preact.js",
22
+ "type": "./lib/preact.d.ts"
19
23
  }
20
24
  },
21
25
  "typesVersions": {
@@ -25,6 +29,9 @@
25
29
  ],
26
30
  "react": [
27
31
  "./lib/react.d.ts"
32
+ ],
33
+ "preact": [
34
+ "./lib/preact.d.ts"
28
35
  ]
29
36
  }
30
37
  },
@@ -38,11 +45,13 @@
38
45
  "css",
39
46
  "classname",
40
47
  "variants",
41
- "react"
48
+ "react",
49
+ "preact"
42
50
  ],
43
51
  "devDependencies": {
44
52
  "@types/react": "^18.0.26",
45
53
  "@types/react-dom": "^18.0.9",
54
+ "preact": "^10.20.2",
46
55
  "react": "^18.2.0",
47
56
  "react-dom": "^18.2.0",
48
57
  "typescript": "^4.9.4"