Skip to content

Commit 59edaec

Browse files
author
John Richard Chipps-Harding
authored
Default Variants (#10)
* Default Variants * version bump * misc * slip in another test
1 parent 43aa405 commit 59edaec

File tree

5 files changed

+161
-78
lines changed

5 files changed

+161
-78
lines changed

README.md

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@ Here is a minimal example of a button component with an optional variant:
1616
import { styled } from "@phntms/css-components";
1717
import css from "./styles.module.css";
1818

19-
export const Button = styled("button", css.root, {
20-
primary: {
21-
true: css.primary,
19+
export const Button = styled("button", {
20+
css: css.root,
21+
variants: {
22+
primary: {
23+
true: css.primary,
24+
},
2225
},
2326
});
2427
```
@@ -67,9 +70,12 @@ components/Button/styles.ts
6770
import { styled } from "@phntms/css-components";
6871
import css from "./styles.module.css";
6972

70-
export const StyledButton = styled("button", css.root, {
71-
primary: {
72-
true: css.primary,
73+
export const StyledButton = styled("button", {
74+
css: css.root,
75+
variants: {
76+
primary: {
77+
true: css.primary,
78+
},
7379
},
7480
});
7581
```
@@ -97,20 +103,42 @@ export const Button = ({ title, onClick, primary }: Props) => (
97103
The variants config object is a simple object that allows you to define the variants that your component supports. Each variant is a key in the object and the value is an object that defines the possible values(css classes) for that variant.
98104

99105
```tsx
100-
const StyledButton = styled("button", css.root, {
101-
big: {
102-
// Boolean values are supported
103-
true: css.big,
106+
const StyledButton = styled("button", {
107+
css: css.root,
108+
variants: {
109+
big: {
110+
// Boolean values are supported
111+
true: css.big,
112+
},
113+
color: {
114+
// String values are supported
115+
primary: css.primary,
116+
secondary: css.secondary,
117+
},
118+
size: {
119+
// Number values are supported
120+
1: css.size1,
121+
2: css.size2,
122+
},
104123
},
105-
color: {
106-
// String values are supported
107-
primary: css.primary,
108-
secondary: css.secondary,
124+
});
125+
```
126+
127+
## Default Variants
128+
129+
You can use the `defaultVariants` feature to set a variant by default:
130+
131+
```tsx
132+
const StyledButton = styled("button", {
133+
css: css.root,
134+
variants: {
135+
big: {
136+
// Boolean values are supported
137+
true: css.big,
138+
},
109139
},
110-
size: {
111-
// Number values are supported
112-
1: css.size1,
113-
2: css.size2,
140+
defaultVariants: {
141+
big: true,
114142
},
115143
});
116144
```
@@ -120,10 +148,9 @@ const StyledButton = styled("button", css.root, {
120148
For more complex variant setups you can use the compound variants argument to define what styles should be applied when multiple variants are used.
121149

122150
```tsx
123-
const StyledButton = styled(
124-
"button",
125-
css.root,
126-
{
151+
const StyledButton = styled("button", {
152+
css: css.root,
153+
variants: {
127154
border: {
128155
true: css.bordered,
129156
},
@@ -132,7 +159,7 @@ const StyledButton = styled(
132159
secondary: css.secondary,
133160
},
134161
},
135-
[
162+
compoundVariants: [
136163
{
137164
border: true,
138165
color: "primary",
@@ -143,8 +170,8 @@ const StyledButton = styled(
143170
color: "secondary",
144171
css: css.greyBorder,
145172
},
146-
]
147-
);
173+
],
174+
});
148175
```
149176

150177
## Other
@@ -158,9 +185,12 @@ import { styled } from "@phntms/css-components";
158185
import shared from "../sharedstyles.module.css";
159186
import css from "./styles.module.css";
160187

161-
const Link = styled("a", [shared.link, shared.fontNormal, css.root], {
162-
big: {
163-
true: [css.big, shared.fontBold],
188+
const Link = styled("a", {
189+
css: [shared.link, shared.fontNormal, css.root],
190+
variants: {
191+
big: {
192+
true: [css.big, shared.fontBold],
193+
},
164194
},
165195
});
166196
```
@@ -173,8 +203,11 @@ We have included a helper that allows you to access the types of the variants yo
173203
import { CSSComponentPropType } from "@phntms/css-components";
174204
import css from "./styles.module.css";
175205

176-
const Button = styled("button", css.baseButton, {
177-
primary: { true: css.primary },
206+
const Button = styled("button", {
207+
css: css.baseButton,
208+
variants: {
209+
primary: { true: css.primary },
210+
},
178211
});
179212

180213
type ButtonTypes = CSSComponentPropType<typeof Button, "primary">;

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@phntms/css-components",
33
"description": "At its core, css-components is a simple wrapper around standard CSS. It allows you to write your CSS how you wish then compose them into a component ready to be used in React.",
4-
"version": "0.0.5",
4+
"version": "0.0.6",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",
77
"homepage": "https://github.com/phantomstudios/css-components#readme",

src/index.ts

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,27 @@ export type PropsOf<
4343
C extends keyof JSX.IntrinsicElements | React.JSXElementConstructor<any>
4444
> = JSX.LibraryManagedAttributes<C, React.ComponentPropsWithoutRef<C>>;
4545

46+
interface Config<V> {
47+
css?: string | string[];
48+
variants?: V;
49+
compoundVariants?: compoundVariantType[];
50+
defaultVariants?: {
51+
[Property in keyof V]?: BooleanIfStringBoolean<keyof V[Property]>;
52+
};
53+
}
54+
4655
export const styled = <
4756
V extends variantsType | object,
4857
E extends React.ElementType
4958
>(
5059
element: E,
51-
baseClassName?: string | string[],
52-
variants?: V,
53-
compoundVariants?: compoundVariantType[]
60+
config?: Config<V>
5461
) => {
5562
const styledComponent = forwardRef<E, { [key: string]: string }>(
5663
(props, ref) => {
64+
const mergedProps = { ...config?.defaultVariants, ...props } as {
65+
[key: string]: string;
66+
};
5767
// Initialize variables to store the new props and styles
5868
const componentProps: { [key: string]: unknown } = {};
5969
const componentStyles: string[] = [];
@@ -65,19 +75,19 @@ export const styled = <
6575
if (ref) componentProps.ref = ref;
6676

6777
// Add the base style(s)
68-
if (baseClassName)
78+
if (config?.css)
6979
componentStyles.push(
70-
Array.isArray(baseClassName) ? baseClassName.join(" ") : baseClassName
80+
Array.isArray(config.css) ? config.css.join(" ") : config.css
7181
);
7282

7383
// Apply any variant styles
74-
Object.keys(props).forEach((key) => {
75-
if (variants && variants.hasOwnProperty(key)) {
76-
const variant = variants[key as keyof typeof variants];
77-
if (variant && variant.hasOwnProperty(props[key])) {
78-
const selector = variant[props[key] as keyof typeof variant] as
79-
| string
80-
| string[];
84+
Object.keys(mergedProps).forEach((key) => {
85+
if (config?.variants && config.variants.hasOwnProperty(key)) {
86+
const variant = config.variants[key as keyof typeof config.variants];
87+
if (variant && variant.hasOwnProperty(mergedProps[key])) {
88+
const selector = variant[
89+
mergedProps[key] as keyof typeof variant
90+
] as string | string[];
8191
componentStyles.push(
8292
Array.isArray(selector) ? selector.join(" ") : selector
8393
);
@@ -88,8 +98,11 @@ export const styled = <
8898
});
8999

90100
// Apply any compound variant styles
91-
if (compoundVariants) {
92-
const matches = findMatchingCompoundVariants(compoundVariants, props);
101+
if (config?.compoundVariants) {
102+
const matches = findMatchingCompoundVariants(
103+
config.compoundVariants,
104+
props
105+
);
93106

94107
matches.forEach((match) => {
95108
if (Array.isArray(match.css)) {

0 commit comments

Comments
 (0)