@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,106 +0,0 @@
|
|
|
1
|
-
import { createContext } from "preact";
|
|
2
|
-
import { useMemo } from "preact/hooks";
|
|
3
|
-
|
|
4
|
-
export const TableSelectionContext = createContext();
|
|
5
|
-
export const useTableSelectionContextValue = (
|
|
6
|
-
selection,
|
|
7
|
-
selectionController,
|
|
8
|
-
) => {
|
|
9
|
-
const selectionContextValue = useMemo(() => {
|
|
10
|
-
const selectedColumnIds = [];
|
|
11
|
-
const selectedRowIds = [];
|
|
12
|
-
const selectedCellIds = [];
|
|
13
|
-
const columnIdWithSomeSelectedCellSet = new Set();
|
|
14
|
-
const rowIdWithSomeSelectedCellSet = new Set();
|
|
15
|
-
for (const item of selection) {
|
|
16
|
-
const selectionValueInfo = parseTableSelectionValue(item);
|
|
17
|
-
if (selectionValueInfo.type === "row") {
|
|
18
|
-
const { rowId } = selectionValueInfo;
|
|
19
|
-
selectedRowIds.push(rowId);
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
if (selectionValueInfo.type === "column") {
|
|
23
|
-
const { columnId } = selectionValueInfo;
|
|
24
|
-
selectedColumnIds.push(columnId);
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
if (selectionValueInfo.type === "cell") {
|
|
28
|
-
const { cellId, columnId, rowId } = selectionValueInfo;
|
|
29
|
-
selectedCellIds.push(cellId);
|
|
30
|
-
columnIdWithSomeSelectedCellSet.add(columnId);
|
|
31
|
-
rowIdWithSomeSelectedCellSet.add(rowId);
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return {
|
|
36
|
-
selection,
|
|
37
|
-
selectionController,
|
|
38
|
-
selectedColumnIds,
|
|
39
|
-
selectedRowIds,
|
|
40
|
-
columnIdWithSomeSelectedCellSet,
|
|
41
|
-
rowIdWithSomeSelectedCellSet,
|
|
42
|
-
};
|
|
43
|
-
}, [selection]);
|
|
44
|
-
|
|
45
|
-
return selectionContextValue;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const parseTableSelectionValue = (selectionValue) => {
|
|
49
|
-
if (selectionValue.startsWith("column:")) {
|
|
50
|
-
const columnId = selectionValue.slice("column:".length);
|
|
51
|
-
return { type: "column", columnId };
|
|
52
|
-
}
|
|
53
|
-
if (selectionValue.startsWith("row:")) {
|
|
54
|
-
const rowId = selectionValue.slice("row:".length);
|
|
55
|
-
return { type: "row", rowId };
|
|
56
|
-
}
|
|
57
|
-
const cellId = selectionValue.slice("cell:".length);
|
|
58
|
-
const [columnId, rowId] = cellId.split("-");
|
|
59
|
-
return { type: "cell", cellId, columnId, rowId };
|
|
60
|
-
};
|
|
61
|
-
export const stringifyTableSelectionValue = (type, value) => {
|
|
62
|
-
if (type === "cell") {
|
|
63
|
-
const { columnId, rowId } = value;
|
|
64
|
-
return `cell:${columnId}-${rowId}`;
|
|
65
|
-
}
|
|
66
|
-
if (type === "column") {
|
|
67
|
-
return `column:${value}`;
|
|
68
|
-
}
|
|
69
|
-
if (type === "row") {
|
|
70
|
-
return `row:${value}`;
|
|
71
|
-
}
|
|
72
|
-
return "";
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Check if a specific cell is selected
|
|
77
|
-
* @param {Array} selection - The selection set or array
|
|
78
|
-
* @param {{rowIndex: number, columnIndex: number}} cellPosition - Cell coordinates
|
|
79
|
-
* @returns {boolean} True if the cell is selected
|
|
80
|
-
*/
|
|
81
|
-
export const isCellSelected = (selection, cellId) => {
|
|
82
|
-
const cellSelectionValue = stringifyTableSelectionValue("cell", cellId);
|
|
83
|
-
return selection.includes(cellSelectionValue);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Check if a specific row is selected
|
|
88
|
-
* @param {Array} selection - The selection set or array
|
|
89
|
-
* @param {number} rowIndex - Row index
|
|
90
|
-
* @returns {boolean} True if the row is selected
|
|
91
|
-
*/
|
|
92
|
-
export const isRowSelected = (selection, rowId) => {
|
|
93
|
-
const rowSelectionValue = stringifyTableSelectionValue("row", rowId);
|
|
94
|
-
return selection.includes(rowSelectionValue);
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Check if a specific column is selected
|
|
99
|
-
* @param {Array} selection - The selection set or array
|
|
100
|
-
* @param {number} columnIndex - Column index
|
|
101
|
-
* @returns {boolean} True if the column is selected
|
|
102
|
-
*/
|
|
103
|
-
export const isColumnSelected = (selection, columnId) => {
|
|
104
|
-
const columnSelectionValue = stringifyTableSelectionValue("column", columnId);
|
|
105
|
-
return selection.has(columnSelectionValue);
|
|
106
|
-
};
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { useLayoutEffect } from "preact/hooks";
|
|
2
|
-
|
|
3
|
-
import { useSelectionController } from "../../selection/selection.jsx";
|
|
4
|
-
|
|
5
|
-
import.meta.css = /* css */ `
|
|
6
|
-
body {
|
|
7
|
-
--selection-border-color: #0078d4;
|
|
8
|
-
--selection-background-color: #eaf1fd;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.navi_table_cell[aria-selected="true"] {
|
|
12
|
-
background-color: var(--selection-background-color);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/* One border */
|
|
16
|
-
.navi_table_cell[data-selection-border-top]::after {
|
|
17
|
-
box-shadow: inset 0 1px 0 0 var(--selection-border-color);
|
|
18
|
-
}
|
|
19
|
-
.navi_table_cell[data-selection-border-right]::after {
|
|
20
|
-
box-shadow: inset -1px 0 0 0 var(--selection-border-color);
|
|
21
|
-
}
|
|
22
|
-
.navi_table_cell[data-selection-border-bottom]::after {
|
|
23
|
-
box-shadow: inset 0 -1px 0 0 var(--selection-border-color);
|
|
24
|
-
}
|
|
25
|
-
.navi_table_cell[data-selection-border-left]::after {
|
|
26
|
-
box-shadow: inset 1px 0 0 0 var(--selection-border-color);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* Two border combinations */
|
|
30
|
-
.navi_table_cell[data-selection-border-top][data-selection-border-right]::after {
|
|
31
|
-
box-shadow:
|
|
32
|
-
inset 0 1px 0 0 var(--selection-border-color),
|
|
33
|
-
inset -1px 0 0 0 var(--selection-border-color);
|
|
34
|
-
}
|
|
35
|
-
.navi_table_cell[data-selection-border-top][data-selection-border-bottom]::after {
|
|
36
|
-
box-shadow:
|
|
37
|
-
inset 0 1px 0 0 var(--selection-border-color),
|
|
38
|
-
inset 0 -1px 0 0 var(--selection-border-color);
|
|
39
|
-
}
|
|
40
|
-
.navi_table_cell[data-selection-border-top][data-selection-border-left]::after {
|
|
41
|
-
box-shadow:
|
|
42
|
-
inset 0 1px 0 0 var(--selection-border-color),
|
|
43
|
-
inset 1px 0 0 0 var(--selection-border-color);
|
|
44
|
-
}
|
|
45
|
-
.navi_table_cell[data-selection-border-right][data-selection-border-bottom]::after {
|
|
46
|
-
box-shadow:
|
|
47
|
-
inset -1px 0 0 0 var(--selection-border-color),
|
|
48
|
-
inset 0 -1px 0 0 var(--selection-border-color);
|
|
49
|
-
}
|
|
50
|
-
.navi_table_cell[data-selection-border-right][data-selection-border-left]::after {
|
|
51
|
-
box-shadow:
|
|
52
|
-
inset -1px 0 0 0 var(--selection-border-color),
|
|
53
|
-
inset 1px 0 0 0 var(--selection-border-color);
|
|
54
|
-
}
|
|
55
|
-
.navi_table_cell[data-selection-border-bottom][data-selection-border-left]::after {
|
|
56
|
-
box-shadow:
|
|
57
|
-
inset 0 -1px 0 0 var(--selection-border-color),
|
|
58
|
-
inset 1px 0 0 0 var(--selection-border-color);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/* Three border combinations */
|
|
62
|
-
.navi_table_cell[data-selection-border-top][data-selection-border-right][data-selection-border-bottom]::after {
|
|
63
|
-
box-shadow:
|
|
64
|
-
inset 0 1px 0 0 var(--selection-border-color),
|
|
65
|
-
inset -1px 0 0 0 var(--selection-border-color),
|
|
66
|
-
inset 0 -1px 0 0 var(--selection-border-color);
|
|
67
|
-
}
|
|
68
|
-
.navi_table_cell[data-selection-border-top][data-selection-border-bottom][data-selection-border-left]::after {
|
|
69
|
-
box-shadow:
|
|
70
|
-
inset 0 1px 0 0 var(--selection-border-color),
|
|
71
|
-
inset 0 -1px 0 0 var(--selection-border-color),
|
|
72
|
-
inset 1px 0 0 0 var(--selection-border-color);
|
|
73
|
-
}
|
|
74
|
-
.navi_table_cell[data-selection-border-top][data-selection-border-right][data-selection-border-left]::after {
|
|
75
|
-
box-shadow:
|
|
76
|
-
inset 0 1px 0 0 var(--selection-border-color),
|
|
77
|
-
inset -1px 0 0 0 var(--selection-border-color),
|
|
78
|
-
inset 1px 0 0 0 var(--selection-border-color);
|
|
79
|
-
}
|
|
80
|
-
.navi_table_cell[data-selection-border-right][data-selection-border-bottom][data-selection-border-left]::after {
|
|
81
|
-
box-shadow:
|
|
82
|
-
inset -1px 0 0 0 var(--selection-border-color),
|
|
83
|
-
inset 0 -1px 0 0 var(--selection-border-color),
|
|
84
|
-
inset 1px 0 0 0 var(--selection-border-color);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/* Four border combinations (full selection) */
|
|
88
|
-
.navi_table_cell[data-selection-border-top][data-selection-border-right][data-selection-border-bottom][data-selection-border-left]::after {
|
|
89
|
-
box-shadow:
|
|
90
|
-
inset 0 1px 0 0 var(--selection-border-color),
|
|
91
|
-
inset -1px 0 0 0 var(--selection-border-color),
|
|
92
|
-
inset 0 -1px 0 0 var(--selection-border-color),
|
|
93
|
-
inset 1px 0 0 0 var(--selection-border-color);
|
|
94
|
-
}
|
|
95
|
-
`;
|
|
96
|
-
|
|
97
|
-
export const useTableSelectionController = ({
|
|
98
|
-
tableRef,
|
|
99
|
-
selection,
|
|
100
|
-
onSelectionChange,
|
|
101
|
-
selectionColor,
|
|
102
|
-
}) => {
|
|
103
|
-
const selectionController = useSelectionController({
|
|
104
|
-
elementRef: tableRef,
|
|
105
|
-
layout: "grid",
|
|
106
|
-
value: selection,
|
|
107
|
-
onChange: onSelectionChange,
|
|
108
|
-
selectAllName: "cell",
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
useLayoutEffect(() => {
|
|
112
|
-
const table = tableRef.current;
|
|
113
|
-
if (!table) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
updateSelectionBorders(table, selectionController);
|
|
117
|
-
}, [selectionController.value]);
|
|
118
|
-
|
|
119
|
-
useLayoutEffect(() => {
|
|
120
|
-
const table = tableRef.current;
|
|
121
|
-
if (!table) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (selectionColor) {
|
|
125
|
-
table.style.setProperty("--selection-border-color", selectionColor);
|
|
126
|
-
} else {
|
|
127
|
-
table.style.removeProperty("--selection-border-color");
|
|
128
|
-
}
|
|
129
|
-
}, [selectionColor]);
|
|
130
|
-
|
|
131
|
-
return selectionController;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const updateSelectionBorders = (tableElement, selectionController) => {
|
|
135
|
-
// Find all selected cells
|
|
136
|
-
const cells = Array.from(tableElement.querySelectorAll(".navi_table_cell"));
|
|
137
|
-
const selectedCells = [];
|
|
138
|
-
for (const cell of cells) {
|
|
139
|
-
if (selectionController.isElementSelected(cell)) {
|
|
140
|
-
selectedCells.push(cell);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Clear all existing selection border attributes
|
|
145
|
-
tableElement
|
|
146
|
-
.querySelectorAll(
|
|
147
|
-
"[data-selection-border-top], [data-selection-border-right], [data-selection-border-bottom], [data-selection-border-left]",
|
|
148
|
-
)
|
|
149
|
-
.forEach((cell) => {
|
|
150
|
-
cell.removeAttribute("data-selection-border-top");
|
|
151
|
-
cell.removeAttribute("data-selection-border-right");
|
|
152
|
-
cell.removeAttribute("data-selection-border-bottom");
|
|
153
|
-
cell.removeAttribute("data-selection-border-left");
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
if (selectedCells.length === 0) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Convert NodeList to array and get cell positions
|
|
161
|
-
|
|
162
|
-
const cellPositions = selectedCells.map((cell) => {
|
|
163
|
-
const row = cell.parentElement;
|
|
164
|
-
const allRows = Array.from(tableElement.querySelectorAll(".navi_tr"));
|
|
165
|
-
return {
|
|
166
|
-
element: cell,
|
|
167
|
-
rowIndex: allRows.indexOf(row),
|
|
168
|
-
columnIndex: Array.from(row.children).indexOf(cell),
|
|
169
|
-
};
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// Create a set for fast lookup of selected cell positions
|
|
173
|
-
const selectedPositions = new Set(
|
|
174
|
-
cellPositions.map((pos) => `${pos.rowIndex},${pos.columnIndex}`),
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
// Apply selection borders based on actual neighbors (for proper L-shaped selection support)
|
|
178
|
-
cellPositions.forEach(({ element, rowIndex, columnIndex }) => {
|
|
179
|
-
// Top border: if cell above is NOT selected or doesn't exist
|
|
180
|
-
const cellAbove = `${rowIndex - 1},${columnIndex}`;
|
|
181
|
-
if (!selectedPositions.has(cellAbove)) {
|
|
182
|
-
element.setAttribute("data-selection-border-top", "");
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Bottom border: if cell below is NOT selected or doesn't exist
|
|
186
|
-
const cellBelow = `${rowIndex + 1},${columnIndex}`;
|
|
187
|
-
if (!selectedPositions.has(cellBelow)) {
|
|
188
|
-
element.setAttribute("data-selection-border-bottom", "");
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Left border: if cell to the left is NOT selected or doesn't exist
|
|
192
|
-
const cellLeft = `${rowIndex},${columnIndex - 1}`;
|
|
193
|
-
if (!selectedPositions.has(cellLeft)) {
|
|
194
|
-
element.setAttribute("data-selection-border-left", "");
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Right border: if cell to the right is NOT selected or doesn't exist
|
|
198
|
-
const cellRight = `${rowIndex},${columnIndex + 1}`;
|
|
199
|
-
if (!selectedPositions.has(cellRight)) {
|
|
200
|
-
element.setAttribute("data-selection-border-right", "");
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
};
|
|
@@ -1,354 +0,0 @@
|
|
|
1
|
-
// TODO: move this to @jsenv/dom (the initStickyGroup part, not the useLayoutEffect)
|
|
2
|
-
|
|
3
|
-
import { createPubSub, setStyles } from "@jsenv/dom";
|
|
4
|
-
import { useLayoutEffect } from "preact/hooks";
|
|
5
|
-
|
|
6
|
-
// React hook version for easy integration
|
|
7
|
-
export const useStickyGroup = (
|
|
8
|
-
elementRef,
|
|
9
|
-
{ elementReceivingCumulativeStickyPositionRef, elementSelector } = {},
|
|
10
|
-
) => {
|
|
11
|
-
useLayoutEffect(() => {
|
|
12
|
-
const element = elementRef.current;
|
|
13
|
-
if (!element) {
|
|
14
|
-
return undefined;
|
|
15
|
-
}
|
|
16
|
-
return initStickyGroup(element, {
|
|
17
|
-
elementSelector,
|
|
18
|
-
elementReceivingCumulativeStickyPosition:
|
|
19
|
-
elementReceivingCumulativeStickyPositionRef.current,
|
|
20
|
-
});
|
|
21
|
-
}, [elementSelector]);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const ITEM_LEFT_VAR = "--sticky-group-item-left";
|
|
25
|
-
const ITEM_TOP_VAR = "--sticky-group-item-top";
|
|
26
|
-
const FRONTIER_LEFT_VAR = "--sticky-group-left";
|
|
27
|
-
const FRONTIER_TOP_VAR = "--sticky-group-top";
|
|
28
|
-
// const FRONTIER_LEFT_VIEWPORT_VAR = "--sticky-group-left-viewport";
|
|
29
|
-
// const FRONTIER_TOP_VIEWPORT_VAR = "--sticky-group-top-viewport";
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Creates a sticky group that manages positioning for multiple sticky elements
|
|
33
|
-
* that need to be aware of each other's dimensions.
|
|
34
|
-
* Always uses CSS variables for positioning.
|
|
35
|
-
*
|
|
36
|
-
* @param {HTMLElement} container The container element
|
|
37
|
-
* @returns {Function} Cleanup function
|
|
38
|
-
*/
|
|
39
|
-
const initStickyGroup = (
|
|
40
|
-
container,
|
|
41
|
-
{ elementSelector, elementReceivingCumulativeStickyPosition } = {},
|
|
42
|
-
) => {
|
|
43
|
-
if (!container) {
|
|
44
|
-
throw new Error("initStickyGroup: container is required");
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const [teardown, addTeardown] = createPubSub();
|
|
48
|
-
const [cleanup, addCleanup, clearCleanup] = createPubSub();
|
|
49
|
-
addTeardown(cleanup);
|
|
50
|
-
|
|
51
|
-
const element = elementSelector
|
|
52
|
-
? container.querySelector(elementSelector)
|
|
53
|
-
: container;
|
|
54
|
-
const isGrid =
|
|
55
|
-
element.tagName === "TABLE" || element.classList.contains("navi_table");
|
|
56
|
-
const updatePositions = () => {
|
|
57
|
-
// Clear all previous CSS variable cleanups before setting new ones
|
|
58
|
-
cleanup();
|
|
59
|
-
clearCleanup();
|
|
60
|
-
|
|
61
|
-
if (isGrid) {
|
|
62
|
-
updateGridPositions();
|
|
63
|
-
} else {
|
|
64
|
-
updateLinearPositions();
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const updateGridPositions = () => {
|
|
69
|
-
// Handle table grid - update both horizontal and vertical sticky elements
|
|
70
|
-
updateTableColumns();
|
|
71
|
-
updateTableRows();
|
|
72
|
-
};
|
|
73
|
-
const updateTableColumns = () => {
|
|
74
|
-
// Find all sticky columns by checking all rows to identify which columns have sticky cells
|
|
75
|
-
const allStickyColumnCells = element.querySelectorAll(
|
|
76
|
-
".navi_table_cell[data-sticky-left]",
|
|
77
|
-
);
|
|
78
|
-
if (allStickyColumnCells.length === 0) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Get the first row to determine column indices (use any row that exists)
|
|
83
|
-
const firstRow = element.querySelector(".navi_tr");
|
|
84
|
-
if (!firstRow) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Group sticky cells by column index
|
|
89
|
-
const stickyColumnsByIndex = new Map();
|
|
90
|
-
allStickyColumnCells.forEach((cell) => {
|
|
91
|
-
const row = cell.closest(".navi_tr");
|
|
92
|
-
const columnIndex = Array.from(row.children).indexOf(cell);
|
|
93
|
-
if (!stickyColumnsByIndex.has(columnIndex)) {
|
|
94
|
-
stickyColumnsByIndex.set(columnIndex, []);
|
|
95
|
-
}
|
|
96
|
-
stickyColumnsByIndex.get(columnIndex).push(cell);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// Sort columns by index and process them
|
|
100
|
-
const sortedColumnIndices = Array.from(stickyColumnsByIndex.keys()).sort(
|
|
101
|
-
(a, b) => a - b,
|
|
102
|
-
);
|
|
103
|
-
let cumulativeWidth = 0;
|
|
104
|
-
|
|
105
|
-
sortedColumnIndices.forEach((columnIndex, stickyIndex) => {
|
|
106
|
-
const cellsInColumn = stickyColumnsByIndex.get(columnIndex);
|
|
107
|
-
const leftPosition = stickyIndex === 0 ? 0 : cumulativeWidth;
|
|
108
|
-
|
|
109
|
-
// Set CSS variable on all sticky cells in this column using setStyles for proper cleanup
|
|
110
|
-
cellsInColumn.forEach((cell) => {
|
|
111
|
-
const restoreStyles = setStyles(cell, {
|
|
112
|
-
[ITEM_LEFT_VAR]: `${leftPosition}px`,
|
|
113
|
-
});
|
|
114
|
-
addCleanup(restoreStyles);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// Also set CSS variable on corresponding <col> element if it exists
|
|
118
|
-
const colgroup = element.querySelector(".navi_colgroup");
|
|
119
|
-
if (colgroup) {
|
|
120
|
-
const colElements = Array.from(colgroup.querySelectorAll(".navi_col"));
|
|
121
|
-
const correspondingCol = colElements[columnIndex];
|
|
122
|
-
if (correspondingCol) {
|
|
123
|
-
const restoreStyles = setStyles(correspondingCol, {
|
|
124
|
-
[ITEM_LEFT_VAR]: `${leftPosition}px`,
|
|
125
|
-
});
|
|
126
|
-
addCleanup(restoreStyles);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Update cumulative width for next column using the first cell in this column as reference
|
|
131
|
-
const referenceCell = cellsInColumn[0];
|
|
132
|
-
const columnWidth = referenceCell.getBoundingClientRect().width;
|
|
133
|
-
if (stickyIndex === 0) {
|
|
134
|
-
cumulativeWidth = columnWidth;
|
|
135
|
-
} else {
|
|
136
|
-
cumulativeWidth += columnWidth;
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Set frontier variables with proper cleanup tracking
|
|
141
|
-
const restoreContainerStyles = setStyles(container, {
|
|
142
|
-
[FRONTIER_LEFT_VAR]: `${cumulativeWidth}px`,
|
|
143
|
-
});
|
|
144
|
-
addCleanup(restoreContainerStyles);
|
|
145
|
-
|
|
146
|
-
if (elementReceivingCumulativeStickyPosition) {
|
|
147
|
-
const restoreCumulativeStyles = setStyles(
|
|
148
|
-
elementReceivingCumulativeStickyPosition,
|
|
149
|
-
{
|
|
150
|
-
[FRONTIER_LEFT_VAR]: `${cumulativeWidth}px`,
|
|
151
|
-
},
|
|
152
|
-
);
|
|
153
|
-
addCleanup(restoreCumulativeStyles);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
const updateTableRows = () => {
|
|
157
|
-
// Handle sticky rows by finding cells with data-sticky-top and grouping by row
|
|
158
|
-
const stickyCells = element.querySelectorAll(
|
|
159
|
-
".navi_table_cell[data-sticky-top]",
|
|
160
|
-
);
|
|
161
|
-
if (stickyCells.length === 0) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Group cells by their parent row
|
|
166
|
-
const rowsWithStickyCells = new Map();
|
|
167
|
-
stickyCells.forEach((cell) => {
|
|
168
|
-
const row = cell.parentElement;
|
|
169
|
-
if (!rowsWithStickyCells.has(row)) {
|
|
170
|
-
rowsWithStickyCells.set(row, []);
|
|
171
|
-
}
|
|
172
|
-
rowsWithStickyCells.get(row).push(cell);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Convert to array and sort by row position in DOM
|
|
176
|
-
const allRows = Array.from(element.querySelectorAll(".navi_tr"));
|
|
177
|
-
const stickyRows = Array.from(rowsWithStickyCells.keys()).sort((a, b) => {
|
|
178
|
-
const aIndex = allRows.indexOf(a);
|
|
179
|
-
const bIndex = allRows.indexOf(b);
|
|
180
|
-
return aIndex - bIndex;
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
let cumulativeHeight = 0;
|
|
184
|
-
stickyRows.forEach((row, index) => {
|
|
185
|
-
const rowCells = rowsWithStickyCells.get(row);
|
|
186
|
-
const topPosition = index === 0 ? 0 : cumulativeHeight;
|
|
187
|
-
|
|
188
|
-
// Set CSS variable on all sticky cells in this row using setStyles for proper cleanup
|
|
189
|
-
rowCells.forEach((cell) => {
|
|
190
|
-
const restoreStyles = setStyles(cell, {
|
|
191
|
-
[ITEM_TOP_VAR]: `${topPosition}px`,
|
|
192
|
-
});
|
|
193
|
-
addCleanup(restoreStyles);
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// Also set CSS variable on the <tr> element itself
|
|
197
|
-
const restoreRowStyles = setStyles(row, {
|
|
198
|
-
[ITEM_TOP_VAR]: `${topPosition}px`,
|
|
199
|
-
});
|
|
200
|
-
addCleanup(restoreRowStyles);
|
|
201
|
-
|
|
202
|
-
// Update cumulative height for next row
|
|
203
|
-
const rowHeight = row.getBoundingClientRect().height;
|
|
204
|
-
if (index === 0) {
|
|
205
|
-
cumulativeHeight = rowHeight;
|
|
206
|
-
} else {
|
|
207
|
-
cumulativeHeight += rowHeight;
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// Set frontier variables with proper cleanup tracking
|
|
212
|
-
const restoreContainerStyles = setStyles(container, {
|
|
213
|
-
[FRONTIER_TOP_VAR]: `${cumulativeHeight}px`,
|
|
214
|
-
});
|
|
215
|
-
addCleanup(restoreContainerStyles);
|
|
216
|
-
|
|
217
|
-
if (elementReceivingCumulativeStickyPosition) {
|
|
218
|
-
const restoreCumulativeStyles = setStyles(
|
|
219
|
-
elementReceivingCumulativeStickyPosition,
|
|
220
|
-
{
|
|
221
|
-
[FRONTIER_TOP_VAR]: `${cumulativeHeight}px`,
|
|
222
|
-
},
|
|
223
|
-
);
|
|
224
|
-
addCleanup(restoreCumulativeStyles);
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const updateLinearPositions = () => {
|
|
229
|
-
// Handle linear container - detect direction from first sticky element
|
|
230
|
-
const stickyElements = element.querySelectorAll(
|
|
231
|
-
"[data-sticky-left], [data-sticky-top]",
|
|
232
|
-
);
|
|
233
|
-
if (stickyElements.length <= 1) return;
|
|
234
|
-
|
|
235
|
-
const firstElement = stickyElements[0];
|
|
236
|
-
const isHorizontal = firstElement.hasAttribute("data-sticky-left");
|
|
237
|
-
const dimensionProperty = isHorizontal ? "width" : "height";
|
|
238
|
-
const cssVariableName = isHorizontal ? ITEM_LEFT_VAR : ITEM_TOP_VAR;
|
|
239
|
-
|
|
240
|
-
let cumulativeSize = 0;
|
|
241
|
-
stickyElements.forEach((element, index) => {
|
|
242
|
-
if (index === 0) {
|
|
243
|
-
// First element stays at position 0
|
|
244
|
-
const restoreStyles = setStyles(element, {
|
|
245
|
-
[cssVariableName]: "0px",
|
|
246
|
-
});
|
|
247
|
-
addCleanup(restoreStyles);
|
|
248
|
-
cumulativeSize = element.getBoundingClientRect()[dimensionProperty];
|
|
249
|
-
} else {
|
|
250
|
-
// Subsequent elements use cumulative positioning
|
|
251
|
-
const position = cumulativeSize;
|
|
252
|
-
const restoreStyles = setStyles(element, {
|
|
253
|
-
[cssVariableName]: `${position}px`,
|
|
254
|
-
});
|
|
255
|
-
addCleanup(restoreStyles);
|
|
256
|
-
cumulativeSize += element.getBoundingClientRect()[dimensionProperty];
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
// Set frontier variables with proper cleanup tracking
|
|
261
|
-
const frontierVar = isHorizontal ? FRONTIER_LEFT_VAR : FRONTIER_TOP_VAR;
|
|
262
|
-
const restoreContainerStyles = setStyles(container, {
|
|
263
|
-
[frontierVar]: `${cumulativeSize}px`,
|
|
264
|
-
});
|
|
265
|
-
addCleanup(restoreContainerStyles);
|
|
266
|
-
|
|
267
|
-
if (elementReceivingCumulativeStickyPosition) {
|
|
268
|
-
const restoreCumulativeStyles = setStyles(
|
|
269
|
-
elementReceivingCumulativeStickyPosition,
|
|
270
|
-
{
|
|
271
|
-
[frontierVar]: `${cumulativeSize}px`,
|
|
272
|
-
},
|
|
273
|
-
);
|
|
274
|
-
addCleanup(restoreCumulativeStyles);
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
// Initial positioning
|
|
279
|
-
updatePositions();
|
|
280
|
-
|
|
281
|
-
// Set up ResizeObserver to handle size changes
|
|
282
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
283
|
-
updatePositions();
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
// Set up MutationObserver to handle DOM changes
|
|
287
|
-
const mutationObserver = new MutationObserver((mutations) => {
|
|
288
|
-
let shouldUpdate = false;
|
|
289
|
-
|
|
290
|
-
mutations.forEach((mutation) => {
|
|
291
|
-
// Check if sticky elements were added/removed or attributes changed
|
|
292
|
-
if (mutation.type === "childList") {
|
|
293
|
-
shouldUpdate = true;
|
|
294
|
-
}
|
|
295
|
-
if (mutation.type === "attributes") {
|
|
296
|
-
// Check if the mutation affects sticky attributes
|
|
297
|
-
if (
|
|
298
|
-
mutation.attributeName === "data-sticky-left" ||
|
|
299
|
-
mutation.attributeName === "data-sticky-top"
|
|
300
|
-
) {
|
|
301
|
-
shouldUpdate = true;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
if (shouldUpdate) {
|
|
307
|
-
updatePositions();
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
// Start observing
|
|
312
|
-
resizeObserver.observe(element);
|
|
313
|
-
addTeardown(() => {
|
|
314
|
-
resizeObserver.disconnect();
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
mutationObserver.observe(element, {
|
|
318
|
-
attributes: true,
|
|
319
|
-
childList: true,
|
|
320
|
-
subtree: true,
|
|
321
|
-
attributeFilter: ["data-sticky-left", "data-sticky-top"],
|
|
322
|
-
});
|
|
323
|
-
addTeardown(() => {
|
|
324
|
-
mutationObserver.disconnect();
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
// Return cleanup function
|
|
328
|
-
return () => {
|
|
329
|
-
teardown();
|
|
330
|
-
};
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
// const visualPositionEffect = (element, callback) => {
|
|
334
|
-
// const updatePosition = () => {
|
|
335
|
-
// const { left, top } = getVisualRect(element, document.body, {
|
|
336
|
-
// isStickyLeft: false,
|
|
337
|
-
// isStickyTop: false,
|
|
338
|
-
// });
|
|
339
|
-
// callback({ left, top });
|
|
340
|
-
// };
|
|
341
|
-
// updatePosition();
|
|
342
|
-
|
|
343
|
-
// window.addEventListener("scroll", updatePosition, { passive: true });
|
|
344
|
-
// window.addEventListener("resize", updatePosition);
|
|
345
|
-
// window.addEventListener("touchmove", updatePosition);
|
|
346
|
-
|
|
347
|
-
// return () => {
|
|
348
|
-
// window.removeEventListener("scroll", updatePosition, {
|
|
349
|
-
// passive: true,
|
|
350
|
-
// });
|
|
351
|
-
// window.removeEventListener("resize", updatePosition);
|
|
352
|
-
// window.removeEventListener("touchmove", updatePosition);
|
|
353
|
-
// };
|
|
354
|
-
// };
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { createContext } from "preact";
|
|
2
|
-
import { useMemo } from "preact/hooks";
|
|
3
|
-
|
|
4
|
-
import { useStableCallback } from "../../use_stable_callback.js";
|
|
5
|
-
|
|
6
|
-
export const TableStickyContext = createContext();
|
|
7
|
-
|
|
8
|
-
export const useTableStickyContextValue = ({
|
|
9
|
-
stickyLeftFrontierColumnIndex,
|
|
10
|
-
stickyTopFrontierRowIndex,
|
|
11
|
-
onStickyLeftFrontierChange,
|
|
12
|
-
onStickyTopFrontierChange,
|
|
13
|
-
}) => {
|
|
14
|
-
onStickyLeftFrontierChange = useStableCallback(onStickyLeftFrontierChange);
|
|
15
|
-
onStickyTopFrontierChange = useStableCallback(onStickyTopFrontierChange);
|
|
16
|
-
|
|
17
|
-
return useMemo(() => {
|
|
18
|
-
return {
|
|
19
|
-
stickyLeftFrontierColumnIndex,
|
|
20
|
-
stickyTopFrontierRowIndex,
|
|
21
|
-
onStickyLeftFrontierChange,
|
|
22
|
-
onStickyTopFrontierChange,
|
|
23
|
-
};
|
|
24
|
-
}, [stickyLeftFrontierColumnIndex, stickyTopFrontierRowIndex]);
|
|
25
|
-
};
|