@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,118 @@
1
+ import.meta.css = /* css */ `
2
+ [data-field],
3
+ [data-field-wrapper] {
4
+ --field-border-width: 1px;
5
+ --field-outline-width: 1px;
6
+
7
+ --field-strong-color: light-dark(#355fcc, #3b82f6);
8
+ --field-outline-color: var(--field-strong-color);
9
+ --field-background-color: light-dark(#f3f4f6, #2d3748);
10
+ --field-border-color: light-dark(#767676, #8e8e93);
11
+
12
+ --field-disabled-border-color: color-mix(
13
+ in srgb,
14
+ var(--field-border-color) 30%,
15
+ white
16
+ );
17
+ --field-readonly-border-color: var(--field-disabled-border-color);
18
+ --field-active-border-color: color-mix(
19
+ in srgb,
20
+ var(--field-border-color) 90%,
21
+ black
22
+ );
23
+ --field-hover-border-color: color-mix(
24
+ in srgb,
25
+ var(--field-border-color) 70%,
26
+ black
27
+ );
28
+
29
+ --field-disabled-background-color: var(--field-background-color);
30
+ --field-readonly-background-color: var(--field-disabled-background-color);
31
+ --field-hover-background-color: color-mix(
32
+ in srgb,
33
+ var(--field-background-color) 95%,
34
+ black
35
+ );
36
+
37
+ --field-disabled-text-color: color-mix(
38
+ in srgb,
39
+ currentColor 30%,
40
+ transparent
41
+ );
42
+ --field-readonly-text-color: var(--field-disabled-text-color);
43
+ }
44
+
45
+ [data-field] {
46
+ border-radius: 2px;
47
+ outline-width: var(--field-border-width);
48
+ outline-style: solid;
49
+ outline-color: transparent;
50
+ outline-offset: calc(-1 * (var(--field-border-width)));
51
+ }
52
+
53
+ [data-field][data-field-with-border] {
54
+ border-width: calc(var(--field-border-width) + var(--field-outline-width));
55
+ border-style: solid;
56
+ border-color: transparent;
57
+ outline-color: var(--field-border-color);
58
+ }
59
+
60
+ [data-field-with-border-hover] {
61
+ border: 0;
62
+ }
63
+
64
+ [data-field-with-background] {
65
+ background-color: var(--field-background-color);
66
+ }
67
+ [data-field-with-background-hover] {
68
+ background: none;
69
+ }
70
+
71
+ [data-field-with-background]:hover {
72
+ background-color: var(--field-hover-background-color);
73
+ }
74
+
75
+ [data-field-with-hover]:hover {
76
+ outline-color: var(--field-hover-border-color);
77
+ }
78
+
79
+ [data-field-with-border]:active,
80
+ [data-field][data-field-with-border][data-active] {
81
+ outline-color: var(--field-active-border-color);
82
+ background-color: none;
83
+ }
84
+
85
+ [data-field-with-border][readonly],
86
+ [data-field-with-border][data-readonly] {
87
+ outline-color: var(--field-readonly-border-color);
88
+ }
89
+
90
+ [data-field][readonly],
91
+ [data-field][data-readonly] {
92
+ color: var(--field-readonly-text-color);
93
+ }
94
+
95
+ [data-field-with-background][readonly],
96
+ [data-field-with-background][data-readonly] {
97
+ background-color: var(--field-readonly-background-color);
98
+ }
99
+
100
+ [data-field]:focus-visible,
101
+ [data-field][data-focus-visible]:focus {
102
+ outline-style: solid;
103
+ outline-width: calc(var(--field-border-width) + var(--field-outline-width));
104
+ outline-offset: calc(
105
+ -1 * (var(--field-border-width) + var(--field-outline-width))
106
+ );
107
+ outline-color: var(--field-outline-color);
108
+ }
109
+
110
+ [data-field]:disabled,
111
+ [data-field][data-disabled],
112
+ [data-field-with-hover]:disabled:hover,
113
+ [data-field-with-hover][data-disabled]:hover {
114
+ outline-color: var(--field-disabled-border-color);
115
+ background-color: var(--field-disabled-background-color);
116
+ color: var(--field-disabled-text-color);
117
+ }
118
+ `;
@@ -0,0 +1,15 @@
1
+ import { forwardRef } from "preact/compat";
2
+ import { InputCheckbox } from "./input_checkbox.jsx";
3
+ import { InputRadio } from "./input_radio.jsx";
4
+ import { InputTextual } from "./input_textual.jsx";
5
+
6
+ export const Input = forwardRef((props, ref) => {
7
+ const { type } = props;
8
+ if (type === "radio") {
9
+ return <InputRadio {...props} ref={ref} />;
10
+ }
11
+ if (type === "checkbox") {
12
+ return <InputCheckbox {...props} ref={ref} />;
13
+ }
14
+ return <InputTextual {...props} ref={ref} />;
15
+ });
@@ -0,0 +1,370 @@
1
+ import { requestAction, useConstraints } from "@jsenv/validation";
2
+ import { forwardRef } from "preact/compat";
3
+ import { useEffect, useImperativeHandle, useRef, useState } from "preact/hooks";
4
+ import { useNavState } from "../../browser_integration/browser_integration.js";
5
+ import { useActionStatus } from "../../use_action_status.js";
6
+ import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
7
+ import {
8
+ useActionBoundToOneParam,
9
+ useOneFormParam,
10
+ } from "../action_execution/use_action.js";
11
+ import { useExecuteAction } from "../action_execution/use_execute_action.js";
12
+ import { LoaderBackground } from "../loader/loader_background.jsx";
13
+ import { useActionEvents } from "../use_action_events.js";
14
+ import { useAutoFocus } from "../use_auto_focus.js";
15
+ import { useFormEvents } from "./use_form_event.js";
16
+
17
+ import.meta.css = /* css */ `
18
+ .custom_checkbox_wrapper {
19
+ display: inline-flex;
20
+ box-sizing: content-box;
21
+
22
+ --checkmark-color: white;
23
+ --checkmark-disabled-color: #eeeeee;
24
+ --checked-color: #3b82f6;
25
+ --checked-disabled-color: #d3d3d3;
26
+ }
27
+
28
+ .custom_checkbox_wrapper input {
29
+ position: absolute;
30
+ opacity: 0;
31
+ inset: 0;
32
+ margin: 0;
33
+ padding: 0;
34
+ border: none;
35
+ }
36
+
37
+ .custom_checkbox {
38
+ width: 13px;
39
+ height: 13px;
40
+ border: 1px solid var(--field-border-color);
41
+ border-radius: 2px;
42
+ box-sizing: border-box;
43
+ display: inline-flex;
44
+ margin: 3px 3px 3px 4px;
45
+ }
46
+ .custom_checkbox svg {
47
+ width: 100%;
48
+ height: 100%;
49
+ opacity: 0;
50
+ transform: scale(0.5);
51
+ transition: all 0.15s ease;
52
+ pointer-events: none;
53
+ }
54
+ .custom_checkbox svg path {
55
+ stroke: var(--checkmark-color);
56
+ }
57
+
58
+ .custom_checkbox_wrapper:hover .custom_checkbox {
59
+ border-color: var(--field-hover-border-color);
60
+ }
61
+ .custom_checkbox_wrapper:hover input:checked + .custom_checkbox {
62
+ background: var(--field-strong-color);
63
+ border-color: var(--field-strong-color);
64
+ }
65
+ .custom_checkbox_wrapper input:checked + .custom_checkbox {
66
+ background: var(--checked-color);
67
+ border-color: var(--checked-color);
68
+ }
69
+ .custom_checkbox_wrapper input:checked + .custom_checkbox svg {
70
+ opacity: 1;
71
+ transform: scale(1);
72
+ }
73
+
74
+ .custom_checkbox_wrapper input[data-readonly] + .custom_checkbox {
75
+ background-color: var(--field-disabled-background-color);
76
+ border-color: var(--field-disabled-border-color);
77
+ }
78
+ .custom_checkbox_wrapper input[data-readonly]:checked + .custom_checkbox {
79
+ background: var(--checked-disabled-color);
80
+ border-color: var(--checked-disabled-color);
81
+ }
82
+ .custom_checkbox_wrapper:hover input[data-readonly] + .custom_checkbox {
83
+ background-color: var(--field-disabled-background-color);
84
+ border-color: var(--field-disabled-border-color);
85
+ }
86
+ .custom_checkbox_wrapper:hover
87
+ input[data-readonly]:checked
88
+ + .custom_checkbox {
89
+ background: var(--checked-disabled-color);
90
+ border-color: var(--checked-disabled-color);
91
+ }
92
+ .custom_checkbox_wrapper
93
+ input[data-readonly]:checked
94
+ + .custom_checkbox
95
+ .custom_checkbox_marker {
96
+ stroke: var(--checkmark-disabled-color);
97
+ }
98
+
99
+ .custom_checkbox_wrapper input:focus-visible + .custom_checkbox {
100
+ outline: 2px solid var(--field-outline-color);
101
+ outline-offset: 1px;
102
+ }
103
+
104
+ .custom_checkbox_wrapper input[disabled] + .custom_checkbox {
105
+ background-color: var(--field-disabled-background-color);
106
+ border-color: var(--field-disabled-border-color);
107
+ }
108
+ .custom_checkbox_wrapper input[disabled]:checked + .custom_checkbox {
109
+ background: var(--checked-disabled-color);
110
+ border-color: var(--checked-disabled-color);
111
+ }
112
+ .custom_checkbox_wrapper
113
+ input[disabled]:checked
114
+ + .custom_checkbox
115
+ .custom_checkbox_marker {
116
+ stroke: var(--checkmark-disabled-color);
117
+ }
118
+ `;
119
+
120
+ export const InputCheckbox = forwardRef((props, ref) => {
121
+ return renderActionableComponent(props, ref, {
122
+ Basic: InputCheckboxBasic,
123
+ WithAction: InputCheckboxWithAction,
124
+ InsideForm: InputCheckboxInsideForm,
125
+ });
126
+ });
127
+
128
+ const InputCheckboxBasic = forwardRef((props, ref) => {
129
+ const {
130
+ autoFocus,
131
+ constraints = [],
132
+ value = "on",
133
+ checked,
134
+ loading,
135
+ readOnly,
136
+ disabled,
137
+ onClick,
138
+ onChange,
139
+ appeareance = "custom", // "custom" or "default"
140
+ ...rest
141
+ } = props;
142
+
143
+ const innerRef = useRef();
144
+ useImperativeHandle(ref, () => innerRef.current);
145
+ useAutoFocus(innerRef, autoFocus);
146
+ useConstraints(innerRef, constraints);
147
+
148
+ const [innerChecked, setInnerChecked] = useState(checked);
149
+ const checkedRef = useRef(checked);
150
+ if (checkedRef.current !== checked) {
151
+ setInnerChecked(checked);
152
+ checkedRef.current = checked;
153
+ }
154
+
155
+ const handleChange = (e) => {
156
+ const isChecked = e.target.checked;
157
+ setInnerChecked(isChecked);
158
+ onChange?.(e);
159
+ };
160
+
161
+ const inputCheckbox = (
162
+ <input
163
+ ref={innerRef}
164
+ type="checkbox"
165
+ value={value}
166
+ checked={innerChecked}
167
+ data-readonly={readOnly && !disabled ? "" : undefined}
168
+ data-validation-message-arrow-x="center"
169
+ disabled={disabled}
170
+ onClick={(e) => {
171
+ if (readOnly) {
172
+ e.preventDefault();
173
+ }
174
+ onClick?.(e);
175
+ }}
176
+ onChange={handleChange}
177
+ {...rest}
178
+ />
179
+ );
180
+
181
+ const inputCheckboxDisplayed =
182
+ appeareance === "custom" ? (
183
+ <CustomCheckbox>{inputCheckbox}</CustomCheckbox>
184
+ ) : (
185
+ inputCheckbox
186
+ );
187
+
188
+ const inputCheckboxWithLoader = (
189
+ <LoaderBackground
190
+ loading={loading}
191
+ inset={-1}
192
+ targetSelector={appeareance === "custom" ? ".custom_checkbox" : ""}
193
+ color="light-dark(#355fcc, #3b82f6)"
194
+ >
195
+ {inputCheckboxDisplayed}
196
+ </LoaderBackground>
197
+ );
198
+
199
+ return inputCheckboxWithLoader;
200
+ });
201
+ const CustomCheckbox = ({ children }) => {
202
+ return (
203
+ <div className="custom_checkbox_wrapper" data-field-wrapper="">
204
+ {children}
205
+ <div className="custom_checkbox">
206
+ <svg viewBox="0 0 12 12" aria-hidden="true">
207
+ <path
208
+ className="custom_checkbox_marker"
209
+ d="M10.5 2L4.5 9L1.5 5.5"
210
+ fill="none"
211
+ strokeWidth="2"
212
+ />
213
+ </svg>
214
+ </div>
215
+ </div>
216
+ );
217
+ };
218
+
219
+ const InputCheckboxWithAction = forwardRef((props, ref) => {
220
+ const {
221
+ id,
222
+ name,
223
+ value = "on",
224
+ checked: checkedExternal,
225
+ valueSignal,
226
+ action,
227
+ readOnly,
228
+ loading,
229
+ onCancel,
230
+ onChange,
231
+ actionErrorEffect,
232
+ onActionPrevented,
233
+ onActionStart,
234
+ onActionAbort,
235
+ onActionError,
236
+ onActionEnd,
237
+ ...rest
238
+ } = props;
239
+ if (import.meta.dev && !name && !valueSignal) {
240
+ console.warn(`InputCheckboxWithAction requires a name prop to be set.`);
241
+ }
242
+
243
+ const innerRef = useRef(null);
244
+ useImperativeHandle(ref, () => innerRef.current);
245
+
246
+ const [navState, setNavState] = useNavState(id);
247
+ const [boundAction, checkedValue, setCheckedValue, resetCheckedValue] =
248
+ useActionBoundToOneParam(
249
+ action,
250
+ name,
251
+ valueSignal ? valueSignal : checkedExternal ? value : undefined,
252
+ navState ? value : undefined,
253
+ );
254
+ const checked = checkedValue === value;
255
+ useEffect(() => {
256
+ if (checkedExternal) {
257
+ setNavState(checked ? false : undefined);
258
+ } else {
259
+ setNavState(checked ? true : undefined);
260
+ }
261
+ }, [checkedExternal, checked]);
262
+ const { loading: actionLoading } = useActionStatus(boundAction);
263
+ const executeAction = useExecuteAction(innerRef, {
264
+ errorEffect: actionErrorEffect,
265
+ });
266
+ const innerLoading = loading || actionLoading;
267
+
268
+ useActionEvents(innerRef, {
269
+ onCancel: (e, reason) => {
270
+ if (reason === "blur_invalid") {
271
+ return;
272
+ }
273
+ setNavState(undefined);
274
+ resetCheckedValue();
275
+ onCancel?.(e, reason);
276
+ },
277
+ onPrevented: onActionPrevented,
278
+ onAction: executeAction,
279
+ onStart: onActionStart,
280
+ onAbort: (e) => {
281
+ resetCheckedValue();
282
+ onActionAbort?.(e);
283
+ },
284
+ onError: (e) => {
285
+ resetCheckedValue();
286
+ onActionError?.(e);
287
+ },
288
+ onEnd: (e) => {
289
+ setNavState(undefined);
290
+ onActionEnd?.(e);
291
+ },
292
+ });
293
+
294
+ return (
295
+ <InputCheckboxBasic
296
+ {...rest}
297
+ ref={innerRef}
298
+ id={id}
299
+ name={name}
300
+ value={value}
301
+ checked={checked}
302
+ data-action={boundAction}
303
+ loading={innerLoading}
304
+ readOnly={readOnly || innerLoading}
305
+ onChange={(e) => {
306
+ const checkboxIsChecked = e.target.checked;
307
+ setCheckedValue(checkboxIsChecked ? value : undefined);
308
+ requestAction(boundAction, { event: e });
309
+ onChange?.(e);
310
+ }}
311
+ />
312
+ );
313
+ });
314
+
315
+ const InputCheckboxInsideForm = forwardRef((props, ref) => {
316
+ const {
317
+ formContext,
318
+ id,
319
+ name,
320
+ value = "on",
321
+ checked: checkedExternal,
322
+ readOnly,
323
+ onChange,
324
+ ...rest
325
+ } = props;
326
+ const { formIsReadOnly } = formContext;
327
+
328
+ const innerRef = useRef(null);
329
+ useImperativeHandle(ref, () => innerRef.current);
330
+
331
+ const [navState, setNavState] = useNavState(id);
332
+ const [checkedValue, setCheckedValue, resetCheckedValue] = useOneFormParam(
333
+ name,
334
+ checkedExternal ? value : undefined,
335
+ navState ? value : undefined,
336
+ );
337
+ const checked = checkedValue === value;
338
+ useEffect(() => {
339
+ if (checkedExternal) {
340
+ setNavState(checked ? false : undefined);
341
+ } else {
342
+ setNavState(checked ? true : undefined);
343
+ }
344
+ }, [checkedExternal, checked]);
345
+
346
+ useFormEvents(innerRef, {
347
+ onFormActionAbort: () => {
348
+ resetCheckedValue();
349
+ },
350
+ onFormActionError: () => {
351
+ resetCheckedValue();
352
+ },
353
+ });
354
+
355
+ return (
356
+ <InputCheckboxBasic
357
+ {...rest}
358
+ ref={innerRef}
359
+ id={id}
360
+ name={name}
361
+ checked={checked}
362
+ readOnly={readOnly || formIsReadOnly}
363
+ onChange={(e) => {
364
+ const checkboxIsChecked = e.target.checked;
365
+ setCheckedValue(checkboxIsChecked ? value : undefined);
366
+ onChange?.(e);
367
+ }}
368
+ />
369
+ );
370
+ });