@jsenv/navi 0.10.2 → 0.11.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.
- package/dist/jsenv_navi.js +13838 -23291
- package/dist/jsenv_navi.js.map +1281 -0
- package/package.json +6 -8
- package/index.js +0 -122
- package/src/action_private_properties.js +0 -11
- package/src/action_proxy_test.html +0 -353
- package/src/action_run_states.js +0 -5
- package/src/actions.js +0 -1401
- package/src/browser_integration/browser_integration.js +0 -216
- package/src/browser_integration/document_back_and_forward.js +0 -17
- package/src/browser_integration/document_loading_signal.js +0 -100
- package/src/browser_integration/document_state_signal.js +0 -9
- package/src/browser_integration/document_url_signal.js +0 -9
- package/src/browser_integration/use_is_visited.js +0 -19
- package/src/browser_integration/via_history.js +0 -232
- package/src/browser_integration/via_navigation.js +0 -168
- package/src/components/action_execution/form_context.js +0 -5
- package/src/components/action_execution/render_actionable_component.jsx +0 -29
- package/src/components/action_execution/use_action.js +0 -99
- package/src/components/action_execution/use_execute_action.js +0 -193
- package/src/components/action_execution/use_run_on_mount.js +0 -9
- package/src/components/action_renderer.jsx +0 -125
- package/src/components/callout/callout.js +0 -990
- package/src/components/callout/callout_demo.html +0 -201
- package/src/components/callout/test_dynamic_positioning.html +0 -161
- package/src/components/callout/test_html_document_iframe.html +0 -182
- package/src/components/demos/0_button_demo.html +0 -707
- package/src/components/demos/10_column_reordering_debug.html +0 -277
- package/src/components/demos/11_table_selection_debug.html +0 -432
- package/src/components/demos/1_checkbox_demo.html +0 -754
- package/src/components/demos/2_input_textual_demo.html +0 -286
- package/src/components/demos/3_radio_demo.html +0 -874
- package/src/components/demos/4_select_demo.html +0 -100
- package/src/components/demos/5_list_scrollable_demo.html +0 -153
- package/src/components/demos/6_tablist_demo.html +0 -77
- package/src/components/demos/7_table_selection_demo.html +0 -176
- package/src/components/demos/8_table_fixed_headers_demo.html +0 -584
- package/src/components/demos/9_table_column_drag_demo.html +0 -325
- package/src/components/demos/action/0_button_demo.html +0 -204
- package/src/components/demos/action/10_shortcuts_demo.html +0 -189
- package/src/components/demos/action/11_nested_shortcuts_demo.xhtml +0 -401
- package/src/components/demos/action/1_input_text_demo.html +0 -876
- package/src/components/demos/action/2_form_multiple.html +0 -303
- package/src/components/demos/action/3_details_demo.html +0 -203
- package/src/components/demos/action/4_input_checkbox_demo.html +0 -731
- package/src/components/demos/action/5_input_checkbox_state_demo.html +0 -270
- package/src/components/demos/action/6_checkbox_list_demo.html +0 -341
- package/src/components/demos/action/7_radio_list_demo.html +0 -357
- package/src/components/demos/action/8_editable_demo.html +0 -431
- package/src/components/demos/action/9_link_demo.html +0 -194
- package/src/components/demos/demo.md +0 -0
- package/src/components/demos/route/basic/basic.html +0 -14
- package/src/components/demos/route/basic/basic_route_demo.jsx +0 -224
- package/src/components/demos/route/multi/multi.html +0 -14
- package/src/components/demos/route/multi/multi_route_demo.jsx +0 -277
- package/src/components/demos/ui_transition/0_action_renderer_ui_transition_demo.html +0 -695
- package/src/components/demos/ui_transition/1_nested_ui_transition_demo.html +0 -429
- package/src/components/demos/ui_transition/2_height_transition_test.html +0 -295
- package/src/components/details/details.jsx +0 -245
- package/src/components/details/summary_marker.jsx +0 -141
- package/src/components/edition/editable.jsx +0 -186
- package/src/components/error_boundary_context.js +0 -9
- package/src/components/field/README.md +0 -247
- package/src/components/field/button.jsx +0 -429
- package/src/components/field/checkbox_list.jsx +0 -185
- package/src/components/field/collect_form_element_values.js +0 -82
- package/src/components/field/custom_field.js +0 -106
- package/src/components/field/form.jsx +0 -209
- package/src/components/field/input.jsx +0 -16
- package/src/components/field/input_checkbox.jsx +0 -434
- package/src/components/field/input_radio.jsx +0 -432
- package/src/components/field/input_textual.jsx +0 -389
- package/src/components/field/label.jsx +0 -46
- package/src/components/field/radio_list.jsx +0 -183
- package/src/components/field/select.jsx +0 -256
- package/src/components/field/use_action_events.js +0 -132
- package/src/components/field/use_form_events.js +0 -59
- package/src/components/field/use_ui_state_controller.js +0 -506
- package/src/components/item_tracker/README.md +0 -461
- package/src/components/item_tracker/use_isolated_item_tracker.jsx +0 -209
- package/src/components/item_tracker/use_isolated_item_tracker_demo.html +0 -148
- package/src/components/item_tracker/use_isolated_item_tracker_demo.jsx +0 -460
- package/src/components/item_tracker/use_item_tracker.jsx +0 -143
- package/src/components/item_tracker/use_item_tracker_demo.html +0 -207
- package/src/components/item_tracker/use_item_tracker_demo.jsx +0 -216
- package/src/components/keyboard_shortcuts/active_keyboard_shortcuts.jsx +0 -87
- package/src/components/keyboard_shortcuts/aria_key_shortcuts.js +0 -61
- package/src/components/keyboard_shortcuts/keyboard_key_meta.js +0 -17
- package/src/components/keyboard_shortcuts/keyboard_shortcuts.js +0 -371
- package/src/components/keyboard_shortcuts/os.js +0 -9
- package/src/components/layout/demos/demo_flex.html +0 -638
- package/src/components/layout/demos/demo_layout_style_buttons.html +0 -351
- package/src/components/layout/demos/demo_layout_style_input.html +0 -226
- package/src/components/layout/demos/demo_layout_style_text.html +0 -514
- package/src/components/layout/flex.jsx +0 -109
- package/src/components/layout/layout_context.jsx +0 -3
- package/src/components/layout/spacing.jsx +0 -20
- package/src/components/layout/use_layout_style.js +0 -249
- package/src/components/link/link.jsx +0 -267
- package/src/components/link/link_with_icon.jsx +0 -52
- package/src/components/loader/loader_background.jsx +0 -372
- package/src/components/loader/loading_spinner.jsx +0 -68
- package/src/components/loader/network_speed.js +0 -83
- package/src/components/loader/rectangle_loading.jsx +0 -244
- package/src/components/props_composition/demos/demo_with_props_style.html +0 -81
- package/src/components/props_composition/with_props_class_name.js +0 -37
- package/src/components/props_composition/with_props_style.js +0 -26
- package/src/components/route.jsx +0 -19
- package/src/components/selection/selection.jsx +0 -1583
- package/src/components/svg/font_sized_svg.jsx +0 -59
- package/src/components/svg/icon_and_text.jsx +0 -21
- package/src/components/svg/svg_mask_overlay.jsx +0 -105
- package/src/components/table/drag/table_drag.jsx +0 -506
- package/src/components/table/resize/table_resize.jsx +0 -650
- package/src/components/table/resize/table_size.js +0 -43
- package/src/components/table/selection/table_selection.js +0 -106
- package/src/components/table/selection/table_selection.jsx +0 -203
- package/src/components/table/sticky/sticky_group.js +0 -354
- package/src/components/table/sticky/table_sticky.js +0 -25
- package/src/components/table/sticky/table_sticky.jsx +0 -501
- package/src/components/table/table.jsx +0 -721
- package/src/components/table/table_css.js +0 -211
- package/src/components/table/table_ui.jsx +0 -49
- package/src/components/table/use_cells_and_columns.js +0 -90
- package/src/components/table/use_object_array_to_cells.js +0 -46
- package/src/components/table/z_indexes.js +0 -23
- package/src/components/tablist/tablist.jsx +0 -99
- package/src/components/text/demos/demo_text_and_icon.html +0 -421
- package/src/components/text/overflow.jsx +0 -15
- package/src/components/text/text.jsx +0 -83
- package/src/components/text/text_and_count.jsx +0 -28
- package/src/components/ui_transition.jsx +0 -128
- package/src/components/use_auto_focus.js +0 -94
- package/src/components/use_batch_during_render.js +0 -33
- package/src/components/use_debounce_true.js +0 -31
- package/src/components/use_dependencies_diff.js +0 -35
- package/src/components/use_focus_group.js +0 -20
- package/src/components/use_initial_value.js +0 -78
- package/src/components/use_is_visited.js +0 -19
- package/src/components/use_ref_array.js +0 -38
- package/src/components/use_signal_sync.js +0 -50
- package/src/components/use_stable_callback.js +0 -68
- package/src/components/use_state_array.js +0 -47
- package/src/docs/actions.md +0 -250
- package/src/docs/demos/resource/action_status.jsx +0 -42
- package/src/docs/demos/resource/demo.md +0 -1
- package/src/docs/demos/resource/resource_demo_0.html +0 -84
- package/src/docs/demos/resource/resource_demo_10_post_gc.html +0 -364
- package/src/docs/demos/resource/resource_demo_11_describe_many.html +0 -362
- package/src/docs/demos/resource/resource_demo_2.html +0 -173
- package/src/docs/demos/resource/resource_demo_3_filtered_users.html +0 -415
- package/src/docs/demos/resource/resource_demo_4_details.html +0 -284
- package/src/docs/demos/resource/resource_demo_5_renderer_lazy.html +0 -115
- package/src/docs/demos/resource/resource_demo_6_gc.html +0 -217
- package/src/docs/demos/resource/resource_demo_7_child_gc.html +0 -240
- package/src/docs/demos/resource/resource_demo_8_proxy_gc.html +0 -319
- package/src/docs/demos/resource/resource_demo_9_describe_one.html +0 -472
- package/src/docs/demos/resource/tata.jsx +0 -3
- package/src/docs/demos/resource/toto.jsx +0 -3
- package/src/docs/demos/user_nav/user_nav.html +0 -12
- package/src/docs/demos/user_nav/user_nav.jsx +0 -330
- package/src/docs/resource_dependencies.md +0 -103
- package/src/docs/resource_with_params.md +0 -80
- package/src/navi_css_vars.js +0 -14
- package/src/notes.md +0 -34
- package/src/route/route.js +0 -596
- package/src/route/route.xtest.html +0 -228
- package/src/store/array_signal_store.js +0 -537
- package/src/store/local_storage_signal.js +0 -17
- package/src/store/resource_graph.js +0 -1304
- package/src/store/tests/resource_graph_autoreload_demo.html +0 -12
- package/src/store/tests/resource_graph_autoreload_demo.jsx +0 -964
- package/src/store/tests/resource_graph_dependencies.test_manual.js +0 -95
- package/src/store/value_in_local_storage.js +0 -187
- package/src/symbol_object_signal.js +0 -1
- package/src/use_action_data.js +0 -10
- package/src/use_action_status.js +0 -47
- package/src/utils/add_many_event_listeners.js +0 -15
- package/src/utils/array_add_remove.js +0 -61
- package/src/utils/array_signal.js +0 -15
- package/src/utils/compare_two_js_values.js +0 -172
- package/src/utils/execute_with_cleanup.js +0 -21
- package/src/utils/get_caller_info.js +0 -85
- package/src/utils/is_signal.js +0 -20
- package/src/utils/js_value_weak_map.js +0 -162
- package/src/utils/js_value_weak_map_demo.html +0 -690
- package/src/utils/merge_two_js_values.js +0 -53
- package/src/utils/stringify_for_display.js +0 -131
- package/src/utils/weak_effect.js +0 -48
- package/src/validation/constraints/confirm_constraint.js +0 -14
- package/src/validation/constraints/create_unique_value_constraint.js +0 -27
- package/src/validation/constraints/native_constraints.js +0 -338
- package/src/validation/constraints/readonly_constraint.js +0 -41
- package/src/validation/constraints/same_as_constraint.js +0 -42
- package/src/validation/constraints/single_space_constraint.js +0 -13
- package/src/validation/custom_constraint_validation.js +0 -793
- package/src/validation/custom_message.js +0 -18
- package/src/validation/demos/browser_style.png +0 -0
- package/src/validation/demos/demo_same_as_constraint.html +0 -259
- package/src/validation/demos/form_validation_demo.html +0 -142
- package/src/validation/demos/form_validation_demo_preact.html +0 -87
- package/src/validation/demos/form_validation_native_popover_demo.html +0 -168
- package/src/validation/demos/form_validation_vs_native_demo.html +0 -172
- package/src/validation/hooks/use_constraints.js +0 -23
- package/src/validation/hooks/use_custom_validation_ref.js +0 -73
- package/src/validation/hooks/use_validation_message.js +0 -19
- package/src/validation/input_change_effect.js +0 -106
|
@@ -1,731 +0,0 @@
|
|
|
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>Checkbox Demo</title>
|
|
8
|
-
<style>
|
|
9
|
-
body {
|
|
10
|
-
font-family:
|
|
11
|
-
system-ui,
|
|
12
|
-
-apple-system,
|
|
13
|
-
sans-serif;
|
|
14
|
-
max-width: 1200px;
|
|
15
|
-
margin: 0 auto;
|
|
16
|
-
padding: 20px;
|
|
17
|
-
}
|
|
18
|
-
.demo-grid {
|
|
19
|
-
display: grid;
|
|
20
|
-
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
|
21
|
-
gap: 20px;
|
|
22
|
-
margin-bottom: 30px;
|
|
23
|
-
}
|
|
24
|
-
.demo-card {
|
|
25
|
-
background: white;
|
|
26
|
-
border-radius: 8px;
|
|
27
|
-
padding: 20px;
|
|
28
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
29
|
-
}
|
|
30
|
-
.demo-title {
|
|
31
|
-
margin: 0 0 15px 0;
|
|
32
|
-
color: #333;
|
|
33
|
-
font-size: 16px;
|
|
34
|
-
font-weight: 600;
|
|
35
|
-
border-bottom: 2px solid #e0e0e0;
|
|
36
|
-
padding-bottom: 8px;
|
|
37
|
-
}
|
|
38
|
-
.result-display {
|
|
39
|
-
margin-top: 15px;
|
|
40
|
-
padding: 12px;
|
|
41
|
-
background: #f8f9fa;
|
|
42
|
-
border: 1px solid #dee2e6;
|
|
43
|
-
border-radius: 4px;
|
|
44
|
-
min-height: 20px;
|
|
45
|
-
font-family: monospace;
|
|
46
|
-
font-size: 14px;
|
|
47
|
-
}
|
|
48
|
-
.result-success {
|
|
49
|
-
background: #d4edda;
|
|
50
|
-
border-color: #c3e6cb;
|
|
51
|
-
color: #155724;
|
|
52
|
-
}
|
|
53
|
-
.result-error {
|
|
54
|
-
background: #f8d7da;
|
|
55
|
-
border-color: #f5c6cb;
|
|
56
|
-
color: #721c24;
|
|
57
|
-
}
|
|
58
|
-
.result-loading {
|
|
59
|
-
background: #d1ecf1;
|
|
60
|
-
border-color: #bee5eb;
|
|
61
|
-
color: #0c5460;
|
|
62
|
-
}
|
|
63
|
-
.button-group {
|
|
64
|
-
display: flex;
|
|
65
|
-
gap: 10px;
|
|
66
|
-
margin-top: 10px;
|
|
67
|
-
}
|
|
68
|
-
.control-group {
|
|
69
|
-
margin-bottom: 15px;
|
|
70
|
-
}
|
|
71
|
-
.checkbox-group {
|
|
72
|
-
display: flex;
|
|
73
|
-
align-items: center;
|
|
74
|
-
gap: 8px;
|
|
75
|
-
margin-bottom: 10px;
|
|
76
|
-
}
|
|
77
|
-
.checkbox-group input[type="checkbox"] {
|
|
78
|
-
width: 18px;
|
|
79
|
-
height: 18px;
|
|
80
|
-
cursor: pointer;
|
|
81
|
-
}
|
|
82
|
-
.checkbox-group label {
|
|
83
|
-
font-weight: 500;
|
|
84
|
-
color: #555;
|
|
85
|
-
cursor: pointer;
|
|
86
|
-
}
|
|
87
|
-
.status-indicator {
|
|
88
|
-
display: inline-block;
|
|
89
|
-
width: 12px;
|
|
90
|
-
height: 12px;
|
|
91
|
-
border-radius: 50%;
|
|
92
|
-
margin-right: 8px;
|
|
93
|
-
}
|
|
94
|
-
.status-idle {
|
|
95
|
-
background: #6c757d;
|
|
96
|
-
}
|
|
97
|
-
.status-loading {
|
|
98
|
-
background: #007bff;
|
|
99
|
-
animation: pulse 1s infinite;
|
|
100
|
-
}
|
|
101
|
-
.status-success {
|
|
102
|
-
background: #28a745;
|
|
103
|
-
}
|
|
104
|
-
.status-error {
|
|
105
|
-
background: #dc3545;
|
|
106
|
-
}
|
|
107
|
-
@keyframes pulse {
|
|
108
|
-
0%,
|
|
109
|
-
100% {
|
|
110
|
-
opacity: 1;
|
|
111
|
-
}
|
|
112
|
-
50% {
|
|
113
|
-
opacity: 0.5;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
nav a {
|
|
117
|
-
color: #007bff;
|
|
118
|
-
text-decoration: none;
|
|
119
|
-
}
|
|
120
|
-
nav a:hover {
|
|
121
|
-
text-decoration: underline;
|
|
122
|
-
}
|
|
123
|
-
h2 {
|
|
124
|
-
margin-top: 40px;
|
|
125
|
-
margin-bottom: 20px;
|
|
126
|
-
padding-top: 20px;
|
|
127
|
-
border-top: 2px solid #e0e0e0;
|
|
128
|
-
}
|
|
129
|
-
h2:first-of-type {
|
|
130
|
-
margin-top: 0;
|
|
131
|
-
border-top: none;
|
|
132
|
-
padding-top: 0;
|
|
133
|
-
}
|
|
134
|
-
</style>
|
|
135
|
-
</head>
|
|
136
|
-
<body>
|
|
137
|
-
<h1>Checkbox Demo</h1>
|
|
138
|
-
<div id="root"></div>
|
|
139
|
-
|
|
140
|
-
<script type="module" jsenv-type="module/jsx">
|
|
141
|
-
import { render } from "preact";
|
|
142
|
-
import { useState, useRef } from "preact/hooks";
|
|
143
|
-
import {
|
|
144
|
-
createAction,
|
|
145
|
-
// eslint-disable-next-line no-unused-vars
|
|
146
|
-
Form,
|
|
147
|
-
// eslint-disable-next-line no-unused-vars
|
|
148
|
-
Input,
|
|
149
|
-
// eslint-disable-next-line no-unused-vars
|
|
150
|
-
Button,
|
|
151
|
-
} from "@jsenv/navi";
|
|
152
|
-
|
|
153
|
-
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
154
|
-
|
|
155
|
-
// eslint-disable-next-line no-unused-vars
|
|
156
|
-
const App = () => {
|
|
157
|
-
const [checkboxBackgroundColor, setCheckboxBackgroundColor] =
|
|
158
|
-
useState(undefined);
|
|
159
|
-
|
|
160
|
-
return (
|
|
161
|
-
<>
|
|
162
|
-
<div className="demo-card" style={{ marginBottom: "30px" }}>
|
|
163
|
-
<h2>Checkbox Demo - Overview</h2>
|
|
164
|
-
<p>
|
|
165
|
-
This demo showcases different ways to use the Input component
|
|
166
|
-
with checkboxes.
|
|
167
|
-
</p>
|
|
168
|
-
|
|
169
|
-
<div
|
|
170
|
-
className="control-group"
|
|
171
|
-
style={{
|
|
172
|
-
marginBottom: "20px",
|
|
173
|
-
padding: "15px",
|
|
174
|
-
backgroundColor: "#f8f9fa",
|
|
175
|
-
borderRadius: "8px",
|
|
176
|
-
}}
|
|
177
|
-
>
|
|
178
|
-
<label>
|
|
179
|
-
<strong>Global Checkbox Background Color:</strong>
|
|
180
|
-
<select
|
|
181
|
-
value={checkboxBackgroundColor || ""}
|
|
182
|
-
onChange={(e) =>
|
|
183
|
-
setCheckboxBackgroundColor(e.target.value || undefined)
|
|
184
|
-
}
|
|
185
|
-
style={{
|
|
186
|
-
marginLeft: "10px",
|
|
187
|
-
padding: "5px 10px",
|
|
188
|
-
borderRadius: "4px",
|
|
189
|
-
border: "1px solid #ccc",
|
|
190
|
-
}}
|
|
191
|
-
>
|
|
192
|
-
<option value="">Default</option>
|
|
193
|
-
<option value="#ff6b6b">Red</option>
|
|
194
|
-
<option value="#51cf66">Green</option>
|
|
195
|
-
</select>
|
|
196
|
-
</label>
|
|
197
|
-
<p
|
|
198
|
-
style={{
|
|
199
|
-
fontSize: "14px",
|
|
200
|
-
color: "#666",
|
|
201
|
-
margin: "8px 0 0 0",
|
|
202
|
-
}}
|
|
203
|
-
>
|
|
204
|
-
This affects all checkboxes below and demonstrates that
|
|
205
|
-
background color changes don't affect checked state.
|
|
206
|
-
</p>
|
|
207
|
-
</div>
|
|
208
|
-
|
|
209
|
-
<nav>
|
|
210
|
-
<h3>Sections:</h3>
|
|
211
|
-
<ul style={{ marginLeft: "20px" }}>
|
|
212
|
-
<li>
|
|
213
|
-
<a href="#basic-checkboxes">
|
|
214
|
-
1. Basic Checkbox (no action/no form)
|
|
215
|
-
</a>{" "}
|
|
216
|
-
- Simple checkboxes with value handling
|
|
217
|
-
</li>
|
|
218
|
-
<li>
|
|
219
|
-
<a href="#checkbox-actions">2. Checkbox with Actions</a> -
|
|
220
|
-
Checkboxes that trigger actions on change, including error
|
|
221
|
-
handling
|
|
222
|
-
</li>
|
|
223
|
-
<li>
|
|
224
|
-
<a href="#checkbox-forms">3. Checkbox inside Form</a> - Form
|
|
225
|
-
integration patterns
|
|
226
|
-
</li>
|
|
227
|
-
</ul>
|
|
228
|
-
</nav>
|
|
229
|
-
</div>
|
|
230
|
-
|
|
231
|
-
<h2 id="basic-checkboxes">1. Basic Checkbox (no action/no form)</h2>
|
|
232
|
-
<div className="demo-grid">
|
|
233
|
-
<CheckboxDemo backgroundColor={checkboxBackgroundColor} />
|
|
234
|
-
<CheckboxDefaultCheckedDemo
|
|
235
|
-
backgroundColor={checkboxBackgroundColor}
|
|
236
|
-
/>
|
|
237
|
-
</div>
|
|
238
|
-
|
|
239
|
-
<h2 id="checkbox-actions">2. Checkbox with Actions</h2>
|
|
240
|
-
<div className="demo-grid">
|
|
241
|
-
<CheckboxActionDemo backgroundColor={checkboxBackgroundColor} />
|
|
242
|
-
<CheckboxActionDefaultCheckedDemo
|
|
243
|
-
backgroundColor={checkboxBackgroundColor}
|
|
244
|
-
/>
|
|
245
|
-
<CheckboxActionErrorDemo
|
|
246
|
-
backgroundColor={checkboxBackgroundColor}
|
|
247
|
-
/>
|
|
248
|
-
<CheckboxActionErrorDefaultCheckedDemo
|
|
249
|
-
backgroundColor={checkboxBackgroundColor}
|
|
250
|
-
/>
|
|
251
|
-
<CheckboxActionErrorOnUncheckedDemo
|
|
252
|
-
backgroundColor={checkboxBackgroundColor}
|
|
253
|
-
/>
|
|
254
|
-
<CheckboxActionObjectDemo
|
|
255
|
-
backgroundColor={checkboxBackgroundColor}
|
|
256
|
-
/>
|
|
257
|
-
</div>
|
|
258
|
-
|
|
259
|
-
<h2 id="checkbox-forms">3. Checkbox inside Form</h2>
|
|
260
|
-
<div className="demo-grid">
|
|
261
|
-
<CheckboxFormControlledErrorDemo
|
|
262
|
-
backgroundColor={checkboxBackgroundColor}
|
|
263
|
-
/>
|
|
264
|
-
</div>
|
|
265
|
-
</>
|
|
266
|
-
);
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
// eslint-disable-next-line no-unused-vars
|
|
270
|
-
const CheckboxDemo = ({ backgroundColor }) => {
|
|
271
|
-
const [result, setResult] = useState("");
|
|
272
|
-
const [status] = useState("idle");
|
|
273
|
-
const ref = useRef();
|
|
274
|
-
|
|
275
|
-
return (
|
|
276
|
-
<div className="demo-card">
|
|
277
|
-
<h3 className="demo-title">
|
|
278
|
-
Basic Checkbox
|
|
279
|
-
<button
|
|
280
|
-
onClick={() => {
|
|
281
|
-
ref.current.dispatchEvent(new CustomEvent("resetuistate"));
|
|
282
|
-
}}
|
|
283
|
-
>
|
|
284
|
-
Reset
|
|
285
|
-
</button>
|
|
286
|
-
</h3>
|
|
287
|
-
<div className="control-group">
|
|
288
|
-
<div className="checkbox-group">
|
|
289
|
-
<label>
|
|
290
|
-
<Input
|
|
291
|
-
ref={ref}
|
|
292
|
-
type="checkbox"
|
|
293
|
-
name="enabled"
|
|
294
|
-
accentColor={backgroundColor}
|
|
295
|
-
onUIStateChange={(checked) => {
|
|
296
|
-
setResult(checked ? "checked" : "unchecked");
|
|
297
|
-
}}
|
|
298
|
-
/>
|
|
299
|
-
Enable feature
|
|
300
|
-
</label>
|
|
301
|
-
</div>
|
|
302
|
-
</div>
|
|
303
|
-
<div
|
|
304
|
-
className={`result-display ${status === "loading" ? "result-loading" : status === "success" ? "result-success" : status === "error" ? "result-error" : ""}`}
|
|
305
|
-
>
|
|
306
|
-
{result || "Check or uncheck to see action..."}
|
|
307
|
-
</div>
|
|
308
|
-
</div>
|
|
309
|
-
);
|
|
310
|
-
};
|
|
311
|
-
// eslint-disable-next-line no-unused-vars
|
|
312
|
-
const CheckboxDefaultCheckedDemo = ({ backgroundColor }) => {
|
|
313
|
-
const [result, setResult] = useState("");
|
|
314
|
-
const [status] = useState("idle");
|
|
315
|
-
const ref = useRef();
|
|
316
|
-
|
|
317
|
-
return (
|
|
318
|
-
<div className="demo-card">
|
|
319
|
-
<h3 className="demo-title">
|
|
320
|
-
Basic Checkbox (Default Checked)
|
|
321
|
-
<button
|
|
322
|
-
onClick={() => {
|
|
323
|
-
ref.current.dispatchEvent(new CustomEvent("resetuistate"));
|
|
324
|
-
}}
|
|
325
|
-
>
|
|
326
|
-
Reset
|
|
327
|
-
</button>
|
|
328
|
-
</h3>
|
|
329
|
-
<div className="control-group">
|
|
330
|
-
<div className="checkbox-group">
|
|
331
|
-
<label>
|
|
332
|
-
<Input
|
|
333
|
-
ref={ref}
|
|
334
|
-
type="checkbox"
|
|
335
|
-
name="enabled"
|
|
336
|
-
defaultChecked
|
|
337
|
-
accentColor={backgroundColor}
|
|
338
|
-
onUIStateChange={(checked) => {
|
|
339
|
-
setResult(checked ? "checked" : "unchecked");
|
|
340
|
-
}}
|
|
341
|
-
/>
|
|
342
|
-
Enable feature
|
|
343
|
-
</label>
|
|
344
|
-
</div>
|
|
345
|
-
</div>
|
|
346
|
-
<div
|
|
347
|
-
className={`result-display ${status === "loading" ? "result-loading" : status === "success" ? "result-success" : status === "error" ? "result-error" : ""}`}
|
|
348
|
-
>
|
|
349
|
-
{result || "Check or uncheck to see action..."}
|
|
350
|
-
</div>
|
|
351
|
-
</div>
|
|
352
|
-
);
|
|
353
|
-
};
|
|
354
|
-
// eslint-disable-next-line no-unused-vars
|
|
355
|
-
const CheckboxActionDemo = ({ backgroundColor }) => {
|
|
356
|
-
const [result, setResult] = useState("");
|
|
357
|
-
const [status, setStatus] = useState("idle");
|
|
358
|
-
|
|
359
|
-
return (
|
|
360
|
-
<div className="demo-card">
|
|
361
|
-
<h3 className="demo-title">Checkbox with Action</h3>
|
|
362
|
-
<div className="control-group">
|
|
363
|
-
<div className="checkbox-group">
|
|
364
|
-
<label>
|
|
365
|
-
<Input
|
|
366
|
-
type="checkbox"
|
|
367
|
-
name="enabled"
|
|
368
|
-
accentColor={backgroundColor}
|
|
369
|
-
action={async (enabled) => {
|
|
370
|
-
setStatus("loading");
|
|
371
|
-
setResult("Processing...");
|
|
372
|
-
try {
|
|
373
|
-
await delay(1000);
|
|
374
|
-
const response = `${enabled ? "✅" : "☐"} Checkbox ${enabled ? "checked" : "unchecked"}`;
|
|
375
|
-
setResult(response);
|
|
376
|
-
setStatus("success");
|
|
377
|
-
return response;
|
|
378
|
-
} catch (error) {
|
|
379
|
-
setResult(`❌ Error: ${error.message}`);
|
|
380
|
-
setStatus("error");
|
|
381
|
-
throw error;
|
|
382
|
-
}
|
|
383
|
-
}}
|
|
384
|
-
/>
|
|
385
|
-
<span className={`status-indicator status-${status}`}></span>
|
|
386
|
-
Enable feature
|
|
387
|
-
</label>
|
|
388
|
-
</div>
|
|
389
|
-
</div>
|
|
390
|
-
<div
|
|
391
|
-
className={`result-display ${status === "loading" ? "result-loading" : status === "success" ? "result-success" : status === "error" ? "result-error" : ""}`}
|
|
392
|
-
>
|
|
393
|
-
{result || "Check or uncheck to see action..."}
|
|
394
|
-
</div>
|
|
395
|
-
</div>
|
|
396
|
-
);
|
|
397
|
-
};
|
|
398
|
-
// eslint-disable-next-line no-unused-vars
|
|
399
|
-
const CheckboxActionDefaultCheckedDemo = ({ backgroundColor }) => {
|
|
400
|
-
const [result, setResult] = useState("");
|
|
401
|
-
|
|
402
|
-
return (
|
|
403
|
-
<div className="demo-card">
|
|
404
|
-
<h3 className="demo-title">
|
|
405
|
-
Checkbox with Action (Default Checked)
|
|
406
|
-
</h3>
|
|
407
|
-
<div className="control-group">
|
|
408
|
-
<div className="checkbox-group">
|
|
409
|
-
<label>
|
|
410
|
-
<Input
|
|
411
|
-
type="checkbox"
|
|
412
|
-
name="agreed"
|
|
413
|
-
defaultChecked
|
|
414
|
-
accentColor={backgroundColor}
|
|
415
|
-
action={async (agreed) => {
|
|
416
|
-
setResult("Processing...");
|
|
417
|
-
await delay(800);
|
|
418
|
-
const response = `${agreed ? "✅" : "☐"} Agreement: ${agreed ? "accepted" : "declined"}`;
|
|
419
|
-
setResult(response);
|
|
420
|
-
return response;
|
|
421
|
-
}}
|
|
422
|
-
/>
|
|
423
|
-
I agree to the terms and conditions
|
|
424
|
-
</label>
|
|
425
|
-
</div>
|
|
426
|
-
</div>
|
|
427
|
-
<div
|
|
428
|
-
className={`result-display ${result.startsWith("✅") || result.startsWith("☐") ? "result-success" : ""}`}
|
|
429
|
-
>
|
|
430
|
-
{result || "Change checkbox to see action..."}
|
|
431
|
-
</div>
|
|
432
|
-
</div>
|
|
433
|
-
);
|
|
434
|
-
};
|
|
435
|
-
// eslint-disable-next-line no-unused-vars
|
|
436
|
-
const CheckboxActionErrorDemo = ({ backgroundColor }) => {
|
|
437
|
-
const [result, setResult] = useState("");
|
|
438
|
-
const [status, setStatus] = useState("idle");
|
|
439
|
-
|
|
440
|
-
return (
|
|
441
|
-
<div className="demo-card">
|
|
442
|
-
<h3 className="demo-title">Checkbox with Action (Always Fails)</h3>
|
|
443
|
-
<div className="control-group">
|
|
444
|
-
<div className="checkbox-group">
|
|
445
|
-
<label>
|
|
446
|
-
<Input
|
|
447
|
-
type="checkbox"
|
|
448
|
-
name="dangerous"
|
|
449
|
-
accentColor={backgroundColor}
|
|
450
|
-
action={async (dangerous) => {
|
|
451
|
-
setStatus("loading");
|
|
452
|
-
setResult("Processing...");
|
|
453
|
-
try {
|
|
454
|
-
await delay(1500);
|
|
455
|
-
throw new Error(
|
|
456
|
-
`Action failed for ${dangerous ? "checked" : "unchecked"} state`,
|
|
457
|
-
);
|
|
458
|
-
} catch (error) {
|
|
459
|
-
setResult(`❌ ${error.message}`);
|
|
460
|
-
setStatus("error");
|
|
461
|
-
throw error;
|
|
462
|
-
}
|
|
463
|
-
}}
|
|
464
|
-
/>
|
|
465
|
-
<span className={`status-indicator status-${status}`}></span>
|
|
466
|
-
Dangerous operation (always fails)
|
|
467
|
-
</label>
|
|
468
|
-
</div>
|
|
469
|
-
</div>
|
|
470
|
-
<div
|
|
471
|
-
className={`result-display ${status === "loading" ? "result-loading" : status === "error" ? "result-error" : ""}`}
|
|
472
|
-
>
|
|
473
|
-
{result || "This checkbox will always trigger an error..."}
|
|
474
|
-
</div>
|
|
475
|
-
</div>
|
|
476
|
-
);
|
|
477
|
-
};
|
|
478
|
-
// eslint-disable-next-line no-unused-vars
|
|
479
|
-
const CheckboxActionErrorDefaultCheckedDemo = ({ backgroundColor }) => {
|
|
480
|
-
const [result, setResult] = useState("");
|
|
481
|
-
const [status, setStatus] = useState("idle");
|
|
482
|
-
|
|
483
|
-
return (
|
|
484
|
-
<div className="demo-card">
|
|
485
|
-
<h3 className="demo-title">
|
|
486
|
-
Checkbox with Action (Default Checked, Always Fails)
|
|
487
|
-
</h3>
|
|
488
|
-
<div className="control-group">
|
|
489
|
-
<div className="checkbox-group">
|
|
490
|
-
<Input
|
|
491
|
-
id="error-initial-checkbox"
|
|
492
|
-
type="checkbox"
|
|
493
|
-
name="risky"
|
|
494
|
-
defaultChecked
|
|
495
|
-
accentColor={backgroundColor}
|
|
496
|
-
action={async (risky) => {
|
|
497
|
-
setStatus("loading");
|
|
498
|
-
setResult("Processing...");
|
|
499
|
-
try {
|
|
500
|
-
await delay(1200);
|
|
501
|
-
throw new Error(
|
|
502
|
-
`Operation failed for ${risky ? "enabled" : "disabled"} risky feature`,
|
|
503
|
-
);
|
|
504
|
-
} catch (error) {
|
|
505
|
-
setResult(`❌ ${error.message}`);
|
|
506
|
-
setStatus("error");
|
|
507
|
-
throw error;
|
|
508
|
-
}
|
|
509
|
-
}}
|
|
510
|
-
/>
|
|
511
|
-
<label htmlFor="error-initial-checkbox">
|
|
512
|
-
<span className={`status-indicator status-${status}`}></span>
|
|
513
|
-
Enable risky feature (starts checked, always fails)
|
|
514
|
-
</label>
|
|
515
|
-
</div>
|
|
516
|
-
</div>
|
|
517
|
-
<div
|
|
518
|
-
className={`result-display ${status === "loading" ? "result-loading" : status === "error" ? "result-error" : ""}`}
|
|
519
|
-
>
|
|
520
|
-
{result ||
|
|
521
|
-
"This checkbox starts checked and will always trigger an error..."}
|
|
522
|
-
</div>
|
|
523
|
-
</div>
|
|
524
|
-
);
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
// eslint-disable-next-line no-unused-vars
|
|
528
|
-
const CheckboxActionErrorOnUncheckedDemo = ({ backgroundColor }) => {
|
|
529
|
-
// for this example the checkbox is going to be controlled because that's how you would
|
|
530
|
-
// implement it in a real world scenario:
|
|
531
|
-
// the fact checkbox is checked comes from a backend so when the operation succeeds
|
|
532
|
-
// the component is re-rendered as checked
|
|
533
|
-
|
|
534
|
-
const [result, setResult] = useState("");
|
|
535
|
-
const [status, setStatus] = useState("idle");
|
|
536
|
-
const [checked, setChecked] = useState(false);
|
|
537
|
-
|
|
538
|
-
return (
|
|
539
|
-
<div className="demo-card">
|
|
540
|
-
<h3 className="demo-title">
|
|
541
|
-
Checkbox with Action (Fails When Unchecked)
|
|
542
|
-
</h3>
|
|
543
|
-
<div className="control-group">
|
|
544
|
-
<div className="checkbox-group">
|
|
545
|
-
<label>
|
|
546
|
-
<Input
|
|
547
|
-
type="checkbox"
|
|
548
|
-
name="protection"
|
|
549
|
-
checked={checked}
|
|
550
|
-
accentColor={backgroundColor}
|
|
551
|
-
action={async (protection) => {
|
|
552
|
-
setStatus("loading");
|
|
553
|
-
setResult("Processing...");
|
|
554
|
-
await delay(1000);
|
|
555
|
-
try {
|
|
556
|
-
if (!protection) {
|
|
557
|
-
throw new Error(
|
|
558
|
-
"Protection must be enabled for security",
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
const response = `✅ Protection ${protection ? "enabled" : "disabled"}`;
|
|
562
|
-
setResult(response);
|
|
563
|
-
setStatus("success");
|
|
564
|
-
setChecked(true);
|
|
565
|
-
return response;
|
|
566
|
-
} catch (error) {
|
|
567
|
-
setResult(`❌ ${error.message}`);
|
|
568
|
-
setStatus("error");
|
|
569
|
-
throw error;
|
|
570
|
-
}
|
|
571
|
-
}}
|
|
572
|
-
/>
|
|
573
|
-
<span className={`status-indicator status-${status}`}></span>
|
|
574
|
-
Enable security protection (fails when unchecked)
|
|
575
|
-
</label>
|
|
576
|
-
</div>
|
|
577
|
-
</div>
|
|
578
|
-
<div
|
|
579
|
-
className={`result-display ${status === "loading" ? "result-loading" : status === "success" ? "result-success" : status === "error" ? "result-error" : ""}`}
|
|
580
|
-
>
|
|
581
|
-
{result ||
|
|
582
|
-
"Toggle checkbox - succeeds when checked, fails when unchecked..."}
|
|
583
|
-
</div>
|
|
584
|
-
</div>
|
|
585
|
-
);
|
|
586
|
-
};
|
|
587
|
-
|
|
588
|
-
const toggleAction = createAction(async ({ notifications }) => {
|
|
589
|
-
await delay(600);
|
|
590
|
-
return `${notifications ? "✅" : "☐"} Notifications ${notifications ? "enabled" : "disabled"}`;
|
|
591
|
-
});
|
|
592
|
-
// eslint-disable-next-line no-unused-vars
|
|
593
|
-
const CheckboxActionObjectDemo = ({ backgroundColor }) => {
|
|
594
|
-
const [result, setResult] = useState("");
|
|
595
|
-
|
|
596
|
-
return (
|
|
597
|
-
<div className="demo-card">
|
|
598
|
-
<h3 className="demo-title">Checkbox with Action Object</h3>
|
|
599
|
-
<div className="control-group">
|
|
600
|
-
<div className="checkbox-group">
|
|
601
|
-
<label>
|
|
602
|
-
<Input
|
|
603
|
-
type="checkbox"
|
|
604
|
-
name="notifications"
|
|
605
|
-
accentColor={backgroundColor}
|
|
606
|
-
action={(notifications) => {
|
|
607
|
-
return toggleAction({ notifications });
|
|
608
|
-
}}
|
|
609
|
-
onActionStart={() => {
|
|
610
|
-
setResult("Processing...");
|
|
611
|
-
}}
|
|
612
|
-
onActionEnd={(e) => {
|
|
613
|
-
setResult(e.detail.data);
|
|
614
|
-
}}
|
|
615
|
-
/>
|
|
616
|
-
Enable notifications (with action object)
|
|
617
|
-
</label>
|
|
618
|
-
</div>
|
|
619
|
-
</div>
|
|
620
|
-
<div
|
|
621
|
-
className={`result-display ${result.startsWith("✅") || result.startsWith("☐") ? "result-success" : ""}`}
|
|
622
|
-
>
|
|
623
|
-
{result || "Toggle checkbox to trigger action object..."}
|
|
624
|
-
</div>
|
|
625
|
-
</div>
|
|
626
|
-
);
|
|
627
|
-
};
|
|
628
|
-
|
|
629
|
-
// eslint-disable-next-line no-unused-vars
|
|
630
|
-
const CheckboxFormControlledErrorDemo = ({ backgroundColor }) => {
|
|
631
|
-
const [checked, setChecked] = useState(true);
|
|
632
|
-
const [result, setResult] = useState("");
|
|
633
|
-
const [status, setStatus] = useState("idle");
|
|
634
|
-
const ref = useRef();
|
|
635
|
-
|
|
636
|
-
return (
|
|
637
|
-
<div className="demo-card">
|
|
638
|
-
<h3 className="demo-title">
|
|
639
|
-
Form with Controlled Checkbox (Fails When Submit Without Check)
|
|
640
|
-
</h3>
|
|
641
|
-
<p
|
|
642
|
-
style={{ fontSize: "14px", color: "#666", marginBottom: "15px" }}
|
|
643
|
-
>
|
|
644
|
-
This demonstrates backend validation when frontend forgets to add
|
|
645
|
-
"required" - the server throws an error during form submission if
|
|
646
|
-
terms aren't agreed.
|
|
647
|
-
</p>
|
|
648
|
-
<Form
|
|
649
|
-
action={async ({ terms }) => {
|
|
650
|
-
setStatus("loading");
|
|
651
|
-
setResult("Processing form...");
|
|
652
|
-
try {
|
|
653
|
-
await delay(1000);
|
|
654
|
-
if (!terms) {
|
|
655
|
-
throw new Error(
|
|
656
|
-
"You must agree to the terms and conditions to proceed",
|
|
657
|
-
);
|
|
658
|
-
}
|
|
659
|
-
setChecked(Boolean(terms));
|
|
660
|
-
const response = "✅ Form submitted successfully!";
|
|
661
|
-
setResult(response);
|
|
662
|
-
setStatus("success");
|
|
663
|
-
return response;
|
|
664
|
-
} catch (error) {
|
|
665
|
-
setResult(`❌ ${error.message}`);
|
|
666
|
-
setStatus("error");
|
|
667
|
-
throw error;
|
|
668
|
-
}
|
|
669
|
-
}}
|
|
670
|
-
>
|
|
671
|
-
<div className="control-group">
|
|
672
|
-
<div className="checkbox-group">
|
|
673
|
-
<label>
|
|
674
|
-
<Input
|
|
675
|
-
ref={ref}
|
|
676
|
-
type="checkbox"
|
|
677
|
-
name="terms"
|
|
678
|
-
checked={checked}
|
|
679
|
-
accentColor={backgroundColor}
|
|
680
|
-
/>
|
|
681
|
-
<span
|
|
682
|
-
className={`status-indicator status-${status}`}
|
|
683
|
-
></span>
|
|
684
|
-
I agree to the terms and conditions
|
|
685
|
-
</label>
|
|
686
|
-
</div>
|
|
687
|
-
</div>
|
|
688
|
-
<div className="button-group">
|
|
689
|
-
<Button type="submit">Submit Form</Button>
|
|
690
|
-
<button
|
|
691
|
-
type="button"
|
|
692
|
-
onClick={() => {
|
|
693
|
-
ref.current.dispatchEvent(
|
|
694
|
-
new CustomEvent("setuistate", {
|
|
695
|
-
detail: { value: true },
|
|
696
|
-
}),
|
|
697
|
-
);
|
|
698
|
-
}}
|
|
699
|
-
>
|
|
700
|
-
Accept Terms
|
|
701
|
-
</button>
|
|
702
|
-
<button
|
|
703
|
-
type="button"
|
|
704
|
-
onClick={() => {
|
|
705
|
-
ref.current.dispatchEvent(
|
|
706
|
-
new CustomEvent("setuistate", {
|
|
707
|
-
detail: { value: false },
|
|
708
|
-
}),
|
|
709
|
-
);
|
|
710
|
-
}}
|
|
711
|
-
>
|
|
712
|
-
Decline Terms
|
|
713
|
-
</button>
|
|
714
|
-
</div>
|
|
715
|
-
</Form>
|
|
716
|
-
<div
|
|
717
|
-
className={`result-display ${status === "loading" ? "result-loading" : status === "success" ? "result-success" : status === "error" ? "result-error" : ""}`}
|
|
718
|
-
>
|
|
719
|
-
Terms agreed: {checked ? "Yes" : "No"}
|
|
720
|
-
<br />
|
|
721
|
-
{result ||
|
|
722
|
-
"Fill out the form - frontend will simulate backend submission rejected when terms not agreed..."}
|
|
723
|
-
</div>
|
|
724
|
-
</div>
|
|
725
|
-
);
|
|
726
|
-
};
|
|
727
|
-
|
|
728
|
-
render(<App />, document.querySelector("#root"));
|
|
729
|
-
</script>
|
|
730
|
-
</body>
|
|
731
|
-
</html>
|