From de1180d547e99f5781eb2e03548ba2b1386e5e40 Mon Sep 17 00:00:00 2001 From: Michael Schramm Date: Sat, 15 May 2021 10:25:45 +0200 Subject: [PATCH] add slider field type --- CHANGELOG.md | 1 + components/form/admin/types/index.ts | 16 ++-- components/form/admin/types/slider.type.tsx | 90 +++++++++++++++++++++ components/form/types/index.ts | 16 ++-- components/form/types/slider.type.tsx | 69 ++++++++++++++++ locales/en/type.json | 7 ++ 6 files changed, 185 insertions(+), 14 deletions(-) create mode 100644 components/form/admin/types/slider.type.tsx create mode 100644 components/form/types/slider.type.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 6867f10..d077cd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - add default page background - add environment list in [doc](doc/environment.md) - show error message on homepage in case there is a problem with api connection +- new slider field type ### Changed diff --git a/components/form/admin/types/index.ts b/components/form/admin/types/index.ts index a19c59f..f66ec12 100644 --- a/components/form/admin/types/index.ts +++ b/components/form/admin/types/index.ts @@ -7,6 +7,7 @@ import { LinkType } from './link.type' import { NumberType } from './number.type' import { RadioType } from './radio.type' import { RatingType } from './rating.type' +import { SliderType } from './slider.type' import { TextType } from './text.type' import { TextareaType } from './textarea.type' import { AdminFieldTypeProps } from './type.props' @@ -15,15 +16,16 @@ import { YesNoType } from './yes_no.type' export const adminTypes: { [key: string]: React.FC } = { - textfield: TextType, date: DateType, - email: EmailType, - textarea: TextareaType, - link: LinkType, dropdown: DropdownType, - rating: RatingType, - radio: RadioType, + email: EmailType, hidden: HiddenType, - yes_no: YesNoType, + link: LinkType, number: NumberType, + radio: RadioType, + rating: RatingType, + slider: SliderType, + textarea: TextareaType, + textfield: TextType, + yes_no: YesNoType, } diff --git a/components/form/admin/types/slider.type.tsx b/components/form/admin/types/slider.type.tsx new file mode 100644 index 0000000..78560a7 --- /dev/null +++ b/components/form/admin/types/slider.type.tsx @@ -0,0 +1,90 @@ +import { Form, InputNumber, Slider } from 'antd' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { AdminFieldTypeProps } from './type.props' + +export const SliderType: React.FC = (props) => { + const { t } = useTranslation() + + return ( +
+ + {(form) => { + const getValue = (name, defaultValue: number): number => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const current = form.getFieldValue([ + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + ...form['prefixName'], + props.field.name as string, + 'optionKeys', + name, + ]) + + if (!current) { + return defaultValue + } + + return parseFloat(current) + } + + const max = getValue('max', 100) + const min = getValue('min', 0) + const step = getValue('step', 1) + + return ( + + typeof value === 'number' ? value.toFixed(2) : value + } + getValueProps={(value: string) => ({ value: value ? parseFloat(value) : undefined })} + > + + + ) + }} + + + + typeof value === 'number' ? value.toFixed(2) : value + } + getValueProps={(e: string) => ({ value: e ? parseFloat(e) : undefined })} + > + + + + + typeof value === 'number' ? value.toFixed(2) : value + } + getValueProps={(e: string) => ({ value: e ? parseFloat(e) : undefined })} + > + + + + + typeof value === 'number' ? value.toFixed(2) : value + } + getValueProps={(e: string) => ({ value: e ? parseFloat(e) : undefined })} + > + + +
+ ) +} diff --git a/components/form/types/index.ts b/components/form/types/index.ts index 36cc842..8fb46fc 100644 --- a/components/form/types/index.ts +++ b/components/form/types/index.ts @@ -6,6 +6,7 @@ import { LinkType } from './link.type' import { NumberType } from './number.type' import { RadioType } from './radio.type' import { RatingType } from './rating.type' +import { SliderType } from './slider.type' import { TextType } from './text.type' import { TextareaType } from './textarea.type' import { FieldTypeProps } from './type.props' @@ -14,14 +15,15 @@ import { YesNoType } from './yes_no.type' export const fieldTypes: { [key: string]: React.FC } = { - textfield: TextType, date: DateType, - email: EmailType, - textarea: TextareaType, - link: LinkType, dropdown: DropdownType, - rating: RatingType, - radio: RadioType, - yes_no: YesNoType, + email: EmailType, + link: LinkType, number: NumberType, + radio: RadioType, + rating: RatingType, + slider: SliderType, + textarea: TextareaType, + textfield: TextType, + yes_no: YesNoType, } diff --git a/components/form/types/slider.type.tsx b/components/form/types/slider.type.tsx new file mode 100644 index 0000000..2aa61d7 --- /dev/null +++ b/components/form/types/slider.type.tsx @@ -0,0 +1,69 @@ +import { Form, Slider, Spin } from 'antd' +import React, { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { FieldTypeProps } from './type.props' + +export const SliderType: React.FC = ({ field, urlValue }) => { + const [min, setMin] = useState() + const [max, setMax] = useState() + const [step, setStep] = useState() + const [loading, setLoading] = useState(true) + + const { t } = useTranslation() + + useEffect(() => { + field.options.forEach((option) => { + if (option.key === 'min') { + setMin(parseFloat(option.value)) + } + if (option.key === 'max') { + setMax(parseFloat(option.value)) + } + if (option.key === 'step') { + setStep(parseFloat(option.value)) + } + }) + + setLoading(false) + }, [field]) + + let initialValue: number = undefined + + if (field.value) { + initialValue = parseFloat(field.value) + } + + if (urlValue) { + initialValue = parseFloat(urlValue) + } + + if (loading) { + return ( +
+ +
+ ) + } + + return ( +
+ + typeof value === 'number' ? value.toFixed(2) : value + } + getValueProps={(value: string) => ({ value: value ? parseFloat(value) : undefined })} + > + + +
+ ) +} diff --git a/locales/en/type.json b/locales/en/type.json index 4f7bc24..1d201ad 100644 --- a/locales/en/type.json +++ b/locales/en/type.json @@ -19,6 +19,13 @@ "titlePlaceholder": "Title", "valuePlaceholder": "Value" }, + "slider": { + "default": "Default Value", + "name": "Slider", + "min": "Min Value", + "max": "Max Value", + "step": "Step Size" + }, "email": { "default": "Default Email", "name": "Email"