@jsenv/navi 0.0.1

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.
Files changed (123) hide show
  1. package/index.js +51 -0
  2. package/package.json +38 -0
  3. package/src/action_private_properties.js +11 -0
  4. package/src/action_proxy_test.html +353 -0
  5. package/src/action_run_states.js +5 -0
  6. package/src/actions.js +1377 -0
  7. package/src/browser_integration/browser_integration.js +191 -0
  8. package/src/browser_integration/document_back_and_forward.js +17 -0
  9. package/src/browser_integration/document_loading_signal.js +100 -0
  10. package/src/browser_integration/document_state_signal.js +9 -0
  11. package/src/browser_integration/document_url_signal.js +9 -0
  12. package/src/browser_integration/use_is_visited.js +19 -0
  13. package/src/browser_integration/via_history.js +199 -0
  14. package/src/browser_integration/via_navigation.js +168 -0
  15. package/src/components/action_execution/form_context.js +8 -0
  16. package/src/components/action_execution/render_actionable_component.jsx +27 -0
  17. package/src/components/action_execution/use_action.js +330 -0
  18. package/src/components/action_execution/use_execute_action.js +161 -0
  19. package/src/components/action_renderer.jsx +136 -0
  20. package/src/components/collect_form_element_values.js +79 -0
  21. package/src/components/demos/0_button_demo.html +155 -0
  22. package/src/components/demos/1_checkbox_demo.html +257 -0
  23. package/src/components/demos/2_input_textual_demo.html +354 -0
  24. package/src/components/demos/3_radio_demo.html +222 -0
  25. package/src/components/demos/4_select_demo.html +104 -0
  26. package/src/components/demos/5_list_scrollable_demo.html +153 -0
  27. package/src/components/demos/action/0_button_demo.html +204 -0
  28. package/src/components/demos/action/10_shortcuts_demo.html +189 -0
  29. package/src/components/demos/action/11_nested_shortcuts_demo.html +401 -0
  30. package/src/components/demos/action/1_input_text_demo.html +461 -0
  31. package/src/components/demos/action/2_form_multiple.html +303 -0
  32. package/src/components/demos/action/3_details_demo.html +172 -0
  33. package/src/components/demos/action/4_input_checkbox_demo.html +611 -0
  34. package/src/components/demos/action/6_checkbox_list_demo.html +109 -0
  35. package/src/components/demos/action/7_radio_list_demo.html +217 -0
  36. package/src/components/demos/action/8_editable_text_demo.html +442 -0
  37. package/src/components/demos/action/9_link_demo.html +172 -0
  38. package/src/components/demos/demo.md +0 -0
  39. package/src/components/demos/route/basic/basic.html +14 -0
  40. package/src/components/demos/route/basic/basic_route_demo.jsx +224 -0
  41. package/src/components/demos/route/multi/multi.html +14 -0
  42. package/src/components/demos/route/multi/multi_route_demo.jsx +277 -0
  43. package/src/components/details/details.jsx +248 -0
  44. package/src/components/details/summary_marker.jsx +141 -0
  45. package/src/components/editable_text/editable_text.jsx +96 -0
  46. package/src/components/error_boundary_context.js +9 -0
  47. package/src/components/form.jsx +144 -0
  48. package/src/components/input/button.jsx +333 -0
  49. package/src/components/input/checkbox_list.jsx +294 -0
  50. package/src/components/input/field.jsx +61 -0
  51. package/src/components/input/field_css.js +118 -0
  52. package/src/components/input/input.jsx +15 -0
  53. package/src/components/input/input_checkbox.jsx +370 -0
  54. package/src/components/input/input_radio.jsx +299 -0
  55. package/src/components/input/input_textual.jsx +338 -0
  56. package/src/components/input/radio_list.jsx +283 -0
  57. package/src/components/input/select.jsx +273 -0
  58. package/src/components/input/use_form_event.js +20 -0
  59. package/src/components/input/use_on_change.js +12 -0
  60. package/src/components/link/link.jsx +291 -0
  61. package/src/components/loader/loader_background.jsx +324 -0
  62. package/src/components/loader/loading_spinner.jsx +68 -0
  63. package/src/components/loader/network_speed.js +83 -0
  64. package/src/components/loader/rectangle_loading.jsx +225 -0
  65. package/src/components/route.jsx +15 -0
  66. package/src/components/selection/selection.js +5 -0
  67. package/src/components/selection/selection_context.jsx +262 -0
  68. package/src/components/shortcut/os.js +9 -0
  69. package/src/components/shortcut/shortcut_context.jsx +390 -0
  70. package/src/components/use_action_events.js +37 -0
  71. package/src/components/use_auto_focus.js +43 -0
  72. package/src/components/use_debounce_true.js +31 -0
  73. package/src/components/use_focus_group.js +19 -0
  74. package/src/components/use_initial_value.js +104 -0
  75. package/src/components/use_is_visited.js +19 -0
  76. package/src/components/use_ref_array.js +38 -0
  77. package/src/components/use_signal_sync.js +50 -0
  78. package/src/components/use_state_array.js +40 -0
  79. package/src/docs/actions.md +228 -0
  80. package/src/docs/demos/resource/action_status.jsx +42 -0
  81. package/src/docs/demos/resource/demo.md +1 -0
  82. package/src/docs/demos/resource/resource_demo_0.html +84 -0
  83. package/src/docs/demos/resource/resource_demo_10_post_gc.html +364 -0
  84. package/src/docs/demos/resource/resource_demo_11_describe_many.html +362 -0
  85. package/src/docs/demos/resource/resource_demo_2.html +173 -0
  86. package/src/docs/demos/resource/resource_demo_3_filtered_users.html +415 -0
  87. package/src/docs/demos/resource/resource_demo_4_details.html +284 -0
  88. package/src/docs/demos/resource/resource_demo_5_renderer_lazy.html +115 -0
  89. package/src/docs/demos/resource/resource_demo_6_gc.html +217 -0
  90. package/src/docs/demos/resource/resource_demo_7_child_gc.html +240 -0
  91. package/src/docs/demos/resource/resource_demo_8_proxy_gc.html +319 -0
  92. package/src/docs/demos/resource/resource_demo_9_describe_one.html +472 -0
  93. package/src/docs/demos/resource/tata.jsx +3 -0
  94. package/src/docs/demos/resource/toto.jsx +3 -0
  95. package/src/docs/demos/user_nav/user_nav.html +12 -0
  96. package/src/docs/demos/user_nav/user_nav.jsx +330 -0
  97. package/src/docs/resource_dependencies.md +103 -0
  98. package/src/docs/resource_with_params.md +80 -0
  99. package/src/notes.md +13 -0
  100. package/src/route/route.js +518 -0
  101. package/src/route/route.test.html +228 -0
  102. package/src/store/array_signal_store.js +537 -0
  103. package/src/store/local_storage_signal.js +17 -0
  104. package/src/store/resource_graph.js +1303 -0
  105. package/src/store/tests/resource_graph_autoreload_demo.html +12 -0
  106. package/src/store/tests/resource_graph_autoreload_demo.jsx +964 -0
  107. package/src/store/tests/resource_graph_dependencies.test.js +95 -0
  108. package/src/store/value_in_local_storage.js +187 -0
  109. package/src/symbol_object_signal.js +1 -0
  110. package/src/use_action_data.js +10 -0
  111. package/src/use_action_status.js +47 -0
  112. package/src/utils/add_many_event_listeners.js +15 -0
  113. package/src/utils/array_add_remove.js +61 -0
  114. package/src/utils/array_signal.js +15 -0
  115. package/src/utils/compare_two_js_values.js +172 -0
  116. package/src/utils/execute_with_cleanup.js +21 -0
  117. package/src/utils/get_caller_info.js +85 -0
  118. package/src/utils/iterable_weak_set.js +62 -0
  119. package/src/utils/js_value_weak_map.js +162 -0
  120. package/src/utils/js_value_weak_map_demo.html +690 -0
  121. package/src/utils/merge_two_js_values.js +53 -0
  122. package/src/utils/stringify_for_display.js +150 -0
  123. package/src/utils/weak_effect.js +48 -0
