@itamarshdev/reactwind 1.0.0 → 1.2.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 +65 -21
- package/dist/chunk-6MX4RX23.js +345 -0
- package/dist/index.cjs +104 -4
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1 -1
- package/dist/jsx-dev-runtime.cjs +104 -4
- package/dist/jsx-dev-runtime.d.cts +1 -1
- package/dist/jsx-dev-runtime.d.ts +1 -1
- package/dist/jsx-dev-runtime.js +1 -1
- package/dist/jsx-runtime.cjs +104 -4
- package/dist/jsx-runtime.d.cts +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +1 -1
- package/dist/types-DuRT-DEW.d.ts +248 -0
- package/dist/types-I6XgQvJp.d.cts +248 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ReactWind
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/reactwind)
|
|
4
|
-
[](https://github.com/
|
|
5
|
-
[](https://
|
|
6
|
-
[](https://www.npmjs.com/package/@itamarshdev/reactwind)
|
|
4
|
+
[](https://github.com/ItamarShDev/reactwind/blob/main/LICENSE)
|
|
5
|
+
[](https://ItamarShDev.github.io/reactwind/storybook/)
|
|
6
|
+
[](https://github.com/semantic-release/semantic-release)
|
|
7
7
|
|
|
8
8
|
**ReactWind** is a JSX runtime wrapper that brings the power of Tailwind CSS shorthands and array-based classNames directly to your React components. No more template literal spaghetti or complex utility merges.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
npm install @itamarshdev/reactwind
|
|
@@ -20,20 +20,20 @@ yarn add @itamarshdev/reactwind
|
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Features
|
|
24
24
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
25
|
+
- **Prop-based Styling**: Use Tailwind utilities as props: `<div flex bg="blue-500" p={4} />`.
|
|
26
|
+
- **Array ClassNames**: Pass classes as clean arrays: `classNames={['text-center', isActive && 'font-bold']}`.
|
|
27
|
+
- **Zero Runtime (Concept)**: Designed for minimal overhead. Most transformations happen at the JSX level.
|
|
28
|
+
- **TypeScript First**: Automatic types for nearly all Tailwind utilities.
|
|
29
|
+
- **Framework Agnostic**: Works with Vite, Next.js, and any stack supporting custom JSX runtimes.
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## Setup
|
|
35
35
|
|
|
36
|
-
Configure your build tool to use
|
|
36
|
+
Configure your build tool to use `@itamarshdev/reactwind` as your JSX import source.
|
|
37
37
|
|
|
38
38
|
### Vite
|
|
39
39
|
|
|
@@ -41,7 +41,7 @@ Configure your build tool to use `reactwind` as your JSX import source.
|
|
|
41
41
|
// vite.config.ts
|
|
42
42
|
export default defineConfig({
|
|
43
43
|
esbuild: {
|
|
44
|
-
jsxImportSource: 'reactwind',
|
|
44
|
+
jsxImportSource: '@itamarshdev/reactwind',
|
|
45
45
|
},
|
|
46
46
|
});
|
|
47
47
|
```
|
|
@@ -53,14 +53,14 @@ export default defineConfig({
|
|
|
53
53
|
{
|
|
54
54
|
"compilerOptions": {
|
|
55
55
|
"jsx": "react-jsx",
|
|
56
|
-
"jsxImportSource": "reactwind"
|
|
56
|
+
"jsxImportSource": "@itamarshdev/reactwind"
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
63
|
-
##
|
|
63
|
+
## Usage Examples
|
|
64
64
|
|
|
65
65
|
### 1. Shorthand Props & Booleans
|
|
66
66
|
|
|
@@ -86,9 +86,53 @@ export default defineConfig({
|
|
|
86
86
|
</div>
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
### 3. Modifier Props (Hover, Focus, Responsive, etc.)
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
// Hyphenated syntax
|
|
93
|
+
<button hover-bg="blue-700" hover-scale="105" focus-ring="2">
|
|
94
|
+
Hover Me
|
|
95
|
+
</button>
|
|
96
|
+
|
|
97
|
+
// Object syntax for multiple props per modifier
|
|
98
|
+
<button hover={{ bg: "blue-700", scale: "105", shadow: "lg" }}>
|
|
99
|
+
Hover Me
|
|
100
|
+
</button>
|
|
101
|
+
|
|
102
|
+
// Stacked modifiers via nesting
|
|
103
|
+
<div dark={{ hover: { bg: "slate-800", text: "white" } }}>
|
|
104
|
+
Dark mode hover styles
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
// Responsive breakpoints
|
|
108
|
+
<div md={{ flex: true, gap: "4" }} lg={{ gap: "8" }}>
|
|
109
|
+
Responsive layout
|
|
110
|
+
</div>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 4. Position & Layout Props
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
<div absolute top="0" right="0" inset-x="4">
|
|
117
|
+
Positioned element
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<div grid grid-cols="3" gap-x="4" gap-y="2">
|
|
121
|
+
Grid with different gaps
|
|
122
|
+
</div>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 5. Gradient & Background Props
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
<div bg-gradient="to-r" from="blue-500" via="purple-500" to="pink-500">
|
|
129
|
+
Gradient background
|
|
130
|
+
</div>
|
|
131
|
+
```
|
|
132
|
+
|
|
89
133
|
---
|
|
90
134
|
|
|
91
|
-
##
|
|
135
|
+
## Goals
|
|
92
136
|
|
|
93
137
|
ReactWind aims to improve the developer experience of styling with Tailwind CSS by:
|
|
94
138
|
1. **Removing syntactic noise**: Replacing long `className` strings with structured props.
|
|
@@ -97,10 +141,10 @@ ReactWind aims to improve the developer experience of styling with Tailwind CSS
|
|
|
97
141
|
|
|
98
142
|
---
|
|
99
143
|
|
|
100
|
-
##
|
|
144
|
+
## Contributing
|
|
101
145
|
|
|
102
146
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
103
147
|
|
|
104
|
-
##
|
|
148
|
+
## License
|
|
105
149
|
|
|
106
|
-
MIT © [
|
|
150
|
+
MIT © [ItamarShDev](https://github.com/ItamarShDev/reactwind)
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
// src/runtime.ts
|
|
2
|
+
var LAYOUT_PROPS = [
|
|
3
|
+
"flex",
|
|
4
|
+
"grid",
|
|
5
|
+
"hidden",
|
|
6
|
+
"block",
|
|
7
|
+
"inline",
|
|
8
|
+
"inline-block",
|
|
9
|
+
"inline-flex",
|
|
10
|
+
"inline-grid",
|
|
11
|
+
"relative",
|
|
12
|
+
"absolute",
|
|
13
|
+
"fixed",
|
|
14
|
+
"sticky",
|
|
15
|
+
"static",
|
|
16
|
+
"flex-row",
|
|
17
|
+
"flex-col",
|
|
18
|
+
"flex-wrap",
|
|
19
|
+
"flex-nowrap",
|
|
20
|
+
"items-center",
|
|
21
|
+
"items-start",
|
|
22
|
+
"items-end",
|
|
23
|
+
"justify-center",
|
|
24
|
+
"justify-between",
|
|
25
|
+
"justify-start",
|
|
26
|
+
"justify-end",
|
|
27
|
+
"grow",
|
|
28
|
+
"shrink",
|
|
29
|
+
"italic",
|
|
30
|
+
"not-italic",
|
|
31
|
+
"underline",
|
|
32
|
+
"uppercase",
|
|
33
|
+
"lowercase",
|
|
34
|
+
"capitalize",
|
|
35
|
+
"truncate",
|
|
36
|
+
"visible",
|
|
37
|
+
"invisible",
|
|
38
|
+
"collapse",
|
|
39
|
+
"pointer-events-none",
|
|
40
|
+
"pointer-events-auto",
|
|
41
|
+
"sr-only",
|
|
42
|
+
"not-sr-only"
|
|
43
|
+
];
|
|
44
|
+
var VALUE_PROPS_MAP = {
|
|
45
|
+
bg: "bg",
|
|
46
|
+
text: "text",
|
|
47
|
+
border: "border",
|
|
48
|
+
fill: "fill",
|
|
49
|
+
stroke: "stroke",
|
|
50
|
+
p: "p",
|
|
51
|
+
m: "m",
|
|
52
|
+
px: "px",
|
|
53
|
+
py: "py",
|
|
54
|
+
mx: "mx",
|
|
55
|
+
my: "my",
|
|
56
|
+
gap: "gap",
|
|
57
|
+
w: "w",
|
|
58
|
+
h: "h",
|
|
59
|
+
rounded: "rounded",
|
|
60
|
+
shadow: "shadow",
|
|
61
|
+
font: "font",
|
|
62
|
+
z: "z",
|
|
63
|
+
mb: "mb",
|
|
64
|
+
mt: "mt",
|
|
65
|
+
ml: "ml",
|
|
66
|
+
mr: "mr",
|
|
67
|
+
pb: "pb",
|
|
68
|
+
pt: "pt",
|
|
69
|
+
pl: "pl",
|
|
70
|
+
pr: "pr",
|
|
71
|
+
tracking: "tracking",
|
|
72
|
+
leading: "leading",
|
|
73
|
+
"max-w": "max-w",
|
|
74
|
+
"min-w": "min-w",
|
|
75
|
+
"min-h": "min-h",
|
|
76
|
+
"max-h": "max-h",
|
|
77
|
+
"grid-cols": "grid-cols",
|
|
78
|
+
"col-span": "col-span",
|
|
79
|
+
"row-span": "row-span",
|
|
80
|
+
"grid-rows": "grid-rows",
|
|
81
|
+
"items": "items",
|
|
82
|
+
"justify": "justify",
|
|
83
|
+
"self": "self",
|
|
84
|
+
"place-content": "place-content",
|
|
85
|
+
"place-items": "place-items",
|
|
86
|
+
"place-self": "place-self",
|
|
87
|
+
"order": "order",
|
|
88
|
+
overflow: "overflow",
|
|
89
|
+
decoration: "decoration",
|
|
90
|
+
whitespace: "whitespace",
|
|
91
|
+
break: "break",
|
|
92
|
+
content: "content",
|
|
93
|
+
opacity: "opacity",
|
|
94
|
+
"bg-opacity": "bg-opacity",
|
|
95
|
+
"text-opacity": "text-opacity",
|
|
96
|
+
"border-opacity": "border-opacity",
|
|
97
|
+
ring: "ring",
|
|
98
|
+
"ring-offset": "ring-offset",
|
|
99
|
+
outline: "outline",
|
|
100
|
+
divide: "divide",
|
|
101
|
+
"mix-blend": "mix-blend",
|
|
102
|
+
"backdrop-blur": "backdrop-blur",
|
|
103
|
+
blur: "blur",
|
|
104
|
+
brightness: "brightness",
|
|
105
|
+
contrast: "contrast",
|
|
106
|
+
grayscale: "grayscale",
|
|
107
|
+
"hue-rotate": "hue-rotate",
|
|
108
|
+
invert: "invert",
|
|
109
|
+
saturate: "saturate",
|
|
110
|
+
sepia: "sepia",
|
|
111
|
+
"drop-shadow": "drop-shadow",
|
|
112
|
+
transition: "transition",
|
|
113
|
+
duration: "duration",
|
|
114
|
+
ease: "ease",
|
|
115
|
+
delay: "delay",
|
|
116
|
+
animate: "animate",
|
|
117
|
+
cursor: "cursor",
|
|
118
|
+
"pointer-events": "pointer-events",
|
|
119
|
+
resize: "resize",
|
|
120
|
+
select: "select",
|
|
121
|
+
scale: "scale",
|
|
122
|
+
rotate: "rotate",
|
|
123
|
+
translate: "translate",
|
|
124
|
+
skew: "skew",
|
|
125
|
+
origin: "origin",
|
|
126
|
+
// Layout & Position
|
|
127
|
+
top: "top",
|
|
128
|
+
right: "right",
|
|
129
|
+
bottom: "bottom",
|
|
130
|
+
left: "left",
|
|
131
|
+
inset: "inset",
|
|
132
|
+
"inset-x": "inset-x",
|
|
133
|
+
"inset-y": "inset-y",
|
|
134
|
+
aspect: "aspect",
|
|
135
|
+
columns: "columns",
|
|
136
|
+
float: "float",
|
|
137
|
+
clear: "clear",
|
|
138
|
+
// Flexbox & Grid
|
|
139
|
+
basis: "basis",
|
|
140
|
+
"gap-x": "gap-x",
|
|
141
|
+
"gap-y": "gap-y",
|
|
142
|
+
"auto-cols": "auto-cols",
|
|
143
|
+
"auto-rows": "auto-rows",
|
|
144
|
+
"grid-flow": "grid-flow",
|
|
145
|
+
"space-x": "space-x",
|
|
146
|
+
"space-y": "space-y",
|
|
147
|
+
"justify-items": "justify-items",
|
|
148
|
+
"justify-self": "justify-self",
|
|
149
|
+
// Sizing
|
|
150
|
+
size: "size",
|
|
151
|
+
// Borders
|
|
152
|
+
"border-t": "border-t",
|
|
153
|
+
"border-r": "border-r",
|
|
154
|
+
"border-b": "border-b",
|
|
155
|
+
"border-l": "border-l",
|
|
156
|
+
"border-x": "border-x",
|
|
157
|
+
"border-y": "border-y",
|
|
158
|
+
"rounded-t": "rounded-t",
|
|
159
|
+
"rounded-r": "rounded-r",
|
|
160
|
+
"rounded-b": "rounded-b",
|
|
161
|
+
"rounded-l": "rounded-l",
|
|
162
|
+
"rounded-tl": "rounded-tl",
|
|
163
|
+
"rounded-tr": "rounded-tr",
|
|
164
|
+
"rounded-bl": "rounded-bl",
|
|
165
|
+
"rounded-br": "rounded-br",
|
|
166
|
+
"border-style": "border",
|
|
167
|
+
// Typography
|
|
168
|
+
"text-align": "text",
|
|
169
|
+
align: "align",
|
|
170
|
+
"line-clamp": "line-clamp",
|
|
171
|
+
list: "list",
|
|
172
|
+
indent: "indent",
|
|
173
|
+
// Backgrounds & Gradients
|
|
174
|
+
"bg-gradient": "bg-gradient",
|
|
175
|
+
from: "from",
|
|
176
|
+
via: "via",
|
|
177
|
+
to: "to",
|
|
178
|
+
"bg-size": "bg",
|
|
179
|
+
"bg-position": "bg",
|
|
180
|
+
"bg-repeat": "bg",
|
|
181
|
+
// Interactivity
|
|
182
|
+
scroll: "scroll",
|
|
183
|
+
snap: "snap",
|
|
184
|
+
touch: "touch",
|
|
185
|
+
"will-change": "will-change",
|
|
186
|
+
caret: "caret",
|
|
187
|
+
accent: "accent",
|
|
188
|
+
// SVG
|
|
189
|
+
"stroke-width": "stroke"
|
|
190
|
+
};
|
|
191
|
+
var MODIFIERS = [
|
|
192
|
+
"hover",
|
|
193
|
+
"focus",
|
|
194
|
+
"active",
|
|
195
|
+
"visited",
|
|
196
|
+
"disabled",
|
|
197
|
+
"group-hover",
|
|
198
|
+
"group-focus",
|
|
199
|
+
"focus-within",
|
|
200
|
+
"focus-visible",
|
|
201
|
+
"target",
|
|
202
|
+
"first",
|
|
203
|
+
"last",
|
|
204
|
+
"only",
|
|
205
|
+
"odd",
|
|
206
|
+
"even",
|
|
207
|
+
"first-of-type",
|
|
208
|
+
"last-of-type",
|
|
209
|
+
"only-of-type",
|
|
210
|
+
"empty",
|
|
211
|
+
"checked",
|
|
212
|
+
"indeterminate",
|
|
213
|
+
"default",
|
|
214
|
+
"required",
|
|
215
|
+
"valid",
|
|
216
|
+
"invalid",
|
|
217
|
+
"in-range",
|
|
218
|
+
"out-of-range",
|
|
219
|
+
"placeholder-shown",
|
|
220
|
+
"autofill",
|
|
221
|
+
"read-only",
|
|
222
|
+
"open",
|
|
223
|
+
// Responsive breakpoints
|
|
224
|
+
"sm",
|
|
225
|
+
"md",
|
|
226
|
+
"lg",
|
|
227
|
+
"xl",
|
|
228
|
+
"2xl",
|
|
229
|
+
// Dark mode
|
|
230
|
+
"dark",
|
|
231
|
+
// Print
|
|
232
|
+
"print"
|
|
233
|
+
];
|
|
234
|
+
var BOOLEAN_VALUE_PROPS = ["shadow", "rounded", "border", "transition", "ring", "outline"];
|
|
235
|
+
var joinClassNames = (classNames) => {
|
|
236
|
+
if (!classNames || classNames.length === 0) {
|
|
237
|
+
return "";
|
|
238
|
+
}
|
|
239
|
+
return classNames.filter(Boolean).join(" ");
|
|
240
|
+
};
|
|
241
|
+
var processModifierObject = (modifier, obj, classes) => {
|
|
242
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
243
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
244
|
+
if (MODIFIERS.includes(key)) {
|
|
245
|
+
processModifierObject(`${modifier}:${key}`, value, classes);
|
|
246
|
+
}
|
|
247
|
+
} else if (key in VALUE_PROPS_MAP) {
|
|
248
|
+
const prefix = VALUE_PROPS_MAP[key];
|
|
249
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
250
|
+
classes.push(`${modifier}:${prefix}-${value}`);
|
|
251
|
+
} else if (value === true && BOOLEAN_VALUE_PROPS.includes(key)) {
|
|
252
|
+
classes.push(`${modifier}:${key}`);
|
|
253
|
+
}
|
|
254
|
+
} else if (LAYOUT_PROPS.includes(key) && value === true) {
|
|
255
|
+
classes.push(`${modifier}:${key}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
var withClassNames = (props) => {
|
|
260
|
+
if (!props) {
|
|
261
|
+
return props;
|
|
262
|
+
}
|
|
263
|
+
if ("sx" in props && typeof props.sx === "object" && props.sx !== null) {
|
|
264
|
+
const { sx, ...restProps } = props;
|
|
265
|
+
return withClassNames({ ...restProps, ...sx });
|
|
266
|
+
}
|
|
267
|
+
const hasClassNames = "classNames" in props;
|
|
268
|
+
const hasLayoutProps = LAYOUT_PROPS.some((k) => k in props);
|
|
269
|
+
const hasValueProps = Object.keys(VALUE_PROPS_MAP).some((k) => k in props);
|
|
270
|
+
const propsKeys = Object.keys(props);
|
|
271
|
+
const hasHyphenatedModifiers = propsKeys.some((key) => {
|
|
272
|
+
return MODIFIERS.some((mod) => key.startsWith(`${mod}-`));
|
|
273
|
+
});
|
|
274
|
+
const hasObjectModifiers = propsKeys.some((key) => {
|
|
275
|
+
return MODIFIERS.includes(key) && typeof props[key] === "object" && props[key] !== null;
|
|
276
|
+
});
|
|
277
|
+
const hasModifiers = hasHyphenatedModifiers || hasObjectModifiers;
|
|
278
|
+
if (!hasClassNames && !hasLayoutProps && !hasValueProps && !hasModifiers) {
|
|
279
|
+
return props;
|
|
280
|
+
}
|
|
281
|
+
const { classNames, className, ...rest } = props;
|
|
282
|
+
const generatedClasses = [];
|
|
283
|
+
const cleanRest = { ...rest };
|
|
284
|
+
for (const prop of LAYOUT_PROPS) {
|
|
285
|
+
if (prop in cleanRest && cleanRest[prop] === true) {
|
|
286
|
+
generatedClasses.push(prop);
|
|
287
|
+
delete cleanRest[prop];
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
for (const [prop, prefix] of Object.entries(VALUE_PROPS_MAP)) {
|
|
291
|
+
if (prop in cleanRest) {
|
|
292
|
+
const value = cleanRest[prop];
|
|
293
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
294
|
+
generatedClasses.push(`${prefix}-${value}`);
|
|
295
|
+
delete cleanRest[prop];
|
|
296
|
+
} else if (value === true && BOOLEAN_VALUE_PROPS.includes(prop)) {
|
|
297
|
+
generatedClasses.push(prop);
|
|
298
|
+
delete cleanRest[prop];
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
for (const modifier of MODIFIERS) {
|
|
303
|
+
if (modifier in cleanRest) {
|
|
304
|
+
const value = cleanRest[modifier];
|
|
305
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
306
|
+
processModifierObject(modifier, value, generatedClasses);
|
|
307
|
+
delete cleanRest[modifier];
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
Object.keys(cleanRest).forEach((key) => {
|
|
312
|
+
const firstHyphenIndex = key.indexOf("-");
|
|
313
|
+
if (firstHyphenIndex === -1) return;
|
|
314
|
+
const modifier = key.substring(0, firstHyphenIndex);
|
|
315
|
+
if (MODIFIERS.includes(modifier)) {
|
|
316
|
+
const restKey = key.substring(firstHyphenIndex + 1);
|
|
317
|
+
const value = cleanRest[key];
|
|
318
|
+
if (restKey in VALUE_PROPS_MAP) {
|
|
319
|
+
const prefix = VALUE_PROPS_MAP[restKey];
|
|
320
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
321
|
+
generatedClasses.push(`${modifier}:${prefix}-${value}`);
|
|
322
|
+
delete cleanRest[key];
|
|
323
|
+
} else if (value === true && BOOLEAN_VALUE_PROPS.includes(restKey)) {
|
|
324
|
+
generatedClasses.push(`${modifier}:${restKey}`);
|
|
325
|
+
delete cleanRest[key];
|
|
326
|
+
}
|
|
327
|
+
} else if (LAYOUT_PROPS.includes(restKey)) {
|
|
328
|
+
if (value === true) {
|
|
329
|
+
generatedClasses.push(`${modifier}:${restKey}`);
|
|
330
|
+
delete cleanRest[key];
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
const joined = joinClassNames(classNames || []);
|
|
336
|
+
const merged = [className, ...generatedClasses, joined].filter(Boolean).join(" ");
|
|
337
|
+
return {
|
|
338
|
+
...cleanRest,
|
|
339
|
+
...merged ? { className: merged } : {}
|
|
340
|
+
};
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export {
|
|
344
|
+
withClassNames
|
|
345
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -148,7 +148,71 @@ var VALUE_PROPS_MAP = {
|
|
|
148
148
|
rotate: "rotate",
|
|
149
149
|
translate: "translate",
|
|
150
150
|
skew: "skew",
|
|
151
|
-
origin: "origin"
|
|
151
|
+
origin: "origin",
|
|
152
|
+
// Layout & Position
|
|
153
|
+
top: "top",
|
|
154
|
+
right: "right",
|
|
155
|
+
bottom: "bottom",
|
|
156
|
+
left: "left",
|
|
157
|
+
inset: "inset",
|
|
158
|
+
"inset-x": "inset-x",
|
|
159
|
+
"inset-y": "inset-y",
|
|
160
|
+
aspect: "aspect",
|
|
161
|
+
columns: "columns",
|
|
162
|
+
float: "float",
|
|
163
|
+
clear: "clear",
|
|
164
|
+
// Flexbox & Grid
|
|
165
|
+
basis: "basis",
|
|
166
|
+
"gap-x": "gap-x",
|
|
167
|
+
"gap-y": "gap-y",
|
|
168
|
+
"auto-cols": "auto-cols",
|
|
169
|
+
"auto-rows": "auto-rows",
|
|
170
|
+
"grid-flow": "grid-flow",
|
|
171
|
+
"space-x": "space-x",
|
|
172
|
+
"space-y": "space-y",
|
|
173
|
+
"justify-items": "justify-items",
|
|
174
|
+
"justify-self": "justify-self",
|
|
175
|
+
// Sizing
|
|
176
|
+
size: "size",
|
|
177
|
+
// Borders
|
|
178
|
+
"border-t": "border-t",
|
|
179
|
+
"border-r": "border-r",
|
|
180
|
+
"border-b": "border-b",
|
|
181
|
+
"border-l": "border-l",
|
|
182
|
+
"border-x": "border-x",
|
|
183
|
+
"border-y": "border-y",
|
|
184
|
+
"rounded-t": "rounded-t",
|
|
185
|
+
"rounded-r": "rounded-r",
|
|
186
|
+
"rounded-b": "rounded-b",
|
|
187
|
+
"rounded-l": "rounded-l",
|
|
188
|
+
"rounded-tl": "rounded-tl",
|
|
189
|
+
"rounded-tr": "rounded-tr",
|
|
190
|
+
"rounded-bl": "rounded-bl",
|
|
191
|
+
"rounded-br": "rounded-br",
|
|
192
|
+
"border-style": "border",
|
|
193
|
+
// Typography
|
|
194
|
+
"text-align": "text",
|
|
195
|
+
align: "align",
|
|
196
|
+
"line-clamp": "line-clamp",
|
|
197
|
+
list: "list",
|
|
198
|
+
indent: "indent",
|
|
199
|
+
// Backgrounds & Gradients
|
|
200
|
+
"bg-gradient": "bg-gradient",
|
|
201
|
+
from: "from",
|
|
202
|
+
via: "via",
|
|
203
|
+
to: "to",
|
|
204
|
+
"bg-size": "bg",
|
|
205
|
+
"bg-position": "bg",
|
|
206
|
+
"bg-repeat": "bg",
|
|
207
|
+
// Interactivity
|
|
208
|
+
scroll: "scroll",
|
|
209
|
+
snap: "snap",
|
|
210
|
+
touch: "touch",
|
|
211
|
+
"will-change": "will-change",
|
|
212
|
+
caret: "caret",
|
|
213
|
+
accent: "accent",
|
|
214
|
+
// SVG
|
|
215
|
+
"stroke-width": "stroke"
|
|
152
216
|
};
|
|
153
217
|
var MODIFIERS = [
|
|
154
218
|
"hover",
|
|
@@ -193,23 +257,50 @@ var MODIFIERS = [
|
|
|
193
257
|
// Print
|
|
194
258
|
"print"
|
|
195
259
|
];
|
|
260
|
+
var BOOLEAN_VALUE_PROPS = ["shadow", "rounded", "border", "transition", "ring", "outline"];
|
|
196
261
|
var joinClassNames = (classNames) => {
|
|
197
262
|
if (!classNames || classNames.length === 0) {
|
|
198
263
|
return "";
|
|
199
264
|
}
|
|
200
265
|
return classNames.filter(Boolean).join(" ");
|
|
201
266
|
};
|
|
267
|
+
var processModifierObject = (modifier, obj, classes) => {
|
|
268
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
269
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
270
|
+
if (MODIFIERS.includes(key)) {
|
|
271
|
+
processModifierObject(`${modifier}:${key}`, value, classes);
|
|
272
|
+
}
|
|
273
|
+
} else if (key in VALUE_PROPS_MAP) {
|
|
274
|
+
const prefix = VALUE_PROPS_MAP[key];
|
|
275
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
276
|
+
classes.push(`${modifier}:${prefix}-${value}`);
|
|
277
|
+
} else if (value === true && BOOLEAN_VALUE_PROPS.includes(key)) {
|
|
278
|
+
classes.push(`${modifier}:${key}`);
|
|
279
|
+
}
|
|
280
|
+
} else if (LAYOUT_PROPS.includes(key) && value === true) {
|
|
281
|
+
classes.push(`${modifier}:${key}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
};
|
|
202
285
|
var withClassNames = (props) => {
|
|
203
286
|
if (!props) {
|
|
204
287
|
return props;
|
|
205
288
|
}
|
|
289
|
+
if ("sx" in props && typeof props.sx === "object" && props.sx !== null) {
|
|
290
|
+
const { sx, ...restProps } = props;
|
|
291
|
+
return withClassNames({ ...restProps, ...sx });
|
|
292
|
+
}
|
|
206
293
|
const hasClassNames = "classNames" in props;
|
|
207
294
|
const hasLayoutProps = LAYOUT_PROPS.some((k) => k in props);
|
|
208
295
|
const hasValueProps = Object.keys(VALUE_PROPS_MAP).some((k) => k in props);
|
|
209
296
|
const propsKeys = Object.keys(props);
|
|
210
|
-
const
|
|
297
|
+
const hasHyphenatedModifiers = propsKeys.some((key) => {
|
|
211
298
|
return MODIFIERS.some((mod) => key.startsWith(`${mod}-`));
|
|
212
299
|
});
|
|
300
|
+
const hasObjectModifiers = propsKeys.some((key) => {
|
|
301
|
+
return MODIFIERS.includes(key) && typeof props[key] === "object" && props[key] !== null;
|
|
302
|
+
});
|
|
303
|
+
const hasModifiers = hasHyphenatedModifiers || hasObjectModifiers;
|
|
213
304
|
if (!hasClassNames && !hasLayoutProps && !hasValueProps && !hasModifiers) {
|
|
214
305
|
return props;
|
|
215
306
|
}
|
|
@@ -228,12 +319,21 @@ var withClassNames = (props) => {
|
|
|
228
319
|
if (typeof value === "string" || typeof value === "number") {
|
|
229
320
|
generatedClasses.push(`${prefix}-${value}`);
|
|
230
321
|
delete cleanRest[prop];
|
|
231
|
-
} else if (value === true && (prop
|
|
322
|
+
} else if (value === true && BOOLEAN_VALUE_PROPS.includes(prop)) {
|
|
232
323
|
generatedClasses.push(prop);
|
|
233
324
|
delete cleanRest[prop];
|
|
234
325
|
}
|
|
235
326
|
}
|
|
236
327
|
}
|
|
328
|
+
for (const modifier of MODIFIERS) {
|
|
329
|
+
if (modifier in cleanRest) {
|
|
330
|
+
const value = cleanRest[modifier];
|
|
331
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
332
|
+
processModifierObject(modifier, value, generatedClasses);
|
|
333
|
+
delete cleanRest[modifier];
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
237
337
|
Object.keys(cleanRest).forEach((key) => {
|
|
238
338
|
const firstHyphenIndex = key.indexOf("-");
|
|
239
339
|
if (firstHyphenIndex === -1) return;
|
|
@@ -246,7 +346,7 @@ var withClassNames = (props) => {
|
|
|
246
346
|
if (typeof value === "string" || typeof value === "number") {
|
|
247
347
|
generatedClasses.push(`${modifier}:${prefix}-${value}`);
|
|
248
348
|
delete cleanRest[key];
|
|
249
|
-
} else if (value === true && (restKey
|
|
349
|
+
} else if (value === true && BOOLEAN_VALUE_PROPS.includes(restKey)) {
|
|
250
350
|
generatedClasses.push(`${modifier}:${restKey}`);
|
|
251
351
|
delete cleanRest[key];
|
|
252
352
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -49,13 +49,17 @@ interface LayoutProps {
|
|
|
49
49
|
shrink?: boolean;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
type SxProp = Partial<ValueProps & LayoutProps>;
|
|
53
|
+
|
|
52
54
|
declare module "react" {
|
|
53
55
|
interface HTMLAttributes<T> extends LayoutProps, ValueProps {
|
|
54
56
|
classNames?: (TailwindClass | string)[];
|
|
57
|
+
sx?: SxProp;
|
|
55
58
|
}
|
|
56
59
|
interface SVGAttributes<T> extends LayoutProps, ValueProps {
|
|
57
60
|
classNames?: (TailwindClass | string)[];
|
|
61
|
+
sx?: SxProp;
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
export type { LayoutProps, ValueProps };
|
|
65
|
+
export type { LayoutProps, SxProp, ValueProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -49,13 +49,17 @@ interface LayoutProps {
|
|
|
49
49
|
shrink?: boolean;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
type SxProp = Partial<ValueProps & LayoutProps>;
|
|
53
|
+
|
|
52
54
|
declare module "react" {
|
|
53
55
|
interface HTMLAttributes<T> extends LayoutProps, ValueProps {
|
|
54
56
|
classNames?: (TailwindClass | string)[];
|
|
57
|
+
sx?: SxProp;
|
|
55
58
|
}
|
|
56
59
|
interface SVGAttributes<T> extends LayoutProps, ValueProps {
|
|
57
60
|
classNames?: (TailwindClass | string)[];
|
|
61
|
+
sx?: SxProp;
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
export type { LayoutProps, ValueProps };
|
|
65
|
+
export type { LayoutProps, SxProp, ValueProps };
|