Skip to content

Commit c715851

Browse files
Merge pull request #823 from buildo/add-table-column-dividers
Add vertical dividers to Table columns
2 parents 850df9c + 1f54cd2 commit c715851

File tree

5 files changed

+289
-26
lines changed

5 files changed

+289
-26
lines changed

packages/bento-design-system/src/Table/Config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ export type TableConfig = {
3737
iconButtonCell: CellPaddingConfig | undefined;
3838
};
3939
boundaryPadding: BentoSprinkles["padding"];
40+
columnDividers: boolean;
4041
};

packages/bento-design-system/src/Table/Table.css.ts

+168-22
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,133 @@ export const lastLeftStickyColumn = bentoSprinkles({
1414
paddingRight: 8,
1515
});
1616

17-
export const columnHeader = bentoSprinkles({
18-
display: "flex",
19-
flexDirection: "column",
20-
justifyContent: "center",
21-
boxShadow: "outlineDecorativeBottom",
22-
height: "full",
17+
export const columnHeader = strictRecipe({
18+
base: bentoSprinkles({
19+
display: "flex",
20+
flexDirection: "column",
21+
justifyContent: "center",
22+
height: "full",
23+
}),
24+
variants: {
25+
withDividers: {
26+
false: bentoSprinkles({
27+
boxShadow: "outlineDecorativeBottom",
28+
}),
29+
},
30+
first: {
31+
true: {},
32+
},
33+
lastLeftSticky: {
34+
true: {},
35+
},
36+
},
37+
compoundVariants: [
38+
{
39+
variants: {
40+
withDividers: true,
41+
first: true,
42+
lastLeftSticky: false,
43+
},
44+
style: bentoSprinkles({
45+
boxShadow: "outlineDecorativeBottom",
46+
}),
47+
},
48+
{
49+
variants: {
50+
withDividers: true,
51+
first: true,
52+
lastLeftSticky: true,
53+
},
54+
style: style({
55+
boxShadow: `inset -1px -1px ${vars.outlineColor.outlineDecorative}`,
56+
}),
57+
},
58+
{
59+
variants: {
60+
withDividers: true,
61+
first: false,
62+
lastLeftSticky: false,
63+
},
64+
style: style({
65+
boxShadow: `inset 1px -1px ${vars.outlineColor.outlineDecorative}`,
66+
}),
67+
},
68+
{
69+
variants: {
70+
withDividers: true,
71+
first: false,
72+
lastLeftSticky: true,
73+
},
74+
style: style({
75+
boxShadow: `inset 1px -1px ${vars.outlineColor.outlineDecorative}, inset -1px -1px ${vars.outlineColor.outlineDecorative}`,
76+
}),
77+
},
78+
],
2379
});
2480

25-
export const columnFooter = style([
26-
{
27-
boxShadow: `inset 0px 1px 0px ${vars.outlineColor.outlineDecorative}`,
28-
},
29-
bentoSprinkles({
81+
export const columnFooter = strictRecipe({
82+
base: bentoSprinkles({
3083
display: "flex",
3184
flexDirection: "column",
3285
justifyContent: "center",
3386
height: "full",
3487
}),
35-
]);
88+
variants: {
89+
withDividers: {
90+
false: style({
91+
boxShadow: `inset 0px 1px ${vars.outlineColor.outlineDecorative}`,
92+
}),
93+
},
94+
first: {
95+
true: {},
96+
},
97+
lastLeftSticky: {
98+
true: {},
99+
},
100+
},
101+
compoundVariants: [
102+
{
103+
variants: {
104+
withDividers: true,
105+
first: true,
106+
lastLeftSticky: false,
107+
},
108+
style: style({
109+
boxShadow: `inset 0px 1px ${vars.outlineColor.outlineDecorative}`,
110+
}),
111+
},
112+
{
113+
variants: {
114+
withDividers: true,
115+
first: true,
116+
lastLeftSticky: true,
117+
},
118+
style: style({
119+
boxShadow: `inset -1px 1px ${vars.outlineColor.outlineDecorative}`,
120+
}),
121+
},
122+
{
123+
variants: {
124+
withDividers: true,
125+
first: false,
126+
lastLeftSticky: false,
127+
},
128+
style: style({
129+
boxShadow: `inset 1px 1px ${vars.outlineColor.outlineDecorative}`,
130+
}),
131+
},
132+
{
133+
variants: {
134+
withDividers: true,
135+
first: false,
136+
lastLeftSticky: true,
137+
},
138+
style: style({
139+
boxShadow: `inset 1px 1px ${vars.outlineColor.outlineDecorative}, inset -1px 1px ${vars.outlineColor.outlineDecorative}`,
140+
}),
141+
},
142+
],
143+
});
36144

37145
export const sortIconContainer = style({
38146
filter: "opacity(80%)",
@@ -88,16 +196,11 @@ export const cellContainerRecipe = strictRecipe({
88196
},
89197
});
90198

91-
export const sectionHeaderContainer = style([
92-
{
93-
zIndex: 1,
94-
},
95-
bentoSprinkles({
96-
position: "sticky",
97-
left: 0,
98-
background: "backgroundPrimary",
99-
}),
100-
]);
199+
export const sectionHeaderContainer = bentoSprinkles({
200+
position: "sticky",
201+
left: 0,
202+
background: "backgroundPrimary",
203+
});
101204

102205
export const sectionHeader = bentoSprinkles({
103206
display: "inline-block",
@@ -106,3 +209,46 @@ export const sectionHeader = bentoSprinkles({
106209
paddingX: 24,
107210
paddingY: 4,
108211
});
212+
213+
export const cellColumnDivider = strictRecipe({
214+
base: style({
215+
boxShadow: `inset 1px 0px 0px ${vars.outlineColor.outlineDecorative}`,
216+
}),
217+
variants: {
218+
first: {
219+
true: {},
220+
},
221+
lastLeftSticky: {
222+
true: {},
223+
},
224+
},
225+
compoundVariants: [
226+
{
227+
variants: {
228+
first: true,
229+
lastLeftSticky: true,
230+
},
231+
style: style({
232+
boxShadow: `inset -1px 0px ${vars.outlineColor.outlineDecorative}`,
233+
}),
234+
},
235+
{
236+
variants: {
237+
first: false,
238+
lastLeftSticky: true,
239+
},
240+
style: style({
241+
boxShadow: `inset 1px 0px ${vars.outlineColor.outlineDecorative}, inset -1px 0px ${vars.outlineColor.outlineDecorative}`,
242+
}),
243+
},
244+
{
245+
variants: {
246+
first: true,
247+
lastLeftSticky: false,
248+
},
249+
style: style({
250+
boxShadow: "none",
251+
}),
252+
},
253+
],
254+
});

packages/bento-design-system/src/Table/Table.tsx

+26-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
vars,
3131
} from "..";
3232
import {
33+
cellColumnDivider,
3334
cellContainerRecipe,
3435
columnFooter,
3536
columnHeader,
@@ -110,6 +111,7 @@ type Props<
110111
height?: { custom: string | number };
111112
onRowPress?: (row: Row<RowType<C>>) => void;
112113
virtualizeRows?: boolean | { estimateRowHeight: (index: number) => number };
114+
columnDividers?: boolean;
113115
} & SortingProps<C>;
114116

115117
/**
@@ -150,6 +152,7 @@ export function Table<
150152
height,
151153
onRowPress,
152154
virtualizeRows: virtualizeRowsConfig,
155+
columnDividers,
153156
}: Props<C>) {
154157
const config = useBentoConfig().table;
155158
const customOrderByFn = useMemo(
@@ -367,6 +370,8 @@ export function Table<
367370
.map(({ gridWidth = "fit-content" }) => gridWidthStyle(gridWidth))
368371
.join(" ");
369372

373+
const withDividers = columnDividers ?? config.columnDividers;
374+
370375
function renderCells<D extends Record<string, unknown>>(
371376
cells: Array<Cell<D>>,
372377
rowIndex: number,
@@ -381,6 +386,7 @@ export function Table<
381386
first={index === 0}
382387
last={(index + 1) % flatColumns.length === 0}
383388
interactiveRow={interactiveRow}
389+
withDividers={withDividers}
384390
>
385391
{cell.render("Cell")}
386392
</CellContainer>
@@ -459,6 +465,7 @@ export function Table<
459465
}
460466
first={index === 0}
461467
last={index + 1 === flatColumns.length}
468+
withDividers={withDividers}
462469
/>
463470
))
464471
)}
@@ -482,6 +489,7 @@ export function Table<
482489
sticky={stickyLeftColumnsIds.includes(header.id)}
483490
first={index === 0}
484491
last={index + 1 === flatColumns.length}
492+
withDividers={withDividers}
485493
/>
486494
))}
487495
</Box>
@@ -523,6 +531,7 @@ function ColumnHeader<D extends Record<string, unknown>>({
523531
sticky,
524532
first,
525533
last,
534+
withDividers,
526535
}: {
527536
column: ColumnInstance<D> | HeaderGroup<D>;
528537
style: CSSProperties;
@@ -531,6 +540,7 @@ function ColumnHeader<D extends Record<string, unknown>>({
531540
sticky: boolean;
532541
first: boolean;
533542
last: boolean;
543+
withDividers: boolean;
534544
}) {
535545
const config = useBentoConfig().table;
536546

@@ -584,7 +594,7 @@ function ColumnHeader<D extends Record<string, unknown>>({
584594
}}
585595
>
586596
<Box
587-
className={columnHeader}
597+
className={[columnHeader({ withDividers, first, lastLeftSticky })]}
588598
background={config.headerBackgroundColor}
589599
color={config.headerForegroundColor}
590600
{...column.getHeaderProps(column.getSortByToggleProps())}
@@ -626,6 +636,7 @@ function ColumnFooter<D extends Record<string, unknown>>({
626636
sticky,
627637
first,
628638
last,
639+
withDividers,
629640
}: {
630641
column: ColumnInstance<D> | HeaderGroup<D>;
631642
style: CSSProperties;
@@ -634,6 +645,7 @@ function ColumnFooter<D extends Record<string, unknown>>({
634645
sticky: boolean;
635646
first: boolean;
636647
last: boolean;
648+
withDividers: boolean;
637649
}) {
638650
const config = useBentoConfig().table;
639651

@@ -646,7 +658,7 @@ function ColumnFooter<D extends Record<string, unknown>>({
646658
}}
647659
>
648660
<Box
649-
className={columnFooter}
661+
className={columnFooter({ withDividers, first, lastLeftSticky })}
650662
background={config.footerBackgroundColor}
651663
color={config.footerForegroundColor}
652664
{...column.getFooterProps()}
@@ -696,6 +708,7 @@ function SectionHeader({
696708
<Box
697709
className={sectionHeaderContainer}
698710
style={{
711+
zIndex: numberOfStickyColumns > 0 ? 1 : undefined,
699712
gridColumn: `1 / ${numberOfStickyColumns > 0 ? numberOfStickyColumns + 1 : -1}`,
700713
}}
701714
>
@@ -723,6 +736,7 @@ function CellContainer({
723736
first,
724737
last,
725738
interactiveRow,
739+
withDividers,
726740
...props
727741
}: {
728742
children: any;
@@ -732,14 +746,18 @@ function CellContainer({
732746
first: boolean;
733747
last: boolean;
734748
interactiveRow: boolean;
749+
withDividers: boolean;
735750
} & TableCellProps) {
736751
const tableConfig = useBentoConfig().table;
737752

738753
return (
739754
<Box className={lastLeftSticky && lastLeftStickyColumn} style={style}>
740755
<Box
741756
background={index % 2 === 0 ? tableConfig.evenRowsBackgroundColor : "backgroundPrimary"}
742-
className={cellContainerRecipe({ interactiveRow })}
757+
className={[
758+
cellContainerRecipe({ interactiveRow }),
759+
withDividers && cellColumnDivider({ first, lastLeftSticky }),
760+
]}
743761
paddingLeft={first ? tableConfig.boundaryPadding : undefined}
744762
paddingRight={last ? tableConfig.boundaryPadding : undefined}
745763
{...props}
@@ -758,7 +776,11 @@ export type {
758776
Row as TableRow,
759777
} from "react-table";
760778

761-
export type { Column as SimpleColumnType, Row as RowType } from "./types";
779+
export type {
780+
Column as SimpleColumnType,
781+
GroupedColumn as GroupedColumnType,
782+
Row as RowType,
783+
} from "./types";
762784

763785
export type { ColumnOptionsBase } from "./tableColumn";
764786
export type { Props as TableProps };

packages/bento-design-system/src/util/defaultConfigs.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ export const table: TableConfig = {
527527
iconButtonCell: { paddingX: 16, paddingY: 16 },
528528
},
529529
boundaryPadding: 8,
530+
columnDividers: false,
530531
};
531532

532533
export const toast: ToastConfig = {

0 commit comments

Comments
 (0)