diff --git a/www/src/components/fields/Number/SideDrawerField.tsx b/www/src/components/fields/Number/SideDrawerField.tsx new file mode 100644 index 00000000..e6963106 --- /dev/null +++ b/www/src/components/fields/Number/SideDrawerField.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { Controller } from "react-hook-form"; +import { ISideDrawerFieldProps } from "../types"; + +import { TextField } from "@material-ui/core"; + +export default function Number_({ + control, + column, + disabled, +}: ISideDrawerFieldProps) { + return ( + { + const handleChange = (e) => onChange(Number(e.target.value)); + + return ( + + ); + }} + /> + ); +} diff --git a/www/src/components/fields/Number/TableCell.tsx b/www/src/components/fields/Number/TableCell.tsx new file mode 100644 index 00000000..2cce9c5e --- /dev/null +++ b/www/src/components/fields/Number/TableCell.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import { ICustomCellProps } from "../types"; + +export default function Number_({ value }: ICustomCellProps) { + return <>{`${value ?? ""}`}; +} diff --git a/www/src/components/fields/Number/index.tsx b/www/src/components/fields/Number/index.tsx new file mode 100644 index 00000000..f7681b9e --- /dev/null +++ b/www/src/components/fields/Number/index.tsx @@ -0,0 +1,28 @@ +import React, { lazy } from "react"; +import { IFieldConfig, FieldType } from "components/fields/types"; +import withCustomCell from "components/Table/withCustomCell"; + +import NumberIcon from "assets/icons/Number"; +import BasicCell from "../_BasicCell/BasicCellValue"; +import TextEditor from "components/Table/editors/TextEditor"; + +const TableCell = lazy( + () => import("./TableCell" /* webpackChunkName: "TableCell-Number" */) +); +const SideDrawerField = lazy( + () => + import("./SideDrawerField" /* webpackChunkName: "SideDrawerField-Number" */) +); + +export const config: IFieldConfig = { + type: FieldType.number, + name: "Number", + dataType: "number", + initialValue: undefined, + icon: , + description: "Numeric data.", + TableCell: withCustomCell(TableCell, BasicCell), + TableEditor: TextEditor, + SideDrawerField, +}; +export default config; diff --git a/www/src/components/fields/Percentage/SideDrawerField.tsx b/www/src/components/fields/Percentage/SideDrawerField.tsx new file mode 100644 index 00000000..4436c14f --- /dev/null +++ b/www/src/components/fields/Percentage/SideDrawerField.tsx @@ -0,0 +1,71 @@ +import React from "react"; +import { Controller, useWatch } from "react-hook-form"; +import { ISideDrawerFieldProps } from "../types"; + +import { makeStyles, createStyles, TextField } from "@material-ui/core"; +import { emphasize } from "@material-ui/core/styles"; +import { resultColorsScale } from "utils/color"; + +const useStyles = makeStyles((theme) => + createStyles({ + resultColor: ({ value }: { value: number | undefined }) => ({ + backgroundColor: + typeof value === "number" + ? resultColorsScale(value).hex() + "!important" + : undefined, + color: + typeof value === "number" + ? emphasize(resultColorsScale(value).hex(), 1) + "!important" + : undefined, + }), + + underline: { + "&::after": { + borderColor: theme.palette.text.primary, + }, + }, + }) +); + +export default function Percentage({ + control, + column, + disabled, +}: ISideDrawerFieldProps) { + const value: number | undefined = useWatch({ control, name: column.key }); + const classes = useStyles({ value }); + + return ( + { + const handleChange = (e) => onChange(Number(e.target.value) / 100); + + return ( + + ); + }} + /> + ); +} diff --git a/www/src/components/fields/Percentage/TableCell.tsx b/www/src/components/fields/Percentage/TableCell.tsx new file mode 100644 index 00000000..f3fa007b --- /dev/null +++ b/www/src/components/fields/Percentage/TableCell.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { ICustomCellProps } from "../types"; + +import { makeStyles, createStyles } from "@material-ui/core"; +import { resultColorsScale } from "utils/color"; + +const useStyles = makeStyles((theme) => + createStyles({ + resultColor: { + position: "absolute", + top: 0, + right: 0, + bottom: 0, + left: 0, + opacity: 0.5, + + zIndex: 0, + }, + + text: { + textAlign: "right", + color: theme.palette.text.primary, + + position: "relative", + zIndex: 1, + }, + }) +); + +export default function Percentage({ value }: ICustomCellProps) { + const classes = useStyles(); + + if (typeof value === "number") + return ( + <> +
+
{Math.round(value * 100)}%
+ + ); + + return null; +} diff --git a/www/src/components/fields/Percentage/index.tsx b/www/src/components/fields/Percentage/index.tsx new file mode 100644 index 00000000..f7b1340f --- /dev/null +++ b/www/src/components/fields/Percentage/index.tsx @@ -0,0 +1,30 @@ +import React, { lazy } from "react"; +import { IFieldConfig, FieldType } from "components/fields/types"; +import withCustomCell from "components/Table/withCustomCell"; + +import PercentageIcon from "assets/icons/Percentage"; +import BasicCell from "../_BasicCell/BasicCellNull"; +import TextEditor from "components/Table/editors/TextEditor"; + +const TableCell = lazy( + () => import("./TableCell" /* webpackChunkName: "TableCell-Percentage" */) +); +const SideDrawerField = lazy( + () => + import( + "./SideDrawerField" /* webpackChunkName: "SideDrawerField-Percentage" */ + ) +); + +export const config: IFieldConfig = { + type: FieldType.percentage, + name: "Percentage", + dataType: "number", + initialValue: undefined, + icon: , + description: "Percentage stored as a number between 0 and 1.", + TableCell: withCustomCell(TableCell, BasicCell), + TableEditor: TextEditor, + SideDrawerField, +}; +export default config; diff --git a/www/src/components/fields/index.tsx b/www/src/components/fields/index.tsx index e0866133..7eb0f746 100644 --- a/www/src/components/fields/index.tsx +++ b/www/src/components/fields/index.tsx @@ -11,6 +11,8 @@ import Email from "./Email"; import Phone from "./Phone"; import Url from "./Url"; import Checkbox from "./Checkbox"; +import Number_ from "./Number"; +import Percentage from "./Percentage"; import Date_ from "./Date"; import DateTime from "./DateTime"; import Duration from "./Duration"; @@ -29,8 +31,8 @@ export const FIELDS: IFieldConfig[] = [ Url, // NUMERIC Checkbox, - // TODO: number, - // TODO: percentage, + Number_, + Percentage, // TODO: rating, // TODO: slider, // TODO: color,