Skip to content

Commit

Permalink
fix(Table): hideable columns action
Browse files Browse the repository at this point in the history
  • Loading branch information
adarshpastakia committed Oct 13, 2024
1 parent 912c0ac commit e638f5f
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 11 deletions.
44 changes: 44 additions & 0 deletions packages/data/src/table/AddColumn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* React Fabric
* @version: 1.0.0
*
*
* The MIT License (MIT)
* Copyright (c) 2024 Adarsh Pastakia
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { CoreIcons, Dropdown, Icon, Menu, MenuItem } from "@react-fabric/core";
import { type ColumnType } from "./types";

export const AddColumn = ({ columns }: { columns: ColumnType[] }) => {
return (
<div className="group font-medium border-e w-6 flex flex-nowrap text-start items-center">
<Dropdown>
<Icon icon={CoreIcons.insert} className="p-1" />
<Menu className="text-sm">
{columns.map((col) => (
<MenuItem
key={String(col.id)}
label={`${col.label ?? String(col.id)}`}
icon={!col.hidden ? CoreIcons.tick : ""}
/>
))}
</Menu>
</Dropdown>
</div>
);
};
39 changes: 36 additions & 3 deletions packages/data/src/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { useDebounce } from "@react-fabric/core";
import {
CoreIcons,
Dropdown,
Icon,
Menu,
MenuItem,
useDebounce,
} from "@react-fabric/core";
import classNames from "classnames";
import { useCallback, useMemo } from "react";
import { BodyCell } from "./BodyCell";
Expand All @@ -36,6 +43,7 @@ export const Table = <T extends KeyValue = KeyValue>({
columns,
keyProperty,
checkableRows,
hideableColumns,
onRowClick,
onCheckedChanged,
}: TableProps<T>) => {
Expand All @@ -44,7 +52,7 @@ export const Table = <T extends KeyValue = KeyValue>({
[],
);

const { state } = useTableColumns(columns);
const { state, onHide } = useTableColumns(columns);
const {
scrollerRef,
items,
Expand Down Expand Up @@ -100,6 +108,26 @@ export const Table = <T extends KeyValue = KeyValue>({
{state.cols?.map((col, idx) => <HeaderCell key={idx} {...col} />)}
<div className={wrapperEnd}>
{state.end?.map((col, idx) => <HeaderCell key={idx} {...col} />)}

{hideableColumns && (
<div className="group font-medium border-e w-6 flex flex-nowrap text-start items-center">
<Dropdown placement="bottom-end">
<Icon icon={CoreIcons.insert} className="p-1" />
<Menu className="text-xs" onClick={onHide}>
{state.columns
.filter((col) => col.hideable !== false)
.map((col) => (
<MenuItem
key={String(col.id)}
id={String(col.id)}
label={`${col.label ?? String(col.id)}`}
icon={!col.hidden ? CoreIcons.tick : ""}
/>
))}
</Menu>
</Dropdown>
</div>
)}
</div>
</div>
<div
Expand Down Expand Up @@ -142,6 +170,7 @@ export const Table = <T extends KeyValue = KeyValue>({
{state.end?.map((col, ide) => (
<BodyCell key={`${key}:${ide}`} column={col} item={data} />
))}
{hideableColumns && <div className="w-6" />}
</div>
</div>
);
Expand All @@ -152,7 +181,11 @@ export const Table = <T extends KeyValue = KeyValue>({
{state.start?.map(emptyCol)}
</div>
{state.cols?.map(emptyCol)}
<div className={wrapperEnd}>{state.end?.map(emptyCol)}</div>
<div className={wrapperEnd}>
{state.end?.map(emptyCol)}

{hideableColumns && <div className="w-6" />}
</div>
</div>
</div>
<div className="area-foot bg-dimmed border-t sticky bottom-0 flex flex-nowrap z-2">
Expand Down
2 changes: 2 additions & 0 deletions packages/data/src/table/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,7 @@ export interface TableProps<T = KeyValue> {
checkableRows?: boolean;
onCheckedChanged?: (rows: Array<keyof T>) => void;

hideableColumns?: boolean;

onRowClick?: (data: T) => void;
}
28 changes: 22 additions & 6 deletions packages/data/src/table/useTableColumns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,36 @@ interface ColumnState {

type ColumnActions =
| { type: "columns"; columns: ColumnType[] }
| { type: "hide"; id: string }
| { type: "unhide"; id: string };
| { type: "hide"; id: string };

export const useTableColumns = (columns: ColumnType[]) => {
const [state, dispatch] = useReducer(
(state: ColumnState, action: ColumnActions) => {
if (action.type === "columns") {
state.columns = action.columns;
}
const grouped = groupBy(
state.columns.filter((col) => !(col.hideable && col.hidden)),
if (action.type === "hide") {
const col = state.columns.find((col) => col.id === action.id);
col &&
state.columns.splice(state.columns.indexOf(col), 1, {
...col,
hidden: col.hidden !== true,
});
}
const {
start = [],
end = [],
cols = [],
} = groupBy(
state.columns.filter((col) => col.hidden !== true),
"locked",
"cols",
);
return {
...state,
...grouped,
start,
end,
cols,
};
},
{
Expand All @@ -65,5 +78,8 @@ export const useTableColumns = (columns: ColumnType[]) => {
dispatch({ type: "columns", columns });
}, [columns]);

return { state };
return {
state,
onHide: (id: string) => dispatch({ type: "hide", id }),
};
};
22 changes: 20 additions & 2 deletions packages/data/stories/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const _Table: Story = {
width: "3rem",
align: "center",
locked: "start",
hideable: false,
renderer(_, data) {
return <Icon icon={`flag ${data.iso2}`} />;
},
Expand All @@ -70,34 +71,51 @@ export const _Table: Story = {
id: "iso2",
width: "3rem",
locked: "start",
hideable: false,
},
{
id: "name",
label: "Name",
locked: "start",
width: "32rem",
hideable: false,
resizable: true,
},
{
id: "continent",
label: "Continent",
width: "12rem",
hidden: true,
},
{
id: "fullname",
label: "Fullname",
width: "48rem",
hidden: true,
},
{
id: "capital",
label: "Capital",
width: "48rem",
hidden: true,
},
{
id: "currency",
label: "Currency",
width: "8rem",
locked: "end",
hidden: true,
},
{
id: "phone",
label: "Phone",
width: "8rem",
locked: "end",
hidden: true,
},
{
id: "tld",
label: "Domain",
width: "8rem",
hidden: true,
},
]}
/>
Expand Down

0 comments on commit e638f5f

Please sign in to comment.