-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Port over existing code * Fix typing errors * Exclude .ts files from prodution build * Exclude all files with .test. from prod build * Add untracked file * Remove unused file * Move tests to another branch * Push trivial change * Revert omit change * Remove NumericControlProps and use cast * Add existing tests * Revert "Add existing tests" This reverts commit 3c671dd. * Update to new registry pattern * Pass min, max, step, and controls to InputNumber also * Only show percentage addonAfter if isPercentage * Only show percentage addonAfter if isPercentage * Fix marginLeft on pure number slider * Update tooltip logic for non-percentages on slider * Update logic to fill functionality gaps * Add logic for required asterisk * Fix tooltips * Update value default logic * Fix more broken empty value logic
- Loading branch information
1 parent
48d8872
commit 1186933
Showing
5 changed files
with
143 additions
and
13 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { createNumericControl } from "./NumericControl" | ||
|
||
export const NumberControl = createNumericControl({ | ||
coerceNumber: (value) => Number(value), | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { ControlProps, RendererProps } from "@jsonforms/core" | ||
import { Col, Form, InputNumber, Row, Slider } from "antd" | ||
import { decimalToPercentage } from "./utils" | ||
|
||
|
||
|
||
export const createNumericControl = (args: { coerceNumber: (value: number) => number; pattern?: string }) => { | ||
return function NumericControl({ | ||
data, | ||
handleChange, | ||
path, | ||
required, | ||
label, | ||
visible, | ||
id, | ||
schema, | ||
uischema, | ||
}: ControlProps & RendererProps) { | ||
const arialLabelWithFallback = label || schema.description || "Value" | ||
const isRequired = required || uischema.options?.required as boolean | ||
|
||
const maxStepsWithoutTextInput = 100 | ||
const { maximum, minimum, multipleOf } = schema | ||
const isRangeDefined = typeof maximum === "number" && typeof minimum === "number" | ||
let step: number | undefined = undefined | ||
let stepCount: number | undefined = undefined | ||
if (isRangeDefined) { | ||
const range = Math.abs(maximum - minimum) | ||
step = multipleOf || (range / maxStepsWithoutTextInput) | ||
stepCount = range / step | ||
} | ||
const isLargeStepCount = stepCount && stepCount > maxStepsWithoutTextInput | ||
|
||
const initialValue: number | undefined = typeof schema?.default === "number" ? schema.default : minimum | ||
const isEmptyObj = typeof data === "object" && data !== undefined && data !== null ? Object.keys(data as object).length === 0 : false | ||
const value = data === undefined || isEmptyObj ? initialValue : data as number | null | ||
|
||
const addonAfter = uischema.options?.addonAfter as string | undefined | ||
const addonBefore = uischema.options?.addonBefore as string | undefined | ||
const isPercentage = addonAfter?.trim() === "%" | ||
|
||
const onChange = (value: number | null) => { | ||
if ((typeof value === "number" && (!isRangeDefined || (isRangeDefined && value >= minimum && value <= maximum))) || value === null) { | ||
handleChange(path, value !== null ? args.coerceNumber(value) : value) | ||
} | ||
} | ||
|
||
const marginLeft = isRangeDefined ? 16 : 0 | ||
const style = { marginLeft: marginLeft, width: "100%" } | ||
const formatter = ((value?: number) => { | ||
if (typeof value !== "undefined") { | ||
if (isPercentage) { | ||
return decimalToPercentage(value) | ||
} else { | ||
return value.toString() | ||
} | ||
} | ||
return "" | ||
}) | ||
|
||
const numberInput = ( | ||
<InputNumber | ||
aria-label={arialLabelWithFallback} | ||
value={value} | ||
defaultValue={initialValue} | ||
pattern={args.pattern} | ||
onChange={onChange} | ||
style={style} | ||
max={maximum} | ||
min={minimum} | ||
formatter={formatter} | ||
controls={false} | ||
addonAfter={addonAfter} | ||
addonBefore={addonBefore} | ||
/> | ||
) | ||
|
||
if (!visible) return null | ||
|
||
const tooltip = { | ||
formatter: (value?: number) => { | ||
if (isPercentage) { | ||
return `${decimalToPercentage(value || initialValue)}%` | ||
} else { | ||
return `${addonBefore ? addonBefore : ""}${value || initialValue}${addonAfter ? addonAfter : ""}` | ||
} | ||
} | ||
} | ||
|
||
const slider = <Slider | ||
value={value === null ? initialValue : value} | ||
defaultValue={initialValue} | ||
min={minimum} | ||
max={maximum} | ||
disabled={initialValue === null} | ||
onChange={onChange} | ||
step={step} | ||
tooltip={tooltip} | ||
/> | ||
|
||
return ( | ||
<Form.Item | ||
label={label} | ||
id={id} | ||
name={path} | ||
required={isRequired} | ||
initialValue={initialValue} | ||
rules={[{ required, message: required ? `${label} is required` : "" }]} | ||
validateTrigger={["onBlur"]} | ||
> | ||
{isRangeDefined ? ( | ||
<Row> | ||
<Col span={8}>{slider}</Col> | ||
{isLargeStepCount ? <Col span={7}>{numberInput}</Col> : null} | ||
</Row> | ||
) : ( | ||
<Col span={18}>{numberInput}</Col> | ||
)} | ||
</Form.Item> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export function decimalToPercentage(value?: number) { | ||
if (value === undefined) return "" | ||
const percentage = parseFloat((value * 100).toFixed(10)) // accounting for 10 digits after the decimal point | ||
return `${percentage}` | ||
} | ||
|
||
export function percentageStringToDecimal(value: string | undefined) { | ||
return Number(value) / 100 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters