mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-15 04:51:06 +02:00
add custom rowId support to lists
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Creates a function to extract row ID from an item based on the getRowId configuration.
|
||||
*
|
||||
* @param getRowId - Either a string property name, a function that extracts the ID, or undefined to use default 'id' property
|
||||
* @returns A function that extracts the row ID from an item
|
||||
*/
|
||||
export const createExtractRowId = (
|
||||
getRowId?: ((item: unknown) => string) | string,
|
||||
): ((item: unknown) => string | undefined) => {
|
||||
return (item: unknown): string | undefined => {
|
||||
if (!item || typeof item !== 'object') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (getRowId === undefined) {
|
||||
// Default behavior: use 'id' property
|
||||
return (item as any).id;
|
||||
}
|
||||
|
||||
if (typeof getRowId === 'string') {
|
||||
// getRowId is a property name
|
||||
return (item as any)[getRowId];
|
||||
}
|
||||
|
||||
// getRowId is a function
|
||||
return getRowId(item);
|
||||
};
|
||||
};
|
||||
@@ -46,12 +46,18 @@ export const getDraggedItems = (
|
||||
return [];
|
||||
}
|
||||
|
||||
const rowId = internalState.extractRowId(data);
|
||||
|
||||
if (!rowId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const draggedItem = data as ItemListStateItemWithRequiredProperties;
|
||||
|
||||
const previouslySelected = internalState.getSelected();
|
||||
const isDraggingSelectedItem = previouslySelected.some((selected) => {
|
||||
if (hasRequiredDragProperties(selected)) {
|
||||
return selected.id === data.id;
|
||||
return internalState.extractRowId(selected) === rowId;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -15,12 +15,16 @@ export const useDefaultItemListControls = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the full item instead of converting to minimal
|
||||
// Extract rowId from the item
|
||||
const rowId = internalState.extractRowId(item);
|
||||
if (!rowId) return;
|
||||
|
||||
// Use the item directly (rowId is separate, used only as key in state)
|
||||
const itemListItem = item as ItemListStateItemWithRequiredProperties;
|
||||
|
||||
// Check if ctrl/cmd key is held for multi-selection
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
const isCurrentlySelected = internalState.isSelected(item.id);
|
||||
const isCurrentlySelected = internalState.isSelected(rowId);
|
||||
|
||||
if (isCurrentlySelected) {
|
||||
// Remove this item from selection
|
||||
@@ -31,8 +35,7 @@ export const useDefaultItemListControls = () => {
|
||||
): selectedItem is ItemListStateItemWithRequiredProperties =>
|
||||
typeof selectedItem === 'object' &&
|
||||
selectedItem !== null &&
|
||||
'id' in selectedItem &&
|
||||
(selectedItem as any).id !== item.id,
|
||||
internalState.extractRowId(selectedItem) !== rowId,
|
||||
);
|
||||
internalState.setSelected(filteredSelected);
|
||||
} else {
|
||||
@@ -58,19 +61,18 @@ export const useDefaultItemListControls = () => {
|
||||
if (
|
||||
lastSelectedItem &&
|
||||
typeof lastSelectedItem === 'object' &&
|
||||
lastSelectedItem !== null &&
|
||||
'id' in lastSelectedItem
|
||||
lastSelectedItem !== null
|
||||
) {
|
||||
// Get the data array from internalState
|
||||
const data = internalState.getData();
|
||||
// Filter out null/undefined values (e.g., header row)
|
||||
const validData = data.filter(
|
||||
(d) => d && typeof d === 'object' && 'id' in d,
|
||||
);
|
||||
const validData = data.filter((d) => d && typeof d === 'object');
|
||||
|
||||
// Find the indices of the last selected item and current item
|
||||
const lastIndex = internalState.findItemIndex((lastSelectedItem as any).id);
|
||||
const currentIndex = internalState.findItemIndex(item.id);
|
||||
const lastRowId = internalState.extractRowId(lastSelectedItem);
|
||||
if (!lastRowId) return;
|
||||
const lastIndex = internalState.findItemIndex(lastRowId);
|
||||
const currentIndex = internalState.findItemIndex(rowId);
|
||||
|
||||
if (lastIndex !== -1 && currentIndex !== -1) {
|
||||
// Create range selection - select ALL items in the range
|
||||
@@ -83,13 +85,15 @@ export const useDefaultItemListControls = () => {
|
||||
if (
|
||||
rangeItem &&
|
||||
typeof rangeItem === 'object' &&
|
||||
'id' in rangeItem &&
|
||||
'_serverId' in rangeItem &&
|
||||
'itemType' in rangeItem
|
||||
) {
|
||||
rangeItems.push(
|
||||
rangeItem as ItemListStateItemWithRequiredProperties,
|
||||
);
|
||||
const rangeRowId = internalState.extractRowId(rangeItem);
|
||||
if (rangeRowId) {
|
||||
rangeItems.push(
|
||||
rangeItem as ItemListStateItemWithRequiredProperties,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +108,12 @@ export const useDefaultItemListControls = () => {
|
||||
),
|
||||
];
|
||||
rangeItems.forEach((rangeItem) => {
|
||||
const rangeRowId = internalState.extractRowId(rangeItem);
|
||||
if (
|
||||
rangeRowId &&
|
||||
!newSelected.some(
|
||||
(selected) => (selected as any).id === rangeItem.id,
|
||||
(selected) =>
|
||||
internalState.extractRowId(selected) === rangeRowId,
|
||||
)
|
||||
) {
|
||||
newSelected.push(rangeItem);
|
||||
@@ -126,8 +133,7 @@ export const useDefaultItemListControls = () => {
|
||||
selectedItems.length === 1 &&
|
||||
typeof selectedItems[0] === 'object' &&
|
||||
selectedItems[0] !== null &&
|
||||
'id' in selectedItems[0] &&
|
||||
(selectedItems[0] as any).id === item.id;
|
||||
internalState.extractRowId(selectedItems[0]) === rowId;
|
||||
|
||||
if (isOnlySelected) {
|
||||
internalState.clearSelected();
|
||||
@@ -146,9 +152,14 @@ export const useDefaultItemListControls = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
return internalState?.toggleExpanded(
|
||||
item as ItemListStateItemWithRequiredProperties,
|
||||
);
|
||||
// Extract rowId from the item
|
||||
const rowId = internalState.extractRowId(item);
|
||||
if (!rowId) return;
|
||||
|
||||
// Use the item directly (rowId is separate, used only as key in state)
|
||||
const itemListItem = item as ItemListStateItemWithRequiredProperties;
|
||||
|
||||
return internalState?.toggleExpanded(itemListItem);
|
||||
},
|
||||
|
||||
onFavorite: ({
|
||||
|
||||
@@ -21,27 +21,47 @@ export const itemGridActions = {
|
||||
type: 'CLEAR_SELECTED',
|
||||
}),
|
||||
|
||||
setDragging: (items: ItemListStateItemWithRequiredProperties[]): ItemListAction => ({
|
||||
setDragging: (
|
||||
items: ItemListStateItemWithRequiredProperties[],
|
||||
extractRowId: (item: unknown) => string | undefined,
|
||||
): ItemListAction => ({
|
||||
extractRowId,
|
||||
payload: items,
|
||||
type: 'SET_DRAGGING',
|
||||
}),
|
||||
|
||||
setExpanded: (items: ItemListStateItemWithRequiredProperties[]): ItemListAction => ({
|
||||
setExpanded: (
|
||||
items: ItemListStateItemWithRequiredProperties[],
|
||||
extractRowId: (item: unknown) => string | undefined,
|
||||
): ItemListAction => ({
|
||||
extractRowId,
|
||||
payload: items,
|
||||
type: 'SET_EXPANDED',
|
||||
}),
|
||||
|
||||
setSelected: (items: ItemListStateItemWithRequiredProperties[]): ItemListAction => ({
|
||||
setSelected: (
|
||||
items: ItemListStateItemWithRequiredProperties[],
|
||||
extractRowId: (item: unknown) => string | undefined,
|
||||
): ItemListAction => ({
|
||||
extractRowId,
|
||||
payload: items,
|
||||
type: 'SET_SELECTED',
|
||||
}),
|
||||
|
||||
toggleExpanded: (item: ItemListStateItemWithRequiredProperties): ItemListAction => ({
|
||||
toggleExpanded: (
|
||||
item: ItemListStateItemWithRequiredProperties,
|
||||
extractRowId: (item: unknown) => string | undefined,
|
||||
): ItemListAction => ({
|
||||
extractRowId,
|
||||
payload: item,
|
||||
type: 'TOGGLE_EXPANDED',
|
||||
}),
|
||||
|
||||
toggleSelected: (item: ItemListStateItemWithRequiredProperties): ItemListAction => ({
|
||||
toggleSelected: (
|
||||
item: ItemListStateItemWithRequiredProperties,
|
||||
extractRowId: (item: unknown) => string | undefined,
|
||||
): ItemListAction => ({
|
||||
extractRowId,
|
||||
payload: item,
|
||||
type: 'TOGGLE_SELECTED',
|
||||
}),
|
||||
@@ -104,16 +124,16 @@ export const itemGridSelectors = {
|
||||
return state.selected.size > 0;
|
||||
},
|
||||
|
||||
isDragging: (state: ItemListState, itemId: string): boolean => {
|
||||
return state.dragging.has(itemId);
|
||||
isDragging: (state: ItemListState, rowId: string): boolean => {
|
||||
return state.dragging.has(rowId);
|
||||
},
|
||||
|
||||
isExpanded: (state: ItemListState, itemId: string): boolean => {
|
||||
return state.expanded.has(itemId);
|
||||
isExpanded: (state: ItemListState, rowId: string): boolean => {
|
||||
return state.expanded.has(rowId);
|
||||
},
|
||||
|
||||
isSelected: (state: ItemListState, itemId: string): boolean => {
|
||||
return state.selected.has(itemId);
|
||||
isSelected: (state: ItemListState, rowId: string): boolean => {
|
||||
return state.selected.has(rowId);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -121,15 +141,15 @@ export const itemListUtils = {
|
||||
/**
|
||||
* Check if all items in a list are selected
|
||||
*/
|
||||
areAllSelected: (state: ItemListState, itemIds: string[]): boolean => {
|
||||
return itemIds.every((id) => state.selected.has(id));
|
||||
areAllSelected: (state: ItemListState, rowIds: string[]): boolean => {
|
||||
return rowIds.every((id) => state.selected.has(id));
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if any items in a list are selected
|
||||
*/
|
||||
areAnySelected: (state: ItemListState, itemIds: string[]): boolean => {
|
||||
return itemIds.some((id) => state.selected.has(id));
|
||||
areAnySelected: (state: ItemListState, rowIds: string[]): boolean => {
|
||||
return rowIds.some((id) => state.selected.has(id));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -152,9 +172,15 @@ export const itemListUtils = {
|
||||
toggleAllExpanded: (
|
||||
items: ItemListStateItemWithRequiredProperties[],
|
||||
currentState: ItemListState,
|
||||
extractRowId: (item: unknown) => string | undefined,
|
||||
): ItemListAction => {
|
||||
const allExpanded = items.every((item) => currentState.expanded.has(item.id));
|
||||
return allExpanded ? itemGridActions.clearExpanded() : itemGridActions.setExpanded(items);
|
||||
const allExpanded = items.every((item) => {
|
||||
const rowId = extractRowId(item);
|
||||
return rowId ? currentState.expanded.has(rowId) : false;
|
||||
});
|
||||
return allExpanded
|
||||
? itemGridActions.clearExpanded()
|
||||
: itemGridActions.setExpanded(items, extractRowId);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -163,8 +189,14 @@ export const itemListUtils = {
|
||||
toggleAllSelected: (
|
||||
items: ItemListStateItemWithRequiredProperties[],
|
||||
currentState: ItemListState,
|
||||
extractRowId: (item: unknown) => string | undefined,
|
||||
): ItemListAction => {
|
||||
const allSelected = items.every((item) => currentState.selected.has(item.id));
|
||||
return allSelected ? itemGridActions.clearSelected() : itemGridActions.setSelected(items);
|
||||
const allSelected = items.every((item) => {
|
||||
const rowId = extractRowId(item);
|
||||
return rowId ? currentState.selected.has(rowId) : false;
|
||||
});
|
||||
return allSelected
|
||||
? itemGridActions.clearSelected()
|
||||
: itemGridActions.setSelected(items, extractRowId);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -4,11 +4,31 @@ import { itemGridSelectors } from '/@/renderer/components/item-list/helpers/item
|
||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||
|
||||
export type ItemListAction =
|
||||
| { payload: ItemListStateItemWithRequiredProperties; type: 'TOGGLE_EXPANDED' }
|
||||
| { payload: ItemListStateItemWithRequiredProperties; type: 'TOGGLE_SELECTED' }
|
||||
| { payload: ItemListStateItemWithRequiredProperties[]; type: 'SET_DRAGGING' }
|
||||
| { payload: ItemListStateItemWithRequiredProperties[]; type: 'SET_EXPANDED' }
|
||||
| { payload: ItemListStateItemWithRequiredProperties[]; type: 'SET_SELECTED' }
|
||||
| {
|
||||
extractRowId: (item: unknown) => string | undefined;
|
||||
payload: ItemListStateItemWithRequiredProperties;
|
||||
type: 'TOGGLE_EXPANDED';
|
||||
}
|
||||
| {
|
||||
extractRowId: (item: unknown) => string | undefined;
|
||||
payload: ItemListStateItemWithRequiredProperties;
|
||||
type: 'TOGGLE_SELECTED';
|
||||
}
|
||||
| {
|
||||
extractRowId: (item: unknown) => string | undefined;
|
||||
payload: ItemListStateItemWithRequiredProperties[];
|
||||
type: 'SET_DRAGGING';
|
||||
}
|
||||
| {
|
||||
extractRowId: (item: unknown) => string | undefined;
|
||||
payload: ItemListStateItemWithRequiredProperties[];
|
||||
type: 'SET_EXPANDED';
|
||||
}
|
||||
| {
|
||||
extractRowId: (item: unknown) => string | undefined;
|
||||
payload: ItemListStateItemWithRequiredProperties[];
|
||||
type: 'SET_SELECTED';
|
||||
}
|
||||
| { type: 'CLEAR_ALL' }
|
||||
| { type: 'CLEAR_DRAGGING' }
|
||||
| { type: 'CLEAR_EXPANDED' }
|
||||
@@ -29,7 +49,8 @@ export interface ItemListStateActions {
|
||||
clearDragging: () => void;
|
||||
clearExpanded: () => void;
|
||||
clearSelected: () => void;
|
||||
findItemIndex: (itemId: string) => number;
|
||||
extractRowId: (item: unknown) => string | undefined;
|
||||
findItemIndex: (rowId: string) => number;
|
||||
getData: () => unknown[];
|
||||
getDragging: () => unknown[];
|
||||
getDraggingIds: () => string[];
|
||||
@@ -41,9 +62,9 @@ export interface ItemListStateActions {
|
||||
hasDragging: () => boolean;
|
||||
hasExpanded: () => boolean;
|
||||
hasSelected: () => boolean;
|
||||
isDragging: (itemId: string) => boolean;
|
||||
isExpanded: (itemId: string) => boolean;
|
||||
isSelected: (itemId: string) => boolean;
|
||||
isDragging: (rowId: string) => boolean;
|
||||
isExpanded: (rowId: string) => boolean;
|
||||
isSelected: (rowId: string) => boolean;
|
||||
setDragging: (items: ItemListStateItemWithRequiredProperties[]) => void;
|
||||
setExpanded: (items: ItemListStateItemWithRequiredProperties[]) => void;
|
||||
setSelected: (items: ItemListStateItemWithRequiredProperties[]) => void;
|
||||
@@ -110,8 +131,11 @@ export const itemListReducer = (state: ItemListState, action: ItemListAction): I
|
||||
const newDraggingItems = new Map<string, unknown>();
|
||||
|
||||
action.payload.forEach((item) => {
|
||||
newDragging.add(item.id);
|
||||
newDraggingItems.set(item.id, item);
|
||||
const rowId = action.extractRowId(item);
|
||||
if (rowId) {
|
||||
newDragging.add(rowId);
|
||||
newDraggingItems.set(rowId, item);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -128,8 +152,11 @@ export const itemListReducer = (state: ItemListState, action: ItemListAction): I
|
||||
|
||||
if (action.payload.length > 0) {
|
||||
const firstItem = action.payload[0];
|
||||
newExpanded.add(firstItem.id);
|
||||
newExpandedItems.set(firstItem.id, firstItem);
|
||||
const rowId = action.extractRowId(firstItem);
|
||||
if (rowId) {
|
||||
newExpanded.add(rowId);
|
||||
newExpandedItems.set(rowId, firstItem);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -145,8 +172,11 @@ export const itemListReducer = (state: ItemListState, action: ItemListAction): I
|
||||
const newSelectedItems = new Map<string, unknown>();
|
||||
|
||||
action.payload.forEach((item) => {
|
||||
newSelected.add(item.id);
|
||||
newSelectedItems.set(item.id, item);
|
||||
const rowId = action.extractRowId(item);
|
||||
if (rowId) {
|
||||
newSelected.add(rowId);
|
||||
newSelectedItems.set(rowId, item);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -161,13 +191,18 @@ export const itemListReducer = (state: ItemListState, action: ItemListAction): I
|
||||
const newExpanded = new Set<string>();
|
||||
const newExpandedItems = new Map<string, unknown>();
|
||||
|
||||
const rowId = action.extractRowId(action.payload);
|
||||
if (!rowId) {
|
||||
return state;
|
||||
}
|
||||
|
||||
// If the item is already expanded, collapse it
|
||||
if (state.expanded.has(action.payload.id)) {
|
||||
if (state.expanded.has(rowId)) {
|
||||
// Item is expanded, so collapse it (leave sets empty)
|
||||
} else {
|
||||
// Item is not expanded, so expand it (clear others first for single expansion)
|
||||
newExpanded.add(action.payload.id);
|
||||
newExpandedItems.set(action.payload.id, action.payload);
|
||||
newExpanded.add(rowId);
|
||||
newExpandedItems.set(rowId, action.payload);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -182,12 +217,17 @@ export const itemListReducer = (state: ItemListState, action: ItemListAction): I
|
||||
const newSelected = new Set(state.selected);
|
||||
const newSelectedItems = new Map(state.selectedItems);
|
||||
|
||||
if (newSelected.has(action.payload.id)) {
|
||||
newSelected.delete(action.payload.id);
|
||||
newSelectedItems.delete(action.payload.id);
|
||||
const rowId = action.extractRowId(action.payload);
|
||||
if (!rowId) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (newSelected.has(rowId)) {
|
||||
newSelected.delete(rowId);
|
||||
newSelectedItems.delete(rowId);
|
||||
} else {
|
||||
newSelected.add(action.payload.id);
|
||||
newSelectedItems.set(action.payload.id, action.payload);
|
||||
newSelected.add(rowId);
|
||||
newSelectedItems.set(rowId, action.payload);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -213,39 +253,91 @@ export const initialItemListState: ItemListState = {
|
||||
version: 0,
|
||||
};
|
||||
|
||||
export const useItemListState = (getDataFn?: () => unknown[]): ItemListStateActions => {
|
||||
export const useItemListState = (
|
||||
getDataFn?: () => unknown[],
|
||||
extractRowId?: (item: unknown) => string | undefined,
|
||||
): ItemListStateActions => {
|
||||
const [state, dispatch] = useReducer(itemListReducer, initialItemListState);
|
||||
|
||||
const setExpanded = useCallback((items: ItemListStateItemWithRequiredProperties[]) => {
|
||||
dispatch({ payload: items, type: 'SET_EXPANDED' });
|
||||
}, []);
|
||||
const extractRowIdFn = useCallback(
|
||||
(item: unknown) => {
|
||||
if (extractRowId) {
|
||||
return extractRowId(item);
|
||||
}
|
||||
// Fallback to id if extractRowId is not provided
|
||||
if (item && typeof item === 'object' && 'id' in item) {
|
||||
return (item as any).id;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
[extractRowId],
|
||||
);
|
||||
|
||||
const setDragging = useCallback((items: ItemListStateItemWithRequiredProperties[]) => {
|
||||
dispatch({ payload: items, type: 'SET_DRAGGING' });
|
||||
}, []);
|
||||
const setExpanded = useCallback(
|
||||
(items: ItemListStateItemWithRequiredProperties[]) => {
|
||||
dispatch({
|
||||
extractRowId: extractRowIdFn,
|
||||
payload: items,
|
||||
type: 'SET_EXPANDED',
|
||||
});
|
||||
},
|
||||
[extractRowIdFn],
|
||||
);
|
||||
|
||||
const setSelected = useCallback((items: ItemListStateItemWithRequiredProperties[]) => {
|
||||
dispatch({ payload: items, type: 'SET_SELECTED' });
|
||||
}, []);
|
||||
const setDragging = useCallback(
|
||||
(items: ItemListStateItemWithRequiredProperties[]) => {
|
||||
dispatch({
|
||||
extractRowId: extractRowIdFn,
|
||||
payload: items,
|
||||
type: 'SET_DRAGGING',
|
||||
});
|
||||
},
|
||||
[extractRowIdFn],
|
||||
);
|
||||
|
||||
const toggleExpanded = useCallback((item: ItemListStateItemWithRequiredProperties) => {
|
||||
dispatch({ payload: item, type: 'TOGGLE_EXPANDED' });
|
||||
}, []);
|
||||
const setSelected = useCallback(
|
||||
(items: ItemListStateItemWithRequiredProperties[]) => {
|
||||
dispatch({
|
||||
extractRowId: extractRowIdFn,
|
||||
payload: items,
|
||||
type: 'SET_SELECTED',
|
||||
});
|
||||
},
|
||||
[extractRowIdFn],
|
||||
);
|
||||
|
||||
const toggleSelected = useCallback((item: ItemListStateItemWithRequiredProperties) => {
|
||||
dispatch({ payload: item, type: 'TOGGLE_SELECTED' });
|
||||
}, []);
|
||||
const toggleExpanded = useCallback(
|
||||
(item: ItemListStateItemWithRequiredProperties) => {
|
||||
dispatch({
|
||||
extractRowId: extractRowIdFn,
|
||||
payload: item,
|
||||
type: 'TOGGLE_EXPANDED',
|
||||
});
|
||||
},
|
||||
[extractRowIdFn],
|
||||
);
|
||||
|
||||
const toggleSelected = useCallback(
|
||||
(item: ItemListStateItemWithRequiredProperties) => {
|
||||
dispatch({
|
||||
extractRowId: extractRowIdFn,
|
||||
payload: item,
|
||||
type: 'TOGGLE_SELECTED',
|
||||
});
|
||||
},
|
||||
[extractRowIdFn],
|
||||
);
|
||||
|
||||
const isExpanded = useCallback(
|
||||
(itemId: string) => {
|
||||
return itemGridSelectors.isExpanded(state, itemId);
|
||||
(rowId: string) => {
|
||||
return itemGridSelectors.isExpanded(state, rowId);
|
||||
},
|
||||
[state],
|
||||
);
|
||||
|
||||
const isSelected = useCallback(
|
||||
(itemId: string) => {
|
||||
return itemGridSelectors.isSelected(state, itemId);
|
||||
(rowId: string) => {
|
||||
return itemGridSelectors.isSelected(state, rowId);
|
||||
},
|
||||
[state],
|
||||
);
|
||||
@@ -307,8 +399,8 @@ export const useItemListState = (getDataFn?: () => unknown[]): ItemListStateActi
|
||||
}, [state]);
|
||||
|
||||
const isDragging = useCallback(
|
||||
(itemId: string) => {
|
||||
return itemGridSelectors.isDragging(state, itemId);
|
||||
(rowId: string) => {
|
||||
return itemGridSelectors.isDragging(state, rowId);
|
||||
},
|
||||
[state],
|
||||
);
|
||||
@@ -318,13 +410,17 @@ export const useItemListState = (getDataFn?: () => unknown[]): ItemListStateActi
|
||||
}, [getDataFn]);
|
||||
|
||||
const findItemIndex = useCallback(
|
||||
(itemId: string) => {
|
||||
(rowId: string) => {
|
||||
const data = getDataFn ? getDataFn() : [];
|
||||
// Filter out null/undefined values (e.g., header row)
|
||||
const validData = data.filter((d) => d && typeof d === 'object' && 'id' in d);
|
||||
return validData.findIndex((d) => (d as any).id === itemId);
|
||||
const validData = data.filter((d) => d && typeof d === 'object');
|
||||
if (!extractRowId) {
|
||||
// Fallback to id if extractRowId is not provided
|
||||
return validData.findIndex((d) => (d as any).id === rowId);
|
||||
}
|
||||
return validData.findIndex((d) => extractRowId(d) === rowId);
|
||||
},
|
||||
[getDataFn],
|
||||
[getDataFn, extractRowId],
|
||||
);
|
||||
|
||||
return useMemo(
|
||||
@@ -333,6 +429,7 @@ export const useItemListState = (getDataFn?: () => unknown[]): ItemListStateActi
|
||||
clearDragging,
|
||||
clearExpanded,
|
||||
clearSelected,
|
||||
extractRowId: extractRowIdFn,
|
||||
findItemIndex,
|
||||
getData,
|
||||
getDragging,
|
||||
@@ -359,6 +456,7 @@ export const useItemListState = (getDataFn?: () => unknown[]): ItemListStateActi
|
||||
clearDragging,
|
||||
clearExpanded,
|
||||
clearSelected,
|
||||
extractRowIdFn,
|
||||
findItemIndex,
|
||||
getData,
|
||||
getDragging,
|
||||
|
||||
Reference in New Issue
Block a user