@wwog/react 1.1.5 → 1.1.6
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 +61 -5
- package/dist/index.d.mts +12 -2
- package/dist/index.js +1 -196
- package/package.json +1 -1
- package/src/ProcessControl/If.tsx +17 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ pnpm add @wwog/react
|
|
|
35
35
|
声明式的条件渲染组件,类似于 if-else 语句,但在 JSX 中使用。
|
|
36
36
|
|
|
37
37
|
```tsx
|
|
38
|
-
import { If } from
|
|
38
|
+
import { If } from "@wwog/react";
|
|
39
39
|
|
|
40
40
|
function Example({ count }) {
|
|
41
41
|
return (
|
|
@@ -59,7 +59,7 @@ function Example({ count }) {
|
|
|
59
59
|
类似于 JavaScript 的 switch 语句,但更具声明性和类型安全性。
|
|
60
60
|
|
|
61
61
|
```tsx
|
|
62
|
-
import { Switch } from
|
|
62
|
+
import { Switch } from "@wwog/react";
|
|
63
63
|
|
|
64
64
|
function Example({ status }) {
|
|
65
65
|
return (
|
|
@@ -81,6 +81,62 @@ function Example({ status }) {
|
|
|
81
81
|
}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
#### `<When>` (v1.1.5+)
|
|
85
|
+
|
|
86
|
+
一个简洁的条件渲染组件,支持多条件逻辑组合。比 <If> 更加简洁,适用于简单的条件渲染场景。
|
|
87
|
+
|
|
88
|
+
```jsx
|
|
89
|
+
import { When } from '@wwog/react';
|
|
90
|
+
|
|
91
|
+
function Example() {
|
|
92
|
+
const isAdmin = useIsAdmin();
|
|
93
|
+
const isLoading = useIsLoading();
|
|
94
|
+
const hasErrors = useHasErrors();
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<>
|
|
98
|
+
{/* 所有条件都为真时渲染 */}
|
|
99
|
+
<When all={[isAdmin, !isLoading]}>
|
|
100
|
+
<AdminPanel />
|
|
101
|
+
</When>
|
|
102
|
+
|
|
103
|
+
{/* 任一条件为真时渲染 */}
|
|
104
|
+
<When any={[isLoading, hasErrors]} fallback={<ReadyContent />}>
|
|
105
|
+
<LoadingOrErrorMessage />
|
|
106
|
+
</When>
|
|
107
|
+
|
|
108
|
+
{/* 所有条件都为假时渲染 */}
|
|
109
|
+
<When none={[isAdmin, isLoading]}>
|
|
110
|
+
<RegularUserContent />
|
|
111
|
+
</When>
|
|
112
|
+
</>
|
|
113
|
+
);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### `<True>` / `<False>` (v1.1.6+)
|
|
117
|
+
|
|
118
|
+
用于简化条件渲染的辅助组件,适合简单的布尔判断场景。
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { True, False } from "@wwog/react";
|
|
122
|
+
|
|
123
|
+
function Example({ isActive }) {
|
|
124
|
+
return (
|
|
125
|
+
<>
|
|
126
|
+
<True condition={isActive}>
|
|
127
|
+
<p>激活状态</p>
|
|
128
|
+
</True>
|
|
129
|
+
<False condition={isActive}>
|
|
130
|
+
<p>未激活状态</p>
|
|
131
|
+
</False>
|
|
132
|
+
</>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- `<True condition={...}>`:当 condition 为 true 时渲染子内容。
|
|
138
|
+
- `<False condition={...}>`:当 condition 为 false 时渲染子内容。
|
|
139
|
+
|
|
84
140
|
### 通用组件
|
|
85
141
|
|
|
86
142
|
#### `<ArrayRender>`
|
|
@@ -88,11 +144,11 @@ function Example({ status }) {
|
|
|
88
144
|
高效渲染数组数据的工具组件,支持过滤和自定义渲染。
|
|
89
145
|
|
|
90
146
|
```tsx
|
|
91
|
-
import { ArrayRender } from
|
|
147
|
+
import { ArrayRender } from "@wwog/react";
|
|
92
148
|
|
|
93
149
|
function UserList({ users }) {
|
|
94
150
|
return (
|
|
95
|
-
<ArrayRender
|
|
151
|
+
<ArrayRender
|
|
96
152
|
items={users}
|
|
97
153
|
filter={(user) => user.active}
|
|
98
154
|
renderItem={(user, index) => (
|
|
@@ -110,7 +166,7 @@ function UserList({ users }) {
|
|
|
110
166
|
创建固定尺寸的容器,用于布局调整和间距控制。
|
|
111
167
|
|
|
112
168
|
```tsx
|
|
113
|
-
import { SizeBox } from
|
|
169
|
+
import { SizeBox } from "@wwog/react";
|
|
114
170
|
|
|
115
171
|
function Layout() {
|
|
116
172
|
return (
|
package/dist/index.d.mts
CHANGED
|
@@ -76,6 +76,16 @@ declare const If: {
|
|
|
76
76
|
Else: (props: ElseProps) => React.ReactElement;
|
|
77
77
|
};
|
|
78
78
|
};
|
|
79
|
+
interface TrueProps {
|
|
80
|
+
condition: boolean;
|
|
81
|
+
children?: ReactNode;
|
|
82
|
+
}
|
|
83
|
+
declare const True: FC<TrueProps>;
|
|
84
|
+
interface FalseProps {
|
|
85
|
+
condition: boolean;
|
|
86
|
+
children?: ReactNode;
|
|
87
|
+
}
|
|
88
|
+
declare const False: FC<FalseProps>;
|
|
79
89
|
|
|
80
90
|
interface WhenProps {
|
|
81
91
|
/**
|
|
@@ -154,5 +164,5 @@ declare function ArrayRender<T>(props: ArrayRenderProps<T>): ReactNode;
|
|
|
154
164
|
*/
|
|
155
165
|
declare function childrenLoop(children: React.ReactNode | undefined, callback: (child: React.ReactNode, index: number) => boolean | void): void;
|
|
156
166
|
|
|
157
|
-
export { ArrayRender, If, SizeBox, Switch, When, childrenLoop };
|
|
158
|
-
export type { ArrayRenderProps, ElseIfProps, ElseProps, IfProps, SwitchCaseProps, SwitchDefaultProps, SwitchProps, ThenProps, WhenProps };
|
|
167
|
+
export { ArrayRender, False, If, SizeBox, Switch, True, When, childrenLoop };
|
|
168
|
+
export type { ArrayRenderProps, ElseIfProps, ElseProps, FalseProps, IfProps, SwitchCaseProps, SwitchDefaultProps, SwitchProps, ThenProps, TrueProps, WhenProps };
|
package/dist/index.js
CHANGED
|
@@ -1,196 +1 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
3
|
-
function childrenLoop(children, callback) {
|
|
4
|
-
if (children === void 0) return;
|
|
5
|
-
let index = 0;
|
|
6
|
-
if (Array.isArray(children)) {
|
|
7
|
-
for (const child of children) {
|
|
8
|
-
const shouldContinue = callback(child, index++);
|
|
9
|
-
if (shouldContinue === false) {
|
|
10
|
-
break;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
} else {
|
|
14
|
-
callback(children, index);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const defaultCompare = (a, b) => {
|
|
19
|
-
return a === b;
|
|
20
|
-
};
|
|
21
|
-
const Case = (props) => {
|
|
22
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, props.children);
|
|
23
|
-
};
|
|
24
|
-
Case.displayName = "Switch_Case";
|
|
25
|
-
const Default = (props) => {
|
|
26
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, props.children);
|
|
27
|
-
};
|
|
28
|
-
Default.displayName = "Switch_Default";
|
|
29
|
-
const Switch = (props) => {
|
|
30
|
-
const { value, compare = defaultCompare, children, strict = false } = props;
|
|
31
|
-
const seenValues = /* @__PURE__ */ new Set();
|
|
32
|
-
let matchedChildren = null;
|
|
33
|
-
let defaultChild = null;
|
|
34
|
-
let hasDefault = false;
|
|
35
|
-
childrenLoop(children, (child, index) => {
|
|
36
|
-
if (!React.isValidElement(child)) {
|
|
37
|
-
throw new Error(
|
|
38
|
-
`Switch Children only accepts valid React elements at index ${index}`
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
const type = child.type;
|
|
42
|
-
if (type.displayName === Case.displayName) {
|
|
43
|
-
const caseProps = child.props;
|
|
44
|
-
if (seenValues.has(caseProps.value)) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
`Switch found duplicate Case value at index ${index}: ${JSON.stringify(
|
|
47
|
-
caseProps.value
|
|
48
|
-
)}${strict ? " (detected in strict mode)" : ""}`
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
seenValues.add(caseProps.value);
|
|
52
|
-
if (!matchedChildren && compare(value, caseProps.value)) {
|
|
53
|
-
matchedChildren = caseProps.children;
|
|
54
|
-
if (strict === false) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
} else if (type.displayName === Default.displayName) {
|
|
59
|
-
if (hasDefault) {
|
|
60
|
-
throw new Error(
|
|
61
|
-
`Switch can only have one Default child at index ${index}`
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
hasDefault = true;
|
|
65
|
-
defaultChild = child.props.children;
|
|
66
|
-
if (!strict && matchedChildren) {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
throw new Error(
|
|
71
|
-
`Switch Children only accepts 'Case' or 'Default' elements, found: ${String(
|
|
72
|
-
type.displayName || type.name || type
|
|
73
|
-
)} at index ${index}`
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, matchedChildren ?? defaultChild);
|
|
78
|
-
};
|
|
79
|
-
Switch.displayName = "Switch";
|
|
80
|
-
Switch.Case = Case;
|
|
81
|
-
Switch.Default = Default;
|
|
82
|
-
Switch.createTyped = function() {
|
|
83
|
-
return {
|
|
84
|
-
Switch,
|
|
85
|
-
Case,
|
|
86
|
-
Default
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const Then = (props) => {
|
|
91
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, props.children);
|
|
92
|
-
};
|
|
93
|
-
const Else = ({ children }) => {
|
|
94
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
95
|
-
};
|
|
96
|
-
const ElseIf = (props) => {
|
|
97
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, props.children);
|
|
98
|
-
};
|
|
99
|
-
Then.displayName = "If_Then";
|
|
100
|
-
Else.displayName = "If_Else";
|
|
101
|
-
ElseIf.displayName = "If_ElseIf";
|
|
102
|
-
const If = ({
|
|
103
|
-
condition,
|
|
104
|
-
children
|
|
105
|
-
}) => {
|
|
106
|
-
let thenChild = null;
|
|
107
|
-
let elseChild = null;
|
|
108
|
-
const elseIfChildren = [];
|
|
109
|
-
React.Children.forEach(children, (child) => {
|
|
110
|
-
if (!React.isValidElement(child)) {
|
|
111
|
-
throw new Error("If component only accepts valid React elements");
|
|
112
|
-
}
|
|
113
|
-
const type = child.type;
|
|
114
|
-
if (type.displayName === Then.displayName) {
|
|
115
|
-
if (thenChild) {
|
|
116
|
-
throw new Error("If component can only have one Then child");
|
|
117
|
-
}
|
|
118
|
-
thenChild = child;
|
|
119
|
-
} else if (type.displayName === ElseIf.displayName) {
|
|
120
|
-
elseIfChildren.push(child);
|
|
121
|
-
} else if (type.displayName === Else.displayName) {
|
|
122
|
-
if (elseChild) {
|
|
123
|
-
throw new Error("If component can only have one Else child");
|
|
124
|
-
}
|
|
125
|
-
elseChild = child;
|
|
126
|
-
} else {
|
|
127
|
-
throw new Error(
|
|
128
|
-
`If component only accepts 'Then', 'ElseIf', or 'Else' elements as children, found: ${String(
|
|
129
|
-
type.displayName || type.name || type
|
|
130
|
-
)}`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
if (condition) {
|
|
135
|
-
return thenChild ? /* @__PURE__ */ React.createElement(React.Fragment, null, thenChild.props.children) : null;
|
|
136
|
-
}
|
|
137
|
-
for (const elseIf of elseIfChildren) {
|
|
138
|
-
if (elseIf.props.condition) {
|
|
139
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, elseIf.props.children);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (elseChild) {
|
|
143
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, elseChild.props.children);
|
|
144
|
-
}
|
|
145
|
-
return null;
|
|
146
|
-
};
|
|
147
|
-
If.displayName = "If";
|
|
148
|
-
If.Then = Then;
|
|
149
|
-
If.ElseIf = ElseIf;
|
|
150
|
-
If.Else = Else;
|
|
151
|
-
If.createTyped = function() {
|
|
152
|
-
return {
|
|
153
|
-
If,
|
|
154
|
-
Then,
|
|
155
|
-
ElseIf,
|
|
156
|
-
Else
|
|
157
|
-
};
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const When = ({ all, any, none, children, fallback }) => {
|
|
161
|
-
const shouldRender = useMemo(() => {
|
|
162
|
-
if (all && (any || none)) {
|
|
163
|
-
console.warn(
|
|
164
|
-
'When: Multiple condition types (all, any, none) provided; "all" takes precedence.'
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
if (all && all.length > 0 && all.every(Boolean)) return true;
|
|
168
|
-
if (any && any.length > 0 && any.some(Boolean)) return true;
|
|
169
|
-
if (none && none.length > 0 && none.every((v) => !v)) return true;
|
|
170
|
-
return false;
|
|
171
|
-
}, [all, any, none]);
|
|
172
|
-
return shouldRender ? /* @__PURE__ */ React.createElement(React.Fragment, null, children) : /* @__PURE__ */ React.createElement(React.Fragment, null, fallback || null);
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const SizeBox = (props) => {
|
|
176
|
-
const { children, h, w, size, height, width } = props;
|
|
177
|
-
const widthValue = size || w || width;
|
|
178
|
-
const heightValue = size || h || height;
|
|
179
|
-
return /* @__PURE__ */ React.createElement("div", { style: { width: widthValue, height: heightValue } }, children);
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
function ArrayRender(props) {
|
|
183
|
-
const { items, renderItem, filter } = props;
|
|
184
|
-
if (!items) {
|
|
185
|
-
console.error("ArrayRender: items is null");
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
return /* @__PURE__ */ React.createElement(Fragment, null, items.map((item, index) => {
|
|
189
|
-
if (filter && !filter(item)) {
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
return renderItem(item, index);
|
|
193
|
-
}));
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export { ArrayRender, If, SizeBox, Switch, When, childrenLoop };
|
|
1
|
+
import n,{useMemo as F,Fragment as I}from"react";function v(e,l){if(e===void 0)return;let t=0;if(Array.isArray(e)){for(const a of e)if(l(a,t++)===!1)break}else l(e,t)}const S=(e,l)=>e===l,f=e=>n.createElement(n.Fragment,null,e.children);f.displayName="Switch_Case";const p=e=>n.createElement(n.Fragment,null,e.children);p.displayName="Switch_Default";const c=e=>{const{value:l,compare:t=S,children:a,strict:i=!1}=e,r=new Set;let o=null,g=null,N=!1;return v(a,(h,u)=>{if(!n.isValidElement(h))throw new Error(`Switch Children only accepts valid React elements at index ${u}`);const d=h.type;if(d.displayName===f.displayName){const m=h.props;if(r.has(m.value))throw new Error(`Switch found duplicate Case value at index ${u}: ${JSON.stringify(m.value)}${i?" (detected in strict mode)":""}`);if(r.add(m.value),!o&&t(l,m.value)&&(o=m.children,i===!1))return!1}else if(d.displayName===p.displayName){if(N)throw new Error(`Switch can only have one Default child at index ${u}`);if(N=!0,g=h.props.children,!i&&o)return!1}else throw new Error(`Switch Children only accepts 'Case' or 'Default' elements, found: ${String(d.displayName||d.name||d)} at index ${u}`)}),n.createElement(n.Fragment,null,o??g)};c.displayName="Switch",c.Case=f,c.Default=p,c.createTyped=function(){return{Switch:c,Case:f,Default:p}};const y=e=>n.createElement(n.Fragment,null,e.children),E=({children:e})=>n.createElement(n.Fragment,null,e),w=e=>n.createElement(n.Fragment,null,e.children);y.displayName="If_Then",E.displayName="If_Else",w.displayName="If_ElseIf";const s=({condition:e,children:l})=>{let t=null,a=null;const i=[];if(n.Children.forEach(l,r=>{if(!n.isValidElement(r))throw new Error("If component only accepts valid React elements");const o=r.type;if(o.displayName===y.displayName){if(t)throw new Error("If component can only have one Then child");t=r}else if(o.displayName===w.displayName)i.push(r);else if(o.displayName===E.displayName){if(a)throw new Error("If component can only have one Else child");a=r}else throw new Error(`If component only accepts 'Then', 'ElseIf', or 'Else' elements as children, found: ${String(o.displayName||o.name||o)}`)}),e)return t?n.createElement(n.Fragment,null,t.props.children):null;for(const r of i)if(r.props.condition)return n.createElement(n.Fragment,null,r.props.children);return a?n.createElement(n.Fragment,null,a.props.children):null};s.displayName="If",s.Then=y,s.ElseIf=w,s.Else=E,s.createTyped=function(){return{If:s,Then:y,ElseIf:w,Else:E}};const C=({condition:e,children:l})=>e?n.createElement(n.Fragment,null,l):null,T=({condition:e,children:l})=>e===!1?n.createElement(n.Fragment,null,l):null,x=({all:e,any:l,none:t,children:a,fallback:i})=>F(()=>(e&&(l||t)&&console.warn('When: Multiple condition types (all, any, none) provided; "all" takes precedence.'),!!(e&&e.length>0&&e.every(Boolean)||l&&l.length>0&&l.some(Boolean)||t&&t.length>0&&t.every(r=>!r))),[e,l,t])?n.createElement(n.Fragment,null,a):n.createElement(n.Fragment,null,i||null),$=e=>{const{children:l,h:t,w:a,size:i,height:r,width:o}=e;return n.createElement("div",{style:{width:i||a||o,height:i||t||r}},l)};function D(e){const{items:l,renderItem:t,filter:a}=e;return l?n.createElement(I,null,l.map((i,r)=>a&&!a(i)?null:t(i,r))):(console.error("ArrayRender: items is null"),null)}export{D as ArrayRender,T as False,s as If,$ as SizeBox,c as Switch,C as True,x as When,v as childrenLoop};
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { type FC } from "react";
|
|
1
|
+
import React, { type FC, type ReactNode } from "react";
|
|
2
2
|
|
|
3
3
|
export interface IfProps {
|
|
4
4
|
condition: boolean;
|
|
@@ -102,3 +102,19 @@ If.createTyped = function () {
|
|
|
102
102
|
Else: (props: ElseProps) => React.ReactElement;
|
|
103
103
|
};
|
|
104
104
|
};
|
|
105
|
+
|
|
106
|
+
export interface TrueProps {
|
|
107
|
+
condition: boolean;
|
|
108
|
+
children?: ReactNode;
|
|
109
|
+
}
|
|
110
|
+
export const True: FC<TrueProps> = ({ condition, children }) => {
|
|
111
|
+
return condition ? <>{children}</> : null;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export interface FalseProps {
|
|
115
|
+
condition: boolean;
|
|
116
|
+
children?: ReactNode;
|
|
117
|
+
}
|
|
118
|
+
export const False: FC<FalseProps> = ({ condition, children }) => {
|
|
119
|
+
return condition === false ? <>{children}</> : null;
|
|
120
|
+
};
|