@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,249 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layout Style Hook
|
|
3
|
-
*
|
|
4
|
-
* This hook processes layout-related props and converts them into CSS styles.
|
|
5
|
-
* It handles spacing (margin/padding), alignment (alignX/alignY), and expansion behavior.
|
|
6
|
-
* The hook is context-aware and adapts behavior based on flex direction.
|
|
7
|
-
*
|
|
8
|
-
* Key features:
|
|
9
|
-
* - Spacing: margin/padding with X/Y shortcuts and directional variants
|
|
10
|
-
* - Alignment: alignX/alignY using align-self and auto margins
|
|
11
|
-
* - Expansion: expand prop for taking remaining space (flexGrow or width: 100%)
|
|
12
|
-
* - Context-aware: behavior changes based on FlexDirectionContext (row/column/none)
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { useContext } from "preact/hooks";
|
|
16
|
-
|
|
17
|
-
import { FlexDirectionContext } from "./layout_context.jsx";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Converts layout props into CSS styles
|
|
21
|
-
* @param {Object} props - Component props containing layout properties
|
|
22
|
-
* @param {string|number} [props.margin] - All-sides margin
|
|
23
|
-
* @param {string|number} [props.marginX] - Horizontal margin (left + right)
|
|
24
|
-
* @param {string|number} [props.marginY] - Vertical margin (top + bottom)
|
|
25
|
-
* @param {string|number} [props.marginLeft] - Left margin
|
|
26
|
-
* @param {string|number} [props.marginRight] - Right margin
|
|
27
|
-
* @param {string|number} [props.marginTop] - Top margin
|
|
28
|
-
* @param {string|number} [props.marginBottom] - Bottom margin
|
|
29
|
-
* @param {string|number} [props.padding] - All-sides padding
|
|
30
|
-
* @param {string|number} [props.paddingX] - Horizontal padding (left + right)
|
|
31
|
-
* @param {string|number} [props.paddingY] - Vertical padding (top + bottom)
|
|
32
|
-
* @param {string|number} [props.paddingLeft] - Left padding
|
|
33
|
-
* @param {string|number} [props.paddingRight] - Right padding
|
|
34
|
-
* @param {string|number} [props.paddingTop] - Top padding
|
|
35
|
-
* @param {string|number} [props.paddingBottom] - Bottom padding
|
|
36
|
-
* @param {"start"|"center"|"end"|"stretch"} [props.alignX] - Horizontal alignment
|
|
37
|
-
* @param {"start"|"center"|"end"|"stretch"} [props.alignY] - Vertical alignment
|
|
38
|
-
* @param {boolean} [props.expandX] - Whether element should expand horizontally to fill available space
|
|
39
|
-
* @param {boolean} [props.expandY] - Whether element should expand vertically to fill available space
|
|
40
|
-
* @returns {Object} Object with categorized styles: { margin, padding, alignment, expansion, all }
|
|
41
|
-
*/
|
|
42
|
-
export const useLayoutStyle = (props) => {
|
|
43
|
-
const flexDirection = useContext(FlexDirectionContext);
|
|
44
|
-
|
|
45
|
-
const marginStyle = {};
|
|
46
|
-
const paddingStyle = {};
|
|
47
|
-
const alignmentStyle = {};
|
|
48
|
-
const expansionStyle = {};
|
|
49
|
-
|
|
50
|
-
spacing: {
|
|
51
|
-
outer_spacing: {
|
|
52
|
-
const margin = props.margin;
|
|
53
|
-
const marginX = props.marginX;
|
|
54
|
-
const marginY = props.marginY;
|
|
55
|
-
const marginLeft = props.marginLeft;
|
|
56
|
-
const marginRight = props.marginRight;
|
|
57
|
-
const marginTop = props.marginTop;
|
|
58
|
-
const marginBottom = props.marginBottom;
|
|
59
|
-
delete props.margin;
|
|
60
|
-
delete props.marginX;
|
|
61
|
-
delete props.marginY;
|
|
62
|
-
delete props.marginLeft;
|
|
63
|
-
delete props.marginRight;
|
|
64
|
-
delete props.marginTop;
|
|
65
|
-
delete props.marginBottom;
|
|
66
|
-
|
|
67
|
-
if (margin !== undefined) {
|
|
68
|
-
marginStyle.margin = margin;
|
|
69
|
-
}
|
|
70
|
-
if (marginLeft !== undefined) {
|
|
71
|
-
marginStyle.marginLeft = marginLeft;
|
|
72
|
-
} else if (marginX !== undefined) {
|
|
73
|
-
marginStyle.marginLeft = marginX;
|
|
74
|
-
}
|
|
75
|
-
if (marginRight !== undefined) {
|
|
76
|
-
marginStyle.marginRight = marginRight;
|
|
77
|
-
} else if (marginX !== undefined) {
|
|
78
|
-
marginStyle.marginRight = marginX;
|
|
79
|
-
}
|
|
80
|
-
if (marginTop !== undefined) {
|
|
81
|
-
marginStyle.marginTop = marginTop;
|
|
82
|
-
} else if (marginY !== undefined) {
|
|
83
|
-
marginStyle.marginTop = marginY;
|
|
84
|
-
}
|
|
85
|
-
if (marginBottom !== undefined) {
|
|
86
|
-
marginStyle.marginBottom = marginBottom;
|
|
87
|
-
} else if (marginY !== undefined) {
|
|
88
|
-
marginStyle.marginBottom = marginY;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
inner_spacing: {
|
|
92
|
-
const padding = props.padding;
|
|
93
|
-
const paddingX = props.paddingX;
|
|
94
|
-
const paddingY = props.paddingY;
|
|
95
|
-
const paddingLeft = props.paddingLeft;
|
|
96
|
-
const paddingRight = props.paddingRight;
|
|
97
|
-
const paddingTop = props.paddingTop;
|
|
98
|
-
const paddingBottom = props.paddingBottom;
|
|
99
|
-
delete props.padding;
|
|
100
|
-
delete props.paddingX;
|
|
101
|
-
delete props.paddingY;
|
|
102
|
-
delete props.paddingLeft;
|
|
103
|
-
delete props.paddingRight;
|
|
104
|
-
delete props.paddingTop;
|
|
105
|
-
delete props.paddingBottom;
|
|
106
|
-
|
|
107
|
-
if (padding !== undefined) {
|
|
108
|
-
paddingStyle.padding = padding;
|
|
109
|
-
}
|
|
110
|
-
if (paddingLeft !== undefined) {
|
|
111
|
-
paddingStyle.paddingLeft = paddingLeft;
|
|
112
|
-
} else if (paddingX !== undefined) {
|
|
113
|
-
paddingStyle.paddingLeft = paddingX;
|
|
114
|
-
}
|
|
115
|
-
if (paddingRight !== undefined) {
|
|
116
|
-
paddingStyle.paddingRight = paddingRight;
|
|
117
|
-
} else if (paddingX !== undefined) {
|
|
118
|
-
paddingStyle.paddingRight = paddingX;
|
|
119
|
-
}
|
|
120
|
-
if (paddingTop !== undefined) {
|
|
121
|
-
paddingStyle.paddingTop = paddingTop;
|
|
122
|
-
} else if (paddingY !== undefined) {
|
|
123
|
-
paddingStyle.paddingTop = paddingY;
|
|
124
|
-
}
|
|
125
|
-
if (paddingBottom !== undefined) {
|
|
126
|
-
paddingStyle.paddingBottom = paddingBottom;
|
|
127
|
-
} else if (paddingY !== undefined) {
|
|
128
|
-
paddingStyle.paddingBottom = paddingY;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
align: {
|
|
134
|
-
const alignX = props.alignX;
|
|
135
|
-
const alignY = props.alignY;
|
|
136
|
-
delete props.alignX;
|
|
137
|
-
delete props.alignY;
|
|
138
|
-
|
|
139
|
-
// flex
|
|
140
|
-
if (flexDirection === "row") {
|
|
141
|
-
// In row direction: alignX controls justify-content, alignY controls align-self
|
|
142
|
-
if (alignY !== undefined && alignY !== "start") {
|
|
143
|
-
alignmentStyle.alignSelf = alignY;
|
|
144
|
-
}
|
|
145
|
-
// For row, alignX uses auto margins for positioning
|
|
146
|
-
// NOTE: Auto margins only work effectively for positioning individual items.
|
|
147
|
-
// When multiple adjacent items have the same auto margin alignment (e.g., alignX="end"),
|
|
148
|
-
// only the first item will be positioned as expected because subsequent items
|
|
149
|
-
// will be positioned relative to the previous item's margins, not the container edge.
|
|
150
|
-
if (alignX !== undefined) {
|
|
151
|
-
if (alignX === "start") {
|
|
152
|
-
alignmentStyle.marginRight = "auto";
|
|
153
|
-
} else if (alignX === "end") {
|
|
154
|
-
alignmentStyle.marginLeft = "auto";
|
|
155
|
-
} else if (alignX === "center") {
|
|
156
|
-
alignmentStyle.marginLeft = "auto";
|
|
157
|
-
alignmentStyle.marginRight = "auto";
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
} else if (flexDirection === "column") {
|
|
161
|
-
// In column direction: alignX controls align-self, alignY uses auto margins
|
|
162
|
-
if (alignX !== undefined && alignX !== "start") {
|
|
163
|
-
alignmentStyle.alignSelf = alignX;
|
|
164
|
-
}
|
|
165
|
-
// For column, alignY uses auto margins for positioning
|
|
166
|
-
// NOTE: Same auto margin limitation applies - multiple adjacent items with
|
|
167
|
-
// the same alignY won't all position relative to container edges.
|
|
168
|
-
if (alignY !== undefined) {
|
|
169
|
-
if (alignY === "start") {
|
|
170
|
-
alignmentStyle.marginBottom = "auto";
|
|
171
|
-
} else if (alignY === "end") {
|
|
172
|
-
alignmentStyle.marginTop = "auto";
|
|
173
|
-
} else if (alignY === "center") {
|
|
174
|
-
alignmentStyle.marginTop = "auto";
|
|
175
|
-
alignmentStyle.marginBottom = "auto";
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
// non flex
|
|
180
|
-
else {
|
|
181
|
-
if (alignX === "start") {
|
|
182
|
-
alignmentStyle.marginRight = "auto";
|
|
183
|
-
} else if (alignX === "center") {
|
|
184
|
-
alignmentStyle.marginLeft = "auto";
|
|
185
|
-
alignmentStyle.marginRight = "auto";
|
|
186
|
-
} else if (alignX === "end") {
|
|
187
|
-
alignmentStyle.marginLeft = "auto";
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (alignY === "start") {
|
|
191
|
-
alignmentStyle.marginBottom = "auto";
|
|
192
|
-
} else if (alignY === "center") {
|
|
193
|
-
alignmentStyle.marginTop = "auto";
|
|
194
|
-
alignmentStyle.marginBottom = "auto";
|
|
195
|
-
} else if (alignY === "end") {
|
|
196
|
-
alignmentStyle.marginTop = "auto";
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
expand: {
|
|
202
|
-
const expand = props.expand;
|
|
203
|
-
delete props.expand;
|
|
204
|
-
|
|
205
|
-
expandX: {
|
|
206
|
-
const expandX = props.expandX || expand;
|
|
207
|
-
delete props.expandX;
|
|
208
|
-
if (expandX) {
|
|
209
|
-
if (flexDirection === "row") {
|
|
210
|
-
expansionStyle.flexGrow = 1; // Grow horizontally in row
|
|
211
|
-
} else if (flexDirection === "column") {
|
|
212
|
-
expansionStyle.width = "100%"; // Take full width in column
|
|
213
|
-
} else {
|
|
214
|
-
expansionStyle.width = "100%"; // Take full width outside flex
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
expandY: {
|
|
220
|
-
const expandY = props.expandY || expand;
|
|
221
|
-
delete props.expandY;
|
|
222
|
-
if (expandY) {
|
|
223
|
-
if (flexDirection === "row") {
|
|
224
|
-
expansionStyle.height = "100%"; // Take full height in row
|
|
225
|
-
} else if (flexDirection === "column") {
|
|
226
|
-
expansionStyle.flexGrow = 1; // Grow vertically in column
|
|
227
|
-
} else {
|
|
228
|
-
expansionStyle.height = "100%"; // Take full height outside flex
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Merge all styles for convenience
|
|
235
|
-
const allStyles = {
|
|
236
|
-
...marginStyle,
|
|
237
|
-
...paddingStyle,
|
|
238
|
-
...alignmentStyle,
|
|
239
|
-
...expansionStyle,
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
margin: marginStyle,
|
|
244
|
-
padding: paddingStyle,
|
|
245
|
-
alignment: alignmentStyle,
|
|
246
|
-
expansion: expansionStyle,
|
|
247
|
-
all: allStyles,
|
|
248
|
-
};
|
|
249
|
-
};
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import { forwardRef } from "preact/compat";
|
|
2
|
-
import {
|
|
3
|
-
useContext,
|
|
4
|
-
useImperativeHandle,
|
|
5
|
-
useLayoutEffect,
|
|
6
|
-
useRef,
|
|
7
|
-
} from "preact/hooks";
|
|
8
|
-
|
|
9
|
-
import { useIsVisited } from "../../browser_integration/use_is_visited.js";
|
|
10
|
-
import { closeValidationMessage } from "../../validation/custom_constraint_validation.js";
|
|
11
|
-
import { useConstraints } from "../../validation/hooks/use_constraints.js";
|
|
12
|
-
import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
|
|
13
|
-
import { useRequestedActionStatus } from "../field/use_action_events.js";
|
|
14
|
-
import { useKeyboardShortcuts } from "../keyboard_shortcuts/keyboard_shortcuts.js";
|
|
15
|
-
import { useLayoutStyle } from "../layout/use_layout_style.js";
|
|
16
|
-
import { LoadableInlineElement } from "../loader/loader_background.jsx";
|
|
17
|
-
import { withPropsClassName } from "../props_composition/with_props_class_name.js";
|
|
18
|
-
import { withPropsStyle } from "../props_composition/with_props_style.js";
|
|
19
|
-
import {
|
|
20
|
-
SelectionContext,
|
|
21
|
-
useSelectableElement,
|
|
22
|
-
} from "../selection/selection.jsx";
|
|
23
|
-
import { useTypographyStyle } from "../text/text.jsx";
|
|
24
|
-
import { useAutoFocus } from "../use_auto_focus.js";
|
|
25
|
-
|
|
26
|
-
/*
|
|
27
|
-
* Apply opacity to child content, not the link element itself.
|
|
28
|
-
*
|
|
29
|
-
* Why not apply opacity directly to .navi_link?
|
|
30
|
-
* - Would make focus outlines semi-transparent too (accessibility issue)
|
|
31
|
-
* - We want dimmed text but full-opacity focus indicators for visibility
|
|
32
|
-
*
|
|
33
|
-
* This approach dims the content while preserving focus outline visibility.
|
|
34
|
-
*/
|
|
35
|
-
import.meta.css = /* css */ `
|
|
36
|
-
.navi_link {
|
|
37
|
-
border-radius: 2px;
|
|
38
|
-
}
|
|
39
|
-
/* Focus */
|
|
40
|
-
.navi_link:focus {
|
|
41
|
-
position: relative;
|
|
42
|
-
z-index: 1; /* Ensure focus outline is above other elements */
|
|
43
|
-
}
|
|
44
|
-
/* Visited */
|
|
45
|
-
.navi_link[data-visited] {
|
|
46
|
-
color: light-dark(#6a1b9a, #ab47bc);
|
|
47
|
-
}
|
|
48
|
-
/* Selected */
|
|
49
|
-
.navi_link[aria-selected] {
|
|
50
|
-
position: relative;
|
|
51
|
-
}
|
|
52
|
-
.navi_link[aria-selected="true"] {
|
|
53
|
-
background-color: light-dark(#bbdefb, #2563eb);
|
|
54
|
-
}
|
|
55
|
-
.navi_link[aria-selected] input[type="checkbox"] {
|
|
56
|
-
position: absolute;
|
|
57
|
-
opacity: 0;
|
|
58
|
-
}
|
|
59
|
-
/* Active */
|
|
60
|
-
.navi_link[data-active] {
|
|
61
|
-
font-weight: bold;
|
|
62
|
-
}
|
|
63
|
-
/* Readonly */
|
|
64
|
-
.navi_link[data-readonly] > * {
|
|
65
|
-
opacity: 0.5;
|
|
66
|
-
}
|
|
67
|
-
/* Disabled */
|
|
68
|
-
.navi_link[inert] {
|
|
69
|
-
pointer-events: none;
|
|
70
|
-
}
|
|
71
|
-
.navi_link[inert] > * {
|
|
72
|
-
opacity: 0.5;
|
|
73
|
-
}
|
|
74
|
-
`;
|
|
75
|
-
|
|
76
|
-
export const Link = forwardRef((props, ref) => {
|
|
77
|
-
return renderActionableComponent(props, ref, {
|
|
78
|
-
Basic: LinkBasic,
|
|
79
|
-
WithAction: LinkWithAction,
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const LinkBasic = forwardRef((props, ref) => {
|
|
84
|
-
const selectionContext = useContext(SelectionContext);
|
|
85
|
-
if (selectionContext) {
|
|
86
|
-
return <LinkWithSelection ref={ref} {...props} />;
|
|
87
|
-
}
|
|
88
|
-
return <LinkPlain ref={ref} {...props} />;
|
|
89
|
-
});
|
|
90
|
-
const LinkPlain = forwardRef((props, ref) => {
|
|
91
|
-
const {
|
|
92
|
-
loading,
|
|
93
|
-
readOnly,
|
|
94
|
-
disabled,
|
|
95
|
-
children,
|
|
96
|
-
autoFocus,
|
|
97
|
-
active,
|
|
98
|
-
visited,
|
|
99
|
-
spaceToClick = true,
|
|
100
|
-
constraints = [],
|
|
101
|
-
onClick,
|
|
102
|
-
onKeyDown,
|
|
103
|
-
href,
|
|
104
|
-
|
|
105
|
-
// visual
|
|
106
|
-
className,
|
|
107
|
-
style,
|
|
108
|
-
...rest
|
|
109
|
-
} = props;
|
|
110
|
-
const innerRef = useRef();
|
|
111
|
-
useImperativeHandle(ref, () => innerRef.current);
|
|
112
|
-
const isVisited = useIsVisited(href);
|
|
113
|
-
|
|
114
|
-
useAutoFocus(innerRef, autoFocus);
|
|
115
|
-
useConstraints(innerRef, constraints);
|
|
116
|
-
const shouldDimColor = readOnly || disabled;
|
|
117
|
-
useDimColorWhen(innerRef, shouldDimColor);
|
|
118
|
-
|
|
119
|
-
const innerClassName = withPropsClassName("navi_link", className);
|
|
120
|
-
const { all } = useLayoutStyle(rest);
|
|
121
|
-
const innerStyle = withPropsStyle(
|
|
122
|
-
{
|
|
123
|
-
...all,
|
|
124
|
-
...useTypographyStyle(rest),
|
|
125
|
-
},
|
|
126
|
-
style,
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
return (
|
|
130
|
-
<LoadableInlineElement
|
|
131
|
-
loading={loading}
|
|
132
|
-
color="light-dark(#355fcc, #3b82f6)"
|
|
133
|
-
>
|
|
134
|
-
<a
|
|
135
|
-
{...rest}
|
|
136
|
-
ref={innerRef}
|
|
137
|
-
href={href}
|
|
138
|
-
className={innerClassName}
|
|
139
|
-
style={innerStyle}
|
|
140
|
-
aria-busy={loading}
|
|
141
|
-
inert={disabled}
|
|
142
|
-
data-disabled={disabled ? "" : undefined}
|
|
143
|
-
data-readonly={readOnly ? "" : undefined}
|
|
144
|
-
data-active={active ? "" : undefined}
|
|
145
|
-
data-visited={visited || isVisited ? "" : undefined}
|
|
146
|
-
onClick={(e) => {
|
|
147
|
-
closeValidationMessage(e.target, "click");
|
|
148
|
-
if (readOnly) {
|
|
149
|
-
e.preventDefault();
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
onClick?.(e);
|
|
153
|
-
}}
|
|
154
|
-
onKeyDown={(e) => {
|
|
155
|
-
if (spaceToClick && e.key === " ") {
|
|
156
|
-
e.preventDefault(); // Prevent page scroll
|
|
157
|
-
if (!readOnly && !disabled) {
|
|
158
|
-
e.target.click();
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
onKeyDown?.(e);
|
|
162
|
-
}}
|
|
163
|
-
>
|
|
164
|
-
{children}
|
|
165
|
-
</a>
|
|
166
|
-
</LoadableInlineElement>
|
|
167
|
-
);
|
|
168
|
-
});
|
|
169
|
-
const LinkWithSelection = forwardRef((props, ref) => {
|
|
170
|
-
const { selection, selectionController } = useContext(SelectionContext);
|
|
171
|
-
const { value = props.href, children, ...rest } = props;
|
|
172
|
-
const innerRef = useRef();
|
|
173
|
-
useImperativeHandle(ref, () => innerRef.current);
|
|
174
|
-
const { selected } = useSelectableElement(innerRef, {
|
|
175
|
-
selection,
|
|
176
|
-
selectionController,
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
return (
|
|
180
|
-
<LinkPlain
|
|
181
|
-
{...rest}
|
|
182
|
-
ref={innerRef}
|
|
183
|
-
data-value={value}
|
|
184
|
-
aria-selected={selected}
|
|
185
|
-
>
|
|
186
|
-
{children}
|
|
187
|
-
</LinkPlain>
|
|
188
|
-
);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
/*
|
|
192
|
-
* Custom hook to apply semi-transparent color when an element should be dimmed.
|
|
193
|
-
*
|
|
194
|
-
* Why we do it this way:
|
|
195
|
-
* 1. **Precise timing**: Captures the element's natural color exactly when transitioning
|
|
196
|
-
* from normal to dimmed state (not before, not after)
|
|
197
|
-
* 2. **Avoids CSS inheritance issues**: CSS `currentColor` and `color-mix()` don't work
|
|
198
|
-
* reliably for creating true transparency that matches `opacity: 0.5`
|
|
199
|
-
* 3. **Performance**: Only executes when the dimmed state actually changes, not on every render
|
|
200
|
-
* 4. **Color accuracy**: Uses `color(from ... / 0.5)` syntax to preserve the exact visual
|
|
201
|
-
* appearance of `opacity: 0.5` but applied only to color
|
|
202
|
-
* 5. **Works with any color**: Handles default blue, visited purple, inherited colors, etc.
|
|
203
|
-
* 6. **Maintains focus outline**: Since we only dim the text color, focus outlines remain
|
|
204
|
-
* fully visible for accessibility
|
|
205
|
-
*/
|
|
206
|
-
const useDimColorWhen = (elementRef, shouldDim) => {
|
|
207
|
-
const shouldDimPreviousRef = useRef();
|
|
208
|
-
useLayoutEffect(() => {
|
|
209
|
-
const element = elementRef.current;
|
|
210
|
-
const shouldDimPrevious = shouldDimPreviousRef.current;
|
|
211
|
-
|
|
212
|
-
if (shouldDim === shouldDimPrevious) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
shouldDimPreviousRef.current = shouldDim;
|
|
216
|
-
if (shouldDim) {
|
|
217
|
-
// Capture color just before applying disabled state
|
|
218
|
-
const computedStyle = getComputedStyle(element);
|
|
219
|
-
const currentColor = computedStyle.color;
|
|
220
|
-
element.style.color = `color(from ${currentColor} srgb r g b / 0.5)`;
|
|
221
|
-
} else {
|
|
222
|
-
// Clear the inline style to let CSS take over
|
|
223
|
-
element.style.color = "";
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const LinkWithAction = forwardRef((props, ref) => {
|
|
229
|
-
const {
|
|
230
|
-
shortcuts = [],
|
|
231
|
-
readOnly,
|
|
232
|
-
onActionPrevented,
|
|
233
|
-
onActionStart,
|
|
234
|
-
onActionAbort,
|
|
235
|
-
onActionError,
|
|
236
|
-
onActionEnd,
|
|
237
|
-
children,
|
|
238
|
-
loading,
|
|
239
|
-
...rest
|
|
240
|
-
} = props;
|
|
241
|
-
const innerRef = useRef();
|
|
242
|
-
useImperativeHandle(ref, () => innerRef.current);
|
|
243
|
-
const { actionPending } = useRequestedActionStatus(innerRef);
|
|
244
|
-
const innerLoading = Boolean(loading || actionPending);
|
|
245
|
-
|
|
246
|
-
useKeyboardShortcuts(innerRef, shortcuts, {
|
|
247
|
-
onActionPrevented,
|
|
248
|
-
onActionStart,
|
|
249
|
-
onActionAbort,
|
|
250
|
-
onActionError,
|
|
251
|
-
onActionEnd,
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
return (
|
|
255
|
-
<LinkBasic
|
|
256
|
-
{...rest}
|
|
257
|
-
ref={innerRef}
|
|
258
|
-
loading={innerLoading}
|
|
259
|
-
readOnly={readOnly || actionPending}
|
|
260
|
-
data-readonly-silent={actionPending && !readOnly ? "" : undefined}
|
|
261
|
-
/* When we have keyboard shortcuts the link outline is visible on focus (not solely on focus-visible) */
|
|
262
|
-
data-focus-visible=""
|
|
263
|
-
>
|
|
264
|
-
{children}
|
|
265
|
-
</LinkBasic>
|
|
266
|
-
);
|
|
267
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { FontSizedSvg } from "../svg/font_sized_svg.jsx";
|
|
2
|
-
import { Link } from "./link.jsx";
|
|
3
|
-
|
|
4
|
-
import.meta.css = /* css */ `
|
|
5
|
-
.link_with_icon {
|
|
6
|
-
white-space: nowrap;
|
|
7
|
-
align-items: center;
|
|
8
|
-
gap: 0.3em;
|
|
9
|
-
min-width: 0;
|
|
10
|
-
display: inline-flex;
|
|
11
|
-
flex-grow: 1;
|
|
12
|
-
}
|
|
13
|
-
`;
|
|
14
|
-
|
|
15
|
-
export const LinkWithIcon = ({
|
|
16
|
-
icon,
|
|
17
|
-
isCurrent,
|
|
18
|
-
children,
|
|
19
|
-
className = "",
|
|
20
|
-
...rest
|
|
21
|
-
}) => {
|
|
22
|
-
return (
|
|
23
|
-
<Link
|
|
24
|
-
className={["link_with_icon", ...className.split(" ")].join(" ")}
|
|
25
|
-
{...rest}
|
|
26
|
-
>
|
|
27
|
-
<FontSizedSvg>{icon}</FontSizedSvg>
|
|
28
|
-
{isCurrent && (
|
|
29
|
-
<FontSizedSvg>
|
|
30
|
-
<CurrentSvg />
|
|
31
|
-
</FontSizedSvg>
|
|
32
|
-
)}
|
|
33
|
-
{children}
|
|
34
|
-
</Link>
|
|
35
|
-
);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const CurrentSvg = () => {
|
|
39
|
-
return (
|
|
40
|
-
<svg
|
|
41
|
-
viewBox="0 0 16 16"
|
|
42
|
-
width="100%"
|
|
43
|
-
height="100%"
|
|
44
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
45
|
-
>
|
|
46
|
-
<path
|
|
47
|
-
d="m 8 0 c -3.3125 0 -6 2.6875 -6 6 c 0.007812 0.710938 0.136719 1.414062 0.386719 2.078125 l -0.015625 -0.003906 c 0.636718 1.988281 3.78125 5.082031 5.625 6.929687 h 0.003906 v -0.003906 c 1.507812 -1.507812 3.878906 -3.925781 5.046875 -5.753906 c 0.261719 -0.414063 0.46875 -0.808594 0.585937 -1.171875 l -0.019531 0.003906 c 0.25 -0.664063 0.382813 -1.367187 0.386719 -2.078125 c 0 -3.3125 -2.683594 -6 -6 -6 z m 0 3.691406 c 1.273438 0 2.308594 1.035156 2.308594 2.308594 s -1.035156 2.308594 -2.308594 2.308594 c -1.273438 -0.003906 -2.304688 -1.035156 -2.304688 -2.308594 c -0.003906 -1.273438 1.03125 -2.304688 2.304688 -2.308594 z m 0 0"
|
|
48
|
-
fill="#2e3436"
|
|
49
|
-
/>
|
|
50
|
-
</svg>
|
|
51
|
-
);
|
|
52
|
-
};
|