@jsenv/navi 0.10.1 → 0.11.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 +13858 -23295
- package/dist/jsenv_navi.js.map +1281 -0
- package/package.json +5 -7
- 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 -177
- 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,695 +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>ActionRenderer with UITransition Demo</title>
|
|
8
|
-
<style>
|
|
9
|
-
body {
|
|
10
|
-
font-family:
|
|
11
|
-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
12
|
-
max-width: 800px;
|
|
13
|
-
margin: 0 auto;
|
|
14
|
-
padding: 20px;
|
|
15
|
-
background: #f5f5f5;
|
|
16
|
-
}
|
|
17
|
-
.demo-container {
|
|
18
|
-
background: white;
|
|
19
|
-
border-radius: 8px;
|
|
20
|
-
padding: 20px;
|
|
21
|
-
margin: 20px 0;
|
|
22
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
23
|
-
}
|
|
24
|
-
.demo-title {
|
|
25
|
-
margin-top: 0;
|
|
26
|
-
color: #333;
|
|
27
|
-
border-bottom: 2px solid #007acc;
|
|
28
|
-
padding-bottom: 10px;
|
|
29
|
-
}
|
|
30
|
-
.control-panel {
|
|
31
|
-
display: flex;
|
|
32
|
-
gap: 10px;
|
|
33
|
-
margin: 20px 0;
|
|
34
|
-
flex-wrap: wrap;
|
|
35
|
-
}
|
|
36
|
-
.control-panel button {
|
|
37
|
-
padding: 8px 16px;
|
|
38
|
-
border: 1px solid #ddd;
|
|
39
|
-
border-radius: 4px;
|
|
40
|
-
background: #f8f9fa;
|
|
41
|
-
cursor: pointer;
|
|
42
|
-
transition: background-color 0.2s;
|
|
43
|
-
}
|
|
44
|
-
.control-panel button:hover {
|
|
45
|
-
background: #e9ecef;
|
|
46
|
-
}
|
|
47
|
-
.control-panel button:disabled {
|
|
48
|
-
opacity: 0.6;
|
|
49
|
-
cursor: not-allowed;
|
|
50
|
-
}
|
|
51
|
-
.content-area {
|
|
52
|
-
min-height: 100px;
|
|
53
|
-
border: 2px dashed #ddd;
|
|
54
|
-
border-radius: 4px;
|
|
55
|
-
padding: 20px;
|
|
56
|
-
margin: 20px 0;
|
|
57
|
-
}
|
|
58
|
-
.loading-spinner {
|
|
59
|
-
display: inline-block;
|
|
60
|
-
width: 20px;
|
|
61
|
-
height: 20px;
|
|
62
|
-
border: 3px solid #f3f3f3;
|
|
63
|
-
border-top: 3px solid #007acc;
|
|
64
|
-
border-radius: 50%;
|
|
65
|
-
animation: spin 1s linear infinite;
|
|
66
|
-
margin-right: 10px;
|
|
67
|
-
}
|
|
68
|
-
@keyframes spin {
|
|
69
|
-
0% {
|
|
70
|
-
transform: rotate(0deg);
|
|
71
|
-
}
|
|
72
|
-
100% {
|
|
73
|
-
transform: rotate(360deg);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
.success-content {
|
|
77
|
-
padding: 20px;
|
|
78
|
-
background: #d4edda;
|
|
79
|
-
border: 1px solid #c3e6cb;
|
|
80
|
-
border-radius: 4px;
|
|
81
|
-
color: #155724;
|
|
82
|
-
}
|
|
83
|
-
.error-content {
|
|
84
|
-
padding: 20px;
|
|
85
|
-
background: #f8d7da;
|
|
86
|
-
border: 1px solid #f5c6cb;
|
|
87
|
-
border-radius: 4px;
|
|
88
|
-
color: #721c24;
|
|
89
|
-
}
|
|
90
|
-
.info-content {
|
|
91
|
-
padding: 20px;
|
|
92
|
-
background: #d1ecf1;
|
|
93
|
-
border: 1px solid #bee5eb;
|
|
94
|
-
border-radius: 4px;
|
|
95
|
-
color: #0c5460;
|
|
96
|
-
}
|
|
97
|
-
.config-section {
|
|
98
|
-
background: #f8f9fa;
|
|
99
|
-
border: 1px solid #e9ecef;
|
|
100
|
-
border-radius: 4px;
|
|
101
|
-
padding: 15px;
|
|
102
|
-
margin: 10px 0;
|
|
103
|
-
}
|
|
104
|
-
.config-section h4 {
|
|
105
|
-
margin-top: 0;
|
|
106
|
-
color: #495057;
|
|
107
|
-
}
|
|
108
|
-
.checkbox-group {
|
|
109
|
-
display: flex;
|
|
110
|
-
gap: 20px;
|
|
111
|
-
flex-wrap: wrap;
|
|
112
|
-
}
|
|
113
|
-
.checkbox-group label {
|
|
114
|
-
display: flex;
|
|
115
|
-
align-items: center;
|
|
116
|
-
gap: 8px;
|
|
117
|
-
cursor: pointer;
|
|
118
|
-
}
|
|
119
|
-
.config-section input[type="range"]:disabled {
|
|
120
|
-
opacity: 0.5;
|
|
121
|
-
cursor: not-allowed;
|
|
122
|
-
}
|
|
123
|
-
.config-section .description {
|
|
124
|
-
margin: 8px 0 0 0;
|
|
125
|
-
font-size: 0.9em;
|
|
126
|
-
color: #666;
|
|
127
|
-
line-height: 1.4;
|
|
128
|
-
}
|
|
129
|
-
</style>
|
|
130
|
-
</head>
|
|
131
|
-
<body>
|
|
132
|
-
<h1>ActionRenderer with UITransition Demo</h1>
|
|
133
|
-
<p>
|
|
134
|
-
This demo showcases how ActionRenderer uses UITransition to smoothly
|
|
135
|
-
animate between different action states (idle, loading, completed, error)
|
|
136
|
-
with different content sizes. You can control whether size changes are
|
|
137
|
-
animated or instant, and customize the duration of all transitions.
|
|
138
|
-
</p>
|
|
139
|
-
|
|
140
|
-
<div id="root"></div>
|
|
141
|
-
|
|
142
|
-
<script type="module" jsenv-type="module/jsx">
|
|
143
|
-
import { render } from "preact";
|
|
144
|
-
import { useState } from "preact/hooks";
|
|
145
|
-
import {
|
|
146
|
-
createAction,
|
|
147
|
-
// eslint-disable-next-line no-unused-vars
|
|
148
|
-
ActionRenderer,
|
|
149
|
-
// eslint-disable-next-line no-unused-vars
|
|
150
|
-
UITransition,
|
|
151
|
-
} from "@jsenv/navi";
|
|
152
|
-
|
|
153
|
-
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
154
|
-
|
|
155
|
-
// Demo actions with different behaviors
|
|
156
|
-
const createSuccessAction = (contentKey, delayMs = 1000) =>
|
|
157
|
-
createAction(async () => {
|
|
158
|
-
await delay(delayMs);
|
|
159
|
-
return {
|
|
160
|
-
contentType: contentKey,
|
|
161
|
-
timestamp: new Date().toISOString(),
|
|
162
|
-
};
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
const createErrorAction = (delayMs = 1000) =>
|
|
166
|
-
createAction(async () => {
|
|
167
|
-
await delay(delayMs);
|
|
168
|
-
throw new Error("Something went wrong! This is a demo error.");
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
const createSlowAction = () =>
|
|
172
|
-
createAction(async () => {
|
|
173
|
-
await delay(3000);
|
|
174
|
-
return {
|
|
175
|
-
contentType: "slow",
|
|
176
|
-
message: "This took 3 seconds to load!",
|
|
177
|
-
timestamp: new Date().toISOString(),
|
|
178
|
-
};
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
const createStuckLoadingAction = () =>
|
|
182
|
-
createAction(async () => {
|
|
183
|
-
// This action never resolves, staying in loading state
|
|
184
|
-
await new Promise(() => {}); // Never resolves
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
// Content renderers for different scenarios
|
|
188
|
-
const renderSmallContent = (data) => (
|
|
189
|
-
<div
|
|
190
|
-
className="success-content"
|
|
191
|
-
data-content-key="small"
|
|
192
|
-
data-ui-name="small-content"
|
|
193
|
-
>
|
|
194
|
-
<h4>Small Content</h4>
|
|
195
|
-
<p>This is small content that loaded successfully.</p>
|
|
196
|
-
<small>Loaded at: {data.timestamp}</small>
|
|
197
|
-
</div>
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
const renderLargeContent = (data) => (
|
|
201
|
-
<div
|
|
202
|
-
className="success-content"
|
|
203
|
-
data-content-key="large"
|
|
204
|
-
data-ui-name="large-content"
|
|
205
|
-
>
|
|
206
|
-
<h4>Large Content</h4>
|
|
207
|
-
<p>
|
|
208
|
-
This is much larger content that should cause a smooth size
|
|
209
|
-
transition when it loads.
|
|
210
|
-
</p>
|
|
211
|
-
<p>
|
|
212
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
|
|
213
|
-
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
|
|
214
|
-
ad minim veniam, quis nostrud exercitation ullamco laboris.
|
|
215
|
-
</p>
|
|
216
|
-
<p>
|
|
217
|
-
Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
218
|
-
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
|
|
219
|
-
cupidatat non proident.
|
|
220
|
-
</p>
|
|
221
|
-
<div style="display: flex; gap: 10px; margin-top: 15px;">
|
|
222
|
-
<div style="flex: 1; padding: 10px; background: rgba(0,123,204,0.1); border-radius: 4px;">
|
|
223
|
-
<strong>Feature 1</strong>
|
|
224
|
-
<br />
|
|
225
|
-
Some additional content here
|
|
226
|
-
</div>
|
|
227
|
-
<div style="flex: 1; padding: 10px; background: rgba(0,123,204,0.1); border-radius: 4px;">
|
|
228
|
-
<strong>Feature 2</strong>
|
|
229
|
-
<br />
|
|
230
|
-
More content in this section
|
|
231
|
-
</div>
|
|
232
|
-
</div>
|
|
233
|
-
<small>Loaded at: {data.timestamp}</small>
|
|
234
|
-
</div>
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
const renderMediumContent = (data) => (
|
|
238
|
-
<div
|
|
239
|
-
className="success-content"
|
|
240
|
-
data-content-key="medium"
|
|
241
|
-
data-ui-name="medium-content"
|
|
242
|
-
>
|
|
243
|
-
<h4>Medium Content</h4>
|
|
244
|
-
<p>
|
|
245
|
-
This is medium-sized content that demonstrates size transitions.
|
|
246
|
-
</p>
|
|
247
|
-
<ul>
|
|
248
|
-
<li>Feature A: Working correctly</li>
|
|
249
|
-
<li>Feature B: All systems operational</li>
|
|
250
|
-
<li>Feature C: Performance optimized</li>
|
|
251
|
-
</ul>
|
|
252
|
-
<small>Loaded at: {data.timestamp}</small>
|
|
253
|
-
</div>
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
const renderSlowContent = (data) => (
|
|
257
|
-
<div
|
|
258
|
-
className="success-content"
|
|
259
|
-
data-content-key="slow"
|
|
260
|
-
data-ui-name="slow-content"
|
|
261
|
-
>
|
|
262
|
-
<h4>Slow Content</h4>
|
|
263
|
-
<p>{data.message}</p>
|
|
264
|
-
<p>
|
|
265
|
-
This content took 3 seconds to load and demonstrates phase
|
|
266
|
-
transitions from loading to content with the same content key.
|
|
267
|
-
</p>
|
|
268
|
-
<small>Loaded at: {data.timestamp}</small>
|
|
269
|
-
</div>
|
|
270
|
-
);
|
|
271
|
-
|
|
272
|
-
const renderLoadingContent = (contentKey) => (
|
|
273
|
-
<div
|
|
274
|
-
className="info-content"
|
|
275
|
-
data-content-phase
|
|
276
|
-
data-content-key={contentKey}
|
|
277
|
-
data-ui-name={`${contentKey}-loading`}
|
|
278
|
-
>
|
|
279
|
-
<div style="display: flex; align-items: center;">
|
|
280
|
-
<div className="loading-spinner"></div>
|
|
281
|
-
<span>Loading content...</span>
|
|
282
|
-
</div>
|
|
283
|
-
</div>
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
const renderErrorContent = (error, contentKey) => (
|
|
287
|
-
<div
|
|
288
|
-
className="error-content"
|
|
289
|
-
data-content-phase
|
|
290
|
-
data-content-key={contentKey}
|
|
291
|
-
data-ui-name={`${contentKey}-error`}
|
|
292
|
-
>
|
|
293
|
-
<h4>❌ Error Occurred</h4>
|
|
294
|
-
<p>{error.message}</p>
|
|
295
|
-
<small>Try again or check your connection.</small>
|
|
296
|
-
</div>
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
// eslint-disable-next-line no-unused-vars
|
|
300
|
-
const App = () => {
|
|
301
|
-
const [currentAction, setCurrentAction] = useState(null);
|
|
302
|
-
const [transitionType, setTransitionType] = useState(() => {
|
|
303
|
-
return (
|
|
304
|
-
localStorage.getItem("ui-transition-demo-type") || "cross-fade"
|
|
305
|
-
);
|
|
306
|
-
});
|
|
307
|
-
const [transitionDuration, setTransitionDuration] = useState(() => {
|
|
308
|
-
const saved = localStorage.getItem("ui-transition-demo-duration");
|
|
309
|
-
return saved ? parseInt(saved) : 300;
|
|
310
|
-
});
|
|
311
|
-
const [phaseTransitionType, setPhaseTransitionType] = useState(() => {
|
|
312
|
-
return (
|
|
313
|
-
localStorage.getItem("ui-transition-demo-phase-type") ||
|
|
314
|
-
"cross-fade"
|
|
315
|
-
);
|
|
316
|
-
});
|
|
317
|
-
const [phaseTransitionDuration, setPhaseTransitionDuration] = useState(
|
|
318
|
-
() => {
|
|
319
|
-
const saved = localStorage.getItem(
|
|
320
|
-
"ui-transition-demo-phase-duration",
|
|
321
|
-
);
|
|
322
|
-
return saved ? parseInt(saved) : 300;
|
|
323
|
-
},
|
|
324
|
-
);
|
|
325
|
-
const [sizeTransition, setSizeTransition] = useState(() => {
|
|
326
|
-
const saved = localStorage.getItem("ui-transition-demo-size-enabled");
|
|
327
|
-
return saved ? saved === "true" : true; // Default to enabled
|
|
328
|
-
});
|
|
329
|
-
const [sizeTransitionDuration, setSizeTransitionDuration] = useState(
|
|
330
|
-
() => {
|
|
331
|
-
const saved = localStorage.getItem(
|
|
332
|
-
"ui-transition-demo-size-duration",
|
|
333
|
-
);
|
|
334
|
-
return saved ? parseInt(saved) : 300;
|
|
335
|
-
},
|
|
336
|
-
);
|
|
337
|
-
|
|
338
|
-
// Create actions with content key metadata
|
|
339
|
-
const smallAction = createSuccessAction("small", 800);
|
|
340
|
-
smallAction.meta = { contentKey: "small" };
|
|
341
|
-
|
|
342
|
-
const mediumAction = createSuccessAction("medium", 1200);
|
|
343
|
-
mediumAction.meta = { contentKey: "medium" };
|
|
344
|
-
|
|
345
|
-
const largeAction = createSuccessAction("large", 1000);
|
|
346
|
-
largeAction.meta = { contentKey: "large" };
|
|
347
|
-
|
|
348
|
-
const errorAction = createErrorAction(500);
|
|
349
|
-
errorAction.meta = { contentKey: "error" };
|
|
350
|
-
|
|
351
|
-
const slowAction = createSlowAction();
|
|
352
|
-
slowAction.meta = { contentKey: "slow" };
|
|
353
|
-
|
|
354
|
-
const stuckLoadingAction = createStuckLoadingAction();
|
|
355
|
-
stuckLoadingAction.meta = { contentKey: "stuck-loading" };
|
|
356
|
-
|
|
357
|
-
// Helper to get content key for an action
|
|
358
|
-
const getContentKeyForAction = (action) => {
|
|
359
|
-
if (!action) return "loading";
|
|
360
|
-
|
|
361
|
-
// Use the contentKey property we set on action.meta
|
|
362
|
-
return action.meta?.contentKey || "loading";
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
const triggerAction = (action) => {
|
|
366
|
-
setCurrentAction(() => action);
|
|
367
|
-
// Clear any previous state and trigger fresh load
|
|
368
|
-
action.rerun();
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
const handleTransitionTypeChange = (newType) => {
|
|
372
|
-
setTransitionType(newType);
|
|
373
|
-
localStorage.setItem("ui-transition-demo-type", newType);
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
const handleTransitionDurationChange = (newDuration) => {
|
|
377
|
-
setTransitionDuration(newDuration);
|
|
378
|
-
localStorage.setItem(
|
|
379
|
-
"ui-transition-demo-duration",
|
|
380
|
-
newDuration.toString(),
|
|
381
|
-
);
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
const handlePhaseTransitionTypeChange = (newType) => {
|
|
385
|
-
setPhaseTransitionType(newType);
|
|
386
|
-
localStorage.setItem("ui-transition-demo-phase-type", newType);
|
|
387
|
-
};
|
|
388
|
-
|
|
389
|
-
const handlePhaseTransitionDurationChange = (newDuration) => {
|
|
390
|
-
setPhaseTransitionDuration(newDuration);
|
|
391
|
-
localStorage.setItem(
|
|
392
|
-
"ui-transition-demo-phase-duration",
|
|
393
|
-
newDuration.toString(),
|
|
394
|
-
);
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
const handleSizeTransitionChange = (enabled) => {
|
|
398
|
-
setSizeTransition(enabled);
|
|
399
|
-
localStorage.setItem(
|
|
400
|
-
"ui-transition-demo-size-enabled",
|
|
401
|
-
enabled.toString(),
|
|
402
|
-
);
|
|
403
|
-
};
|
|
404
|
-
|
|
405
|
-
const handleSizeTransitionDurationChange = (newDuration) => {
|
|
406
|
-
setSizeTransitionDuration(newDuration);
|
|
407
|
-
localStorage.setItem(
|
|
408
|
-
"ui-transition-demo-size-duration",
|
|
409
|
-
newDuration.toString(),
|
|
410
|
-
);
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
return (
|
|
414
|
-
<div>
|
|
415
|
-
<div className="demo-container">
|
|
416
|
-
<h2 className="demo-title">🎭 Basic Action State Transitions</h2>
|
|
417
|
-
<p>
|
|
418
|
-
Click buttons to trigger different actions and watch smooth
|
|
419
|
-
transitions between loading, success, and error states.
|
|
420
|
-
</p>
|
|
421
|
-
|
|
422
|
-
<div className="control-panel">
|
|
423
|
-
<button onClick={() => triggerAction(smallAction)}>
|
|
424
|
-
Load Small Content
|
|
425
|
-
</button>
|
|
426
|
-
<button onClick={() => triggerAction(mediumAction)}>
|
|
427
|
-
Load Medium Content
|
|
428
|
-
</button>
|
|
429
|
-
<button onClick={() => triggerAction(largeAction)}>
|
|
430
|
-
Load Large Content
|
|
431
|
-
</button>
|
|
432
|
-
<button onClick={() => triggerAction(errorAction)}>
|
|
433
|
-
Trigger Error
|
|
434
|
-
</button>
|
|
435
|
-
<button onClick={() => triggerAction(slowAction)}>
|
|
436
|
-
Slow Loading (3s)
|
|
437
|
-
</button>
|
|
438
|
-
<button onClick={() => triggerAction(stuckLoadingAction)}>
|
|
439
|
-
Stay Loading
|
|
440
|
-
</button>
|
|
441
|
-
<button onClick={() => setCurrentAction(null)}>
|
|
442
|
-
Clear Content
|
|
443
|
-
</button>
|
|
444
|
-
</div>
|
|
445
|
-
|
|
446
|
-
<div className="content-area">
|
|
447
|
-
<UITransition
|
|
448
|
-
sizeTransition={sizeTransition}
|
|
449
|
-
sizeTransitionDuration={sizeTransitionDuration}
|
|
450
|
-
transitionType={transitionType}
|
|
451
|
-
transitionDuration={transitionDuration}
|
|
452
|
-
phaseTransitionType={phaseTransitionType}
|
|
453
|
-
phaseTransitionDuration={phaseTransitionDuration}
|
|
454
|
-
>
|
|
455
|
-
<ActionRenderer action={currentAction}>
|
|
456
|
-
{{
|
|
457
|
-
loading: () => {
|
|
458
|
-
// Use the content key of what we're loading
|
|
459
|
-
const contentKey =
|
|
460
|
-
getContentKeyForAction(currentAction);
|
|
461
|
-
return renderLoadingContent(contentKey);
|
|
462
|
-
},
|
|
463
|
-
error: (error) => {
|
|
464
|
-
const contentKey =
|
|
465
|
-
getContentKeyForAction(currentAction);
|
|
466
|
-
return renderErrorContent(error, contentKey);
|
|
467
|
-
},
|
|
468
|
-
completed: (data) => {
|
|
469
|
-
if (!data) return null;
|
|
470
|
-
switch (data.contentType) {
|
|
471
|
-
case "small":
|
|
472
|
-
return renderSmallContent(data);
|
|
473
|
-
case "medium":
|
|
474
|
-
return renderMediumContent(data);
|
|
475
|
-
case "large":
|
|
476
|
-
return renderLargeContent(data);
|
|
477
|
-
case "slow":
|
|
478
|
-
return renderSlowContent(data);
|
|
479
|
-
default:
|
|
480
|
-
return renderSmallContent(data);
|
|
481
|
-
}
|
|
482
|
-
},
|
|
483
|
-
}}
|
|
484
|
-
</ActionRenderer>
|
|
485
|
-
</UITransition>
|
|
486
|
-
</div>
|
|
487
|
-
</div>
|
|
488
|
-
|
|
489
|
-
<div className="demo-container">
|
|
490
|
-
<h2 className="demo-title">⚙️ Transition Configuration</h2>
|
|
491
|
-
|
|
492
|
-
<div className="config-section">
|
|
493
|
-
<h4>Content Transition Type</h4>
|
|
494
|
-
<div className="checkbox-group">
|
|
495
|
-
<label>
|
|
496
|
-
<input
|
|
497
|
-
type="radio"
|
|
498
|
-
name="transition-type"
|
|
499
|
-
value="cross-fade"
|
|
500
|
-
checked={transitionType === "cross-fade"}
|
|
501
|
-
onChange={(e) =>
|
|
502
|
-
handleTransitionTypeChange(e.target.value)
|
|
503
|
-
}
|
|
504
|
-
/>
|
|
505
|
-
Cross Fade
|
|
506
|
-
</label>
|
|
507
|
-
<label>
|
|
508
|
-
<input
|
|
509
|
-
type="radio"
|
|
510
|
-
name="transition-type"
|
|
511
|
-
value="slide-left"
|
|
512
|
-
checked={transitionType === "slide-left"}
|
|
513
|
-
onChange={(e) =>
|
|
514
|
-
handleTransitionTypeChange(e.target.value)
|
|
515
|
-
}
|
|
516
|
-
/>
|
|
517
|
-
Slide Left
|
|
518
|
-
</label>
|
|
519
|
-
</div>
|
|
520
|
-
</div>
|
|
521
|
-
|
|
522
|
-
<div className="config-section">
|
|
523
|
-
<h4>Phase Transition Type</h4>
|
|
524
|
-
<div className="checkbox-group">
|
|
525
|
-
<label>
|
|
526
|
-
<input
|
|
527
|
-
type="radio"
|
|
528
|
-
name="phase-transition-type"
|
|
529
|
-
value="cross-fade"
|
|
530
|
-
checked={phaseTransitionType === "cross-fade"}
|
|
531
|
-
onChange={(e) =>
|
|
532
|
-
handlePhaseTransitionTypeChange(e.target.value)
|
|
533
|
-
}
|
|
534
|
-
/>
|
|
535
|
-
Cross Fade
|
|
536
|
-
</label>
|
|
537
|
-
<label>
|
|
538
|
-
<input
|
|
539
|
-
type="radio"
|
|
540
|
-
name="phase-transition-type"
|
|
541
|
-
value="slide-left"
|
|
542
|
-
checked={phaseTransitionType === "slide-left"}
|
|
543
|
-
onChange={(e) =>
|
|
544
|
-
handlePhaseTransitionTypeChange(e.target.value)
|
|
545
|
-
}
|
|
546
|
-
/>
|
|
547
|
-
Slide Left
|
|
548
|
-
</label>
|
|
549
|
-
</div>
|
|
550
|
-
<p className="description">
|
|
551
|
-
<strong>Content Transitions:</strong> Between different
|
|
552
|
-
content keys (small → medium → large)
|
|
553
|
-
<br />
|
|
554
|
-
<strong>Phase Transitions:</strong> Between loading/content
|
|
555
|
-
states (loading → content) for same key
|
|
556
|
-
</p>
|
|
557
|
-
</div>
|
|
558
|
-
|
|
559
|
-
<div className="config-section">
|
|
560
|
-
<h4>Content Transition Duration</h4>
|
|
561
|
-
<label style="display: flex; align-items: center; gap: 10px;">
|
|
562
|
-
<span>Duration: {transitionDuration}ms</span>
|
|
563
|
-
<input
|
|
564
|
-
type="range"
|
|
565
|
-
min="100"
|
|
566
|
-
max="1000"
|
|
567
|
-
step="50"
|
|
568
|
-
value={transitionDuration}
|
|
569
|
-
onChange={(e) =>
|
|
570
|
-
handleTransitionDurationChange(parseInt(e.target.value))
|
|
571
|
-
}
|
|
572
|
-
style="flex: 1;"
|
|
573
|
-
/>
|
|
574
|
-
</label>
|
|
575
|
-
</div>
|
|
576
|
-
|
|
577
|
-
<div className="config-section">
|
|
578
|
-
<h4>Phase Transition Duration</h4>
|
|
579
|
-
<label style="display: flex; align-items: center; gap: 10px;">
|
|
580
|
-
<span>Duration: {phaseTransitionDuration}ms</span>
|
|
581
|
-
<input
|
|
582
|
-
type="range"
|
|
583
|
-
min="100"
|
|
584
|
-
max="1000"
|
|
585
|
-
step="50"
|
|
586
|
-
value={phaseTransitionDuration}
|
|
587
|
-
onChange={(e) =>
|
|
588
|
-
handlePhaseTransitionDurationChange(
|
|
589
|
-
parseInt(e.target.value),
|
|
590
|
-
)
|
|
591
|
-
}
|
|
592
|
-
style="flex: 1;"
|
|
593
|
-
/>
|
|
594
|
-
</label>
|
|
595
|
-
</div>
|
|
596
|
-
|
|
597
|
-
<div className="config-section">
|
|
598
|
-
<h4>Size Transition</h4>
|
|
599
|
-
<div className="checkbox-group">
|
|
600
|
-
<label>
|
|
601
|
-
<input
|
|
602
|
-
type="checkbox"
|
|
603
|
-
checked={sizeTransition}
|
|
604
|
-
onChange={(e) =>
|
|
605
|
-
handleSizeTransitionChange(e.target.checked)
|
|
606
|
-
}
|
|
607
|
-
/>
|
|
608
|
-
Enable Size Transitions
|
|
609
|
-
</label>
|
|
610
|
-
</div>
|
|
611
|
-
<p className="description">
|
|
612
|
-
When enabled, the container smoothly animates to accommodate
|
|
613
|
-
different content sizes. When disabled, size changes are
|
|
614
|
-
instant.
|
|
615
|
-
</p>
|
|
616
|
-
</div>
|
|
617
|
-
|
|
618
|
-
<div className="config-section">
|
|
619
|
-
<h4>Size Transition Duration</h4>
|
|
620
|
-
<label style="display: flex; align-items: center; gap: 10px;">
|
|
621
|
-
<span>Duration: {sizeTransitionDuration}ms</span>
|
|
622
|
-
<input
|
|
623
|
-
type="range"
|
|
624
|
-
min="100"
|
|
625
|
-
max="1000"
|
|
626
|
-
step="50"
|
|
627
|
-
value={sizeTransitionDuration}
|
|
628
|
-
onChange={(e) =>
|
|
629
|
-
handleSizeTransitionDurationChange(
|
|
630
|
-
parseInt(e.target.value),
|
|
631
|
-
)
|
|
632
|
-
}
|
|
633
|
-
style="flex: 1;"
|
|
634
|
-
disabled={!sizeTransition}
|
|
635
|
-
/>
|
|
636
|
-
</label>
|
|
637
|
-
<p className="description">
|
|
638
|
-
Controls how fast the container animates when content size
|
|
639
|
-
changes. Only applies when size transitions are enabled.
|
|
640
|
-
</p>
|
|
641
|
-
</div>
|
|
642
|
-
</div>
|
|
643
|
-
|
|
644
|
-
<div className="demo-container">
|
|
645
|
-
<h2 className="demo-title">📝 What's Happening</h2>
|
|
646
|
-
<ul>
|
|
647
|
-
<li>
|
|
648
|
-
<strong>UITransition Integration:</strong> ActionRenderer
|
|
649
|
-
wraps all content in UITransition for smooth state changes
|
|
650
|
-
</li>
|
|
651
|
-
<li>
|
|
652
|
-
<strong>Size Adaptation:</strong> Container can smoothly
|
|
653
|
-
animate to accommodate different content sizes (when enabled)
|
|
654
|
-
</li>
|
|
655
|
-
<li>
|
|
656
|
-
<strong>Optional Size Transitions:</strong> Toggle between
|
|
657
|
-
instant and animated size changes using the "Enable Size
|
|
658
|
-
Transitions" checkbox
|
|
659
|
-
</li>
|
|
660
|
-
<li>
|
|
661
|
-
<strong>Content Phases:</strong> Loading and error states are
|
|
662
|
-
marked with <code>data-content-phase</code>
|
|
663
|
-
</li>
|
|
664
|
-
<li>
|
|
665
|
-
<strong>Content Keys:</strong> Each content type has a unique{" "}
|
|
666
|
-
<code>data-content-key</code> for transition tracking
|
|
667
|
-
</li>
|
|
668
|
-
<li>
|
|
669
|
-
<strong>Stay Loading:</strong> The "Stay Loading" button
|
|
670
|
-
demonstrates persistent loading states that never complete
|
|
671
|
-
</li>
|
|
672
|
-
</ul>
|
|
673
|
-
</div>
|
|
674
|
-
|
|
675
|
-
<div className="demo-container">
|
|
676
|
-
<h2 className="demo-title">🔧 Developer Tools</h2>
|
|
677
|
-
<p>
|
|
678
|
-
Open browser dev tools and watch the console for debug logs
|
|
679
|
-
showing:
|
|
680
|
-
</p>
|
|
681
|
-
<ul>
|
|
682
|
-
<li>Size measurements and transitions</li>
|
|
683
|
-
<li>Content key changes and transition scenarios</li>
|
|
684
|
-
<li>Resize observer events</li>
|
|
685
|
-
<li>Animation progress and completion</li>
|
|
686
|
-
</ul>
|
|
687
|
-
</div>
|
|
688
|
-
</div>
|
|
689
|
-
);
|
|
690
|
-
};
|
|
691
|
-
|
|
692
|
-
render(<App />, document.querySelector("#root"));
|
|
693
|
-
</script>
|
|
694
|
-
</body>
|
|
695
|
-
</html>
|