Skip to content

Commit

Permalink
Merge pull request #889 from buildo/bento-887
Browse files Browse the repository at this point in the history
[Table] allow to specify align and other params on single cells
  • Loading branch information
veej authored Sep 2, 2024
2 parents adc33f1 + 0f6db77 commit 1ea8c33
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 27 deletions.
43 changes: 32 additions & 11 deletions packages/bento-design-system/src/Table/cells.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,37 @@ export function ButtonLinkCell({
);
}

type TextCellValue =
| LocalizedString
| ({ text: LocalizedString } & Partial<Pick<BodyProps, "size" | "weight" | "color" | "align">>);
export function TextCell({
value,
column: { align },
column,
options,
}: CellProps<any, LocalizedString> & {
}: CellProps<any, TextCellValue> & {
options: Partial<Pick<BodyProps, "size" | "weight" | "color">>;
}) {
const config = useBentoConfig().table;
const padding = config.padding.textCell ?? config.padding.defaultCell;
const { size, weight, color } = mergeProps(config.defaultCellOptions.textCell, options);
const cellOptions: Omit<TextCellValue, "text"> = typeof value === "string" ? {} : value;

const { size, weight, color, align } = mergeProps(
column,
config.defaultCellOptions.textCell,
options,
cellOptions
);
return (
<Box {...padding} textAlign={align}>
<Body size={size} weight={weight} color={color}>
{value}
{typeof value === "string" ? value : value.text}
</Body>
</Box>
);
}

