Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
fix: creating a custom DateTimeWidget for datetime-local inputs (#895)
Browse files Browse the repository at this point in the history
* fix: creating a custom DateTimeWidget for datetime-local inputs

* docs: removing an outdated comment

* test: updating some broken tests
  • Loading branch information
erunion authored Aug 27, 2020
1 parent bae7b7a commit dcf0258
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 17 deletions.
1 change: 0 additions & 1 deletion example/swagger-files/types.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
"format": "date"
},
"string (format: date-time)": {
"description": "Temporarily disabled back to a simple string input due to a bug in RJSF",
"type": "string",
"format": "date-time"
},
Expand Down
6 changes: 3 additions & 3 deletions packages/api-explorer/__tests__/Params.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,9 @@ describe('schema handling', () => {
});

it.each([
['date', 'text', stringOas.operation('/format-date', 'get'), 'date'],
['date-time', 'text', stringOas.operation('/format-date-time', 'get'), 'string'],
['dateTime', 'text', stringOas.operation('/format-dateTime', 'get'), 'string'],
['date', 'date', stringOas.operation('/format-date', 'get'), 'date'],
['date-time', 'datetime-local', stringOas.operation('/format-date-time', 'get'), 'date-time'],
['dateTime', 'datetime-local', stringOas.operation('/format-dateTime', 'get'), 'date-time'],
['password', 'password', stringOas.operation('/format-password', 'get'), 'password'],
['uri', 'url', stringOas.operation('/format-uri', 'get'), 'uri'],
['url', 'url', stringOas.operation('/format-url', 'get'), 'url'],
Expand Down
27 changes: 14 additions & 13 deletions packages/api-explorer/src/Params.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const Form = require('@readme/react-jsonschema-form').default;
const slug = require('lodash.kebabcase');

const {
// DateTimeWidget,
DateWidget,
PasswordWidget,
TextWidget,
UpDownWidget,
Expand All @@ -13,15 +13,16 @@ const {
const Oas = require('@readme/oas-tooling');
const { parametersToJsonSchema } = require('@readme/oas-tooling/utils');

const DescriptionField = require('./form-components/DescriptionField');
const UnsupportedField = require('./form-components/UnsupportedField');
const createBaseInput = require('./form-components/BaseInput');
const createSelectWidget = require('./form-components/SelectWidget');
const createArrayField = require('./form-components/ArrayField');
const createBaseInput = require('./form-components/BaseInput');
const createDateTimeWidget = require('./form-components/DateTimeWidget');
const createFileWidget = require('./form-components/FileWidget');
const createSchemaField = require('./form-components/SchemaField');
const createSelectWidget = require('./form-components/SelectWidget');
const createTextareaWidget = require('./form-components/TextareaWidget');
const createFileWidget = require('./form-components/FileWidget');
const createURLWidget = require('./form-components/URLWidget');
const DescriptionField = require('./form-components/DescriptionField');
const UnsupportedField = require('./form-components/UnsupportedField');

const { Operation } = Oas;

Expand All @@ -46,6 +47,7 @@ class Params extends React.Component {
const {
ArrayField,
BaseInput,
DateTimeWidget,
FileWidget,
formData,
onChange,
Expand Down Expand Up @@ -91,13 +93,9 @@ class Params extends React.Component {
binary: FileWidget,
blob: TextareaWidget,
byte: TextWidget,
date: TextWidget,

// 🚨 Temporarily disabling support for rendering the datetime widget as RJSF appears to be disabling it in
// browsers that don't fully support it.
/* dateTime: DateTimeWidget,
'date-time': DateTimeWidget, */

date: DateWidget,
dateTime: DateTimeWidget,
'date-time': DateTimeWidget,
double: UpDownWidget,
duration: TextWidget,
float: UpDownWidget,
Expand Down Expand Up @@ -133,6 +131,7 @@ class Params extends React.Component {
Params.propTypes = {
ArrayField: PropTypes.func.isRequired,
BaseInput: PropTypes.func.isRequired,
DateTimeWidget: PropTypes.func.isRequired,
FileWidget: PropTypes.func.isRequired,
formData: PropTypes.shape({}).isRequired,
oas: PropTypes.instanceOf(Oas).isRequired,
Expand All @@ -153,6 +152,7 @@ Params.defaultProps = {
function createParams(oas) {
const ArrayField = createArrayField(oas);
const BaseInput = createBaseInput(oas);
const DateTimeWidget = createDateTimeWidget(oas);
const FileWidget = createFileWidget(oas);
const SchemaField = createSchemaField();
const SelectWidget = createSelectWidget(oas);
Expand All @@ -166,6 +166,7 @@ function createParams(oas) {
{...props}
ArrayField={ArrayField}
BaseInput={BaseInput}
DateTimeWidget={DateTimeWidget}
FileWidget={FileWidget}
SchemaField={SchemaField}
SelectWidget={SelectWidget}
Expand Down
35 changes: 35 additions & 0 deletions packages/api-explorer/src/form-components/DateTimeWidget.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const React = require('react');
const PropTypes = require('prop-types');
const extensions = require('@readme/oas-extensions');

function createDateTimeWidget(oas) {
const explorerEnabled = oas[extensions.EXPLORER_ENABLED];

// Return a function that renders null when the explorer is disabled
if (!explorerEnabled) return () => null;

// Why use this instead of the DateTimeWidget that RJSF provides? Well that's running UTC conversion on dates that
// doesn't actually need to happen for browsers that support `datetime-local`, and when it does that in browsers that
// don't support it, it's overwriting the data that the user inputs with an empty string.
function DateTimeWidget(props) {
const {
registry: {
widgets: { BaseInput },
},
} = props;

return <BaseInput type="datetime-local" {...props} />;
}

DateTimeWidget.propTypes = {
registry: PropTypes.shape({
FieldTemplate: PropTypes.func,
rootSchema: PropTypes.object,
widgets: PropTypes.object,
}).isRequired,
};

return DateTimeWidget;
}

module.exports = createDateTimeWidget;

0 comments on commit dcf0258

Please sign in to comment.