Skip to content

Commit b4c881d

Browse files
authored
Merge pull request #825 from buildo/table_cells_config
Add Table configs for header/footer size and default cells options
2 parents ece8548 + 736c90f commit b4c881d

File tree

6 files changed

+166
-30
lines changed

6 files changed

+166
-30
lines changed

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

+27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@ import { TooltipPlacement } from "../Field/FieldProps";
22
import { IconProps } from "../Icons";
33
import { BentoSprinkles } from "../internal";
44
import { vars } from "../vars.css";
5+
import { LabelProps } from "../Typography/Label/Label";
6+
import { BodyProps } from "../Typography/Body/Body";
7+
import { ComponentProps } from "react";
8+
import {
9+
ButtonCell,
10+
ButtonLinkCell,
11+
IconButtonCell,
12+
IconCell,
13+
LabelCell,
14+
LinkCell,
15+
TextCell,
16+
TextWithIconCell,
17+
} from "./cells";
518

619
type CellPaddingConfig = {
720
paddingX: BentoSprinkles["paddingX"];
@@ -10,11 +23,14 @@ type CellPaddingConfig = {
1023

1124
export type TableConfig = {
1225
headerInfoIcon: (props: IconProps) => JSX.Element;
26+
headerHintIcon: (props: IconProps) => JSX.Element;
1327
emptyIcon: (props: IconProps) => JSX.Element;
1428
headerBackgroundColor: BentoSprinkles["background"];
1529
headerForegroundColor: BentoSprinkles["color"];
30+
headerSize: LabelProps["size"];
1631
footerBackgroundColor: BentoSprinkles["background"];
1732
footerForegroundColor: BentoSprinkles["color"];
33+
footerSize: LabelProps["size"];
1834
hintPlacement: TooltipPlacement;
1935
cellTooltipPlacement: TooltipPlacement;
2036
evenRowsBackgroundColor: BentoSprinkles["background"];
@@ -36,6 +52,17 @@ export type TableConfig = {
3652
iconCell: CellPaddingConfig | undefined;
3753
iconButtonCell: CellPaddingConfig | undefined;
3854
};
55+
defaultCellOptions: {
56+
defaultCell: { size: BodyProps["size"] };
57+
buttonCell: Required<ComponentProps<typeof ButtonCell>["options"]>;
58+
buttonLinkCell: Required<ComponentProps<typeof ButtonLinkCell>["options"]>;
59+
textCell: Required<ComponentProps<typeof TextCell>["options"]>;
60+
textWithIconCell: Required<ComponentProps<typeof TextWithIconCell>["options"]>;
61+
labelCell: Required<ComponentProps<typeof LabelCell>["options"]>;
62+
linkCell: Required<ComponentProps<typeof LinkCell>["options"]>;
63+
iconCell: Required<ComponentProps<typeof IconCell>["options"]>;
64+
iconButtonCell: Required<ComponentProps<typeof IconButtonCell>["options"]>;
65+
};
3966
boundaryPadding: BentoSprinkles["padding"];
4067
columnDividers: boolean;
4168
};

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

+4-5
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ import {
5252
Row as RowType,
5353
} from "./types";
5454
import { useLayoutEffect, useMemo, useState, CSSProperties, useEffect, useRef } from "react";
55-
import { IconQuestionSolid, IconInfo } from "../Icons";
5655
import { match, __ } from "ts-pattern";
5756
import { useBentoConfig } from "../BentoConfigContext";
5857
import { assignInlineVars } from "@vanilla-extract/dynamic";
@@ -561,7 +560,7 @@ function ColumnHeader<D extends Record<string, unknown>>({
561560
const hint = column.hint ? (
562561
typeof column.hint === "object" ? (
563562
<IconButton
564-
icon={IconQuestionSolid}
563+
icon={config.headerHintIcon}
565564
onPress={column.hint.onPress}
566565
kind="transparent"
567566
hierarchy="primary"
@@ -572,7 +571,7 @@ function ColumnHeader<D extends Record<string, unknown>>({
572571
<Tooltip
573572
trigger={(ref, props) => (
574573
<Box as="div" display="inline-block" ref={ref} {...props}>
575-
<IconInfo size={12} color="currentColor" />
574+
<config.headerInfoIcon size={12} color="currentColor" />
576575
</Box>
577576
)}
578577
content={column.hint}
@@ -611,7 +610,7 @@ function ColumnHeader<D extends Record<string, unknown>>({
611610
<Columns space={8} alignY="center" align={column.align}>
612611
{column.Header ? (
613612
<Column width="content">
614-
<Label size="large">{column.render("Header") as any}</Label>
613+
<Label size={config.headerSize}>{column.render("Header") as any}</Label>
615614
</Column>
616615
) : null}
617616
{hint && <Column width="content">{hint}</Column>}
@@ -677,7 +676,7 @@ function ColumnFooter<D extends Record<string, unknown>>({
677676
>
678677
<Columns space={8} alignY="center" align={column.align}>
679678
<Column width="content">
680-
<Label size="large">{column.render("Footer") as any}</Label>
679+
<Label size={config.footerSize}>{column.render("Footer") as any}</Label>
681680
</Column>
682681
</Columns>
683682
</Box>

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

+39-22
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,25 @@ import {
2020
ButtonLink,
2121
ButtonLinkProps,
2222
BodyProps,
23+
LabelProps,
2324
} from "..";
2425
import { useBentoConfig } from "../BentoConfigContext";
26+
import { mergeProps } from "@react-aria/utils";
2527

2628
export function ButtonCell({
2729
value: buttonProps,
2830
column: { align },
29-
options: { size },
31+
options,
3032
}: CellProps<{}, Omit<ButtonProps, "size">> & {
3133
options: Partial<Pick<ButtonProps, "size">>;
3234
}) {
3335
const config = useBentoConfig().table;
36+
const { size } = mergeProps(config.defaultCellOptions.buttonCell, options);
3437
const padding = config.padding.buttonCell ?? config.padding.defaultCell;
3538
return (
3639
<Inset spaceX={padding.paddingX} spaceY={padding.paddingY}>
3740
<Inline space={0} align={align} alignY="center">
38-
<Button size={size ?? "medium"} {...buttonProps} />
41+
<Button size={size} {...buttonProps} />
3942
</Inline>
4043
</Inset>
4144
);
@@ -44,16 +47,17 @@ export function ButtonCell({
4447
export function ButtonLinkCell({
4548
value: buttonProps,
4649
column: { align },
47-
options: { size },
50+
options,
4851
}: CellProps<{}, Omit<ButtonLinkProps, "size">> & {
4952
options: Partial<Pick<ButtonLinkProps, "size">>;
5053
}) {
5154
const config = useBentoConfig().table;
55+
const { size } = mergeProps(config.defaultCellOptions.buttonLinkCell, options);
5256
const padding = config.padding.buttonLinkCell ?? config.padding.defaultCell;
5357
return (
5458
<Inset spaceX={padding.paddingX} spaceY={padding.paddingY}>
5559
<Inline space={0} align={align}>
56-
<ButtonLink size={size ?? "medium"} {...buttonProps} />
60+
<ButtonLink size={size} {...buttonProps} />
5761
</Inline>
5862
</Inset>
5963
);
@@ -62,15 +66,16 @@ export function ButtonLinkCell({
6266
export function TextCell({
6367
value,
6468
column: { align },
65-
options: { size, weight, color },
69+
options,
6670
}: CellProps<{}, LocalizedString> & {
6771
options: Partial<Pick<BodyProps, "size" | "weight" | "color">>;
6872
}) {
6973
const config = useBentoConfig().table;
7074
const padding = config.padding.textCell ?? config.padding.defaultCell;
75+
const { size, weight, color } = mergeProps(config.defaultCellOptions.textCell, options);
7176
return (
7277
<Box {...padding} textAlign={align}>
73-
<Body size={size ?? "medium"} weight={weight} color={color}>
78+
<Body size={size} weight={weight} color={color}>
7479
{value}
7580
</Body>
7681
</Box>
@@ -80,7 +85,7 @@ export function TextCell({
8085
export function TextWithIconCell({
8186
value: { icon, iconPosition, text, tooltipContent },
8287
column: { align },
83-
options: { size, weight, color, iconSize, iconColor },
88+
options,
8489
}: CellProps<
8590
{},
8691
{
@@ -96,8 +101,12 @@ export function TextWithIconCell({
96101
};
97102
}) {
98103
const config = useBentoConfig().table;
104+
const { size, weight, color, iconSize, iconColor } = mergeProps(
105+
config.defaultCellOptions.textWithIconCell,
106+
options
107+
);
99108
const padding = config.padding.textWithIconCell ?? config.padding.defaultCell;
100-
const icon_ = icon && icon({ size: iconSize ?? 12, color: iconColor });
109+
const icon_ = icon && icon({ size: iconSize, color: iconColor });
101110

102111
return (
103112
<Inset spaceX={padding.paddingX} spaceY={padding.paddingY}>
@@ -115,7 +124,7 @@ export function TextWithIconCell({
115124
) : (
116125
icon_
117126
)}
118-
<Body size={size ?? "medium"} weight={weight} color={color}>
127+
<Body size={size} weight={weight} color={color}>
119128
{text}
120129
</Body>
121130
</Inline>
@@ -135,28 +144,38 @@ export function ChipCell({ value: chipProps, column: { align } }: CellProps<{},
135144
);
136145
}
137146

138-
export function LabelCell({ value, column: { align } }: CellProps<{}, LocalizedString>) {
147+
export function LabelCell({
148+
value,
149+
column: { align },
150+
options,
151+
}: CellProps<{}, LocalizedString> & {
152+
options: Partial<Pick<LabelProps, "size" | "color">>;
153+
}) {
139154
const config = useBentoConfig().table;
140155
const padding = config.padding.labelCell ?? config.padding.defaultCell;
156+
const { size, color } = mergeProps(config.defaultCellOptions.labelCell, options);
141157
return (
142158
<Box {...padding} textAlign={align}>
143-
<Label size="large">{value}</Label>
159+
<Label size={size} color={color}>
160+
{value}
161+
</Label>
144162
</Box>
145163
);
146164
}
147165

148166
export function LinkCell({
149167
value,
150168
column: { align },
151-
options: { size, weight },
169+
options,
152170
}: CellProps<{}, ComponentProps<typeof Link>> & {
153171
options: Partial<Pick<BodyProps, "size" | "weight">>;
154172
}) {
155173
const config = useBentoConfig().table;
156174
const padding = config.padding.linkCell ?? config.padding.defaultCell;
175+
const { size, weight } = mergeProps(config.defaultCellOptions.linkCell, options);
157176
return (
158177
<Box {...padding} textAlign={align}>
159-
<Body size={size ?? "medium"} weight={weight}>
178+
<Body size={size} weight={weight}>
160179
<Link {...value} />
161180
</Body>
162181
</Box>
@@ -166,37 +185,35 @@ export function LinkCell({
166185
export function IconCell({
167186
value,
168187
column: { align },
169-
options: { size, color },
188+
options,
170189
}: CellProps<{}, { icon: (props: IconProps) => JSX.Element; label: LocalizedString }> & {
171190
options: Partial<Pick<IconProps, "size" | "color">>;
172191
}) {
173192
const config = useBentoConfig().table;
193+
const { size, color } = mergeProps(config.defaultCellOptions.iconCell, options);
174194
const padding = config.padding.iconCell ?? config.padding.defaultCell;
175195
return (
176196
<Box {...padding} textAlign={align} aria-label={value.label}>
177-
{value.icon({ size: size ?? 16, color: color ?? "default" })}
197+
{value.icon({ size, color })}
178198
</Box>
179199
);
180200
}
181201

182202
export function IconButtonCell({
183203
value: iconButtonProps,
184204
column: { align },
185-
options: { size, hierarchy, kind },
205+
options,
186206
}: CellProps<{}, Omit<IconButtonProps, "size" | "kind" | "hierarchy">> & {
187207
options: Partial<Pick<IconButtonProps, "size" | "kind" | "hierarchy">>;
188208
}) {
189209
const config = useBentoConfig().table;
210+
const { size, hierarchy, kind } = mergeProps(config.defaultCellOptions.iconButtonCell, options);
190211
const padding = config.padding.iconButtonCell ?? config.padding.defaultCell;
212+
191213
return (
192214
<Inset spaceX={padding.paddingX} spaceY={padding.paddingY}>
193215
<Inline space={0} align={align} alignY="center">
194-
<IconButton
195-
kind={kind ?? "transparent"}
196-
hierarchy={hierarchy ?? "primary"}
197-
size={size ?? 16}
198-
{...iconButtonProps}
199-
/>
216+
<IconButton kind={kind} hierarchy={hierarchy} size={size} {...iconButtonProps} />
200217
</Inline>
201218
</Inset>
202219
);

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

+10-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
IconButtonProps,
1010
BodyProps,
1111
ButtonProps,
12+
LabelProps,
1213
} from "..";
1314
import { Column } from "./types";
1415
import {
@@ -55,7 +56,7 @@ export function custom<A extends string, V, D extends Record<string, unknown>>({
5556
const value = missingValue ?? defaultMessages.Table.missingValue;
5657
return (
5758
<Box {...config.padding.defaultCell} textAlign={options.align}>
58-
<Body size="medium">{value}</Body>
59+
<Body size={config.defaultCellOptions.defaultCell.size}>{value}</Body>
5960
</Box>
6061
);
6162
} else {
@@ -234,10 +235,16 @@ export function numberWithIcon<A extends string>({
234235
});
235236
}
236237

237-
export function label<A extends string>(options: ColumnOptionsBase<A>) {
238+
export function label<A extends string>({
239+
size,
240+
color,
241+
...options
242+
}: ColumnOptionsBase<A> & Partial<Pick<LabelProps, "size" | "color">>) {
238243
return custom({
239244
...options,
240-
Cell: LabelCell,
245+
Cell: (props: Omit<ComponentProps<typeof TextCell>, "options">) => (
246+
<LabelCell {...{ ...props, options: { size, color } }} />
247+
),
241248
});
242249
}
243250

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

+44
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
IconPositiveCircle,
2424
IconQuestionCircle,
2525
IconNegative,
26+
IconQuestionSolid,
2627
} from "../Icons";
2728
import type { ButtonConfig } from "../Button/Config";
2829
import type { CardConfig } from "../Card/Config";
@@ -504,11 +505,14 @@ export const dropdown: DropdownConfig = {
504505

505506
export const table: TableConfig = {
506507
headerInfoIcon: IconInfo,
508+
headerHintIcon: IconQuestionSolid,
507509
emptyIcon: IconSearch,
508510
headerBackgroundColor: "backgroundPrimary",
509511
headerForegroundColor: "foregroundPrimary",
512+
headerSize: "large",
510513
footerBackgroundColor: "backgroundPrimary",
511514
footerForegroundColor: "foregroundPrimary",
515+
footerSize: "large",
512516
hintPlacement: "top",
513517
cellTooltipPlacement: "bottom",
514518
evenRowsBackgroundColor: "backgroundSecondary",
@@ -527,6 +531,46 @@ export const table: TableConfig = {
527531
iconCell: { paddingX: 16, paddingY: 16 },
528532
iconButtonCell: { paddingX: 16, paddingY: 16 },
529533
},
534+
defaultCellOptions: {
535+
defaultCell: {
536+
size: "medium",
537+
},
538+
textCell: {
539+
size: "medium",
540+
weight: "default",
541+
color: "default",
542+
},
543+
textWithIconCell: {
544+
size: "medium",
545+
weight: "default",
546+
color: "default",
547+
iconSize: 12,
548+
iconColor: "default",
549+
},
550+
iconCell: {
551+
size: 16,
552+
color: "default",
553+
},
554+
buttonCell: {
555+
size: "medium",
556+
},
557+
buttonLinkCell: {
558+
size: "medium",
559+
},
560+
labelCell: {
561+
size: "large",
562+
color: "default",
563+
},
564+
iconButtonCell: {
565+
size: 16,
566+
hierarchy: "primary",
567+
kind: "transparent",
568+
},
569+
linkCell: {
570+
size: "medium",
571+
weight: "default",
572+
},
573+
},
530574
boundaryPadding: 8,
531575
columnDividers: false,
532576
};

0 commit comments

Comments
 (0)