From 0252e6f0d6a7cd38b7da023337351941354f7b1c Mon Sep 17 00:00:00 2001 From: Vincenzo Guerrisi Date: Mon, 26 Aug 2024 11:43:01 +0200 Subject: [PATCH] [Table] allow to specify align and other params on single cells --- .../bento-design-system/src/Table/cells.tsx | 43 ++++++++++++++----- .../src/Table/tableColumn.tsx | 34 ++++++++++----- .../stories/Components/Table.stories.tsx | 12 ++++-- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/packages/bento-design-system/src/Table/cells.tsx b/packages/bento-design-system/src/Table/cells.tsx index 6d6c15416..6c83a3bbf 100644 --- a/packages/bento-design-system/src/Table/cells.tsx +++ b/packages/bento-design-system/src/Table/cells.tsx @@ -63,27 +63,37 @@ export function ButtonLinkCell({ ); } +type TextCellValue = + | LocalizedString + | ({ text: LocalizedString } & Partial>); export function TextCell({ value, - column: { align }, + column, options, -}: CellProps & { +}: CellProps & { options: Partial>; }) { const config = useBentoConfig().table; const padding = config.padding.textCell ?? config.padding.defaultCell; - const { size, weight, color } = mergeProps(config.defaultCellOptions.textCell, options); + const cellOptions: Omit = typeof value === "string" ? {} : value; + + const { size, weight, color, align } = mergeProps( + column, + config.defaultCellOptions.textCell, + options, + cellOptions + ); return ( - {value} + {typeof value === "string" ? value : value.text} ); } export function TextWithIconCell({ - value: { icon, iconPosition, text, tooltipContent }, + value: { icon, iconPosition, text, tooltipContent, ...cellOptions }, column: { align }, options, }: CellProps< @@ -93,7 +103,7 @@ export function TextWithIconCell({ iconPosition: "left" | "right"; text: LocalizedString; tooltipContent?: Children; - } + } & Partial> > & { options: Partial> & { iconSize?: IconProps["size"]; @@ -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 }); @@ -144,20 +155,30 @@ export function ChipCell({ value: chipProps, column: { align } }: CellProps>); export function LabelCell({ value, - column: { align }, + column, options, -}: CellProps & { +}: CellProps & { options: Partial>; }) { 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 ( ); diff --git a/packages/bento-design-system/src/Table/tableColumn.tsx b/packages/bento-design-system/src/Table/tableColumn.tsx index 51300dc1a..29ba72a93 100644 --- a/packages/bento-design-system/src/Table/tableColumn.tsx +++ b/packages/bento-design-system/src/Table/tableColumn.tsx @@ -151,7 +151,7 @@ export function textWithIcon({ icon: ((props: IconProps) => Children) | null; text: LocalizedString; tooltipContent?: Children; - } + } & Partial> >) => { const value = { ..._value, iconPosition }; const textWithIconCellProps = { @@ -166,6 +166,9 @@ export function textWithIcon({ }); } +type NumberCellValue = + | number + | ({ numericValue: number } & Partial>); export function number({ valueFormatter, size, @@ -177,17 +180,27 @@ export function number({ } & Partial>) { return custom({ ...options, - Cell: ({ value: numericValue, ...props }: CellProps) => { - const value = valueFormatter(numericValue); + Cell: ({ value, ...props }: CellProps) => { + 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 ; }, - 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; + }, }); } @@ -203,7 +216,7 @@ export function numberWithIcon({ return custom({ ...options, Cell: ({ - value: { numericValue, icon, tooltipContent }, + value: { numericValue, icon, tooltipContent, ...cellOptions }, ...props }: CellProps< any, @@ -211,13 +224,14 @@ export function numberWithIcon({ icon: ((props: IconProps) => Children) | null; numericValue: number; tooltipContent?: Children; - } + } & Partial> >) => { const value = { text: valueFormatter(numericValue), icon, iconPosition: "right" as const, tooltipContent, + ...cellOptions, }; const textCellProps = { ...props, @@ -242,7 +256,7 @@ export function label({ }: ColumnOptionsBase & Partial>) { return custom({ ...options, - Cell: (props: Omit, "options">) => ( + Cell: (props: Omit, "options">) => ( ), }); diff --git a/packages/bento-design-system/stories/Components/Table.stories.tsx b/packages/bento-design-system/stories/Components/Table.stories.tsx index 9d073483c..45c0c98cd 100644 --- a/packages/bento-design-system/stories/Components/Table.stories.tsx +++ b/packages/bento-design-system/stories/Components/Table.stories.tsx @@ -34,6 +34,7 @@ const exampleColumns = [ headerLabel: "Extended complete address", accessor: "address", width: { custom: 200 }, + align: "center", }), tableColumn.textWithIcon({ headerLabel: "Country", @@ -317,7 +318,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", @@ -334,7 +338,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", @@ -379,7 +383,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, @@ -436,7 +440,7 @@ const exampleData = [ group: "Group 1", deleteAction, }, -]; +] as const; const meta = { component: Table,