export function TextWithIconCell({
value: { icon, iconPosition, text, tooltipContent },
value: { icon, iconPosition, text, tooltipContent, ...cellOptions },
column: { align },
options,
}: CellProps<
Expand All @@ -93,7 +103,7 @@ export function TextWithIconCell({
iconPosition: "left" | "right";
text: LocalizedString;
tooltipContent?: Children;
}
} & Partial<Pick<BodyProps, "size" | "weight" | "color">>
> & {
options: Partial<Pick<BodyProps, "size" | "weight" | "color">> & {
iconSize?: IconProps["size"];
Expand All @@ -103,7 +113,8 @@ export function TextWithIconCell({
const config = useBentoConfig().table;
const { size, weight, color, iconSize, iconColor } = mergeProps(
config.defaultCellOptions.textWithIconCell,
options
options,
cellOptions
);
const padding = config.padding.textWithIconCell ?? config.padding.defaultCell;
const icon_ = icon && icon({ size: iconSize, color: iconColor });
Expand Down Expand Up @@ -144,20 +155,30 @@ export function ChipCell({ value: chipProps, column: { align } }: CellProps<any,
);
}

type LabelCellValue =
| LocalizedString
| ({ text: LocalizedString } & Partial<Pick<LabelProps, "size" | "color" | "align">>);
export function LabelCell({
value,
column: { align },
column,
options,
}: CellProps<any, LocalizedString> & {
}: CellProps<any, LabelCellValue> & {
options: Partial<Pick<LabelProps, "size" | "color">>;
}) {
const config = useBentoConfig().table;
const padding = config.padding.labelCell ?? config.padding.defaultCell;
const { size, color } = mergeProps(config.defaultCellOptions.labelCell, options);
const cellOptions = typeof value === "string" ? {} : value;

const { size, color, align } = mergeProps(
column,
config.defaultCellOptions.labelCell,
options,
cellOptions
);
return (
<Box {...padding} textAlign={align}>
<Label size={size} color={color}>
{value}
{typeof value === "string" ? value : value.text}
</Label>
</Box>
);
Expand Down
34 changes: 24 additions & 10 deletions packages/bento-design-system/src/Table/tableColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export function textWithIcon<A extends string>({
icon: ((props: IconProps) => Children) | null;
text: LocalizedString;
tooltipContent?: Children;
}
} & Partial<Pick<BodyProps, "size" | "weight" | "color">>
>) => {
const value = { ..._value, iconPosition };
const textWithIconCellProps = {
Expand All @@ -166,6 +166,9 @@ export function textWithIcon<A extends string>({
});
}

type NumberCellValue =
| number
| ({ numericValue: number } & Partial<Pick<BodyProps, "size" | "weight" | "color" | "align">>);
export function number<A extends string>({
valueFormatter,
size,
Expand All @@ -177,17 +180,27 @@ export function number<A extends string>({
} & Partial<Pick<BodyProps, "size" | "weight" | "color">>) {
return custom({
...options,
Cell: ({ value: numericValue, ...props }: CellProps<any, number>) => {
const value = valueFormatter(numericValue);
Cell: ({ value, ...props }: CellProps<any, NumberCellValue>) => {
const numericValue = typeof value === "number" ? value : value.numericValue;
const formattedValue = valueFormatter(numericValue);
const textCellProps = {
...props,
value,
cell: { ...props.cell, value },
options: { size, weight, color },
value: formattedValue,
cell: { ...props.cell, value: formattedValue },
options: {
size,
weight,
color,
align: typeof value === "number" ? undefined : value.align,
},
};
return <TextCell {...textCellProps} />;
},
sortType: (a = 0, b = 0) => a - b,
sortType: (a = 0, b = 0) => {
const aValue = typeof a === "number" ? a : a.numericValue;
const bValue = typeof b === "number" ? b : b.numericValue;
return aValue - bValue;
},
});
}

Expand All @@ -203,21 +216,22 @@ export function numberWithIcon<A extends string>({
return custom({
...options,
Cell: ({
value: { numericValue, icon, tooltipContent },
value: { numericValue, icon, tooltipContent, ...cellOptions },
...props
}: CellProps<
any,
{
icon: ((props: IconProps) => Children) | null;
numericValue: number;
tooltipContent?: Children;
}
} & Partial<Pick<BodyProps, "size" | "weight" | "color">>
>) => {
const value = {
text: valueFormatter(numericValue),
icon,
iconPosition: "right" as const,
tooltipContent,
...cellOptions,
};
const textCellProps = {
...props,
Expand All @@ -242,7 +256,7 @@ export function label<A extends string>({
}: ColumnOptionsBase<A> & Partial<Pick<LabelProps, "size" | "color">>) {
return custom({
...options,
Cell: (props: Omit<ComponentProps<typeof TextCell>, "options">) => (
Cell: (props: Omit<ComponentProps<typeof LabelCell>, "options">) => (
<LabelCell {...{ ...props, options: { size, color } }} />
),
});
Expand Down
30 changes: 24 additions & 6 deletions packages/bento-design-system/stories/Components/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const exampleColumns = [
headerLabel: "Extended complete address",
accessor: "address",
width: { custom: 200 },
align: "center",
}),
tableColumn.textWithIcon({
headerLabel: "Country",
Expand Down Expand Up @@ -113,7 +114,14 @@ const exampleColumnsWithFooter = [
hint: { onPress: action("hint") },
footer: ({ rows }) =>
Intl.NumberFormat("en").format(
rows.reduce((acc, row) => acc + (row.values.applications ?? 0), 0)
rows.reduce(
(acc, row) =>
acc +
(typeof row.values.applications === "number"
? row.values.applications ?? 0
: row.values.applications?.numericValue ?? 0),
0
)
),
}),
tableColumn.numberWithIcon({
Expand Down Expand Up @@ -192,7 +200,14 @@ const exampleGroupedColumns = [
hint: { onPress: action("hint") },
footer: ({ rows }) =>
Intl.NumberFormat("en").format(
rows.reduce((acc, row) => acc + (row.values.applications ?? 0), 0)
rows.reduce(
(acc, row) =>
acc +
(typeof row.values.applications === "number"
? row.values.applications ?? 0
: row.values.applications?.numericValue ?? 0),
0
)
),
}),
tableColumn.numberWithIcon({
Expand Down Expand Up @@ -317,7 +332,10 @@ const deleteAction = {
const exampleData = [
{
name: "Amazon",
address: "Theodore Lowe Ap #867-859 Sit Rd. Azusa New York 39531",
address: {
text: "Theodore Lowe Ap #867-859 Sit Rd. Azusa New York 39531",
weight: "strong",
},
country: {
icon: IconInfoSolid,
text: "US",
Expand All @@ -334,7 +352,7 @@ const exampleData = [
numericValue: 100,
icon: IconInfoSolid,
},
type: "Private",
type: { text: "Private", color: "secondary", align: "right" },
website: { href: "http://www.amazon.com", label: "Link" },
alerts: { icon: IconWarningSolid, label: "Warning" },
group: "Group 1",
Expand Down Expand Up @@ -379,7 +397,7 @@ const exampleData = [
hierarchy: "primary",
onPress: () => {},
} as const,
applications: 1_000,
applications: { numericValue: 1_000, align: "left" },
status: { label: "Pending", color: "yellow" } as const,
value: {
numericValue: 120,
Expand Down Expand Up @@ -436,7 +454,7 @@ const exampleData = [
group: "Group 1",
deleteAction,
},
];
] as const;

const meta = {
component: Table,
Expand Down

0 comments on commit 1ea8c33

Please sign in to comment.