diff --git a/package-lock.json b/package-lock.json
index 3a51b8c..0b96412 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,18 +1,20 @@
{
"name": "@indec/form-builder",
- "version": "1.0.0",
+ "version": "1.2.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@indec/form-builder",
- "version": "1.0.0",
+ "version": "1.2.2",
"license": "ISC",
"dependencies": {
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.3",
+ "@mui/x-date-pickers": "^5.0.16",
+ "date-fns": "^2.29.3",
"formik": "^2.2.9",
"framer-motion": "^8.1.9",
"prop-types": "^15.8.1",
@@ -2548,6 +2550,75 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
+ "node_modules/@date-io/core": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.16.0.tgz",
+ "integrity": "sha512-DYmSzkr+jToahwWrsiRA2/pzMEtz9Bq1euJwoOuYwuwIYXnZFtHajY2E6a1VNVDc9jP8YUXK1BvnZH9mmT19Zg=="
+ },
+ "node_modules/@date-io/date-fns": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.16.0.tgz",
+ "integrity": "sha512-bfm5FJjucqlrnQcXDVU5RD+nlGmL3iWgkHTq3uAZWVIuBu6dDmGa3m8a6zo2VQQpu8ambq9H22UyUpn7590joA==",
+ "dependencies": {
+ "@date-io/core": "^2.16.0"
+ },
+ "peerDependencies": {
+ "date-fns": "^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "date-fns": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@date-io/dayjs": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.16.0.tgz",
+ "integrity": "sha512-y5qKyX2j/HG3zMvIxTobYZRGnd1FUW2olZLS0vTj7bEkBQkjd2RO7/FEwDY03Z1geVGlXKnzIATEVBVaGzV4Iw==",
+ "dependencies": {
+ "@date-io/core": "^2.16.0"
+ },
+ "peerDependencies": {
+ "dayjs": "^1.8.17"
+ },
+ "peerDependenciesMeta": {
+ "dayjs": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@date-io/luxon": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.16.1.tgz",
+ "integrity": "sha512-aeYp5K9PSHV28946pC+9UKUi/xMMYoaGelrpDibZSgHu2VWHXrr7zWLEr+pMPThSs5vt8Ei365PO+84pCm37WQ==",
+ "dependencies": {
+ "@date-io/core": "^2.16.0"
+ },
+ "peerDependencies": {
+ "luxon": "^1.21.3 || ^2.x || ^3.x"
+ },
+ "peerDependenciesMeta": {
+ "luxon": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@date-io/moment": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.16.1.tgz",
+ "integrity": "sha512-JkxldQxUqZBfZtsaCcCMkm/dmytdyq5pS1RxshCQ4fHhsvP5A7gSqPD22QbVXMcJydi3d3v1Y8BQdUKEuGACZQ==",
+ "dependencies": {
+ "@date-io/core": "^2.16.0"
+ },
+ "peerDependencies": {
+ "moment": "^2.24.0"
+ },
+ "peerDependenciesMeta": {
+ "moment": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@design-systems/utils": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/@design-systems/utils/-/utils-2.12.0.tgz",
@@ -5151,6 +5222,64 @@
"react": "^17.0.0 || ^18.0.0"
}
},
+ "node_modules/@mui/x-date-pickers": {
+ "version": "5.0.16",
+ "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.16.tgz",
+ "integrity": "sha512-dfnz9e/zyYXMFH08PKhYHatBLzCt3hnEmbReaKTW+9FXLeZ8hTm4wM3IZi5kplEZuV5aVBJGzynwQ1o3EBoxoA==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.9",
+ "@date-io/core": "^2.15.0",
+ "@date-io/date-fns": "^2.15.0",
+ "@date-io/dayjs": "^2.15.0",
+ "@date-io/luxon": "^2.15.0",
+ "@date-io/moment": "^2.15.0",
+ "@mui/utils": "^5.10.3",
+ "@types/react-transition-group": "^4.4.5",
+ "clsx": "^1.2.1",
+ "prop-types": "^15.7.2",
+ "react-transition-group": "^4.4.5",
+ "rifm": "^0.12.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "@emotion/react": "^11.9.0",
+ "@emotion/styled": "^11.8.1",
+ "@mui/material": "^5.4.1",
+ "@mui/system": "^5.4.1",
+ "date-fns": "^2.25.0",
+ "dayjs": "^1.10.7",
+ "luxon": "^1.28.0 || ^2.0.0 || ^3.0.0",
+ "moment": "^2.29.1",
+ "react": "^17.0.2 || ^18.0.0",
+ "react-dom": "^17.0.2 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/react": {
+ "optional": true
+ },
+ "@emotion/styled": {
+ "optional": true
+ },
+ "date-fns": {
+ "optional": true
+ },
+ "dayjs": {
+ "optional": true
+ },
+ "luxon": {
+ "optional": true
+ },
+ "moment": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@nicolo-ribaudo/chokidar-2": {
"version": "2.1.8-no-fsevents.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz",
@@ -17152,6 +17281,18 @@
"node": ">=12"
}
},
+ "node_modules/date-fns": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
+ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -29660,6 +29801,14 @@
"node": ">=0.10.0"
}
},
+ "node_modules/rifm": {
+ "version": "0.12.1",
+ "resolved": "https://registry.npmjs.org/rifm/-/rifm-0.12.1.tgz",
+ "integrity": "sha512-OGA1Bitg/dSJtI/c4dh90svzaUPt228kzFsUkJbtA2c964IqEAwWXeL9ZJi86xWv3j5SMqRvGULl7bA6cK0Bvg==",
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -35224,6 +35373,43 @@
}
}
},
+ "@date-io/core": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.16.0.tgz",
+ "integrity": "sha512-DYmSzkr+jToahwWrsiRA2/pzMEtz9Bq1euJwoOuYwuwIYXnZFtHajY2E6a1VNVDc9jP8YUXK1BvnZH9mmT19Zg=="
+ },
+ "@date-io/date-fns": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.16.0.tgz",
+ "integrity": "sha512-bfm5FJjucqlrnQcXDVU5RD+nlGmL3iWgkHTq3uAZWVIuBu6dDmGa3m8a6zo2VQQpu8ambq9H22UyUpn7590joA==",
+ "requires": {
+ "@date-io/core": "^2.16.0"
+ }
+ },
+ "@date-io/dayjs": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.16.0.tgz",
+ "integrity": "sha512-y5qKyX2j/HG3zMvIxTobYZRGnd1FUW2olZLS0vTj7bEkBQkjd2RO7/FEwDY03Z1geVGlXKnzIATEVBVaGzV4Iw==",
+ "requires": {
+ "@date-io/core": "^2.16.0"
+ }
+ },
+ "@date-io/luxon": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.16.1.tgz",
+ "integrity": "sha512-aeYp5K9PSHV28946pC+9UKUi/xMMYoaGelrpDibZSgHu2VWHXrr7zWLEr+pMPThSs5vt8Ei365PO+84pCm37WQ==",
+ "requires": {
+ "@date-io/core": "^2.16.0"
+ }
+ },
+ "@date-io/moment": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.16.1.tgz",
+ "integrity": "sha512-JkxldQxUqZBfZtsaCcCMkm/dmytdyq5pS1RxshCQ4fHhsvP5A7gSqPD22QbVXMcJydi3d3v1Y8BQdUKEuGACZQ==",
+ "requires": {
+ "@date-io/core": "^2.16.0"
+ }
+ },
"@design-systems/utils": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/@design-systems/utils/-/utils-2.12.0.tgz",
@@ -37188,6 +37374,25 @@
"react-is": "^18.2.0"
}
},
+ "@mui/x-date-pickers": {
+ "version": "5.0.16",
+ "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.16.tgz",
+ "integrity": "sha512-dfnz9e/zyYXMFH08PKhYHatBLzCt3hnEmbReaKTW+9FXLeZ8hTm4wM3IZi5kplEZuV5aVBJGzynwQ1o3EBoxoA==",
+ "requires": {
+ "@babel/runtime": "^7.18.9",
+ "@date-io/core": "^2.15.0",
+ "@date-io/date-fns": "^2.15.0",
+ "@date-io/dayjs": "^2.15.0",
+ "@date-io/luxon": "^2.15.0",
+ "@date-io/moment": "^2.15.0",
+ "@mui/utils": "^5.10.3",
+ "@types/react-transition-group": "^4.4.5",
+ "clsx": "^1.2.1",
+ "prop-types": "^15.7.2",
+ "react-transition-group": "^4.4.5",
+ "rifm": "^0.12.1"
+ }
+ },
"@nicolo-ribaudo/chokidar-2": {
"version": "2.1.8-no-fsevents.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz",
@@ -46565,6 +46770,11 @@
"whatwg-url": "^11.0.0"
}
},
+ "date-fns": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
+ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
+ },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -56194,6 +56404,11 @@
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
+ "rifm": {
+ "version": "0.12.1",
+ "resolved": "https://registry.npmjs.org/rifm/-/rifm-0.12.1.tgz",
+ "integrity": "sha512-OGA1Bitg/dSJtI/c4dh90svzaUPt228kzFsUkJbtA2c964IqEAwWXeL9ZJi86xWv3j5SMqRvGULl7bA6cK0Bvg=="
+ },
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
diff --git a/package.json b/package.json
index 3d11047..49cbafa 100644
--- a/package.json
+++ b/package.json
@@ -73,6 +73,8 @@
"@emotion/styled": "^11.10.5",
"@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.3",
+ "@mui/x-date-pickers": "^5.0.16",
+ "date-fns": "^2.29.3",
"formik": "^2.2.9",
"framer-motion": "^8.1.9",
"prop-types": "^15.8.1",
diff --git a/src/components/DatePicker/DatePicker.js b/src/components/DatePicker/DatePicker.js
new file mode 100644
index 0000000..8b92bc5
--- /dev/null
+++ b/src/components/DatePicker/DatePicker.js
@@ -0,0 +1,72 @@
+import PropTypes from 'prop-types';
+import {es} from 'date-fns/locale';
+import {AdapterDateFns} from '@mui/x-date-pickers/AdapterDateFns';
+import {LocalizationProvider} from '@mui/x-date-pickers/LocalizationProvider';
+import MuiInputLabel from '@mui/material/InputLabel';
+import Stack from '@mui/material/Stack';
+
+import dateTypes from '@/constants/dateTypes';
+import formikField from '@/utils/propTypes/formikField';
+import formikForm from '@/utils/propTypes/formikForm';
+
+import TextField from '../TextField';
+import DateTimePickerSelector from './DatePickerSelector';
+
+function DatePicker({
+ metadata: {dateType}, field, label, required, form, ...props
+}) {
+ const isRange = [dateTypes.RANGE_WITHOUT_HOUR, dateTypes.RANGE_WITH_HOUR].includes(dateType);
+ return (
+
+ {label}
+
+ form.setFieldValue(isRange ? `${field.name}.start` : field.name, newValue)}
+ renderInput={params => (
+
+ )}
+ />
+ {isRange && (
+ form.setFieldValue(`${field.name}.end`, newValue)}
+ renderInput={params => (
+
+ )}
+ minDateTime={new Date(field.value.start)}
+ disabled={!field.value.start}
+ />
+ )}
+
+
+ );
+}
+
+DatePicker.propTypes = {
+ label: PropTypes.string.isRequired,
+ field: formikField.isRequired,
+ form: formikForm.isRequired,
+ required: PropTypes.bool.isRequired,
+ metadata: PropTypes.shape({
+ dateType: PropTypes.oneOf(Object.values(dateTypes)).isRequired
+ }).isRequired
+};
+
+export default DatePicker;
diff --git a/src/components/DatePicker/DatePicker.stories.js b/src/components/DatePicker/DatePicker.stories.js
new file mode 100644
index 0000000..9e2e534
--- /dev/null
+++ b/src/components/DatePicker/DatePicker.stories.js
@@ -0,0 +1,146 @@
+import React from 'react';
+import {Formik, Field} from 'formik';
+import Button from '@mui/material/Button';
+
+import getWarnings from '@/utils/getWarnings';
+import getSchemas from '@/utils/getSchemas';
+
+import DatePicker from './DatePicker';
+
+export default {
+ title: 'Date',
+ component: DatePicker,
+ argTypes: {
+ backgroundColor: {control: 'color'}
+ }
+};
+
+function Template(args) {
+ const {
+ withErrors, withWarnings, initialValues, section, ...props
+ } = args;
+ const {errorSchema: validateSchema, warningSchema} = getSchemas(section);
+ return (
+
+ {({values, submitForm}) => {
+ const warnings = withWarnings ? getWarnings(warningSchema, values) || {} : {};
+ return (
+ <>
+
+ {
+ withErrors
+ ?
+ : null
+ }
+ >
+ );
+ }}
+
+ );
+}
+
+const section = dateType => ({
+ id: 1,
+ name: 'S1',
+ label: 'Sección 1',
+ questions: [
+ {
+ id: 1,
+ label: 'Select a date',
+ name: 'S1P1',
+ number: '1',
+ type: 6,
+ metadata: {dateType},
+ validations: [
+ {
+ id: 1,
+ type: 'required',
+ params: [
+ {
+ id: 1,
+ message: 'Must select a date'
+ }
+ ],
+ messageType: 'error'
+ }
+ ],
+ userVarName: 's1p1'
+ }
+ ],
+ userVarName: 's1'
+});
+
+export const Basic = Template.bind({});
+Basic.args = {
+ readOnlyMode: false,
+ label: 'Select dates',
+ required: false,
+ name: 'S1.0.S1P1.answer',
+ warnings: {},
+ metadata: {
+ dateType: 'dateWithoutHour'
+ },
+ initialValues: {S1: [{S1P1: {id: 1, answer: ''}}]},
+ section: section('dateWithoutHour')
+};
+
+export const DateWithHour = Template.bind({});
+DateWithHour.args = {
+ readOnlyMode: false,
+ label: 'Select dates',
+ required: false,
+ name: 'S1.0.S1P1.answer',
+ warnings: {},
+ metadata: {
+ dateType: 'dateWithHour'
+ },
+ initialValues: {S1: [{S1P1: {id: 1, answer: ''}}]},
+ section: section('dateWithHour')
+};
+
+export const RangeWithoutHour = Template.bind({});
+RangeWithoutHour.args = {
+ readOnlyMode: false,
+ label: 'Select dates',
+ required: false,
+ name: 'S1.0.S1P1.answer',
+ warnings: {},
+ metadata: {
+ dateType: 'rangeWithoutHour'
+ },
+ initialValues: {S1: [{S1P1: {id: 1, answer: {start: '', end: ''}}}]},
+ section: section('rangeWithoutHour')
+};
+
+export const RangeWithHour = Template.bind({});
+RangeWithHour.args = {
+ readOnlyMode: false,
+ label: 'Select dates',
+ required: false,
+ name: 'S1.0.S1P1.answer',
+ warnings: {},
+ metadata: {
+ dateType: 'rangeWithHour'
+ },
+ initialValues: {S1: [{S1P1: {id: 1, answer: {start: '', end: ''}}}]},
+ section: section('rangeWithHour')
+};
+
+export const WithErrors = Template.bind({});
+WithErrors.args = {
+ readOnlyMode: false,
+ label: 'Select dates',
+ required: false,
+ name: 'S1.0.S1P1.answer',
+ warnings: {},
+ metadata: {
+ dateType: 'rangeWithHour'
+ },
+ initialValues: {S1: [{S1P1: {id: 1, answer: {start: '', end: ''}}}]},
+ withErrors: true,
+ section: section('rangeWithHour')
+};
diff --git a/src/components/DatePicker/DatePickerSelector.js b/src/components/DatePicker/DatePickerSelector.js
new file mode 100644
index 0000000..715a81f
--- /dev/null
+++ b/src/components/DatePicker/DatePickerSelector.js
@@ -0,0 +1,22 @@
+import PropTypes from 'prop-types';
+import {DatePicker as MuiDatePicker} from '@mui/x-date-pickers/DatePicker';
+import {DateTimePicker as MuiDateTimePicker} from '@mui/x-date-pickers/DateTimePicker';
+
+import dateTypes from '@/constants/dateTypes';
+
+function DateTimePickerSelector({type, ...props}) {
+ if ([dateTypes.DATE_WITH_HOUR, dateTypes.RANGE_WITH_HOUR].includes(type)) {
+ return (
+
+ );
+ }
+ return (
+
+ );
+}
+
+DateTimePickerSelector.propTypes = {
+ type: PropTypes.oneOf(Object.values(dateTypes)).isRequired
+};
+
+export default DateTimePickerSelector;
diff --git a/src/components/DatePicker/index.js b/src/components/DatePicker/index.js
new file mode 100644
index 0000000..949a924
--- /dev/null
+++ b/src/components/DatePicker/index.js
@@ -0,0 +1,3 @@
+import DatePicker from './DatePicker';
+
+export default DatePicker;
diff --git a/src/components/QuestionBuilder/QuestionBuilder.js b/src/components/QuestionBuilder/QuestionBuilder.js
index 390081c..6aea1b1 100644
--- a/src/components/QuestionBuilder/QuestionBuilder.js
+++ b/src/components/QuestionBuilder/QuestionBuilder.js
@@ -4,6 +4,7 @@ import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import Checkbox from '@/components/Checkbox';
+import DatePicker from '@/components/DatePicker';
import Radio from '@/components/Radio';
import RadioTable from '@/components/RadioTable';
import Select from '@/components/Select';
@@ -89,6 +90,20 @@ const getComponent = (section, sectionIndex, questionIndex, readOnlyMode, warnin
/>
);
break;
+ case questionTypes.DATE:
+ QuestionComponent = (
+
+ );
+ break;
default:
QuestionComponent = Invalid component.;
}
diff --git a/src/components/Radio/Radio.stories.js b/src/components/Radio/Radio.stories.js
index 9da351a..9e23f16 100644
--- a/src/components/Radio/Radio.stories.js
+++ b/src/components/Radio/Radio.stories.js
@@ -1,6 +1,6 @@
import React from 'react';
import {Formik, Field} from 'formik';
-import {Button} from '@mui/material';
+import Button from '@mui/material/Button';
import getWarnings from '@/utils/getWarnings';
import getSchemas from '@/utils/getSchemas';
diff --git a/src/components/TextField/TextField.js b/src/components/TextField/TextField.js
index 80f70cd..717e3ea 100644
--- a/src/components/TextField/TextField.js
+++ b/src/components/TextField/TextField.js
@@ -17,7 +17,14 @@ function TextField({
}) {
return (
-
+
{readOnlyMode ? (
{field.value || defaultMessages.UNANSWERED}
) : (
diff --git a/src/constants/dateTypes.js b/src/constants/dateTypes.js
new file mode 100644
index 0000000..dec4877
--- /dev/null
+++ b/src/constants/dateTypes.js
@@ -0,0 +1,6 @@
+export default {
+ DATE_WITH_HOUR: 'dateWithHour',
+ DATE_WITHOUT_HOUR: 'dateWithoutHour',
+ RANGE_WITH_HOUR: 'rangeWithHour',
+ RANGE_WITHOUT_HOUR: 'rangeWithoutHour'
+};
diff --git a/src/utils/buildQuestions.js b/src/utils/buildQuestions.js
index 12cb460..48a633d 100644
--- a/src/utils/buildQuestions.js
+++ b/src/utils/buildQuestions.js
@@ -1,4 +1,5 @@
import questionTypes from '@/constants/questionTypes';
+import dateTypes from '@/constants/dateTypes';
const buildQuestions = section => {
const values = {[section.name]: {id: 1}};
@@ -24,6 +25,14 @@ const buildQuestions = section => {
values[section.name][question.name].answer = opts;
return;
}
+ if (question.type === questionTypes.DATE) {
+ if ([dateTypes.RANGE_WITHOUT_HOUR, dateTypes.RANGE_WITH_HOUR].includes(question.metadata.dateType)) {
+ values[section.name][question.name].answer = {start: '', end: ''};
+ } else {
+ values[section.name][question.name].answer = '';
+ }
+ return;
+ }
values[section.name][question.name].answer = '';
});
values[section.name] = [values[section.name]];
diff --git a/src/utils/buildYupSchema.js b/src/utils/buildYupSchema.js
index b9f5f95..cbb5669 100644
--- a/src/utils/buildYupSchema.js
+++ b/src/utils/buildYupSchema.js
@@ -1,8 +1,9 @@
import * as Yup from 'yup';
+import dateTypes from '@/constants/dateTypes';
import questionTypes from '@/constants/questionTypes';
-const getValidatorType = (type, options, {isRequired, message}) => {
+const getValidatorType = (type, options, {isRequired, message, metadata}) => {
let validator;
switch (type) {
case questionTypes.TEXT_FIELD:
@@ -25,6 +26,15 @@ const getValidatorType = (type, options, {isRequired, message}) => {
validator = Yup.object(opts);
break;
}
+ case questionTypes.DATE: {
+ const field = isRequired ? Yup.string().required(message) : Yup.string();
+ if ([dateTypes.RANGE_WITHOUT_HOUR, dateTypes.RANGE_WITH_HOUR].includes(metadata.dateType)) {
+ validator = Yup.object({start: field, end: field});
+ } else {
+ validator = Yup.string();
+ }
+ break;
+ }
default:
return validator;
}
@@ -34,13 +44,17 @@ const getValidatorType = (type, options, {isRequired, message}) => {
export default function buildYupSchema(schema, config, opts = {}) {
const schemaWithValidations = schema;
const {
- name, type, validations, options
+ name, type, validations, options, metadata
} = config;
const requiredField = validations.find(validation => validation.type === 'required');
let validator = getValidatorType(
type,
options,
- {isRequired: !!requiredField, message: requiredField?.params?.[0]?.message}
+ {
+ isRequired: !!requiredField,
+ message: requiredField?.params?.[0]?.message,
+ metadata
+ }
);
if (!validator) {
return schemaWithValidations;
diff --git a/src/utils/propTypes/formikField.js b/src/utils/propTypes/formikField.js
index bd6751f..f60c9b1 100644
--- a/src/utils/propTypes/formikField.js
+++ b/src/utils/propTypes/formikField.js
@@ -1,5 +1,8 @@
import PropTypes from 'prop-types';
export default PropTypes.shape({
- name: PropTypes.string.isRequired
+ name: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.shape({start: PropTypes.string, end: PropTypes.string})
+ ]).isRequired
});