diff --git a/src/controls/NumericControl/NumericControl.tsx b/src/controls/NumericControl/NumericControl.tsx
index 99e0381..63a84a5 100644
--- a/src/controls/NumericControl/NumericControl.tsx
+++ b/src/controls/NumericControl/NumericControl.tsx
@@ -1,88 +1,50 @@
import { ControlProps, RendererProps } from "@jsonforms/core"
-import { Col, Form, InputNumber } from "antd"
-import { coerceToInteger, coerceToNumber, decimalToPercentage } from "../utils"
+import { Col, Form } from "antd"
+import { NumericInput } from "../../renderers/NumericInput"
+import { coerceToInteger, coerceToNumber } from "../utils"
-export const NumericControl = ({
- data,
- handleChange,
- path,
- required,
- label,
- visible,
- id,
- schema,
- uischema,
-}: ControlProps & RendererProps) => {
- if (!visible) return null
+export const NumericControl = (props: ControlProps & RendererProps) => {
+ if (!props.visible) return null
- const arialLabelWithFallback = label || schema.description || "Value"
+ const schema = props.schema
- const minimum = schema.properties?.minimum as number
- const maximum = schema.properties?.maximum as number
-
- const defaultValue = typeof schema?.default === "number" ? schema.default : undefined
- const isEmptyObj = typeof data === "object" && data !== undefined && data !== null ? Object.keys(data as object).length === 0 : false
- const value = data === undefined || isEmptyObj ? defaultValue : 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 ariaLabel = props.label || schema.description || "Value"
+ const initialValue = typeof schema.default === "number" ? schema.default : undefined
const numberType = schema.properties?.type as string
const onChange = (value: number | null) => {
if (value !== null) {
if (numberType === "integer") {
- handleChange(path, value !== null ? coerceToInteger(value) : value)
+ props.handleChange(props.path, value !== null ? coerceToInteger(value) : value)
} else {
- handleChange(path, value !== null ? coerceToNumber(value) : value)
+ props.handleChange(props.path, value !== null ? coerceToNumber(value) : value)
}
}
}
- const style = { marginLeft: 0, width: "100%" }
- const formatter = ((value?: number) => {
- if (typeof value !== "undefined") {
- if (isPercentage) {
- return decimalToPercentage(value)
- } else {
- return value.toString()
- }
- }
- return ""
- })
-
- const numberInput = (
-
- )
-
const rules = [
- { required, message: required ? `${label} is required` : "" },
+ { message: props.required ? `${props.label} is required` : "" },
]
+ const numericInputProps = {
+ ...props,
+ ...onChange,
+ "aria-label": ariaLabel,
+ }
+ const numericInput = NumericInput(numericInputProps)
+
return (
- {numberInput}
+ {numericInput}
)
}
diff --git a/src/controls/NumericControl/NumericSliderControl.tsx b/src/controls/NumericControl/NumericSliderControl.tsx
index ca104e1..2e4212b 100644
--- a/src/controls/NumericControl/NumericSliderControl.tsx
+++ b/src/controls/NumericControl/NumericSliderControl.tsx
@@ -1,108 +1,57 @@
import { ControlProps, RendererProps } from "@jsonforms/core"
-import { Col, Form, InputNumber, Slider } from "antd"
-import { coerceToNumber, coerceToInteger, decimalToPercentage } from "../utils"
+import { Col, Form } from "antd"
+import { NumericInput } from "../../renderers/NumericInput"
+import { NumericSlider } from "../../renderers/NumericSlider"
+import { coerceToInteger, coerceToNumber } from "../utils"
-export function NumericSliderControl({
- data,
- handleChange,
- path,
- required,
- label,
- visible,
- id,
- schema,
- uischema,
-}: ControlProps & RendererProps) {
- if (!visible) return null
+export const NumericSliderControl = (props: ControlProps & RendererProps) => {
+ if (!props.visible) return null
- const arialLabelWithFallback = label || schema.description || "Value"
+ const schema = props.schema
- const minimum = schema.properties?.minimum as number
- const maximum = schema.properties?.maximum as number
- const step = schema.properties?.multipleOf as number
+ const initialValue = typeof schema.default === "number" ? schema.default : undefined
- const defaultValue = 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 ? defaultValue : 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 numberType = schema.properties?.type as string
+ const numberType = props.schema.properties?.type as string
+ const minimum = props.schema.properties?.minimum as number | undefined
+ const maximum = props.schema.properties?.maximum as number | undefined
const onChange = (value: number | null) => {
- if (value !== null && value >= minimum && value <= maximum) {
+ if (value !== null && (minimum && value >= minimum) && (maximum && value <= maximum)) {
if (numberType === "integer") {
- handleChange(path, value !== null ? coerceToInteger(value) : value)
- } else {
- handleChange(path, value !== null ? coerceToNumber(value) : value)
- }
- }
- }
-
- const style = { marginLeft: 16, width: "100%" }
- const formatter = ((value?: number) => {
- if (typeof value !== "undefined") {
- if (isPercentage) {
- return decimalToPercentage(value)
+ props.handleChange(props.path, value !== null ? coerceToInteger(value) : value)
} else {
- return value.toString()
+ props.handleChange(props.path, value !== null ? coerceToNumber(value) : value)
}
}
- return ""
- })
-
- const numberInput = (
-
- )
-
- const tooltip = {
- formatter: (value?: number) => {
- const tooltipValue = value !== undefined ? value : defaultValue
- const formattedTooltipValue = isPercentage ? decimalToPercentage(tooltipValue) : tooltipValue
- return `${addonBefore ? addonBefore : ""}${formattedTooltipValue}${addonAfter ? addonAfter : ""}`
- }
}
- const slider =
-
const rules = [
- { required, message: required ? `${label} is required` : "" },
+ { message: props.required ? `${props.label} is required` : "" },
]
+ const numericSliderProps = {
+ ...props,
+ ...onChange,
+ }
+ const numericSlider = NumericSlider(numericSliderProps)
+
+ const numericInputProps = {
+ ...numericSliderProps,
+ "aria-label": props.label || schema.description || "Value",
+ }
+ const numericInput = NumericInput(numericInputProps)
+
return (
- {slider}{numberInput}
+ {numericSlider}{numericInput}
)
}
diff --git a/src/controls/testerConditions.ts b/src/controls/testerConditions.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/src/renderers/NumericInput.tsx b/src/renderers/NumericInput.tsx
new file mode 100644
index 0000000..af88c9d
--- /dev/null
+++ b/src/renderers/NumericInput.tsx
@@ -0,0 +1,50 @@
+import { ReactElement } from "react"
+import { RendererProps } from "@jsonforms/core"
+import { InputNumber } from "antd"
+import { decimalToPercentage } from "../controls/utils"
+
+type NumericInput = ReactElement
+type NumericInputProps = RendererProps & React.ComponentProps
+
+export const NumericInput = (props: NumericInputProps): NumericInput => {
+ const schema = props.schema
+
+ const min = schema.properties?.minimum as number | undefined
+ const max = schema.properties?.maximum as number | undefined
+
+ const defaultValue = typeof schema?.default === "number" ? schema.default : undefined
+
+ const isNonNullObject = typeof props.data === "object" && props.data !== undefined && props.data !== null
+ const isEmptyObj = isNonNullObject ? Object.keys(props.data as object).length === 0 : false
+ const value = props.data === undefined || isEmptyObj ? defaultValue : props.data as number | null
+
+ const addonAfter = props.uischema.options?.addonAfter as string | undefined
+ const addonBefore = props.uischema.options?.addonBefore as string | undefined
+ const isPercentage = addonAfter?.trim() === "%"
+
+ const style = { marginLeft: 0, width: "100%" }
+ const formatter = ((value?: number) => {
+ if (typeof value !== "undefined") {
+ if (isPercentage) {
+ return decimalToPercentage(value)
+ } else {
+ return value.toString()
+ }
+ }
+ return ""
+ })
+
+ return
+}
diff --git a/src/renderers/NumericSlider.tsx b/src/renderers/NumericSlider.tsx
new file mode 100644
index 0000000..90a0e9f
--- /dev/null
+++ b/src/renderers/NumericSlider.tsx
@@ -0,0 +1,45 @@
+import { ReactElement } from "react"
+import { RendererProps } from "@jsonforms/core"
+import { Slider } from "antd"
+import { decimalToPercentage } from "../controls/utils"
+
+type NumericSlider = ReactElement
+type NumericSliderProps = RendererProps & React.ComponentProps
+
+export const NumericSlider = (props: NumericSliderProps): NumericSlider => {
+ const schema = props.schema
+
+ const min = schema.properties?.minimum as number | undefined
+ const max = schema.properties?.maximum as number | undefined
+ const step = schema.properties?.multipleOf as number | undefined
+
+ const defaultValue = typeof schema?.default === "number" ? schema.default : min
+
+ const isNonNullObject = typeof props.data === "object" && props.data !== undefined && props.data !== null
+ const isEmptyObj = isNonNullObject ? Object.keys(props.data as object).length === 0 : false
+ const value = props.data === undefined || isEmptyObj ? defaultValue : props.data as number | null
+
+ const addonAfter = props.uischema.options?.addonAfter as string | undefined
+ const addonBefore = props.uischema.options?.addonBefore as string | undefined
+ const isPercentage = addonAfter?.trim() === "%"
+
+ const tooltip = {
+ formatter: (value?: number) => {
+ const tooltipValue = value !== undefined ? value : defaultValue
+ const formattedTooltipValue = isPercentage ? decimalToPercentage(tooltipValue) : tooltipValue
+ return `${addonBefore ? addonBefore : ""}${formattedTooltipValue}${addonAfter ? addonAfter : ""}`
+ }
+ }
+
+ return void}
+ min={min}
+ max={max}
+ step={step}
+ tooltip={tooltip}
+ range={false}
+ />
+}