@jsenv/navi 0.1.1 → 0.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/dist/jsenv_navi.js +8399 -3784
- package/package.json +2 -2
- package/src/components/action_execution/form_context.js +1 -4
- package/src/components/action_execution/use_action.js +2 -2
- package/src/components/demos/0_button_demo.html +149 -68
- package/src/components/demos/1_checkbox_demo.html +122 -2
- package/src/components/demos/2_input_textual_demo.html +44 -55
- package/src/components/demos/3_radio_demo.html +811 -157
- package/src/components/demos/action/0_button_demo.html +6 -4
- package/src/components/demos/action/1_input_text_demo.html +19 -25
- package/src/components/field/button.jsx +174 -71
- package/src/components/field/custom_field.js +106 -0
- package/src/components/field/field_css.js +51 -85
- package/src/components/field/form.jsx +9 -4
- package/src/components/field/input_checkbox.jsx +170 -99
- package/src/components/field/input_radio.jsx +179 -153
- package/src/components/field/input_textual.jsx +96 -5
- package/src/components/field/label.jsx +15 -3
- package/src/components/field/navi_css_vars.js +8 -0
- package/src/components/loader/loader_background.jsx +41 -14
- package/src/validation/constraints/readonly_constraint.js +5 -0
- package/src/validation/validation_message.js +78 -70
|
@@ -4,10 +4,310 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<link rel="icon" href="data:," />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>Radio
|
|
7
|
+
<title>Radio Demo</title>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
font-family:
|
|
11
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
12
|
+
max-width: 1400px;
|
|
13
|
+
margin: 0 auto;
|
|
14
|
+
padding: 20px;
|
|
15
|
+
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
h1 {
|
|
20
|
+
text-align: center;
|
|
21
|
+
color: #2c3e50;
|
|
22
|
+
margin-bottom: 30px;
|
|
23
|
+
font-size: 2.5rem;
|
|
24
|
+
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.demo-grid {
|
|
28
|
+
display: grid;
|
|
29
|
+
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
|
30
|
+
gap: 20px;
|
|
31
|
+
margin-bottom: 30px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.demo-card {
|
|
35
|
+
background: white;
|
|
36
|
+
border-radius: 12px;
|
|
37
|
+
padding: 25px;
|
|
38
|
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
39
|
+
border: 1px solid #e1e8ed;
|
|
40
|
+
transition:
|
|
41
|
+
transform 0.2s ease,
|
|
42
|
+
box-shadow 0.2s ease;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.demo-card:hover {
|
|
46
|
+
transform: translateY(-2px);
|
|
47
|
+
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.15);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.demo-title {
|
|
51
|
+
color: #2c3e50;
|
|
52
|
+
margin: 0 0 20px 0;
|
|
53
|
+
font-size: 1.3rem;
|
|
54
|
+
font-weight: 600;
|
|
55
|
+
border-bottom: 3px solid #e74c3c;
|
|
56
|
+
padding-bottom: 10px;
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 10px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.demo-title::before {
|
|
63
|
+
content: "🔘";
|
|
64
|
+
font-size: 1.2rem;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.radio-row {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
gap: 15px;
|
|
71
|
+
margin: 15px 0;
|
|
72
|
+
padding: 12px;
|
|
73
|
+
background: #f8f9fa;
|
|
74
|
+
border-radius: 8px;
|
|
75
|
+
border: 1px solid #e9ecef;
|
|
76
|
+
transition: background 0.2s ease;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.radio-row:hover {
|
|
80
|
+
background: #e8f4f8;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.radio-label {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
gap: 10px;
|
|
87
|
+
font-size: 1rem;
|
|
88
|
+
color: #495057;
|
|
89
|
+
flex: 1;
|
|
90
|
+
min-width: 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.toggle-button {
|
|
94
|
+
padding: 8px 16px;
|
|
95
|
+
background: linear-gradient(45deg, #e74c3c, #c0392b);
|
|
96
|
+
color: white;
|
|
97
|
+
border: none;
|
|
98
|
+
border-radius: 6px;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
font-size: 0.9rem;
|
|
101
|
+
font-weight: 500;
|
|
102
|
+
transition: all 0.2s ease;
|
|
103
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
104
|
+
flex-shrink: 0;
|
|
105
|
+
white-space: nowrap;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.toggle-button:hover {
|
|
109
|
+
background: linear-gradient(45deg, #c0392b, #a93226);
|
|
110
|
+
transform: translateY(-1px);
|
|
111
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.comparison {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
gap: 8px;
|
|
118
|
+
margin-top: 15px;
|
|
119
|
+
padding: 12px;
|
|
120
|
+
background: #fff3cd;
|
|
121
|
+
border-radius: 6px;
|
|
122
|
+
border-left: 4px solid #ffc107;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.comparison-label {
|
|
126
|
+
font-size: 0.85rem;
|
|
127
|
+
color: #856404;
|
|
128
|
+
font-weight: 500;
|
|
129
|
+
margin-bottom: 5px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.native-examples {
|
|
133
|
+
display: flex;
|
|
134
|
+
flex-direction: column;
|
|
135
|
+
gap: 8px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.native-examples label {
|
|
139
|
+
display: flex;
|
|
140
|
+
align-items: center;
|
|
141
|
+
gap: 10px;
|
|
142
|
+
font-size: 0.9rem;
|
|
143
|
+
color: #495057;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.prop-control-demo {
|
|
147
|
+
grid-column: 1 / -1;
|
|
148
|
+
background: linear-gradient(45deg, #e74c3c 0%, #c0392b 100%);
|
|
149
|
+
color: white;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.prop-control-demo .demo-title {
|
|
153
|
+
color: white;
|
|
154
|
+
border-bottom-color: #ffffff;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.prop-control-demo .demo-title::before {
|
|
158
|
+
content: "🎛️";
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.color-controls {
|
|
162
|
+
margin-bottom: 25px;
|
|
163
|
+
display: grid;
|
|
164
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
165
|
+
gap: 15px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.color-select-group {
|
|
169
|
+
background: rgba(255, 255, 255, 0.1);
|
|
170
|
+
padding: 15px;
|
|
171
|
+
border-radius: 8px;
|
|
172
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.color-select-label {
|
|
176
|
+
display: block;
|
|
177
|
+
margin-bottom: 8px;
|
|
178
|
+
font-weight: 500;
|
|
179
|
+
font-size: 0.95rem;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.color-select {
|
|
183
|
+
width: 100%;
|
|
184
|
+
padding: 8px 12px;
|
|
185
|
+
border: none;
|
|
186
|
+
border-radius: 6px;
|
|
187
|
+
background: white;
|
|
188
|
+
color: #333;
|
|
189
|
+
font-size: 0.9rem;
|
|
190
|
+
cursor: pointer;
|
|
191
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.state-controls {
|
|
195
|
+
background: rgba(255, 255, 255, 0.1);
|
|
196
|
+
padding: 15px;
|
|
197
|
+
border-radius: 8px;
|
|
198
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
199
|
+
margin-bottom: 20px;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.state-controls h4 {
|
|
203
|
+
margin-top: 0;
|
|
204
|
+
margin-bottom: 15px;
|
|
205
|
+
font-size: 1.1rem;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.state-toggles {
|
|
209
|
+
display: grid;
|
|
210
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
211
|
+
gap: 10px;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.state-toggle {
|
|
215
|
+
background: rgba(255, 255, 255, 0.9);
|
|
216
|
+
color: #333;
|
|
217
|
+
border: none;
|
|
218
|
+
padding: 10px 15px;
|
|
219
|
+
border-radius: 6px;
|
|
220
|
+
cursor: pointer;
|
|
221
|
+
font-size: 0.9rem;
|
|
222
|
+
font-weight: 500;
|
|
223
|
+
transition: all 0.2s ease;
|
|
224
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.state-toggle:hover {
|
|
228
|
+
background: white;
|
|
229
|
+
transform: translateY(-1px);
|
|
230
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.state-toggle.active {
|
|
234
|
+
background: #ffffff;
|
|
235
|
+
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.radio-group {
|
|
239
|
+
display: flex;
|
|
240
|
+
flex-direction: column;
|
|
241
|
+
gap: 10px;
|
|
242
|
+
margin: 15px 0;
|
|
243
|
+
padding: 15px;
|
|
244
|
+
background: rgba(255, 255, 255, 0.1);
|
|
245
|
+
border-radius: 8px;
|
|
246
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.radio-group h4 {
|
|
250
|
+
margin: 0 0 10px 0;
|
|
251
|
+
font-size: 1rem;
|
|
252
|
+
color: white;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.custom-styles-test {
|
|
256
|
+
background: rgba(255, 255, 255, 0.9);
|
|
257
|
+
color: #333;
|
|
258
|
+
padding: 20px;
|
|
259
|
+
border-radius: 8px;
|
|
260
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
261
|
+
margin: 15px 0;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.custom-styles-test h4 {
|
|
265
|
+
margin-top: 0;
|
|
266
|
+
color: #2c3e50;
|
|
267
|
+
font-size: 1.1rem;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.custom-styles-comparison {
|
|
271
|
+
display: grid;
|
|
272
|
+
grid-template-columns: 1fr 1fr;
|
|
273
|
+
gap: 20px;
|
|
274
|
+
margin-top: 15px;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.comparison-item {
|
|
278
|
+
background: rgba(255, 255, 255, 0.05);
|
|
279
|
+
padding: 15px;
|
|
280
|
+
border-radius: 6px;
|
|
281
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.comparison-item h5 {
|
|
285
|
+
margin-top: 0;
|
|
286
|
+
margin-bottom: 10px;
|
|
287
|
+
color: #34495e;
|
|
288
|
+
font-size: 0.9rem;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@media (max-width: 768px) {
|
|
292
|
+
.demo-grid {
|
|
293
|
+
grid-template-columns: 1fr;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
h1 {
|
|
297
|
+
font-size: 2rem;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.radio-row {
|
|
301
|
+
flex-direction: column;
|
|
302
|
+
align-items: stretch;
|
|
303
|
+
gap: 10px;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
</style>
|
|
8
307
|
</head>
|
|
9
308
|
<body>
|
|
10
|
-
<
|
|
309
|
+
<h1>🔘 Interactive Radio Demo</h1>
|
|
310
|
+
<div id="root"></div>
|
|
11
311
|
|
|
12
312
|
<script type="module" jsenv-type="module/jsx">
|
|
13
313
|
import { render } from "preact";
|
|
@@ -15,206 +315,560 @@
|
|
|
15
315
|
import {
|
|
16
316
|
// eslint-disable-next-line no-unused-vars
|
|
17
317
|
Input,
|
|
318
|
+
// eslint-disable-next-line no-unused-vars
|
|
319
|
+
Label,
|
|
18
320
|
} from "@jsenv/navi";
|
|
19
321
|
|
|
20
322
|
// eslint-disable-next-line no-unused-vars
|
|
21
323
|
const App = () => {
|
|
324
|
+
return (
|
|
325
|
+
<div className="demo-grid">
|
|
326
|
+
<LoadingDemo />
|
|
327
|
+
<ReadOnlyDemo />
|
|
328
|
+
<DisabledDemo />
|
|
329
|
+
<PropControlDemo />
|
|
330
|
+
<CustomStylesDemo />
|
|
331
|
+
</div>
|
|
332
|
+
);
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// eslint-disable-next-line no-unused-vars
|
|
336
|
+
const LoadingDemo = () => {
|
|
22
337
|
const [loading, setLoading] = useState(false);
|
|
23
|
-
const [
|
|
24
|
-
const [loadingD, setLoadingD] = useState(false);
|
|
25
|
-
const [loadingE, setLoadingE] = useState(false);
|
|
26
|
-
const [loadingF, setLoadingF] = useState(false);
|
|
338
|
+
const [selectedValue, setSelectedValue] = useState("option1");
|
|
27
339
|
|
|
28
340
|
return (
|
|
29
|
-
<div>
|
|
30
|
-
<
|
|
31
|
-
<div>
|
|
32
|
-
<p>
|
|
33
|
-
<strong>Loading</strong>
|
|
34
|
-
</p>
|
|
35
|
-
|
|
36
|
-
<Field
|
|
37
|
-
input={
|
|
38
|
-
<Input type="radio" name="loading" loading={loading} />
|
|
39
|
-
}
|
|
40
|
-
label="Coucou"
|
|
41
|
-
></Field>
|
|
42
|
-
|
|
43
|
-
<button>
|
|
44
|
-
<span
|
|
45
|
-
onClick={() => {
|
|
46
|
-
setLoading(!loading);
|
|
47
|
-
}}
|
|
48
|
-
>
|
|
49
|
-
Toggle
|
|
50
|
-
</span>
|
|
51
|
-
</button>
|
|
341
|
+
<div className="demo-card">
|
|
342
|
+
<h3 className="demo-title">Loading States</h3>
|
|
52
343
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
344
|
+
<div className="radio-group">
|
|
345
|
+
<h4>Radio Group (Loading: {loading ? "Yes" : "No"})</h4>
|
|
346
|
+
<Label className="radio-label">
|
|
347
|
+
<Input
|
|
348
|
+
type="radio"
|
|
349
|
+
name="loading-demo"
|
|
350
|
+
value="option1"
|
|
351
|
+
checked={selectedValue === "option1"}
|
|
352
|
+
onUIStateChange={(checked) => {
|
|
353
|
+
if (checked) {
|
|
354
|
+
setSelectedValue("option1");
|
|
355
|
+
}
|
|
356
|
+
}}
|
|
357
|
+
loading={loading}
|
|
358
|
+
/>
|
|
359
|
+
Option 1
|
|
360
|
+
</Label>
|
|
361
|
+
<Label className="radio-label">
|
|
362
|
+
<Input
|
|
363
|
+
type="radio"
|
|
364
|
+
name="loading-demo"
|
|
365
|
+
value="option2"
|
|
366
|
+
checked={selectedValue === "option2"}
|
|
367
|
+
onUIStateChange={(checked) => {
|
|
368
|
+
if (checked) {
|
|
369
|
+
setSelectedValue("option2");
|
|
370
|
+
}
|
|
371
|
+
}}
|
|
372
|
+
loading={loading}
|
|
373
|
+
/>
|
|
374
|
+
Option 2
|
|
375
|
+
</Label>
|
|
376
|
+
<Label className="radio-label">
|
|
377
|
+
<Input
|
|
378
|
+
type="radio"
|
|
379
|
+
name="loading-demo"
|
|
380
|
+
value="option3"
|
|
381
|
+
checked={selectedValue === "option3"}
|
|
382
|
+
onUIStateChange={(checked) => {
|
|
383
|
+
if (checked) {
|
|
384
|
+
setSelectedValue("option3");
|
|
385
|
+
}
|
|
386
|
+
}}
|
|
387
|
+
loading={loading}
|
|
388
|
+
/>
|
|
389
|
+
Option 3
|
|
390
|
+
</Label>
|
|
391
|
+
</div>
|
|
392
|
+
|
|
393
|
+
<button
|
|
394
|
+
className="toggle-button"
|
|
395
|
+
onClick={() => setLoading(!loading)}
|
|
396
|
+
>
|
|
397
|
+
{loading ? "Stop Loading" : "Start Loading"}
|
|
398
|
+
</button>
|
|
399
|
+
|
|
400
|
+
<div className="comparison">
|
|
401
|
+
<span className="comparison-label">Native comparison:</span>
|
|
402
|
+
<div className="native-examples">
|
|
403
|
+
<label>
|
|
404
|
+
<input type="radio" name="native-loading" value="1" />
|
|
405
|
+
Native Radio 1
|
|
406
|
+
</label>
|
|
407
|
+
<label>
|
|
408
|
+
<input type="radio" name="native-loading" value="2" />
|
|
409
|
+
Native Radio 2
|
|
410
|
+
</label>
|
|
411
|
+
<label>
|
|
412
|
+
<input type="radio" name="native-loading" value="3" />
|
|
413
|
+
Native Radio 3
|
|
414
|
+
</label>
|
|
59
415
|
</div>
|
|
60
416
|
</div>
|
|
417
|
+
</div>
|
|
418
|
+
);
|
|
419
|
+
};
|
|
61
420
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
</p>
|
|
421
|
+
// eslint-disable-next-line no-unused-vars
|
|
422
|
+
const ReadOnlyDemo = () => {
|
|
423
|
+
const [readOnly, setReadOnly] = useState(true);
|
|
424
|
+
const [selectedValue, setSelectedValue] = useState("option2");
|
|
67
425
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
426
|
+
return (
|
|
427
|
+
<div className="demo-card">
|
|
428
|
+
<h3 className="demo-title">Read-Only States</h3>
|
|
429
|
+
|
|
430
|
+
<div className="radio-group">
|
|
431
|
+
<h4>Radio Group (Read-only: {readOnly ? "Yes" : "No"})</h4>
|
|
432
|
+
<Label className="radio-label">
|
|
433
|
+
<Input
|
|
434
|
+
type="radio"
|
|
435
|
+
name="readonly-demo"
|
|
436
|
+
value="option1"
|
|
437
|
+
checked={selectedValue === "option1"}
|
|
438
|
+
onChange={() => !readOnly && setSelectedValue("option1")}
|
|
439
|
+
readOnly={readOnly}
|
|
440
|
+
/>
|
|
441
|
+
Option 1
|
|
442
|
+
</Label>
|
|
443
|
+
<Label className="radio-label">
|
|
444
|
+
<Input
|
|
445
|
+
type="radio"
|
|
446
|
+
name="readonly-demo"
|
|
447
|
+
value="option2"
|
|
448
|
+
checked={selectedValue === "option2"}
|
|
449
|
+
onChange={() => !readOnly && setSelectedValue("option2")}
|
|
450
|
+
readOnly={readOnly}
|
|
451
|
+
/>
|
|
452
|
+
Option 2 (Initially Selected)
|
|
453
|
+
</Label>
|
|
454
|
+
<Label className="radio-label">
|
|
455
|
+
<Input
|
|
456
|
+
type="radio"
|
|
457
|
+
name="readonly-demo"
|
|
458
|
+
value="option3"
|
|
459
|
+
checked={selectedValue === "option3"}
|
|
460
|
+
onChange={() => !readOnly && setSelectedValue("option3")}
|
|
461
|
+
readOnly={readOnly}
|
|
78
462
|
/>
|
|
463
|
+
Option 3
|
|
464
|
+
</Label>
|
|
465
|
+
</div>
|
|
79
466
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Toggle
|
|
87
|
-
</span>
|
|
88
|
-
</button>
|
|
467
|
+
<button
|
|
468
|
+
className="toggle-button"
|
|
469
|
+
onClick={() => setReadOnly(!readOnly)}
|
|
470
|
+
>
|
|
471
|
+
{readOnly ? "Make Editable" : "Make Read-Only"}
|
|
472
|
+
</button>
|
|
89
473
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
474
|
+
<div className="comparison">
|
|
475
|
+
<span className="comparison-label">Native comparison:</span>
|
|
476
|
+
<div className="native-examples">
|
|
477
|
+
<label>
|
|
478
|
+
<input
|
|
479
|
+
type="radio"
|
|
480
|
+
name="native-readonly"
|
|
481
|
+
value="1"
|
|
482
|
+
readOnly
|
|
483
|
+
/>
|
|
484
|
+
Native Read-Only Radio 1
|
|
485
|
+
</label>
|
|
486
|
+
<label>
|
|
487
|
+
<input
|
|
488
|
+
type="radio"
|
|
489
|
+
name="native-readonly"
|
|
490
|
+
value="2"
|
|
491
|
+
readOnly
|
|
492
|
+
checked
|
|
493
|
+
/>
|
|
494
|
+
Native Read-Only Radio 2
|
|
495
|
+
</label>
|
|
496
|
+
<label>
|
|
497
|
+
<input
|
|
498
|
+
type="radio"
|
|
499
|
+
name="native-readonly"
|
|
500
|
+
value="3"
|
|
501
|
+
readOnly
|
|
502
|
+
/>
|
|
503
|
+
Native Read-Only Radio 3
|
|
504
|
+
</label>
|
|
95
505
|
</div>
|
|
96
506
|
</div>
|
|
507
|
+
</div>
|
|
508
|
+
);
|
|
509
|
+
};
|
|
97
510
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<strong>Read only + checked</strong>
|
|
102
|
-
</p>
|
|
511
|
+
// eslint-disable-next-line no-unused-vars
|
|
512
|
+
const DisabledDemo = () => {
|
|
513
|
+
const [disabled, setDisabled] = useState(true);
|
|
103
514
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
515
|
+
return (
|
|
516
|
+
<div className="demo-card">
|
|
517
|
+
<h3 className="demo-title">Disabled States</h3>
|
|
518
|
+
|
|
519
|
+
<div className="radio-group">
|
|
520
|
+
<h4>Radio Group (Disabled: {disabled ? "Yes" : "No"})</h4>
|
|
521
|
+
<Label className="radio-label">
|
|
522
|
+
<Input
|
|
523
|
+
type="radio"
|
|
524
|
+
name="disabled-demo"
|
|
525
|
+
value="option1"
|
|
526
|
+
checked={true}
|
|
527
|
+
onUIStateChange={() => {}}
|
|
528
|
+
disabled={disabled}
|
|
529
|
+
/>
|
|
530
|
+
Option 1 (Initially Selected)
|
|
531
|
+
</Label>
|
|
532
|
+
<Label className="radio-label">
|
|
533
|
+
<Input
|
|
534
|
+
type="radio"
|
|
535
|
+
name="disabled-demo"
|
|
536
|
+
value="option2"
|
|
537
|
+
disabled={disabled}
|
|
538
|
+
/>
|
|
539
|
+
Option 2
|
|
540
|
+
</Label>
|
|
541
|
+
<Label className="radio-label">
|
|
542
|
+
<Input
|
|
543
|
+
type="radio"
|
|
544
|
+
name="disabled-demo"
|
|
545
|
+
value="option3"
|
|
546
|
+
disabled={disabled}
|
|
115
547
|
/>
|
|
548
|
+
Option 3
|
|
549
|
+
</Label>
|
|
550
|
+
</div>
|
|
116
551
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
Toggle
|
|
124
|
-
</span>
|
|
125
|
-
</button>
|
|
552
|
+
<button
|
|
553
|
+
className="toggle-button"
|
|
554
|
+
onClick={() => setDisabled(!disabled)}
|
|
555
|
+
>
|
|
556
|
+
{disabled ? "Enable Radios" : "Disable Radios"}
|
|
557
|
+
</button>
|
|
126
558
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
559
|
+
<div className="comparison">
|
|
560
|
+
<span className="comparison-label">Native comparison:</span>
|
|
561
|
+
<div className="native-examples">
|
|
562
|
+
<label>
|
|
563
|
+
<input
|
|
564
|
+
type="radio"
|
|
565
|
+
name="native-disabled"
|
|
566
|
+
value="1"
|
|
567
|
+
disabled
|
|
568
|
+
checked
|
|
569
|
+
/>
|
|
570
|
+
Native Disabled Radio 1
|
|
571
|
+
</label>
|
|
572
|
+
<label>
|
|
573
|
+
<input
|
|
574
|
+
type="radio"
|
|
575
|
+
name="native-disabled"
|
|
576
|
+
value="2"
|
|
577
|
+
disabled
|
|
578
|
+
/>
|
|
579
|
+
Native Disabled Radio 2
|
|
580
|
+
</label>
|
|
581
|
+
<label>
|
|
582
|
+
<input
|
|
583
|
+
type="radio"
|
|
584
|
+
name="native-disabled"
|
|
585
|
+
value="3"
|
|
586
|
+
disabled
|
|
587
|
+
/>
|
|
588
|
+
Native Disabled Radio 3
|
|
589
|
+
</label>
|
|
132
590
|
</div>
|
|
133
591
|
</div>
|
|
592
|
+
</div>
|
|
593
|
+
);
|
|
594
|
+
};
|
|
134
595
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
596
|
+
// eslint-disable-next-line no-unused-vars
|
|
597
|
+
const PropControlDemo = () => {
|
|
598
|
+
const [radiomarkColor, setRadiomarkColor] = useState("#e74c3c");
|
|
599
|
+
const [borderColor, setBorderColor] = useState("#767676");
|
|
600
|
+
const [backgroundColor, setBackgroundColor] = useState("#ffffff");
|
|
601
|
+
const [loading, setLoading] = useState(false);
|
|
602
|
+
const [readOnly, setReadOnly] = useState(false);
|
|
603
|
+
const [disabled, setDisabled] = useState(false);
|
|
604
|
+
const [selectedValue, setSelectedValue] = useState("option2");
|
|
140
605
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
disabled
|
|
145
|
-
type="radio"
|
|
146
|
-
name="disabled"
|
|
147
|
-
loading={loadingE}
|
|
148
|
-
/>
|
|
149
|
-
}
|
|
150
|
-
label="E"
|
|
151
|
-
/>
|
|
606
|
+
return (
|
|
607
|
+
<div className="demo-card prop-control-demo">
|
|
608
|
+
<h3 className="demo-title">Property Controls</h3>
|
|
152
609
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
610
|
+
<div className="color-controls">
|
|
611
|
+
<div className="color-select-group">
|
|
612
|
+
<label className="color-select-label">Radiomark Color:</label>
|
|
613
|
+
<select
|
|
614
|
+
className="color-select"
|
|
615
|
+
value={radiomarkColor}
|
|
616
|
+
onChange={(e) => setRadiomarkColor(e.target.value)}
|
|
617
|
+
>
|
|
618
|
+
<option value="#e74c3c">Red (Default)</option>
|
|
619
|
+
<option value="#3498db">Blue</option>
|
|
620
|
+
<option value="#2ecc71">Green</option>
|
|
621
|
+
<option value="#f39c12">Orange</option>
|
|
622
|
+
<option value="#9b59b6">Purple</option>
|
|
623
|
+
<option value="#1abc9c">Teal</option>
|
|
624
|
+
<option value="#34495e">Dark Gray</option>
|
|
625
|
+
</select>
|
|
626
|
+
</div>
|
|
162
627
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
628
|
+
<div className="color-select-group">
|
|
629
|
+
<label className="color-select-label">Border Color:</label>
|
|
630
|
+
<select
|
|
631
|
+
className="color-select"
|
|
632
|
+
value={borderColor}
|
|
633
|
+
onChange={(e) => setBorderColor(e.target.value)}
|
|
634
|
+
>
|
|
635
|
+
<option value="#767676">Gray (Default)</option>
|
|
636
|
+
<option value="#e74c3c">Red</option>
|
|
637
|
+
<option value="#3498db">Blue</option>
|
|
638
|
+
<option value="#2ecc71">Green</option>
|
|
639
|
+
<option value="#34495e">Dark</option>
|
|
640
|
+
<option value="#95a5a6">Light Gray</option>
|
|
641
|
+
</select>
|
|
642
|
+
</div>
|
|
643
|
+
|
|
644
|
+
<div className="color-select-group">
|
|
645
|
+
<label className="color-select-label">Background Color:</label>
|
|
646
|
+
<select
|
|
647
|
+
className="color-select"
|
|
648
|
+
value={backgroundColor}
|
|
649
|
+
onChange={(e) => setBackgroundColor(e.target.value)}
|
|
650
|
+
>
|
|
651
|
+
<option value="#ffffff">White (Default)</option>
|
|
652
|
+
<option value="#ecf0f1">Light Gray</option>
|
|
653
|
+
<option value="#bdc3c7">Medium Gray</option>
|
|
654
|
+
<option value="#f8f9fa">Off White</option>
|
|
655
|
+
<option value="#fff5f5">Light Pink</option>
|
|
656
|
+
<option value="#f0f8ff">Light Blue</option>
|
|
657
|
+
</select>
|
|
168
658
|
</div>
|
|
169
659
|
</div>
|
|
170
660
|
|
|
171
|
-
<div>
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
661
|
+
<div className="state-controls">
|
|
662
|
+
<h4>State Controls:</h4>
|
|
663
|
+
<div className="state-toggles">
|
|
664
|
+
<button
|
|
665
|
+
className={`state-toggle ${loading ? "active" : ""}`}
|
|
666
|
+
onClick={() => setLoading(!loading)}
|
|
667
|
+
>
|
|
668
|
+
{loading ? "Stop Loading" : "Start Loading"}
|
|
669
|
+
</button>
|
|
670
|
+
<button
|
|
671
|
+
className={`state-toggle ${readOnly ? "active" : ""}`}
|
|
672
|
+
onClick={() => setReadOnly(!readOnly)}
|
|
673
|
+
>
|
|
674
|
+
{readOnly ? "Make Editable" : "Make Read-Only"}
|
|
675
|
+
</button>
|
|
676
|
+
<button
|
|
677
|
+
className={`state-toggle ${disabled ? "active" : ""}`}
|
|
678
|
+
onClick={() => setDisabled(!disabled)}
|
|
679
|
+
>
|
|
680
|
+
{disabled ? "Enable" : "Disable"}
|
|
681
|
+
</button>
|
|
682
|
+
</div>
|
|
683
|
+
</div>
|
|
176
684
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
685
|
+
<div
|
|
686
|
+
className="radio-group"
|
|
687
|
+
style={{
|
|
688
|
+
"--navi-radiomark-color": radiomarkColor,
|
|
689
|
+
"--border-color": borderColor,
|
|
690
|
+
"--background-color": backgroundColor,
|
|
691
|
+
}}
|
|
692
|
+
>
|
|
693
|
+
<h4>Customized Radio Group</h4>
|
|
694
|
+
<Label className="radio-label">
|
|
695
|
+
<Input
|
|
696
|
+
type="radio"
|
|
697
|
+
name="prop-control-demo"
|
|
698
|
+
value="option1"
|
|
699
|
+
checked={selectedValue === "option1"}
|
|
700
|
+
onChange={() =>
|
|
701
|
+
!readOnly && !disabled && setSelectedValue("option1")
|
|
186
702
|
}
|
|
187
|
-
|
|
703
|
+
loading={loading}
|
|
704
|
+
readOnly={readOnly}
|
|
705
|
+
disabled={disabled}
|
|
188
706
|
/>
|
|
707
|
+
Option 1
|
|
708
|
+
</Label>
|
|
709
|
+
<Label className="radio-label">
|
|
710
|
+
<Input
|
|
711
|
+
type="radio"
|
|
712
|
+
name="prop-control-demo"
|
|
713
|
+
value="option2"
|
|
714
|
+
checked={selectedValue === "option2"}
|
|
715
|
+
onChange={() =>
|
|
716
|
+
!readOnly && !disabled && setSelectedValue("option2")
|
|
717
|
+
}
|
|
718
|
+
loading={loading}
|
|
719
|
+
readOnly={readOnly}
|
|
720
|
+
disabled={disabled}
|
|
721
|
+
/>
|
|
722
|
+
Option 2 (Initially Selected)
|
|
723
|
+
</Label>
|
|
724
|
+
<Label className="radio-label">
|
|
725
|
+
<Input
|
|
726
|
+
type="radio"
|
|
727
|
+
name="prop-control-demo"
|
|
728
|
+
value="option3"
|
|
729
|
+
checked={selectedValue === "option3"}
|
|
730
|
+
onChange={() =>
|
|
731
|
+
!readOnly && !disabled && setSelectedValue("option3")
|
|
732
|
+
}
|
|
733
|
+
loading={loading}
|
|
734
|
+
readOnly={readOnly}
|
|
735
|
+
disabled={disabled}
|
|
736
|
+
/>
|
|
737
|
+
Option 3
|
|
738
|
+
</Label>
|
|
739
|
+
</div>
|
|
189
740
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
741
|
+
<div className="custom-styles-test">
|
|
742
|
+
<h4>Current CSS Custom Properties:</h4>
|
|
743
|
+
<pre style={{ fontSize: "0.8rem", lineHeight: "1.4" }}>
|
|
744
|
+
{`--navi-radiomark-color: ${radiomarkColor};
|
|
745
|
+
--border-color: ${borderColor};
|
|
746
|
+
--background-color: ${backgroundColor};`}
|
|
747
|
+
</pre>
|
|
748
|
+
</div>
|
|
749
|
+
</div>
|
|
750
|
+
);
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
// eslint-disable-next-line no-unused-vars
|
|
754
|
+
const CustomStylesDemo = () => {
|
|
755
|
+
const [selectedValue1, setSelectedValue1] = useState("small");
|
|
756
|
+
const [selectedValue2, setSelectedValue2] = useState("medium");
|
|
757
|
+
|
|
758
|
+
return (
|
|
759
|
+
<div className="demo-card">
|
|
760
|
+
<h3 className="demo-title">Custom Styles</h3>
|
|
761
|
+
|
|
762
|
+
<div className="custom-styles-comparison">
|
|
763
|
+
<div className="comparison-item">
|
|
764
|
+
<h5>Small Radio Buttons</h5>
|
|
765
|
+
<div
|
|
766
|
+
className="radio-group"
|
|
767
|
+
style={{
|
|
768
|
+
"--width": "10px",
|
|
769
|
+
"--height": "10px",
|
|
770
|
+
"--navi-radiomark-color": "#3498db",
|
|
771
|
+
}}
|
|
772
|
+
>
|
|
773
|
+
<Label className="radio-label">
|
|
774
|
+
<Input
|
|
775
|
+
type="radio"
|
|
776
|
+
name="small-radios"
|
|
777
|
+
value="small"
|
|
778
|
+
checked={selectedValue1 === "small"}
|
|
779
|
+
onChange={() => setSelectedValue1("small")}
|
|
780
|
+
/>
|
|
781
|
+
Small Option
|
|
782
|
+
</Label>
|
|
783
|
+
<Label className="radio-label">
|
|
784
|
+
<Input
|
|
785
|
+
type="radio"
|
|
786
|
+
name="small-radios"
|
|
787
|
+
value="medium"
|
|
788
|
+
checked={selectedValue1 === "medium"}
|
|
789
|
+
onChange={() => setSelectedValue1("medium")}
|
|
790
|
+
/>
|
|
791
|
+
Medium Option
|
|
792
|
+
</Label>
|
|
793
|
+
<Label className="radio-label">
|
|
794
|
+
<Input
|
|
795
|
+
type="radio"
|
|
796
|
+
name="small-radios"
|
|
797
|
+
value="large"
|
|
798
|
+
checked={selectedValue1 === "large"}
|
|
799
|
+
onChange={() => setSelectedValue1("large")}
|
|
800
|
+
/>
|
|
801
|
+
Large Option
|
|
802
|
+
</Label>
|
|
803
|
+
</div>
|
|
804
|
+
</div>
|
|
199
805
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
806
|
+
<div className="comparison-item">
|
|
807
|
+
<h5>Large Radio Buttons</h5>
|
|
808
|
+
<div
|
|
809
|
+
className="radio-group"
|
|
810
|
+
style={{
|
|
811
|
+
"--width": "20px",
|
|
812
|
+
"--height": "20px",
|
|
813
|
+
"--navi-radiomark-color": "#e74c3c",
|
|
814
|
+
}}
|
|
815
|
+
>
|
|
816
|
+
<Label className="radio-label">
|
|
817
|
+
<Input
|
|
203
818
|
type="radio"
|
|
204
|
-
name="
|
|
205
|
-
|
|
206
|
-
checked
|
|
819
|
+
name="large-radios"
|
|
820
|
+
value="small"
|
|
821
|
+
checked={selectedValue2 === "small"}
|
|
822
|
+
onChange={() => setSelectedValue2("small")}
|
|
207
823
|
/>
|
|
208
|
-
|
|
209
|
-
</
|
|
824
|
+
Small Option
|
|
825
|
+
</Label>
|
|
826
|
+
<Label className="radio-label">
|
|
827
|
+
<Input
|
|
828
|
+
type="radio"
|
|
829
|
+
name="large-radios"
|
|
830
|
+
value="medium"
|
|
831
|
+
checked={selectedValue2 === "medium"}
|
|
832
|
+
onChange={() => setSelectedValue2("medium")}
|
|
833
|
+
/>
|
|
834
|
+
Medium Option
|
|
835
|
+
</Label>
|
|
836
|
+
<Label className="radio-label">
|
|
837
|
+
<Input
|
|
838
|
+
type="radio"
|
|
839
|
+
name="large-radios"
|
|
840
|
+
value="large"
|
|
841
|
+
checked={selectedValue2 === "large"}
|
|
842
|
+
onChange={() => setSelectedValue2("large")}
|
|
843
|
+
/>
|
|
844
|
+
Large Option
|
|
845
|
+
</Label>
|
|
210
846
|
</div>
|
|
211
847
|
</div>
|
|
212
848
|
</div>
|
|
849
|
+
|
|
850
|
+
<div className="comparison">
|
|
851
|
+
<span className="comparison-label">Native comparison:</span>
|
|
852
|
+
<div className="native-examples">
|
|
853
|
+
<label>
|
|
854
|
+
<input type="radio" name="native-custom" value="1" />
|
|
855
|
+
Native Radio 1
|
|
856
|
+
</label>
|
|
857
|
+
<label>
|
|
858
|
+
<input type="radio" name="native-custom" value="2" />
|
|
859
|
+
Native Radio 2
|
|
860
|
+
</label>
|
|
861
|
+
<label>
|
|
862
|
+
<input type="radio" name="native-custom" value="3" />
|
|
863
|
+
Native Radio 3
|
|
864
|
+
</label>
|
|
865
|
+
</div>
|
|
866
|
+
</div>
|
|
213
867
|
</div>
|
|
214
868
|
);
|
|
215
869
|
};
|
|
216
870
|
|
|
217
|
-
render(<App />, document.
|
|
871
|
+
render(<App />, document.getElementById("root"));
|
|
218
872
|
</script>
|
|
219
873
|
</body>
|
|
220
874
|
</html>
|