Skip to content

Commit

Permalink
Allow specifying label and value independently in dropdown cell
Browse files Browse the repository at this point in the history
  • Loading branch information
jassmith committed Dec 24, 2023
1 parent 11a48c9 commit d603f4f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
10 changes: 9 additions & 1 deletion packages/cells/src/cell.stories.tsx
Expand Up @@ -265,7 +265,15 @@ export const CustomCells: React.VFC = () => {
copyData: "4",
data: {
kind: "dropdown-cell",
allowedValues: ["Good", "Better", "Best"],
allowedValues: [
null,
"Good",
"Better",
{
value: "best",
label: "Best",
},
],
value: "Good",
},
};
Expand Down
32 changes: 21 additions & 11 deletions packages/cells/src/cells/dropdown-cell.tsx
Expand Up @@ -19,10 +19,12 @@ const CustomMenu: React.FC<CustomMenuProps> = p => {
return <Menu {...rest}>{children}</Menu>;
};

type DropdownOption = string | { value: string; label: string } | undefined | null;

interface DropdownCellProps {
readonly kind: "dropdown-cell";
readonly value: string | undefined | null;
readonly allowedValues: readonly (string | undefined | null)[];
readonly allowedValues: readonly DropdownOption[];
}

export type DropdownCell = CustomCell<DropdownCellProps>;
Expand Down Expand Up @@ -66,14 +68,14 @@ const Editor: ReturnType<ProvideEditorCallback<DropdownCell>> = p => {

const theme = useTheme();

const values = React.useMemo(
() =>
allowedValues.map(x => ({
value: x,
label: x,
})),
[allowedValues]
);
const values = React.useMemo(() => {
return allowedValues.map(option => {
if (typeof option === "string" || option === null || option === undefined) {
return { value: option, label: option?.toString() ?? "" };
}
return option;
});
}, [allowedValues]);

if (cell.readonly) {
return (
Expand Down Expand Up @@ -176,10 +178,18 @@ const renderer: CustomRenderer<DropdownCell> = {
draw: (args, cell) => {
const { ctx, theme, rect } = args;
const { value } = cell.data;
if (value) {
const foundOption = cell.data.allowedValues.find(opt => {
if (typeof opt === "string" || opt === null || opt === undefined) {
return opt === value;
}
return opt.value === value;
});

const displayText = typeof foundOption === "string" ? foundOption : foundOption?.label ?? "";
if (displayText) {
ctx.fillStyle = theme.textDark;
ctx.fillText(
value,
displayText,
rect.x + theme.cellHorizontalPadding,
rect.y + rect.height / 2 + getMiddleCenterBias(ctx, theme)
);
Expand Down

0 comments on commit d603f4f

Please sign in to comment.