@wwog/react 1.2.5 → 1.2.7
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 +410 -410
- package/dist/index.d.mts +95 -65
- package/dist/index.js +1 -1
- package/package.json +12 -6
- package/src/components/ProcessControl/Switch.tsx +2 -2
- package/src/components/ProcessControl/index.ts +4 -4
- package/src/components/Struct/index.ts +2 -2
- package/src/components/Sundry/Styles.test.tsx +128 -0
- package/src/components/Sundry/Styles.tsx +131 -0
- package/src/components/Sundry/index.ts +4 -4
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useControlled.ts +22 -27
- package/src/index.ts +9 -5
- package/src/utils/cx.test.ts +33 -0
- package/src/utils/cx.ts +25 -0
- package/src/utils/reactUtils.ts +22 -0
- package/src/utils/sundry.test.ts +130 -0
- package/src/utils/sundry.ts +130 -0
- package/src/components/Sundry/ClassName.tsx +0 -86
- package/src/utils/index.ts +0 -185
package/README.md
CHANGED
|
@@ -1,410 +1,410 @@
|
|
|
1
|
-
# @wwog/react
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@wwog/react)
|
|
6
|
-
[](https://nodejs.org/api/esm.html)
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
[
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
#
|
|
16
|
-
npm install @wwog/react
|
|
17
|
-
|
|
18
|
-
#
|
|
19
|
-
yarn add @wwog/react
|
|
20
|
-
|
|
21
|
-
#
|
|
22
|
-
pnpm add @wwog/react
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
##
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
```tsx
|
|
151
|
-
import { Toggle } from "@wwog/react";
|
|
152
|
-
|
|
153
|
-
<Toggle
|
|
154
|
-
options={["light", "dark"]}
|
|
155
|
-
render={(value, toggle) => {
|
|
156
|
-
/* xxx */
|
|
157
|
-
}}
|
|
158
|
-
/>;
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
- `options
|
|
162
|
-
- `index
|
|
163
|
-
- `next
|
|
164
|
-
- `render
|
|
165
|
-
|
|
166
|
-
###
|
|
167
|
-
|
|
168
|
-
#### `<ArrayRender>`
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
```tsx
|
|
173
|
-
import { ArrayRender } from "@wwog/react";
|
|
174
|
-
|
|
175
|
-
function UserList({ users }) {
|
|
176
|
-
return (
|
|
177
|
-
<ArrayRender
|
|
178
|
-
items={users}
|
|
179
|
-
filter={(user) => user.active}
|
|
180
|
-
renderItem={(user, index) => (
|
|
181
|
-
<div key={user.id}>
|
|
182
|
-
{index + 1}. {user.name}
|
|
183
|
-
</div>
|
|
184
|
-
)}
|
|
185
|
-
/>
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### `<Pipe>` (v1.1.7+)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
>
|
|
195
|
-
>
|
|
196
|
-
>
|
|
197
|
-
|
|
198
|
-
```tsx
|
|
199
|
-
import { Pipe } from "@wwog/react";
|
|
200
|
-
|
|
201
|
-
function Example({ users }) {
|
|
202
|
-
return (
|
|
203
|
-
<Pipe
|
|
204
|
-
data={users}
|
|
205
|
-
transform={[
|
|
206
|
-
(data) => data.filter((user) => user.active),
|
|
207
|
-
(data) => data.map((user) => user.name),
|
|
208
|
-
]}
|
|
209
|
-
render={(names) => <div>{names.join(", ")}</div>}
|
|
210
|
-
fallback={<div>No Data</div>}
|
|
211
|
-
/>
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
- `data
|
|
217
|
-
- `transform
|
|
218
|
-
- `render
|
|
219
|
-
- `fallback
|
|
220
|
-
|
|
221
|
-
#### `<Scope>` (v1.1.7+)
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
>
|
|
226
|
-
>
|
|
227
|
-
>
|
|
228
|
-
|
|
229
|
-
```tsx
|
|
230
|
-
import { Scope } from "@wwog/react";
|
|
231
|
-
|
|
232
|
-
function Example() {
|
|
233
|
-
return (
|
|
234
|
-
<Scope let={{ count: 1, text: "Hello" }}>
|
|
235
|
-
{({ count, text }) => (
|
|
236
|
-
<div>
|
|
237
|
-
{text} {count}
|
|
238
|
-
</div>
|
|
239
|
-
)}
|
|
240
|
-
</Scope>
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
//
|
|
245
|
-
<Scope
|
|
246
|
-
let={(props) => ({ total: props.items.length })}
|
|
247
|
-
props={{ items: [1, 2] }}
|
|
248
|
-
fallback={<div>Empty</div>}
|
|
249
|
-
>
|
|
250
|
-
{({ total }) => <div>Total: {total}</div>}
|
|
251
|
-
</Scope>;
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
- `let
|
|
255
|
-
- `props
|
|
256
|
-
- `children
|
|
257
|
-
- `fallback
|
|
258
|
-
|
|
259
|
-
#### `<DateRender>` (v1.2.3+)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
```tsx
|
|
264
|
-
import { DateRender } from "@wwog/react";
|
|
265
|
-
|
|
266
|
-
function Example() {
|
|
267
|
-
return (
|
|
268
|
-
<>
|
|
269
|
-
{/*
|
|
270
|
-
<DateRender source="2025-05-06">
|
|
271
|
-
{(formatted) => <div
|
|
272
|
-
</DateRender>
|
|
273
|
-
|
|
274
|
-
{/*
|
|
275
|
-
<DateRender
|
|
276
|
-
source={new Date()}
|
|
277
|
-
format={(date) => date.toLocaleDateString("
|
|
278
|
-
>
|
|
279
|
-
{(formatted) => <div
|
|
280
|
-
</DateRender>
|
|
281
|
-
</>
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
- `source
|
|
287
|
-
- `format
|
|
288
|
-
- `children
|
|
289
|
-
|
|
290
|
-
#### `<SizeBox>`
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
> v1.1.8: Fixed SizeBox not working in 'flex' layouts, add classname props
|
|
295
|
-
|
|
296
|
-
```tsx
|
|
297
|
-
import { SizeBox } from "@wwog/react";
|
|
298
|
-
|
|
299
|
-
function Layout() {
|
|
300
|
-
return (
|
|
301
|
-
<div>
|
|
302
|
-
<Header />
|
|
303
|
-
{/*
|
|
304
|
-
<SizeBox height={20} />
|
|
305
|
-
<Content />
|
|
306
|
-
{/*
|
|
307
|
-
<SizeBox width={200} height={150}>
|
|
308
|
-
<SideContent />
|
|
309
|
-
</SizeBox>
|
|
310
|
-
</div>
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
#### `<
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
```tsx
|
|
320
|
-
import {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
1
|
+
# @wwog/react
|
|
2
|
+
|
|
3
|
+
A practical React component library providing declarative flow control and common UI utility components to make your React code more concise and readable.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@wwog/react)
|
|
6
|
+
[](https://nodejs.org/api/esm.html)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
[中文文档](./README_zh.md)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Using npm
|
|
16
|
+
npm install @wwog/react
|
|
17
|
+
|
|
18
|
+
# Using yarn
|
|
19
|
+
yarn add @wwog/react
|
|
20
|
+
|
|
21
|
+
# Using pnpm
|
|
22
|
+
pnpm add @wwog/react
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- **ESModule only**: Modern module system support
|
|
28
|
+
- **Full TypeScript support**: Written in TypeScript with complete type definitions
|
|
29
|
+
- **Zero dependencies**: Only React and React DOM as peer dependencies
|
|
30
|
+
- **Declarative flow control**: JSX-style conditional rendering and flow control components
|
|
31
|
+
- **Utility components**: Simple and practical common UI utility components
|
|
32
|
+
- **Lightweight and efficient** Excellent performance and compact size
|
|
33
|
+
|
|
34
|
+
## Components & Usage
|
|
35
|
+
|
|
36
|
+
### Flow Control Components
|
|
37
|
+
|
|
38
|
+
#### `<If>`
|
|
39
|
+
|
|
40
|
+
A declarative conditional rendering component, similar to if-else statements but used in JSX.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { If } from "@wwog/react";
|
|
44
|
+
|
|
45
|
+
function Example({ count }) {
|
|
46
|
+
return (
|
|
47
|
+
<If condition={count > 10}>
|
|
48
|
+
<If.Then>
|
|
49
|
+
<p>Count is greater than 10</p>
|
|
50
|
+
</If.Then>
|
|
51
|
+
<If.ElseIf condition={count > 5}>
|
|
52
|
+
<p>Count is greater than 5</p>
|
|
53
|
+
</If.ElseIf>
|
|
54
|
+
<If.Else>
|
|
55
|
+
<p>Count is 5 or less</p>
|
|
56
|
+
</If.Else>
|
|
57
|
+
</If>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### `<Switch>`, `<Case>`, `<Default>`
|
|
63
|
+
|
|
64
|
+
A declarative and type-safe alternative to JavaScript's switch statement.
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { Switch } from "@wwog/react";
|
|
68
|
+
|
|
69
|
+
function Example({ status }) {
|
|
70
|
+
return (
|
|
71
|
+
<Switch value={status}>
|
|
72
|
+
<Switch.Case value="loading">
|
|
73
|
+
<Loading />
|
|
74
|
+
</Switch.Case>
|
|
75
|
+
<Switch.Case value="success">
|
|
76
|
+
<Success />
|
|
77
|
+
</Switch.Case>
|
|
78
|
+
<Switch.Case value="error">
|
|
79
|
+
<Error />
|
|
80
|
+
</Switch.Case>
|
|
81
|
+
<Switch.Default>
|
|
82
|
+
<p>Unknown status</p>
|
|
83
|
+
</Switch.Default>
|
|
84
|
+
</Switch>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `<When>` (v1.1.5+)
|
|
90
|
+
|
|
91
|
+
A concise conditional rendering component supporting multiple logic combinations. More succinct than <If>, suitable for simple conditions.
|
|
92
|
+
|
|
93
|
+
```jsx
|
|
94
|
+
import { When } from "@wwog/react";
|
|
95
|
+
|
|
96
|
+
function Example() {
|
|
97
|
+
const isAdmin = useIsAdmin();
|
|
98
|
+
const isLoading = useIsLoading();
|
|
99
|
+
const hasErrors = useHasErrors();
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<>
|
|
103
|
+
{/* Render when all conditions are true */}
|
|
104
|
+
<When all={[isAdmin, !isLoading]}>
|
|
105
|
+
<AdminPanel />
|
|
106
|
+
</When>
|
|
107
|
+
|
|
108
|
+
{/* Render when any condition is true */}
|
|
109
|
+
<When any={[isLoading, hasErrors]} fallback={<ReadyContent />}>
|
|
110
|
+
<LoadingOrErrorMessage />
|
|
111
|
+
</When>
|
|
112
|
+
|
|
113
|
+
{/* Render when all conditions are false */}
|
|
114
|
+
<When none={[isAdmin, isLoading]}>
|
|
115
|
+
<RegularUserContent />
|
|
116
|
+
</When>
|
|
117
|
+
</>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### `<True>` / `<False>` (v1.1.6+)
|
|
123
|
+
|
|
124
|
+
Helper components for simple boolean conditional rendering.
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { True, False } from "@wwog/react";
|
|
128
|
+
|
|
129
|
+
function Example({ isActive }) {
|
|
130
|
+
return (
|
|
131
|
+
<>
|
|
132
|
+
<True condition={isActive}>
|
|
133
|
+
<p>Active</p>
|
|
134
|
+
</True>
|
|
135
|
+
<False condition={isActive}>
|
|
136
|
+
<p>Inactive</p>
|
|
137
|
+
</False>
|
|
138
|
+
</>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- `<True condition={...}>`: Renders children when condition is true.
|
|
144
|
+
- `<False condition={...}>`: Renders children when condition is false.
|
|
145
|
+
|
|
146
|
+
#### `<Toggle>`
|
|
147
|
+
|
|
148
|
+
A declarative toggle component that switches values among predefined options and passes them to child components via specified props, supporting custom toggle logic.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { Toggle } from "@wwog/react";
|
|
152
|
+
|
|
153
|
+
<Toggle
|
|
154
|
+
options={["light", "dark"]}
|
|
155
|
+
render={(value, toggle) => {
|
|
156
|
+
/* xxx */
|
|
157
|
+
}}
|
|
158
|
+
/>;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
- `options`: Array of values to toggle between.
|
|
162
|
+
- `index`: Initial Options index.
|
|
163
|
+
- `next`: Custom toggle logic function.
|
|
164
|
+
- `render`: Render Function.
|
|
165
|
+
|
|
166
|
+
### Utility Components
|
|
167
|
+
|
|
168
|
+
#### `<ArrayRender>`
|
|
169
|
+
|
|
170
|
+
Efficiently render array data, supports filtering and custom rendering.
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
import { ArrayRender } from "@wwog/react";
|
|
174
|
+
|
|
175
|
+
function UserList({ users }) {
|
|
176
|
+
return (
|
|
177
|
+
<ArrayRender
|
|
178
|
+
items={users}
|
|
179
|
+
filter={(user) => user.active}
|
|
180
|
+
renderItem={(user, index) => (
|
|
181
|
+
<div key={user.id}>
|
|
182
|
+
{index + 1}. {user.name}
|
|
183
|
+
</div>
|
|
184
|
+
)}
|
|
185
|
+
/>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### `<Pipe>` (v1.1.7+)
|
|
191
|
+
|
|
192
|
+
A declarative data pipeline component for multi-step data transformation and chaining.
|
|
193
|
+
|
|
194
|
+
> Declarative data processing, replacing nested function calls.
|
|
195
|
+
> Improves code readability and logic clarity.
|
|
196
|
+
> Suitable for data cleaning, formatting, etc.
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
import { Pipe } from "@wwog/react";
|
|
200
|
+
|
|
201
|
+
function Example({ users }) {
|
|
202
|
+
return (
|
|
203
|
+
<Pipe
|
|
204
|
+
data={users}
|
|
205
|
+
transform={[
|
|
206
|
+
(data) => data.filter((user) => user.active),
|
|
207
|
+
(data) => data.map((user) => user.name),
|
|
208
|
+
]}
|
|
209
|
+
render={(names) => <div>{names.join(", ")}</div>}
|
|
210
|
+
fallback={<div>No Data</div>}
|
|
211
|
+
/>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
- `data`: Initial data.
|
|
217
|
+
- `transform`: Array of transformation functions, applied in order.
|
|
218
|
+
- `render`: Render the final result.
|
|
219
|
+
- `fallback`: Content to render if result is null/undefined.
|
|
220
|
+
|
|
221
|
+
#### `<Scope>` (v1.1.7+)
|
|
222
|
+
|
|
223
|
+
Provides a local scope for children, declaratively defines temporary variables, and simplifies complex rendering logic.
|
|
224
|
+
|
|
225
|
+
> Avoids defining temporary state or calculations outside the component.
|
|
226
|
+
> Declaratively defines local variables for better self-containment.
|
|
227
|
+
> Suitable for forms, computation-heavy rendering, etc.
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
import { Scope } from "@wwog/react";
|
|
231
|
+
|
|
232
|
+
function Example() {
|
|
233
|
+
return (
|
|
234
|
+
<Scope let={{ count: 1, text: "Hello" }}>
|
|
235
|
+
{({ count, text }) => (
|
|
236
|
+
<div>
|
|
237
|
+
{text} {count}
|
|
238
|
+
</div>
|
|
239
|
+
)}
|
|
240
|
+
</Scope>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Function-style let is supported
|
|
245
|
+
<Scope
|
|
246
|
+
let={(props) => ({ total: props.items.length })}
|
|
247
|
+
props={{ items: [1, 2] }}
|
|
248
|
+
fallback={<div>Empty</div>}
|
|
249
|
+
>
|
|
250
|
+
{({ total }) => <div>Total: {total}</div>}
|
|
251
|
+
</Scope>;
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
- `let`: Object or function defining scope variables.
|
|
255
|
+
- `props`: Props passed to the let function.
|
|
256
|
+
- `children`: Render function for scope variables.
|
|
257
|
+
- `fallback`: Fallback content when empty.
|
|
258
|
+
|
|
259
|
+
#### `<DateRender>` (v1.2.3+)
|
|
260
|
+
|
|
261
|
+
A declarative component for formatting and rendering dates, simple to use with support for custom formatting.
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
import { DateRender } from "@wwog/react";
|
|
265
|
+
|
|
266
|
+
function Example() {
|
|
267
|
+
return (
|
|
268
|
+
<>
|
|
269
|
+
{/* Using default formatting */}
|
|
270
|
+
<DateRender source="2025-05-06">
|
|
271
|
+
{(formatted) => <div>Date: {formatted}</div>}
|
|
272
|
+
</DateRender>
|
|
273
|
+
|
|
274
|
+
{/* Using custom formatting */}
|
|
275
|
+
<DateRender
|
|
276
|
+
source={new Date()}
|
|
277
|
+
format={(date) => date.toLocaleDateString("en-US")}
|
|
278
|
+
>
|
|
279
|
+
{(formatted) => <div>Date: {formatted}</div>}
|
|
280
|
+
</DateRender>
|
|
281
|
+
</>
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
- `source`: The input date to render (Date object, ISO string, or timestamp).
|
|
287
|
+
- `format`: Optional function to format the date, defaults to `toLocaleString()`.
|
|
288
|
+
- `children`: Function to render the formatted date, receives the formatted date as an argument.
|
|
289
|
+
|
|
290
|
+
#### `<SizeBox>`
|
|
291
|
+
|
|
292
|
+
Create a fixed-size container for layout adjustment and spacing control.
|
|
293
|
+
|
|
294
|
+
> v1.1.8: Fixed SizeBox not working in 'flex' layouts, add classname props
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
import { SizeBox } from "@wwog/react";
|
|
298
|
+
|
|
299
|
+
function Layout() {
|
|
300
|
+
return (
|
|
301
|
+
<div>
|
|
302
|
+
<Header />
|
|
303
|
+
{/* Vertical spacing */}
|
|
304
|
+
<SizeBox height={20} />
|
|
305
|
+
<Content />
|
|
306
|
+
{/* Fixed-size container */}
|
|
307
|
+
<SizeBox width={200} height={150}>
|
|
308
|
+
<SideContent />
|
|
309
|
+
</SizeBox>
|
|
310
|
+
</div>
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### `<Styles>` (v1.2.7+)
|
|
316
|
+
|
|
317
|
+
Categorically write styles and basic string styles, with built-in functionality similar to clsx for combining type description object values, supporting duplicate class name removal and nesting.
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
import { Styles } from "@wwog/react";
|
|
321
|
+
import clazz from './index.module.css'
|
|
322
|
+
|
|
323
|
+
function Example() {
|
|
324
|
+
return (
|
|
325
|
+
<Styles
|
|
326
|
+
className={{
|
|
327
|
+
base: "p-2 bg-white",
|
|
328
|
+
hover: "hover:bg-gray-100",
|
|
329
|
+
active: "active:bg-gray-200",
|
|
330
|
+
focus: "focus:ring-2",
|
|
331
|
+
other: "button",
|
|
332
|
+
}}
|
|
333
|
+
>
|
|
334
|
+
<Styles className={clazz.button}>
|
|
335
|
+
<button>Click me</button>
|
|
336
|
+
</Styles>
|
|
337
|
+
</Styles>
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
You can also use a container wrapper element:
|
|
343
|
+
|
|
344
|
+
```tsx
|
|
345
|
+
<Styles
|
|
346
|
+
className={{
|
|
347
|
+
base: ["p-2", { "bg-red-500": isError }],
|
|
348
|
+
hover: { "hover:bg-blue-500": true },
|
|
349
|
+
}}
|
|
350
|
+
asWrapper="span"
|
|
351
|
+
>
|
|
352
|
+
Content
|
|
353
|
+
</Styles>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
- `className` [string | StylesDescriptor]: Category object for class names, all values in the object will be merged
|
|
357
|
+
- `asWrapper` [boolean | HTMLElementType]: Whether to generate a wrapper containing all classNames, default is false, pass tag name like 'div' or 'span'
|
|
358
|
+
- `children` : Only works with a single child element; if there are multiple child elements, please pass asWrapper to write types and avoid ambiguity
|
|
359
|
+
|
|
360
|
+
### hooks
|
|
361
|
+
|
|
362
|
+
#### useControlled
|
|
363
|
+
|
|
364
|
+
- Applied to states that can be controlled or uncontrolled components
|
|
365
|
+
|
|
366
|
+
### utils
|
|
367
|
+
|
|
368
|
+
> Internal functions used by some components, which can also be used if needed
|
|
369
|
+
|
|
370
|
+
#### `formatDate`
|
|
371
|
+
|
|
372
|
+
A relatively standard date formatting function
|
|
373
|
+
|
|
374
|
+
#### `childrenLoop`
|
|
375
|
+
|
|
376
|
+
Interruptible child node traversal, enabling some branch processes to have ultimate performance
|
|
377
|
+
|
|
378
|
+
#### `Counter`
|
|
379
|
+
|
|
380
|
+
Incrementally class
|
|
381
|
+
|
|
382
|
+
#### `cx` (v1.2.5+)
|
|
383
|
+
|
|
384
|
+
An efficient CSS class name merging utility function, similar to `clsx` or `classnames`, but automatically removes duplicate class names.
|
|
385
|
+
|
|
386
|
+
```tsx
|
|
387
|
+
import { cx } from "@wwog/react";
|
|
388
|
+
|
|
389
|
+
function Example({ isActive, isDisabled }) {
|
|
390
|
+
return (
|
|
391
|
+
<div
|
|
392
|
+
className={cx("base-class", ["array-class-1", "array-class-2"], {
|
|
393
|
+
"active-class": isActive,
|
|
394
|
+
"disabled-class": isDisabled,
|
|
395
|
+
})}
|
|
396
|
+
>
|
|
397
|
+
Content
|
|
398
|
+
</div>
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Supports various parameter types:
|
|
404
|
+
|
|
405
|
+
- String: `"class1 class2"`
|
|
406
|
+
- String array: `["class1", "class2"]`
|
|
407
|
+
- Object: `{ "class1": true, "class2": false }`
|
|
408
|
+
- Any combination of the above types
|
|
409
|
+
|
|
410
|
+
## License
|