Skip to content

Commit

Permalink
#483 add CheckboxCell renderer for boolean columns
Browse files Browse the repository at this point in the history
- also adds this renderer as the default for boolean columns in
  case no renderer is specified.
  • Loading branch information
junaidzm13 committed Dec 7, 2023
1 parent 70fdd01 commit de0a4d3
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,20 @@ export type description = string;
export type exchange = string;
// seed for price generation
export type price = number;
type supported = boolean;
type wishlist = boolean;

export type InstrumentsDataRow = [
type InstrumentsDataRow = [
bbg,
currency,
description,
exchange,
string,
number,
ric,
price
price,
supported,
wishlist
];

export const InstrumentColumnMap = {
Expand All @@ -34,6 +38,8 @@ export const InstrumentColumnMap = {
number: 5,
ric: 6,
price: 7,
supported: 8,
wishlist: 9,
};

const instruments: InstrumentsDataRow[] = [];
Expand Down Expand Up @@ -63,8 +69,9 @@ for (const char of chars) {
const lotSize = lotsizes[random(0, lotsizes.length - 1)];

const exchange = locations[suffix][1];

const price = randomPrice();
const supported = random(0, 1) === 1;
const wishlist = random(0, 1) === 1;

instruments.push([
bbg,
Expand All @@ -75,6 +82,8 @@ for (const char of chars) {
lotSize,
ric,
price,
supported,
wishlist,
]);
}
}
Expand Down
3 changes: 3 additions & 0 deletions vuu-ui/packages/vuu-data-test/src/simul/simul-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export const schemas: Readonly<Record<SimulTableName, Readonly<TableSchema>>> =
{ name: "isin", serverDataType: "string" },
{ name: "lotSize", serverDataType: "int" },
{ name: "ric", serverDataType: "string" },
{ name: "price", serverDataType: "double" },
{ name: "supported", serverDataType: "boolean" },
{ name: "wishlist", serverDataType: "boolean" },
],
key: "ric",
table: { module: "SIMUL", table: "instruments" },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { memo, useCallback } from "react";
import { TableCellRendererProps } from "@finos/vuu-datagrid-types";
import { CheckboxIcon, WarnCommit } from "@finos/vuu-ui-controls";
import { Checkbox } from "@salt-ds/core";
import { dataAndColumnUnchanged } from "../cell-utils";
import { dispatchCustomEvent, registerComponent } from "@finos/vuu-utils";

export const CheckboxCell: React.FC<TableCellRendererProps> = memo(
({ column, columnMap, onCommit = WarnCommit, row }) => {
const dataIdx = columnMap[column.name];
const isChecked = row[dataIdx];

const handleCommit = useCallback(
(value) => async (evt: React.MouseEvent) => {
const res = await onCommit(value);
if (res === true) {
dispatchCustomEvent(evt.target as HTMLElement, "vuu-commit");
}
return res;
},
[onCommit]
);

return (
<React.Fragment>
{!!column.editable ? (
<Checkbox checked={isChecked} onClick={handleCommit(!isChecked)} />
) : (
<CheckboxIcon checked={isChecked} disabled={true} />
)}
</React.Fragment>
);
},
dataAndColumnUnchanged
);

registerComponent("checkbox-cell", CheckboxCell, "cell-renderer", {
serverDataType: "boolean",
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./CheckboxCell";
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./checkbox-cell";
export * from "./dropdown-cell";
export * from "./input-cell";
export * from "./lookup-cell";
Expand Down
82 changes: 54 additions & 28 deletions vuu-ui/packages/vuu-ui-controls/src/list/CheckboxIcon.css
Original file line number Diff line number Diff line change
@@ -1,33 +1,59 @@
.vuuCheckboxIcon {
--vuu-icon-size: 12px;
--vuu-icon-left: -1px;
--vuu-icon-top: -1px;
--vuu-icon-svg: var(--vuu-svg-tick);
border-style: solid;
border-color: var(--vuuCheckboxIcon-borderColor, var(--salt-selectable-borderColor));
border-radius: var(--vuuCheckboxIcon-borderRadius, 3px);
border-width: 1px;
display: inline-block;
height: var(--vuuCheckboxIcon-size, 12px);
position: relative;
width: var(--vuuCheckboxIcon-size, 12px);
--vuuCheckboxIcon-background-checked: var(--vuu-color-purple-10);
--vuu-icon-size: 12px;
--vuu-icon-left: -1px;
--vuu-icon-top: -1px;
--vuu-icon-svg: var(--vuu-svg-tick);
border-style: solid;
border-color: var(
--vuuCheckboxIcon-borderColor,
var(--salt-selectable-borderColor)
);
border-radius: var(--vuuCheckboxIcon-borderRadius, 3px);
border-width: 1px;
display: inline-block;
height: var(--vuuCheckboxIcon-size, 12px);
position: relative;
width: var(--vuuCheckboxIcon-size, 12px);
}

.vuuCheckboxIcon-checked {
background-color: var(--vuuCheckboxIcon-background-checked, var(--salt-selectable-background-selected));
border-color: var(--vuuCheckboxIcon-borderColor-checked, var(--salt-selectable-borderColor-selected));
.vuuCheckboxIcon-checked-enabled {
background-color: var(
--vuuCheckboxIcon-background-checked,
var(--salt-selectable-background-selected)
);
border-color: var(
--vuuCheckboxIcon-borderColor-checked,
var(--salt-selectable-borderColor-selected)
);
}

.vuuCheckboxIcon-checked:after {
content: "";
background-color: white;
left: var(--vuu-icon-left, auto);
height: var(--vuu-icon-height, var(--vuu-icon-size, 12px));
-webkit-mask: var(--vuu-icon-svg) center center/var(--vuu-icon-size) var(--vuu-icon-size);
mask: var(--vuu-icon-svg) center center/var(--vuu-icon-size) var(--vuu-icon-size);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
position: absolute;
top: var(--vuu-icon-top, auto);
width: var(--vuu-icon-width, var(--vuu-icon-size, 12px));
}
.vuuCheckboxIcon-checked-enabled::after,
.vuuCheckboxIcon-checked-disabled::after {
content: "";
background-color: white;
left: var(--vuu-icon-left, auto);
height: var(--vuu-icon-height, var(--vuu-icon-size, 12px));
-webkit-mask: var(--vuu-icon-svg) center center/var(--vuu-icon-size)
var(--vuu-icon-size);
mask: var(--vuu-icon-svg) center center/var(--vuu-icon-size)
var(--vuu-icon-size);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
position: absolute;
top: var(--vuu-icon-top, auto);
width: var(--vuu-icon-width, var(--vuu-icon-size, 12px));
}

.vuuCheckboxIcon-checked-disabled {
--vuuCheckboxIcon-background-disabled: var(
--vuuCheckboxIcon-background-disbaled,
var(--salt-selectable-background-disabled)
);
background-color: var(--vuuCheckboxIcon-background-disabled);
border-color: var(--vuuCheckboxIcon-background-disabled);
}

.vuuCheckboxIcon-checked-disabled::after {
background-color: var(--vuu-color-gray-30);
}
6 changes: 5 additions & 1 deletion vuu-ui/packages/vuu-ui-controls/src/list/CheckboxIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ const classBase = "vuuCheckboxIcon";

export interface CheckboxIconProps extends HTMLAttributes<HTMLSpanElement> {
checked?: boolean;
disabled?: boolean;
}
export const CheckboxIcon = ({
checked = false,
disabled = false,
...htmlAttributes
}: CheckboxIconProps) => (
<span
{...htmlAttributes}
className={cx(classBase, { [`${classBase}-checked`]: checked })}
className={cx(classBase, {
[`${classBase}-checked-${disabled ? "disabled" : "enabled"}`]: checked,
})}
/>
);
29 changes: 17 additions & 12 deletions vuu-ui/packages/vuu-utils/src/component-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,25 +149,30 @@ export function getCellRenderer(
cellType: "cell" | "col-content" | "col-label" = "cell"
) {
if (cellType === "cell") {
if (isTypeDescriptor(column.type)) {
const { renderer } = column.type;
if (isColumnTypeRenderer(renderer)) {
return cellRenderersMap.get(renderer.name);
}
}
if (column.editable) {
// we can only offer a text input edit as a generic editor.
// If a more specialised editor is required, user must configure
// it in column config.
return cellRenderersMap.get("input-cell");
}
return dataCellRenderer(column);
} else if (cellType === "col-label" && column.colHeaderLabelRenderer) {
return cellRenderersMap.get(column.colHeaderLabelRenderer);
} else if (cellType === "col-content" && column.colHeaderContentRenderer) {
return cellRenderersMap.get(column.colHeaderContentRenderer);
}
}

function dataCellRenderer(column: ColumnDescriptor) {
if (isTypeDescriptor(column.type)) {
const { renderer } = column.type;
if (isColumnTypeRenderer(renderer)) {
return cellRenderersMap.get(renderer.name);
}
} else if (column.serverDataType === "boolean") {
return cellRenderersMap.get("checkbox-cell");
} else if (column.editable) {
// we can only offer a text input edit as a generic editor.
// If a more specialised editor is required, user must configure
// it in column config.
return cellRenderersMap.get("input-cell");
}
}

export function getConfigurationEditor(configEditor = "") {
return configEditorsMap.get(configEditor);
}
Expand Down
2 changes: 2 additions & 0 deletions vuu-ui/showcase/src/examples/Table/TableNext.examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ export const EditableTableNextArrayData = () => {
},
},
};
case "wishlist":
return { editable: true };
}
},
[]
Expand Down

0 comments on commit de0a4d3

Please sign in to comment.