Skip to content

Commit

Permalink
- Responded to reviewer feedback by creating a separate type for `Bas…
Browse files Browse the repository at this point in the history
…eInputTemplate`
  • Loading branch information
heath-freenome committed Mar 6, 2023
1 parent 1dd96c7 commit c556613
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 113 deletions.
13 changes: 7 additions & 6 deletions packages/antd/src/templates/BaseInputTemplate/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { ChangeEvent, FocusEvent } from "react";
import Input from "antd/lib/input";
import InputNumber from "antd/lib/input-number";
import {
ariaDescribedByIds,
BaseInputTemplateProps,
examplesId,
getInputProps,
FormContextType,
GenericObjectType,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
GenericObjectType,
} from "@rjsf/utils";

const INPUT_STYLE = {
Expand All @@ -25,7 +26,7 @@ export default function BaseInputTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: WidgetProps<T, S, F>) {
>(props: BaseInputTemplateProps<T, S, F>) {
const {
disabled,
formContext,
Expand All @@ -48,13 +49,13 @@ export default function BaseInputTemplate<

const handleTextChange = onChangeOverride
? onChangeOverride
: ({ target }: React.ChangeEvent<HTMLInputElement>) =>
: ({ target }: ChangeEvent<HTMLInputElement>) =>
onChange(target.value === "" ? options.emptyValue : target.value);

const handleBlur = ({ target }: React.FocusEvent<HTMLInputElement>) =>
const handleBlur = ({ target }: FocusEvent<HTMLInputElement>) =>
onBlur(id, target.value);

const handleFocus = ({ target }: React.FocusEvent<HTMLInputElement>) =>
const handleFocus = ({ target }: FocusEvent<HTMLInputElement>) =>
onFocus(id, target.value);

const input =
Expand Down
16 changes: 7 additions & 9 deletions packages/bootstrap-4/src/BaseInputTemplate/BaseInputTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ChangeEvent, FocusEvent } from "react";
import Form from "react-bootstrap/Form";
import {
ariaDescribedByIds,
BaseInputTemplateProps,
examplesId,
FormContextType,
getInputProps,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
} from "@rjsf/utils";

export default function BaseInputTemplate<
Expand All @@ -31,20 +32,17 @@ export default function BaseInputTemplate<
rawErrors = [],
children,
extraProps,
}: WidgetProps<T, S, F>) {
}: BaseInputTemplateProps<T, S, F>) {
const inputProps = {
...extraProps,
...getInputProps<T, S, F>(schema, type, options),
};
const _onChange = ({
target: { value },
}: React.ChangeEvent<HTMLInputElement>) =>
const _onChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
onChange(value === "" ? options.emptyValue : value);
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onBlur(id, value);
const _onFocus = ({
target: { value },
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onFocus(id, value);

// const classNames = [rawErrors.length > 0 ? "is-invalid" : "", type === 'file' ? 'custom-file-label': ""]
return (
Expand Down
16 changes: 7 additions & 9 deletions packages/chakra-ui/src/BaseInputTemplate/BaseInputTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { ChangeEvent, FocusEvent } from "react";
import { FormControl, FormLabel, Input } from "@chakra-ui/react";
import {
ariaDescribedByIds,
BaseInputTemplateProps,
examplesId,
FormContextType,
getInputProps,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
} from "@rjsf/utils";
import { getChakra } from "../utils";

export default function BaseInputTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: WidgetProps<T, S, F>) {
>(props: BaseInputTemplateProps<T, S, F>) {
const {
id,
type,
Expand All @@ -39,15 +40,12 @@ export default function BaseInputTemplate<
const chakraProps = getChakra({ uiSchema });
const { schemaUtils } = registry;

const _onChange = ({
target: { value },
}: React.ChangeEvent<HTMLInputElement>) =>
const _onChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
onChange(value === "" ? options.emptyValue : value);
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onBlur(id, value);
const _onFocus = ({
target: { value },
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onFocus(id, value);

const displayLabel =
schemaUtils.getDisplayLabel(schema, uiSchema) &&
Expand Down
14 changes: 6 additions & 8 deletions packages/core/src/components/templates/BaseInputTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useCallback } from "react";
import { ChangeEvent, FocusEvent, useCallback } from "react";
import {
ariaDescribedByIds,
BaseInputTemplateProps,
examplesId,
getInputProps,
FormContextType,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
} from "@rjsf/utils";

/** The `BaseInputTemplate` is the template to use to render the basic `<input>` component for the `core` theme.
Expand All @@ -19,7 +19,7 @@ export default function BaseInputTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: WidgetProps<T, S, F>) {
>(props: BaseInputTemplateProps<T, S, F>) {
const {
id,
name, // remove this from ...rest
Expand Down Expand Up @@ -60,18 +60,16 @@ export default function BaseInputTemplate<
}

const _onChange = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLInputElement>) =>
({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
onChange(value === "" ? options.emptyValue : value),
[onChange, options]
);
const _onBlur = useCallback(
({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
onBlur(id, value),
({ target: { value } }: FocusEvent<HTMLInputElement>) => onBlur(id, value),
[onBlur, id]
);
const _onFocus = useCallback(
({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
onFocus(id, value),
({ target: { value } }: FocusEvent<HTMLInputElement>) => onFocus(id, value),
[onFocus, id]
);

Expand Down
17 changes: 10 additions & 7 deletions packages/docs/docs/advanced-customization/custom-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ If you desire a different implementation for the `<input>` based widgets, you ca
For instance, say you have a `CustomTextInput` component that you want to integrate:

```tsx
import { getInputProps, RJSFSchema, WidgetProps } from "@rjsf/utils";
import { ChangeEvent, FocusEvent } from 'react';
import { getInputProps, RJSFSchema, BaseInputTemplateProps } from "@rjsf/utils";
import validator from '@rjsf/validator-ajv8';

import CustomTextInput from '../CustomTextInput';
Expand All @@ -301,7 +302,7 @@ const schema: RJSFSchema = {
description: "input description"
};

function BaseInputTemplate(props: WidgetProps) {
function BaseInputTemplate (props: BaseInputTemplateProps) {
const {
schema,
id,
Expand All @@ -315,6 +316,7 @@ function BaseInputTemplate(props: WidgetProps) {
readonly,
autofocus,
onChange,
onChangeOverride,
onBlur,
onFocus,
rawErrors,
Expand All @@ -324,12 +326,12 @@ function BaseInputTemplate(props: WidgetProps) {
formContext,
...rest
} = props;
const onTextChange = ({ target: { value: val } }: React.ChangeEvent<HTMLInputElement>) => {
const onTextChange = ({ target: { value: val } }: ChangeEvent<HTMLInputElement>) => {
// Use the options.emptyValue if it is specified and newVal is also an empty string
onChange(val === '' ? options.emptyValue || '' : val);
};
const onTextBlur = ({ target: { value: val } }: React.FocusEvent<HTMLInputElement>) => onBlur(id, val);
const onTextFocus = ({ target: { value: val } }: React.FocusEvent<HTMLInputElement>) => onFocus(id, val);
const onTextBlur = ({ target: { value: val } }: FocusEvent<HTMLInputElement>) => onBlur(id, val);
const onTextFocus = ({ target: { value: val } }: FocusEvent<HTMLInputElement>) => onFocus(id, val);

const inputProps = { ...rest, ...getInputProps(schema, type, options) };
const hasError = rawErrors.length > 0 && !hideError;
Expand All @@ -345,7 +347,7 @@ function BaseInputTemplate(props: WidgetProps) {
autoFocus={autofocus}
error={hasError}
errors={hasError ? rawErrors : undefined}
onChange={onTextChange}
onChange={onChangeOverride || onTextChange}
onBlur={onTextBlur}
onFocus={onTextFocus}
{...inputProps}
Expand All @@ -354,7 +356,7 @@ function BaseInputTemplate(props: WidgetProps) {
}

render((
<Form schema={schema} validator={validator} templates={{ BaseInputTemplate }} />
<Form schema={schema} validator={validator} templates={{ BaseInputTemplate }}/>
), document.getElementById("app"));
```

Expand All @@ -373,6 +375,7 @@ The following props are passed to the `BaseInputTemplate`:
- `label`: The computed label for this widget, as a string
- `multiple`: A boolean value stating if the widget can accept multiple values;
- `onChange`: The value change event handler; call it with the new value every time it changes;
- `onChangeOverride`: A `BaseInputTemplate` implements a default `onChange` handler that it passes to the HTML input component to handle the `ChangeEvent`. Sometimes a widget may need to handle the `ChangeEvent` using custom logic. If that is the case, that widget should provide its own handler via this prop;
- `onKeyChange`: The key change event handler (only called for fields with `additionalProperties`); pass the new value every time it changes;
- `onBlur`: The input blur event handler; call it with the widget id and value;
- `onFocus`: The input focus event handler; call it with the widget id and value;
Expand Down
18 changes: 8 additions & 10 deletions packages/fluent-ui/src/BaseInputTemplate/BaseInputTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ChangeEvent, FocusEvent } from "react";
import { TextField } from "@fluentui/react";
import {
ariaDescribedByIds,
BaseInputTemplateProps,
examplesId,
FormContextType,
getInputProps,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
} from "@rjsf/utils";
import _pick from "lodash/pick";

Expand Down Expand Up @@ -75,18 +76,15 @@ export default function BaseInputTemplate<
multiline,
registry,
uiSchema,
}: WidgetProps<T, S, F>) {
}: BaseInputTemplateProps<T, S, F>) {
const { schemaUtils } = registry;
const inputProps = getInputProps<T, S, F>(schema, type, options);
const _onChange = ({
target: { value },
}: React.ChangeEvent<HTMLInputElement>) =>
const _onChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
onChange(value === "" ? options.emptyValue : value);
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onBlur(id, value);
const _onFocus = ({
target: { value },
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onFocus(id, value);

const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema);
const uiProps = _pick((options.props as object) || {}, allowedProps);
Expand All @@ -107,7 +105,7 @@ export default function BaseInputTemplate<
// name={name}
{...inputProps}
value={value || value === 0 ? value : ""}
onChange={onChangeOverride || _onChange}
onChange={(onChangeOverride as any) || _onChange}
onBlur={_onBlur}
onFocus={_onFocus}
errorMessage={(rawErrors || []).join("\n")}
Expand Down
16 changes: 7 additions & 9 deletions packages/material-ui/src/BaseInputTemplate/BaseInputTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ChangeEvent, FocusEvent } from "react";
import TextField, { TextFieldProps } from "@material-ui/core/TextField";
import {
ariaDescribedByIds,
BaseInputTemplateProps,
examplesId,
getInputProps,
FormContextType,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
} from "@rjsf/utils";

const TYPES_THAT_SHRINK_LABEL = ["date", "datetime-local", "file"];
Expand All @@ -21,7 +22,7 @@ export default function BaseInputTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: WidgetProps<T, S, F>) {
>(props: BaseInputTemplateProps<T, S, F>) {
const {
id,
name, // remove this from textFieldProps
Expand Down Expand Up @@ -58,15 +59,12 @@ export default function BaseInputTemplate<
},
...rest,
};
const _onChange = ({
target: { value },
}: React.ChangeEvent<HTMLInputElement>) =>
const _onChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
onChange(value === "" ? options.emptyValue : value);
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onBlur(id, value);
const _onFocus = ({
target: { value },
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onFocus(id, value);

const { schemaUtils } = registry;
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema);
Expand Down
16 changes: 7 additions & 9 deletions packages/mui/src/BaseInputTemplate/BaseInputTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ChangeEvent, FocusEvent } from "react";
import TextField, { TextFieldProps } from "@mui/material/TextField";
import {
ariaDescribedByIds,
BaseInputTemplateProps,
examplesId,
getInputProps,
FormContextType,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
} from "@rjsf/utils";

const TYPES_THAT_SHRINK_LABEL = ["date", "datetime-local", "file"];
Expand All @@ -21,7 +22,7 @@ export default function BaseInputTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: WidgetProps<T, S, F>) {
>(props: BaseInputTemplateProps<T, S, F>) {
const {
id,
name, // remove this from textFieldProps
Expand Down Expand Up @@ -58,15 +59,12 @@ export default function BaseInputTemplate<
},
...rest,
};
const _onChange = ({
target: { value },
}: React.ChangeEvent<HTMLInputElement>) =>
const _onChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) =>
onChange(value === "" ? options.emptyValue : value);
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
const _onBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onBlur(id, value);
const _onFocus = ({
target: { value },
}: React.FocusEvent<HTMLInputElement>) => onFocus(id, value);
const _onFocus = ({ target: { value } }: FocusEvent<HTMLInputElement>) =>
onFocus(id, value);

const { schemaUtils } = registry;
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema);
Expand Down
Loading

0 comments on commit c556613

Please sign in to comment.