-
Notifications
You must be signed in to change notification settings - Fork 0
/
react-condition.js
186 lines (168 loc) · 5.23 KB
/
react-condition.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
98
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
var React,
{ Children, createElement, useState } = require("react");
/**
* Use the `test` prop with `<If>` and `<ElseIf>` elements to conditionally
* include certain elements. When an `<If>` test is _truthy_ it does not
* render any `<ElseIf>` or `<Else>` children. However when it is _falsey_ it
* _only_ renders `<ElseIf>` and `<Else>` children.
*
* <If test={someCondition}>
* This will only be shown if someCondition is truthy.
* <ElseIf test={otherCondition}>
* This will only be shown if someCondition is falsey
* and otherCondition is truthy.
* <Else>
* This will only be shown if both someCondition and
* otherCondition are both falsey.
* </Else>
* </ElseIf>
* <Else>
* This will be shown if someCondition is falsey.
* <If test={finalCondition}>
* This will be shown if someCondition is falsey
* and finalCondition is truthy.
* </If>
* </Else>
* </If>
*
* Alternatively, you can provide `then` and `else` props.
*
* <If
* test={someCondition}
* then={'This will only be shown if someCondition is truthy.'}
* else={'This will be shown if someCondition is falsey.'}
* />
*
*/
function If(props) {
var hasTest = props.hasOwnProperty("test");
if (!hasTest && !props.hasOwnProperty("case")) {
throw new TypeError("<If> requires a `test` prop.");
}
var condition = Boolean(hasTest ? props.test : props.case);
var hasElse = props.hasOwnProperty("else");
var hasThen = props.hasOwnProperty("then");
if (hasElse && !hasThen) {
throw new TypeError("<If> only use `else` prop alongside `then` prop.");
}
if ((hasThen ^ props.hasOwnProperty("children")) === 0) {
throw new TypeError("<If> expects either a `then` prop or children.");
}
if (hasThen) {
return condition ? props.then : hasElse ? props.else : null;
}
return Children.map(props.children, function(child) {
var isElse = child.type === Else || child.type === ElseIf;
return condition !== isElse ? child : null;
});
}
/**
* Use the `expression` prop with `<Switch>` element to conditionally include
* certain elements. When an `<Switch>` compares a value from `<Case>` and the
* comparison is _truthy_ it _only_ renders the matching child. However, when
* the comparison is _falsey_ it continues through the children until it finds
* a match, or falls back to `<Default>`.
*
* <Switch expression={"blue"}>
* <Case value={"red"}>
* red
* </Case>
* <Case value={"green"}>
* green
* </Case>
* <Case value={"blue"}>
* blue
* </Case>
* </Switch>
*
*
* <Switch expression={"hot fucking pink"}>
* <Case value={"red"}>
* red
* </Case>
* <Case value={"green"}>
* green
* </Case>
* <Case value={"blue"}>
* blue
* </Case>
* <Default>
* no color
* </Default>
* </Switch>
*
*
* Alternatively, you can provide `then` as props to `<Case>` or `<Default>`
*
* <Switch expression={"hot fucking pink"}>
* <Case value={"red"} then={"red"} />
* <Case value={"red"} then={"green"} />
* <Case value={"red"} then={"blue"} />
* <Default then={"no color"} />
* </Switch>
*
*/
function Else(props) {
return props.children;
}
function ElseIf(props) {
return createElement(If, props);
}
function Switch(props) {
var match = null;
var count = Children.count(props.children);
var hasExpression = props.hasOwnProperty("expression");
if (!hasExpression) {
throw new TypeError("<Switch> requires an `expression` prop.");
}
Children.forEach(props.children, (child, i) => {
if (match) return;
if (child.type !== Case && child.type !== Default && child !== null) {
throw new TypeError(
"<Switch> requires a child of type <Case>, <Default>, or null."
);
}
if (i + 1 === count) {
if (child.type === Default) {
match = child;
}
} else {
if (child.type === Default) {
throw new TypeError(
"<Default> is required to be the last node if present."
);
}
}
child.props.value === props.expression ? (match = child) : null;
});
return match;
}
function Case(props) {
var hasValue = props.hasOwnProperty("value");
var hasThen = props.hasOwnProperty("then");
if (!hasValue) {
throw new TypeError("<Case> requires an `value` prop.");
}
if ((hasThen ^ props.hasOwnProperty("children")) === 0) {
throw new TypeError("<Case> expects either a `then` prop or children.");
}
return props.then || props.children || null;
}
function Default(props) {
var hasThen = props.hasOwnProperty("then");
if ((hasThen ^ props.hasOwnProperty("children")) === 0) {
throw new TypeError(
"<Default> expects either a `then` prop or children. Remove <Default> for null."
);
}
return props.then || props.children || null;
}
Object.defineProperties(exports, {
If: { enumerable: true, value: If },
Else: { enumerable: true, value: Else },
ElseIf: { enumerable: true, value: ElseIf },
Switch: { enumerable: true, value: Switch },
Case: { enumerable: true, value: Case },
Default: { enumerable: true, value: Default },
__esModule: { value: true }
});