@wwog/react 1.2.6 → 1.2.8

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,411 +1,410 @@
1
- # @wwog/react
2
-
3
- 一个实用的 React 组件库,提供声明式流程控制组件和常用 UI 工具组件,使您的 React 代码更加简洁和可读。
4
-
5
- [![npm version](https://img.shields.io/npm/v/@wwog/react.svg)](https://www.npmjs.com/package/@wwog/react)
6
- [![ESM](https://img.shields.io/badge/📦-ESM%20only-brightgreen.svg)](https://nodejs.org/api/esm.html)
7
-
8
- ---
9
-
10
- [English Documentation](./README_en.md)
11
-
12
- ## 安装
13
-
14
- ```bash
15
- # 使用 npm
16
- npm install @wwog/react
17
-
18
- # 使用 yarn
19
- yarn add @wwog/react
20
-
21
- # 使用 pnpm
22
- pnpm add @wwog/react
23
- ```
24
-
25
- ## 功能特性
26
-
27
- - **仅 ESModule**:现代化的模块系统支持
28
- - **完全类型支持**:用 TypeScript 编写,提供完整的类型定义
29
- - **零依赖**:仅依赖 React React DOM 作为 peer dependencies
30
- - **声明式流程控制**:JSX 风格的条件渲染和流程控制组件
31
- - **通用工具组件**:简单实用的常见 UI 工具组件
32
-
33
- ## 组件和用法
34
-
35
- ### 流程控制组件
36
-
37
- #### `<If>`
38
-
39
- 声明式的条件渲染组件,类似于 if-else 语句,但在 JSX 中使用。
40
-
41
- ```tsx
42
- import { If } from "@wwog/react";
43
-
44
- function Example({ count }) {
45
- return (
46
- <If condition={count > 10}>
47
- <If.Then>
48
- <p>Count is greater than 10</p>
49
- </If.Then>
50
- <If.ElseIf condition={count > 5}>
51
- <p>Count is greater than 5</p>
52
- </If.ElseIf>
53
- <If.Else>
54
- <p>Count is 5 or less</p>
55
- </If.Else>
56
- </If>
57
- );
58
- }
59
- ```
60
-
61
- #### `<Switch>`, `<Case>`, `<Default>`
62
-
63
- 类似于 JavaScript 的 switch 语句,但更具声明性和类型安全性。
64
-
65
- ```tsx
66
- import { Switch } from "@wwog/react";
67
-
68
- function Example({ status }) {
69
- return (
70
- <Switch value={status}>
71
- <Switch.Case value="loading">
72
- <Loading />
73
- </Switch.Case>
74
- <Switch.Case value="success">
75
- <Success />
76
- </Switch.Case>
77
- <Switch.Case value="error">
78
- <Error />
79
- </Switch.Case>
80
- <Switch.Default>
81
- <p>Unknown status</p>
82
- </Switch.Default>
83
- </Switch>
84
- );
85
- }
86
- ```
87
-
88
- #### `<When>` (v1.1.5+)
89
-
90
- 一个简洁的条件渲染组件,支持多条件逻辑组合。比 <If> 更加简洁,适用于简单的条件渲染场景。
91
-
92
- ```jsx
93
- import { When } from '@wwog/react';
94
-
95
- function Example() {
96
- const isAdmin = useIsAdmin();
97
- const isLoading = useIsLoading();
98
- const hasErrors = useHasErrors();
99
-
100
- return (
101
- <>
102
- {/* 所有条件都为真时渲染 */}
103
- <When all={[isAdmin, !isLoading]}>
104
- <AdminPanel />
105
- </When>
106
-
107
- {/* 任一条件为真时渲染 */}
108
- <When any={[isLoading, hasErrors]} fallback={<ReadyContent />}>
109
- <LoadingOrErrorMessage />
110
- </When>
111
-
112
- {/* 所有条件都为假时渲染 */}
113
- <When none={[isAdmin, isLoading]}>
114
- <RegularUserContent />
115
- </When>
116
- </>
117
- );
118
- ```
119
-
120
- #### `<True>` / `<False>` (v1.1.6+)
121
-
122
- 用于简化条件渲染的辅助组件,适合简单的布尔判断场景。
123
-
124
- ```tsx
125
- import { True, False } from "@wwog/react";
126
-
127
- function Example({ isActive }) {
128
- return (
129
- <>
130
- <True condition={isActive}>
131
- <p>激活状态</p>
132
- </True>
133
- <False condition={isActive}>
134
- <p>未激活状态</p>
135
- </False>
136
- </>
137
- );
138
- }
139
- ```
140
-
141
- - `<True condition={...}>`:当 condition 为 true 时渲染子内容。
142
- - `<False condition={...}>`:当 condition 为 false 时渲染子内容。
143
-
144
- #### `<Toggle>` (v1.2.0+)
145
-
146
- 声明式切换组件,在预定义选项中切换值,并通过指定属性传递给子组件,支持自定义切换逻辑。
147
-
148
- > v1.2.1 Indexing is now used to fix bugs with arbitrary values
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`:默认:0。
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`:结果为 null/undefined 时的兜底内容。
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
- // 支持函数式 let
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`:传递给 let 函数的参数。
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>日期: {formatted}</div>}
272
- </DateRender>
273
-
274
- {/* 使用自定义格式化 */}
275
- <DateRender
276
- source={new Date()}
277
- format={(date) => date.toLocaleDateString("zh-CN")}
278
- >
279
- {(formatted) => <div>日期: {formatted}</div>}
280
- </DateRender>
281
- </>
282
- );
283
- }
284
- ```
285
-
286
- - `source`:要渲染的输入日期(Date 对象、ISO 字符串或时间戳)。
287
- - `format`:可选的格式化日期的函数,默认使用 `toLocaleString()`。
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
- #### `<ClassName>` (v1.2.5+)
316
-
317
- 用于将 CSS 类名分类编写的组件,内置类似`clsx`的功能,并且可以去除重复的 className。
318
-
319
- ```tsx
320
- import { ClassName } from "@wwog/react";
321
-
322
- function Example() {
323
- return (
324
- <ClassName
325
- className={{
326
- base: "p-2 bg-white",
327
- hover: "hover:bg-gray-100",
328
- active: "active:bg-gray-200",
329
- focus: "focus:ring-2",
330
- other: "button",
331
- }}
332
- >
333
- <button>点击我</button>
334
- </ClassName>
335
- );
336
- }
337
- ```
338
-
339
- 还可以使用容器包装元素:
340
-
341
- ```tsx
342
- <ClassName
343
- className={{
344
- base: ["p-2", { "bg-red-500": isError }],
345
- hover: { "hover:bg-blue-500": true },
346
- }}
347
- asWrapper="span"
348
- >
349
- 内容
350
- </ClassName>
351
- ```
352
-
353
- - `className`:分类的类名对象,支持各种状态的类名(base, hover, active, focus, disabled 等)
354
- - `asWrapper`:是否生成包含所有 className 的 wrapper,默认 false,传递标签名如'div'或'span'
355
- - `children`:子元素,通常是一个 React 元素
356
-
357
- ### hooks
358
-
359
- - 一些常用的 hooks 的封装
360
-
361
- #### useControlled (v1.2.0+)
362
-
363
- - 受控组件和非受控组件的切换,方便组件开发
364
-
365
- ### utils
366
-
367
- - 用于部分组件的内部函数,如需要也可使用
368
-
369
- #### `formatDate`
370
-
371
- 比较标准的格式化时间函数
372
-
373
- #### `childrenLoop`
374
-
375
- 可以中断的子节点遍历,让一些分支流程拥有极致性能
376
-
377
- #### `Counter`
378
-
379
- 计数器
380
-
381
- #### `cn` (v1.2.5+)
382
-
383
- 一个高效的 CSS 类名合并工具函数,类似于`clsx`或`classnames`,但能自动去除重复的类名。
384
-
385
- ```tsx
386
- import { cn } from "@wwog/react";
387
-
388
- function Example({ isActive, isDisabled }) {
389
- return (
390
- <div
391
- className={cn("base-class", ["array-class-1", "array-class-2"], {
392
- "active-class": isActive,
393
- "disabled-class": isDisabled,
394
- })}
395
- >
396
- 内容
397
- </div>
398
- );
399
- }
400
- ```
401
-
402
- 支持多种参数类型:
403
-
404
- - 字符串: `"class1 class2"`
405
- - 字符串数组: `["class1", "class2"]`
406
- - 对象: `{ "class1": true, "class2": false }`
407
- - 以上类型的任意组合
408
-
409
- ## License
410
-
411
- MIT
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
+ [![npm version](https://img.shields.io/npm/v/@wwog/react.svg)](https://www.npmjs.com/package/@wwog/react)
6
+ [![ESM](https://img.shields.io/badge/📦-ESM%20only-brightgreen.svg)](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"],
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