Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Clicking the "Manage columns" button will open the column management modal. The

### With drag and drop reordering

When `enableDragDrop` is set to `true`, users can drag and drop columns to reorder them. The order changes are reflected both in the modal and in the table when applied. This is useful when column order matters for the user experience.
When `enableDragDrop` is set to `true`, users can drag and drop columns to reorder them. The order changes are reflected both in the modal and in the table when applied. Select a column's **Sticky** checkbox to keep it at its current position; other columns cannot be moved into that position. The `isSticky` column property reflects this selection. In this example, the first `ID` column is sticky.

```js file="./ColumnManagementModalDragDropExample.tsx"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const DEFAULT_COLUMNS: ColumnManagementModalColumn[] = [
key: 'id',
isShownByDefault: true,
isShown: true,
isUntoggleable: true
isUntoggleable: true,
isSticky: true
},
{
title: 'Publish date',
Expand Down Expand Up @@ -128,4 +129,4 @@ export const ColumnManagementModalDragDropExample: FunctionComponent = () => {
</Table>
</>
);
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export interface ColumnManagementModalColumn {
isShownByDefault: boolean;
/** The checkbox will be disabled, this is applicable to columns which should not be toggleable by user */
isUntoggleable?: boolean;
/** Keep this column at its current position when columns are reordered */
isSticky?: boolean;
}

/** extends ModalProps */
Expand Down Expand Up @@ -74,7 +76,8 @@ const ColumnManagementModal: FunctionComponent<ColumnManagementModalProps> = (
title: column.title,
isSelected: column.isShown,
isShownByDefault: column.isShownByDefault,
isUntoggleable: column.isUntoggleable
isUntoggleable: column.isUntoggleable,
isSticky: column.isSticky
}));

const resetToDefault = () => {
Expand All @@ -87,7 +90,11 @@ const ColumnManagementModal: FunctionComponent<ColumnManagementModalProps> = (
const newColumns = currentColumns.map(column => {
const matchingItem = items.find(item => item.key === column.key);
return matchingItem
? { ...column, isShown: matchingItem.isSelected ?? column.isShownByDefault }
? {
...column,
isShown: matchingItem.isSelected ?? column.isShownByDefault,
isSticky: matchingItem.isSticky ?? column.isSticky
}
: column;
});
setCurrentColumns(newColumns);
Expand All @@ -97,6 +104,10 @@ const ColumnManagementModal: FunctionComponent<ColumnManagementModalProps> = (
updateColumns([ item ]);
};

const handleStickyChange = (item: ListManagerItem) => {
updateColumns([ item ]);
};

const handleSelectAll = (items: ListManagerItem[]) => {
updateColumns(items);
};
Expand All @@ -108,7 +119,11 @@ const ColumnManagementModal: FunctionComponent<ColumnManagementModalProps> = (
if (!originalColumn) {
throw new Error(`Column with key ${item.key} not found`);
}
return { ...originalColumn, isShown: item.isSelected ?? originalColumn.isShownByDefault };
return {
...originalColumn,
isShown: item.isSelected ?? originalColumn.isShownByDefault,
isSticky: item.isSticky ?? originalColumn.isSticky
};
});
setCurrentColumns(newColumns);
};
Expand All @@ -119,7 +134,8 @@ const ColumnManagementModal: FunctionComponent<ColumnManagementModalProps> = (
title: item.title,
isShown: item.isSelected,
isShownByDefault: item.isShownByDefault,
isUntoggleable: item.isUntoggleable
isUntoggleable: item.isUntoggleable,
isSticky: item.isSticky
}));
applyColumns(updatedColumns);
onClose({} as KeyboardEvent);
Expand Down Expand Up @@ -150,6 +166,7 @@ const ColumnManagementModal: FunctionComponent<ColumnManagementModalProps> = (
columns={listManagerItems}
ouiaId={ouiaId}
onSelect={handleSelect}
onStickyChange={handleStickyChange}
onSelectAll={handleSelectAll}
onOrderChange={handleOrderChange}
onSave={handleSave}
Expand Down
15 changes: 13 additions & 2 deletions packages/module/src/ListManager/ListManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export interface ListManagerItem {
isShownByDefault: boolean;
/** The checkbox will be disabled, this is applicable to columns which should not be toggleable by user */
isUntoggleable?: boolean;
/** Keep this column at its current position when columns are reordered */
isSticky?: boolean;
}

export interface ListManagerProps {
Expand All @@ -36,6 +38,8 @@ export interface ListManagerProps {
ouiaId?: string | number;
/** Callback when a column is selected or deselected */
onSelect?: (column: ListManagerItem) => void;
/** Callback when a column's sticky state changes */
onStickyChange?: (column: ListManagerItem) => void;
/** Callback when all columns are selected or deselected */
onSelectAll?: (columns: ListManagerItem[]) => void;
/** Callback when the column order changes */
Expand Down Expand Up @@ -75,7 +79,7 @@ const ListManager: FunctionComponent<ListManagerProps> = (
const newColumns = [ ...currentColumns ];
const index = newColumns.findIndex(col => col.key === columnKey);
if (index === -1) {return;}

const changedColumn = { ...newColumns[index] };
changedColumn.isSelected = !changedColumn.isSelected;
newColumns[index] = changedColumn;
Expand All @@ -85,13 +89,20 @@ const ListManager: FunctionComponent<ListManagerProps> = (
};

const onDrag = (_event: unknown, newOrder: DraggableObject[]) => {
const newColumns = newOrder.map((item: DraggableObject) => {
const reorderedColumns = newOrder.map((item: DraggableObject) => {
const found = currentColumns.find(c => c.key === String(item.id));
if (!found) {
throw new Error(`Column with key ${item.id} not found`);
}
return found;
});

// Sticky columns reserve their current positions. Reorder only the remaining columns.
const reorderedNonStickyColumns = reorderedColumns.filter(column => !column.isSticky);
let nonStickyIndex = 0;
const newColumns = currentColumns.map(column => (
column.isSticky ? column : reorderedNonStickyColumns[nonStickyIndex++]
));
setCurrentColumns(newColumns);
onOrderChange?.(newColumns);
};
Expand Down
Loading