@@ -0,0 +1,354 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" href="data:," />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Input Textual 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-color: #f8f9fa;
16
+ }
17
+
18
+ h1 {
19
+ text-align: center;
20
+ color: #333;
21
+ margin-bottom: 30px;
22
+ }
23
+
24
+ .demo-grid {
25
+ display: grid;
26
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
27
+ gap: 20px;
28
+ }
29
+
30
+ .demo-card {
31
+ background: white;
32
+ border-radius: 8px;
33
+ padding: 20px;
34
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
35
+ border: 1px solid #e1e8ed;
36
+ }
37
+
38
+ .demo-title {
39
+ color: #2c3e50;
40
+ margin-top: 0;
41
+ margin-bottom: 15px;
42
+ font-size: 18px;
43
+ font-weight: 600;
44
+ border-bottom: 2px solid #3498db;
45
+ padding-bottom: 8px;
46
+ }
47
+
48
+ .native-comparison {
49
+ display: grid;
50
+ grid-template-columns: 1fr 1fr;
51
+ gap: 15px;
52
+ margin: 15px 0;
53
+ }
54
+
55
+ .native-demo {
56
+ background: #f8f9fa;
57
+ padding: 15px;
58
+ border-radius: 6px;
59
+ border: 1px solid #dee2e6;
60
+ }
61
+
62
+ .native-demo h4 {
63
+ margin-top: 0;
64
+ margin-bottom: 10px;
65
+ color: #495057;
66
+ font-size: 14px;
67
+ font-weight: 500;
68
+ }
69
+
70
+ input[type="text"],
71
+ input[type="email"],
72
+ input[type="password"],
73
+ input[type="number"],
74
+ input[type="tel"],
75
+ input[type="url"],
76
+ input[type="search"],
77
+ textarea {
78
+ width: 100%;
79
+ padding: 8px 12px;
80
+ border: 1px solid #ddd;
81
+ border-radius: 4px;
82
+ font-size: 14px;
83
+ box-sizing: border-box;
84
+ }
85
+
86
+ input:focus,
87
+ textarea:focus {
88
+ outline: none;
89
+ border-color: #3498db;
90
+ box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
91
+ }
92
+
93
+ .control-group {
94
+ margin-bottom: 15px;
95
+ }
96
+
97
+ label {
98
+ display: block;
99
+ margin-bottom: 5px;
100
+ font-weight: 500;
101
+ color: #555;
102
+ }
103
+
104
+ .result-display {
105
+ background: #f8f9fa;
106
+ border: 1px solid #dee2e6;
107
+ border-radius: 4px;
108
+ padding: 12px;
109
+ margin-top: 15px;
110
+ font-family:
111
+ "SF Mono", "Monaco", "Inconsolata", "Fira Code", "Fira Mono",
112
+ "Droid Sans Mono", "Courier New", monospace;
113
+ font-size: 13px;
114
+ color: #495057;
115
+ min-height: 20px;
116
+ white-space: pre-wrap;
117
+ }
118
+
119
+ .result-success {
120
+ background: #d4edda;
121
+ border-color: #c3e6cb;
122
+ color: #155724;
123
+ }
124
+
125
+ .result-error {
126
+ background: #f8d7da;
127
+ border-color: #f5c6cb;
128
+ color: #721c24;
129
+ }
130
+
131
+ .result-loading {
132
+ background: #d1ecf1;
133
+ border-color: #bee5eb;
134
+ color: #0c5460;
135
+ animation: pulse 1.5s ease-in-out infinite;
136
+ }
137
+
138
+ @keyframes pulse {
139
+ 0%,
140
+ 100% {
141
+ opacity: 1;
142
+ }
143
+ 50% {
144
+ opacity: 0.7;
145
+ }
146
+ }
147
+
148
+ .button-group {
149
+ display: flex;
150
+ gap: 8px;
151
+ margin-top: 12px;
152
+ flex-wrap: wrap;
153
+ }
154
+
155
+ button {
156
+ padding: 6px 12px;
157
+ border: 1px solid #3498db;
158
+ background: #3498db;
159
+ color: white;
160
+ border-radius: 4px;
161
+ cursor: pointer;
162
+ font-size: 14px;
163
+ transition: all 0.2s ease;
164
+ box-sizing: border-box;
165
+ }
166
+
167
+ button:hover {
168
+ background: #2980b9;
169
+ border-color: #2980b9;
170
+ }
171
+
172
+ button:disabled {
173
+ background: #95a5a6;
174
+ border-color: #95a5a6;
175
+ cursor: not-allowed;
176
+ }
177
+
178
+ @media (max-width: 768px) {
179
+ .demo-grid {
180
+ grid-template-columns: 1fr;
181
+ }
182
+
183
+ .native-comparison {
184
+ grid-template-columns: 1fr;
185
+ gap: 10px;
186
+ }
187
+ }
188
+ </style>
189
+ </head>
190
+ <body>
191
+ <h1>Input Textual Demo</h1>
192
+ <div id="root"></div>
193
+
194
+ <script type="module" jsenv-type="module/jsx">
195
+ import { render } from "preact";
196
+ import { useState } from "preact/hooks";
197
+ import {
198
+ // eslint-disable-next-line no-unused-vars
199
+ Input,
200
+ // eslint-disable-next-line no-unused-vars
201
+ Field,
202
+ } from "@jsenv/navi";
203
+
204
+ // eslint-disable-next-line no-unused-vars
205
+ const App = () => {
206
+ const [loading, setLoading] = useState(false);
207
+ const [loadingB, setLoadingB] = useState(false);
208
+ const [loadingC, setLoadingC] = useState(false);
209
+ const [loadingD, setLoadingD] = useState(false);
210
+
211
+ return (
212
+ <div className="demo-grid">
213
+ <div className="demo-card">
214
+ <h3 className="demo-title">💫 Loading State</h3>
215
+ <div className="control-group">
216
+ <Field
217
+ input={
218
+ <Input loading={loading} placeholder="Enter some text..." />
219
+ }
220
+ label="Basic Input"
221
+ />
222
+ </div>
223
+ <div className="native-comparison">
224
+ <div className="native-demo">
225
+ <h4>@jsenv/navi Input</h4>
226
+ <Input loading={loading} placeholder="Enter some text..." />
227
+ </div>
228
+ <div className="native-demo">
229
+ <h4>Native HTML Input</h4>
230
+ <input placeholder="Native comparison" />
231
+ </div>
232
+ </div>
233
+ <div className="button-group">
234
+ <button onClick={() => setLoading(!loading)}>
235
+ {loading ? "Stop Loading" : "Start Loading"}
236
+ </button>
237
+ </div>
238
+ </div>
239
+
240
+ <div className="demo-card">
241
+ <h3 className="demo-title">⚡ Action Input</h3>
242
+ <div className="control-group">
243
+ <Field
244
+ input={
245
+ <Input
246
+ name="action-input"
247
+ action={() => {}}
248
+ loading={loadingB}
249
+ placeholder="Input with action..."
250
+ />
251
+ }
252
+ label="Action Input"
253
+ />
254
+ </div>
255
+ <div className="native-comparison">
256
+ <div className="native-demo">
257
+ <h4>@jsenv/navi Input with Action</h4>
258
+ <Input
259
+ name="action-input"
260
+ action={() => {}}
261
+ loading={loadingB}
262
+ placeholder="Input with action..."
263
+ />
264
+ </div>
265
+ <div className="native-demo">
266
+ <h4>Native HTML Input</h4>
267
+ <input placeholder="Native has no built-in action" />
268
+ </div>
269
+ </div>
270
+ <div className="button-group">
271
+ <button onClick={() => setLoadingB(!loadingB)}>
272
+ {loadingB ? "Stop Loading" : "Start Loading"}
273
+ </button>
274
+ </div>
275
+ </div>
276
+
277
+ <div className="demo-card">
278
+ <h3 className="demo-title">🔒 Read-only State</h3>
279
+ <div className="control-group">
280
+ <Field
281
+ input={
282
+ <Input
283
+ value="This is read-only content"
284
+ readonly
285
+ loading={loadingC}
286
+ />
287
+ }
288
+ label="Read-only Input"
289
+ readonly
290
+ />
291
+ </div>
292
+ <div className="native-comparison">
293
+ <div className="native-demo">
294
+ <h4>@jsenv/navi Read-only</h4>
295
+ <Input
296
+ value="This is read-only content"
297
+ readonly
298
+ loading={loadingC}
299
+ />
300
+ </div>
301
+ <div className="native-demo">
302
+ <h4>Native Read-only</h4>
303
+ <input readonly value="Native read-only" />
304
+ </div>
305
+ </div>
306
+ <div className="button-group">
307
+ <button onClick={() => setLoadingC(!loadingC)}>
308
+ {loadingC ? "Stop Loading" : "Start Loading"}
309
+ </button>
310
+ </div>
311
+ </div>
312
+
313
+ <div className="demo-card">
314
+ <h3 className="demo-title">🚫 Disabled State</h3>
315
+ <div className="control-group">
316
+ <Field
317
+ input={
318
+ <Input
319
+ disabled
320
+ loading={loadingD}
321
+ placeholder="Disabled input..."
322
+ />
323
+ }
324
+ label="Disabled Input"
325
+ />
326
+ </div>
327
+ <div className="native-comparison">
328
+ <div className="native-demo">
329
+ <h4>@jsenv/navi Disabled</h4>
330
+ <Input
331
+ disabled
332
+ loading={loadingD}
333
+ placeholder="Disabled input..."
334
+ />
335
+ </div>
336
+ <div className="native-demo">
337
+ <h4>Native Disabled</h4>
338
+ <input disabled placeholder="Native disabled" />
339
+ </div>
340
+ </div>
341
+ <div className="button-group">
342
+ <button onClick={() => setLoadingD(!loadingD)}>
343
+ {loadingD ? "Stop Loading" : "Start Loading"}
344
+ </button>
345
+ </div>
346
+ </div>
347
+ </div>
348
+ );
349
+ };
350
+
351
+ render(<App />, document.querySelector("#root"));
352
+ </script>
353
+ </body>
354
+ </html>
@@ -0,0 +1,222 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" href="data:," />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Radio loading demo</title>
8
+ </head>
9
+ <body>
10
+ <div id="root" style="position: relative"></div>
11
+
12
+ <script type="module" jsenv-type="module/jsx">
13
+ import { render } from "preact";
14
+ import { useState } from "preact/hooks";
15
+ import {
16
+ // eslint-disable-next-line no-unused-vars
17
+ Input,
18
+ // eslint-disable-next-line no-unused-vars
19
+ Field,
20
+ } from "@jsenv/navi";
21
+
22
+ // eslint-disable-next-line no-unused-vars
23
+ const App = () => {
24
+ const [loading, setLoading] = useState(false);
25
+ const [loadingC, setLoadingC] = useState(false);
26
+ const [loadingD, setLoadingD] = useState(false);
27
+ const [loadingE, setLoadingE] = useState(false);
28
+ const [loadingF, setLoadingF] = useState(false);
29
+
30
+ return (
31
+ <div>
32
+ <div style="display: flex; flex-direction: row; gap: 30px">
33
+ <div>
34
+ <p>
35
+ <strong>Loading</strong>
36
+ </p>
37
+
38
+ <Field
39
+ input={
40
+ <Input type="radio" name="loading" loading={loading} />
41
+ }
42
+ label="Coucou"
43
+ ></Field>
44
+
45
+ <button>
46
+ <span
47
+ onClick={() => {
48
+ setLoading(!loading);
49
+ }}
50
+ >
51
+ Toggle
52
+ </span>
53
+ </button>
54
+
55
+ <div>
56
+ <label>
57
+ <input type="radio" name="loading_native" />
58
+ Coucou
59
+ </label>
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+ <div>
65
+ <div>
66
+ <p>
67
+ <strong>Read only</strong>
68
+ </p>
69
+
70
+ <Field
71
+ input={
72
+ <Input
73
+ readOnly
74
+ type="radio"
75
+ name="readonly"
76
+ loading={loadingE}
77
+ />
78
+ }
79
+ label="C"
80
+ />
81
+
82
+ <button>
83
+ <span
84
+ onClick={() => {
85
+ setLoadingC(!loadingC);
86
+ }}
87
+ >
88
+ Toggle
89
+ </span>
90
+ </button>
91
+
92
+ <div>
93
+ <label>
94
+ <input type="radio" name="readonly_native" readonly />C
95
+ </label>
96
+ </div>
97
+ </div>
98
+ </div>
99
+
100
+ <div>
101
+ <div>
102
+ <p>
103
+ <strong>Read only + checked</strong>
104
+ </p>
105
+
106
+ <Field
107
+ input={
108
+ <Input
109
+ readOnly
110
+ checked
111
+ type="radio"
112
+ name="readonly_checked"
113
+ loading={loadingD}
114
+ />
115
+ }
116
+ label="D"
117
+ />
118
+
119
+ <button>
120
+ <span
121
+ onClick={() => {
122
+ setLoadingD(!loadingD);
123
+ }}
124
+ >
125
+ Toggle
126
+ </span>
127
+ </button>
128
+
129
+ <div>
130
+ <label>
131
+ <input type="radio" name="readonly_native" readonly />D
132
+ </label>
133
+ </div>
134
+ </div>
135
+ </div>
136
+
137
+ <div>
138
+ <div>
139
+ <p>
140
+ <strong>Disabled</strong>
141
+ </p>
142
+
143
+ <Field
144
+ input={
145
+ <Input
146
+ disabled
147
+ type="radio"
148
+ name="disabled"
149
+ loading={loadingE}
150
+ />
151
+ }
152
+ label="E"
153
+ />
154
+
155
+ <button>
156
+ <span
157
+ onClick={() => {
158
+ setLoadingE(!loadingE);
159
+ }}
160
+ >
161
+ Toggle
162
+ </span>
163
+ </button>
164
+
165
+ <div>
166
+ <label>
167
+ <input type="radio" name="disabled_native" disabled />E
168
+ </label>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <div>
174
+ <div>
175
+ <p>
176
+ <strong>Disabled checked</strong>
177
+ </p>
178
+
179
+ <Field
180
+ input={
181
+ <Input
182
+ disabled
183
+ checked
184
+ type="radio"
185
+ name="disabled_checked"
186
+ loading={loadingF}
187
+ />
188
+ }
189
+ label="F"
190
+ />
191
+
192
+ <button>
193
+ <span
194
+ onClick={() => {
195
+ setLoadingF(!loadingF);
196
+ }}
197
+ >
198
+ Toggle
199
+ </span>
200
+ </button>
201
+
202
+ <div>
203
+ <label>
204
+ <input
205
+ type="radio"
206
+ name="disabled_checked_native"
207
+ disabled
208
+ checked
209
+ />
210
+ F
211
+ </label>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </div>
216
+ );
217
+ };
218
+
219
+ render(<App />, document.querySelector("#root"));
220
+ </script>
221
+ </body>
222
+ </html>
@@ -0,0 +1,104 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" href="data:," />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Select demo</title>
8
+ </head>
9
+ <body>
10
+ <div id="root" style="position: relative"></div>
11
+
12
+ <script type="module" jsenv-type="module/jsx">
13
+ import { render } from "preact";
14
+ import { useState } from "preact/hooks";
15
+ import {
16
+ // eslint-disable-next-line no-unused-vars
17
+ Select,
18
+ // eslint-disable-next-line no-unused-vars
19
+ Field,
20
+ } from "@jsenv/navi";
21
+
22
+ // eslint-disable-next-line no-unused-vars
23
+ const App = () => {
24
+ const [loading, setLoading] = useState(false);
25
+
26
+ return (
27
+ <div>
28
+ <button>
29
+ <span
30
+ onClick={() => {
31
+ setLoading(!loading);
32
+ }}
33
+ >
34
+ {loading ? "Stop loading" : "Start loading"}
35
+ </span>
36
+ </button>
37
+
38
+ <div style="display: flex; flex-direction: row; gap: 30px">
39
+ <div>
40
+ <p>
41
+ <strong>Loading</strong>
42
+ </p>
43
+
44
+ <Field
45
+ input={
46
+ <Select name="loading" loading={loading}>
47
+ {[
48
+ { label: "a", value: "a" },
49
+ { label: "b", value: "b" },
50
+ ]}
51
+ </Select>
52
+ }
53
+ label="Coucou"
54
+ ></Field>
55
+
56
+ <div>
57
+ <label>
58
+ <select name="loading_native">
59
+ <option value="a">a</option>
60
+ <option value="b">b</option>
61
+ </select>
62
+ Coucou
63
+ </label>
64
+ </div>
65
+ </div>
66
+
67
+ <div>
68
+ <p>
69
+ <strong>Readonly</strong>
70
+ </p>
71
+
72
+ <Field
73
+ input={
74
+ <Select name="loading" loading={loading} value="b" readOnly>
75
+ {[
76
+ { label: "a", value: "a" },
77
+ { label: "b", value: "b" },
78
+ ]}
79
+ </Select>
80
+ }
81
+ label="Coucou"
82
+ ></Field>
83
+
84
+ <div>
85
+ <label>
86
+ <select name="loading_native" readonly>
87
+ <option value="a">a</option>
88
+ <option value="b" selected>
89
+ b
90
+ </option>
91
+ </select>
92
+ Coucou
93
+ </label>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ );
99
+ };
100
+
101
+ render(<App />, document.querySelector("#root"));
102
+ </script>
103
+ </body>
104
+ </html>