@rjsf/antd 5.11.2 → 5.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/antd.esm.js +891 -1117
- package/dist/antd.esm.js.map +7 -1
- package/dist/antd.umd.js +1184 -0
- package/dist/index.js +1347 -5
- package/dist/index.js.map +7 -0
- package/lib/components/DatePicker/index.d.ts +48 -0
- package/lib/components/DatePicker/index.js +5 -0
- package/lib/components/DatePicker/index.js.map +1 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +17 -0
- package/lib/index.js.map +1 -0
- package/lib/templates/ArrayFieldItemTemplate/index.d.ts +7 -0
- package/lib/templates/ArrayFieldItemTemplate/index.js +21 -0
- package/lib/templates/ArrayFieldItemTemplate/index.js.map +1 -0
- package/lib/templates/ArrayFieldTemplate/index.d.ts +7 -0
- package/lib/templates/ArrayFieldTemplate/index.js +38 -0
- package/lib/templates/ArrayFieldTemplate/index.js.map +1 -0
- package/lib/templates/BaseInputTemplate/index.d.ts +9 -0
- package/lib/templates/BaseInputTemplate/index.js +31 -0
- package/lib/templates/BaseInputTemplate/index.js.map +1 -0
- package/lib/templates/DescriptionField/index.d.ts +7 -0
- package/lib/templates/DescriptionField/index.js +13 -0
- package/lib/templates/DescriptionField/index.js.map +1 -0
- package/lib/templates/ErrorList/index.d.ts +7 -0
- package/lib/templates/ErrorList/index.js +16 -0
- package/lib/templates/ErrorList/index.js.map +1 -0
- package/lib/templates/FieldErrorTemplate/index.d.ts +7 -0
- package/lib/templates/FieldErrorTemplate/index.js +15 -0
- package/lib/templates/FieldErrorTemplate/index.js.map +1 -0
- package/lib/templates/FieldTemplate/index.d.ts +8 -0
- package/lib/templates/FieldTemplate/index.js +34 -0
- package/lib/templates/FieldTemplate/index.js.map +1 -0
- package/lib/templates/IconButton/index.d.ts +10 -0
- package/lib/templates/IconButton/index.js +36 -0
- package/lib/templates/IconButton/index.js.map +1 -0
- package/lib/templates/ObjectFieldTemplate/index.d.ts +9 -0
- package/lib/templates/ObjectFieldTemplate/index.js +71 -0
- package/lib/templates/ObjectFieldTemplate/index.js.map +1 -0
- package/lib/templates/SubmitButton/index.d.ts +5 -0
- package/lib/templates/SubmitButton/index.js +13 -0
- package/lib/templates/SubmitButton/index.js.map +1 -0
- package/lib/templates/TitleField/index.d.ts +7 -0
- package/lib/templates/TitleField/index.js +34 -0
- package/lib/templates/TitleField/index.js.map +1 -0
- package/lib/templates/WrapIfAdditionalTemplate/index.d.ts +8 -0
- package/lib/templates/WrapIfAdditionalTemplate/index.js +34 -0
- package/lib/templates/WrapIfAdditionalTemplate/index.js.map +1 -0
- package/lib/templates/index.d.ts +4 -0
- package/lib/templates/index.js +36 -0
- package/lib/templates/index.js.map +1 -0
- package/lib/widgets/AltDateTimeWidget/index.d.ts +15 -0
- package/lib/widgets/AltDateTimeWidget/index.js +8 -0
- package/lib/widgets/AltDateTimeWidget/index.js.map +1 -0
- package/lib/widgets/AltDateWidget/index.d.ts +15 -0
- package/lib/widgets/AltDateWidget/index.js +89 -0
- package/lib/widgets/AltDateWidget/index.js.map +1 -0
- package/lib/widgets/CheckboxWidget/index.d.ts +8 -0
- package/lib/widgets/CheckboxWidget/index.js +23 -0
- package/lib/widgets/CheckboxWidget/index.js.map +1 -0
- package/lib/widgets/CheckboxesWidget/index.d.ts +8 -0
- package/lib/widgets/CheckboxesWidget/index.js +26 -0
- package/lib/widgets/CheckboxesWidget/index.js.map +1 -0
- package/lib/widgets/DateTimeWidget/index.d.ts +8 -0
- package/lib/widgets/DateTimeWidget/index.js +22 -0
- package/lib/widgets/DateTimeWidget/index.js.map +1 -0
- package/lib/widgets/DateWidget/index.d.ts +8 -0
- package/lib/widgets/DateWidget/index.js +22 -0
- package/lib/widgets/DateWidget/index.js.map +1 -0
- package/lib/widgets/PasswordWidget/index.d.ts +7 -0
- package/lib/widgets/PasswordWidget/index.js +17 -0
- package/lib/widgets/PasswordWidget/index.js.map +1 -0
- package/lib/widgets/RadioWidget/index.d.ts +8 -0
- package/lib/widgets/RadioWidget/index.js +19 -0
- package/lib/widgets/RadioWidget/index.js.map +1 -0
- package/lib/widgets/RangeWidget/index.d.ts +8 -0
- package/lib/widgets/RangeWidget/index.js +26 -0
- package/lib/widgets/RangeWidget/index.js.map +1 -0
- package/lib/widgets/SelectWidget/index.d.ts +8 -0
- package/lib/widgets/SelectWidget/index.js +36 -0
- package/lib/widgets/SelectWidget/index.js.map +1 -0
- package/lib/widgets/TextareaWidget/index.d.ts +7 -0
- package/lib/widgets/TextareaWidget/index.js +23 -0
- package/lib/widgets/TextareaWidget/index.js.map +1 -0
- package/lib/widgets/index.d.ts +4 -0
- package/lib/widgets/index.js +28 -0
- package/lib/widgets/index.js.map +1 -0
- package/package.json +24 -16
- package/src/components/DatePicker/index.ts +6 -0
- package/src/index.less +38 -0
- package/src/index.ts +33 -0
- package/src/templates/ArrayFieldItemTemplate/index.tsx +90 -0
- package/src/templates/ArrayFieldTemplate/index.tsx +132 -0
- package/src/templates/BaseInputTemplate/index.tsx +105 -0
- package/src/templates/DescriptionField/index.tsx +17 -0
- package/src/templates/ErrorList/index.tsx +37 -0
- package/src/templates/FieldErrorTemplate/index.tsx +25 -0
- package/src/templates/FieldTemplate/index.tsx +114 -0
- package/src/templates/IconButton/index.tsx +94 -0
- package/src/templates/ObjectFieldTemplate/index.tsx +175 -0
- package/src/templates/SubmitButton/index.tsx +20 -0
- package/src/templates/TitleField/index.tsx +57 -0
- package/src/templates/WrapIfAdditionalTemplate/index.tsx +124 -0
- package/src/templates/index.ts +43 -0
- package/src/widgets/AltDateTimeWidget/index.tsx +17 -0
- package/src/widgets/AltDateWidget/index.tsx +197 -0
- package/src/widgets/CheckboxWidget/index.tsx +52 -0
- package/src/widgets/CheckboxesWidget/index.tsx +75 -0
- package/src/widgets/DateTimeWidget/index.tsx +54 -0
- package/src/widgets/DateWidget/index.tsx +52 -0
- package/src/widgets/PasswordWidget/index.tsx +46 -0
- package/src/widgets/RadioWidget/index.tsx +73 -0
- package/src/widgets/RangeWidget/index.tsx +69 -0
- package/src/widgets/SelectWidget/index.tsx +97 -0
- package/src/widgets/TextareaWidget/index.tsx +67 -0
- package/src/widgets/index.ts +35 -0
- package/dist/antd.cjs.development.js +0 -1643
- package/dist/antd.cjs.development.js.map +0 -1
- package/dist/antd.cjs.production.min.js +0 -2
- package/dist/antd.cjs.production.min.js.map +0 -1
- package/dist/antd.umd.development.js +0 -1617
- package/dist/antd.umd.development.js.map +0 -1
- package/dist/antd.umd.production.min.js +0 -2
- package/dist/antd.umd.production.min.js.map +0 -1
- package/dist/index.d.ts +0 -16
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Button, { ButtonType } from 'antd/lib/button';
|
|
2
|
+
import { getSubmitButtonOptions, FormContextType, RJSFSchema, StrictRJSFSchema, SubmitButtonProps } from '@rjsf/utils';
|
|
3
|
+
|
|
4
|
+
/** The `SubmitButton` renders a button that represent the `Submit` action on a form
|
|
5
|
+
*/
|
|
6
|
+
export default function SubmitButton<
|
|
7
|
+
T = any,
|
|
8
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
9
|
+
F extends FormContextType = any
|
|
10
|
+
>({ uiSchema }: SubmitButtonProps<T, S, F>) {
|
|
11
|
+
const { submitText, norender, props: submitButtonProps } = getSubmitButtonOptions(uiSchema);
|
|
12
|
+
if (norender) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return (
|
|
16
|
+
<Button type={'submit' as ButtonType} {...submitButtonProps} htmlType='submit'>
|
|
17
|
+
{submitText}
|
|
18
|
+
</Button>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import { ConfigConsumer, ConfigConsumerProps } from 'antd/lib/config-provider/context';
|
|
3
|
+
import { FormContextType, TitleFieldProps, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';
|
|
4
|
+
|
|
5
|
+
/** The `TitleField` is the template to use to render the title of a field
|
|
6
|
+
*
|
|
7
|
+
* @param props - The `TitleFieldProps` for this component
|
|
8
|
+
*/
|
|
9
|
+
export default function TitleField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>({
|
|
10
|
+
id,
|
|
11
|
+
required,
|
|
12
|
+
registry,
|
|
13
|
+
title,
|
|
14
|
+
}: TitleFieldProps<T, S, F>) {
|
|
15
|
+
const { formContext } = registry;
|
|
16
|
+
const { colon = true } = formContext;
|
|
17
|
+
|
|
18
|
+
let labelChildren = title;
|
|
19
|
+
if (colon && typeof title === 'string' && title.trim() !== '') {
|
|
20
|
+
labelChildren = title.replace(/[::]\s*$/, '');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const handleLabelClick = () => {
|
|
24
|
+
if (!id) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const control: HTMLLabelElement | null = document.querySelector(`[id="${id}"]`);
|
|
29
|
+
if (control && control.focus) {
|
|
30
|
+
control.focus();
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return title ? (
|
|
35
|
+
<ConfigConsumer>
|
|
36
|
+
{(configProps: ConfigConsumerProps) => {
|
|
37
|
+
const { getPrefixCls } = configProps;
|
|
38
|
+
const prefixCls = getPrefixCls('form');
|
|
39
|
+
const labelClassName = classNames({
|
|
40
|
+
[`${prefixCls}-item-required`]: required,
|
|
41
|
+
[`${prefixCls}-item-no-colon`]: !colon,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<label
|
|
46
|
+
className={labelClassName}
|
|
47
|
+
htmlFor={id}
|
|
48
|
+
onClick={handleLabelClick}
|
|
49
|
+
title={typeof title === 'string' ? title : ''}
|
|
50
|
+
>
|
|
51
|
+
{labelChildren}
|
|
52
|
+
</label>
|
|
53
|
+
);
|
|
54
|
+
}}
|
|
55
|
+
</ConfigConsumer>
|
|
56
|
+
) : null;
|
|
57
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { FocusEvent } from 'react';
|
|
2
|
+
import Col from 'antd/lib/col';
|
|
3
|
+
import Form from 'antd/lib/form';
|
|
4
|
+
import Input from 'antd/lib/input';
|
|
5
|
+
import Row from 'antd/lib/row';
|
|
6
|
+
import {
|
|
7
|
+
ADDITIONAL_PROPERTY_FLAG,
|
|
8
|
+
UI_OPTIONS_KEY,
|
|
9
|
+
FormContextType,
|
|
10
|
+
RJSFSchema,
|
|
11
|
+
StrictRJSFSchema,
|
|
12
|
+
TranslatableString,
|
|
13
|
+
WrapIfAdditionalTemplateProps,
|
|
14
|
+
} from '@rjsf/utils';
|
|
15
|
+
|
|
16
|
+
const VERTICAL_LABEL_COL = { span: 24 };
|
|
17
|
+
const VERTICAL_WRAPPER_COL = { span: 24 };
|
|
18
|
+
|
|
19
|
+
const INPUT_STYLE = {
|
|
20
|
+
width: '100%',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** The `WrapIfAdditional` component is used by the `FieldTemplate` to rename, or remove properties that are
|
|
24
|
+
* part of an `additionalProperties` part of a schema.
|
|
25
|
+
*
|
|
26
|
+
* @param props - The `WrapIfAdditionalProps` for this component
|
|
27
|
+
*/
|
|
28
|
+
export default function WrapIfAdditionalTemplate<
|
|
29
|
+
T = any,
|
|
30
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
31
|
+
F extends FormContextType = any
|
|
32
|
+
>(props: WrapIfAdditionalTemplateProps<T, S, F>) {
|
|
33
|
+
const {
|
|
34
|
+
children,
|
|
35
|
+
classNames,
|
|
36
|
+
style,
|
|
37
|
+
disabled,
|
|
38
|
+
id,
|
|
39
|
+
label,
|
|
40
|
+
onDropPropertyClick,
|
|
41
|
+
onKeyChange,
|
|
42
|
+
readonly,
|
|
43
|
+
required,
|
|
44
|
+
registry,
|
|
45
|
+
schema,
|
|
46
|
+
uiSchema,
|
|
47
|
+
} = props;
|
|
48
|
+
const {
|
|
49
|
+
colon,
|
|
50
|
+
labelCol = VERTICAL_LABEL_COL,
|
|
51
|
+
readonlyAsDisabled = true,
|
|
52
|
+
rowGutter = 24,
|
|
53
|
+
toolbarAlign = 'top',
|
|
54
|
+
wrapperCol = VERTICAL_WRAPPER_COL,
|
|
55
|
+
wrapperStyle,
|
|
56
|
+
} = registry.formContext;
|
|
57
|
+
const { templates, translateString } = registry;
|
|
58
|
+
// Button templates are not overridden in the uiSchema
|
|
59
|
+
const { RemoveButton } = templates.ButtonTemplates;
|
|
60
|
+
const keyLabel = translateString(TranslatableString.KeyLabel, [label]);
|
|
61
|
+
const additional = ADDITIONAL_PROPERTY_FLAG in schema;
|
|
62
|
+
|
|
63
|
+
if (!additional) {
|
|
64
|
+
return (
|
|
65
|
+
<div className={classNames} style={style}>
|
|
66
|
+
{children}
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const handleBlur = ({ target }: FocusEvent<HTMLInputElement>) => onKeyChange(target.value);
|
|
72
|
+
|
|
73
|
+
// The `block` prop is not part of the `IconButtonProps` defined in the template, so put it into the uiSchema instead
|
|
74
|
+
const uiOptions = uiSchema ? uiSchema[UI_OPTIONS_KEY] : {};
|
|
75
|
+
const buttonUiOptions = {
|
|
76
|
+
...uiSchema,
|
|
77
|
+
[UI_OPTIONS_KEY]: { ...uiOptions, block: true },
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div className={classNames} style={style}>
|
|
82
|
+
<Row align={toolbarAlign} gutter={rowGutter}>
|
|
83
|
+
<Col className='form-additional' flex='1'>
|
|
84
|
+
<div className='form-group'>
|
|
85
|
+
<Form.Item
|
|
86
|
+
colon={colon}
|
|
87
|
+
className='form-group'
|
|
88
|
+
hasFeedback
|
|
89
|
+
htmlFor={`${id}-key`}
|
|
90
|
+
label={keyLabel}
|
|
91
|
+
labelCol={labelCol}
|
|
92
|
+
required={required}
|
|
93
|
+
style={wrapperStyle}
|
|
94
|
+
wrapperCol={wrapperCol}
|
|
95
|
+
>
|
|
96
|
+
<Input
|
|
97
|
+
className='form-control'
|
|
98
|
+
defaultValue={label}
|
|
99
|
+
disabled={disabled || (readonlyAsDisabled && readonly)}
|
|
100
|
+
id={`${id}-key`}
|
|
101
|
+
name={`${id}-key`}
|
|
102
|
+
onBlur={!readonly ? handleBlur : undefined}
|
|
103
|
+
style={INPUT_STYLE}
|
|
104
|
+
type='text'
|
|
105
|
+
/>
|
|
106
|
+
</Form.Item>
|
|
107
|
+
</div>
|
|
108
|
+
</Col>
|
|
109
|
+
<Col className='form-additional' flex='1'>
|
|
110
|
+
{children}
|
|
111
|
+
</Col>
|
|
112
|
+
<Col flex='192px'>
|
|
113
|
+
<RemoveButton
|
|
114
|
+
className='array-item-remove'
|
|
115
|
+
disabled={disabled || readonly}
|
|
116
|
+
onClick={onDropPropertyClick(label)}
|
|
117
|
+
uiSchema={buttonUiOptions}
|
|
118
|
+
registry={registry}
|
|
119
|
+
/>
|
|
120
|
+
</Col>
|
|
121
|
+
</Row>
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FormContextType, RJSFSchema, StrictRJSFSchema, TemplatesType } from '@rjsf/utils';
|
|
2
|
+
|
|
3
|
+
import ArrayFieldItemTemplate from './ArrayFieldItemTemplate';
|
|
4
|
+
import ArrayFieldTemplate from './ArrayFieldTemplate';
|
|
5
|
+
import BaseInputTemplate from './BaseInputTemplate';
|
|
6
|
+
import DescriptionField from './DescriptionField';
|
|
7
|
+
import ErrorList from './ErrorList';
|
|
8
|
+
import { AddButton, CopyButton, MoveDownButton, MoveUpButton, RemoveButton } from './IconButton';
|
|
9
|
+
import FieldErrorTemplate from './FieldErrorTemplate';
|
|
10
|
+
import FieldTemplate from './FieldTemplate';
|
|
11
|
+
import ObjectFieldTemplate from './ObjectFieldTemplate';
|
|
12
|
+
import SubmitButton from './SubmitButton';
|
|
13
|
+
import TitleField from './TitleField';
|
|
14
|
+
import WrapIfAdditionalTemplate from './WrapIfAdditionalTemplate';
|
|
15
|
+
|
|
16
|
+
export function generateTemplates<
|
|
17
|
+
T = any,
|
|
18
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
19
|
+
F extends FormContextType = any
|
|
20
|
+
>(): Partial<TemplatesType<T, S, F>> {
|
|
21
|
+
return {
|
|
22
|
+
ArrayFieldItemTemplate,
|
|
23
|
+
ArrayFieldTemplate,
|
|
24
|
+
BaseInputTemplate,
|
|
25
|
+
ButtonTemplates: {
|
|
26
|
+
AddButton,
|
|
27
|
+
CopyButton,
|
|
28
|
+
MoveDownButton,
|
|
29
|
+
MoveUpButton,
|
|
30
|
+
RemoveButton,
|
|
31
|
+
SubmitButton,
|
|
32
|
+
},
|
|
33
|
+
DescriptionFieldTemplate: DescriptionField,
|
|
34
|
+
ErrorListTemplate: ErrorList,
|
|
35
|
+
FieldErrorTemplate,
|
|
36
|
+
FieldTemplate,
|
|
37
|
+
ObjectFieldTemplate,
|
|
38
|
+
TitleFieldTemplate: TitleField,
|
|
39
|
+
WrapIfAdditionalTemplate,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default generateTemplates();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FormContextType, RJSFSchema, StrictRJSFSchema, WidgetProps } from '@rjsf/utils';
|
|
2
|
+
|
|
3
|
+
import _AltDateWidget from '../AltDateWidget';
|
|
4
|
+
|
|
5
|
+
export default function AltDateTimeWidget<
|
|
6
|
+
T = any,
|
|
7
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
8
|
+
F extends FormContextType = any
|
|
9
|
+
>(props: WidgetProps<T, S, F>) {
|
|
10
|
+
const { AltDateWidget } = props.registry.widgets;
|
|
11
|
+
return <AltDateWidget showTime {...props} />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
AltDateTimeWidget.defaultProps = {
|
|
15
|
+
..._AltDateWidget.defaultProps,
|
|
16
|
+
showTime: true,
|
|
17
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { MouseEvent, useEffect, useState } from 'react';
|
|
2
|
+
import Button from 'antd/lib/button';
|
|
3
|
+
import Col from 'antd/lib/col';
|
|
4
|
+
import Row from 'antd/lib/row';
|
|
5
|
+
import {
|
|
6
|
+
ariaDescribedByIds,
|
|
7
|
+
pad,
|
|
8
|
+
parseDateString,
|
|
9
|
+
toDateString,
|
|
10
|
+
DateObject,
|
|
11
|
+
FormContextType,
|
|
12
|
+
GenericObjectType,
|
|
13
|
+
RJSFSchema,
|
|
14
|
+
StrictRJSFSchema,
|
|
15
|
+
TranslatableString,
|
|
16
|
+
WidgetProps,
|
|
17
|
+
} from '@rjsf/utils';
|
|
18
|
+
|
|
19
|
+
type DateElementProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = Pick<
|
|
20
|
+
WidgetProps<T, S, F>,
|
|
21
|
+
'id' | 'name' | 'value' | 'disabled' | 'readonly' | 'autofocus' | 'registry' | 'onBlur' | 'onFocus'
|
|
22
|
+
> & {
|
|
23
|
+
select: (property: keyof DateObject, value: any) => void;
|
|
24
|
+
type: string;
|
|
25
|
+
range: [number, number];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const rangeOptions = (start: number, stop: number) => {
|
|
29
|
+
const options = [];
|
|
30
|
+
for (let i = start; i <= stop; i++) {
|
|
31
|
+
options.push({ value: i, label: pad(i, 2) });
|
|
32
|
+
}
|
|
33
|
+
return options;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const readyForChange = (state: DateObject) => {
|
|
37
|
+
return Object.values(state).every((value) => value !== -1);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function dateElementProps(
|
|
41
|
+
state: DateObject,
|
|
42
|
+
time: boolean,
|
|
43
|
+
yearsRange: [number, number] = [1900, new Date().getFullYear() + 2]
|
|
44
|
+
) {
|
|
45
|
+
const { year, month, day, hour, minute, second } = state;
|
|
46
|
+
const data = [
|
|
47
|
+
{
|
|
48
|
+
type: 'year',
|
|
49
|
+
range: yearsRange,
|
|
50
|
+
value: year,
|
|
51
|
+
},
|
|
52
|
+
{ type: 'month', range: [1, 12], value: month },
|
|
53
|
+
{ type: 'day', range: [1, 31], value: day },
|
|
54
|
+
] as { type: string; range: [number, number]; value: number }[];
|
|
55
|
+
if (time) {
|
|
56
|
+
data.push(
|
|
57
|
+
{ type: 'hour', range: [0, 23], value: hour || -1 },
|
|
58
|
+
{ type: 'minute', range: [0, 59], value: minute || -1 },
|
|
59
|
+
{ type: 'second', range: [0, 59], value: second || -1 }
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return data;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default function AltDateWidget<
|
|
66
|
+
T = any,
|
|
67
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
68
|
+
F extends FormContextType = any
|
|
69
|
+
>(props: WidgetProps<T, S, F>) {
|
|
70
|
+
const {
|
|
71
|
+
autofocus,
|
|
72
|
+
disabled,
|
|
73
|
+
formContext,
|
|
74
|
+
id,
|
|
75
|
+
onBlur,
|
|
76
|
+
onChange,
|
|
77
|
+
onFocus,
|
|
78
|
+
options,
|
|
79
|
+
readonly,
|
|
80
|
+
registry,
|
|
81
|
+
showTime,
|
|
82
|
+
value,
|
|
83
|
+
} = props;
|
|
84
|
+
const { translateString, widgets } = registry;
|
|
85
|
+
const { SelectWidget } = widgets;
|
|
86
|
+
const { rowGutter = 24 } = formContext as GenericObjectType;
|
|
87
|
+
|
|
88
|
+
const [state, setState] = useState(parseDateString(value, showTime));
|
|
89
|
+
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
setState(parseDateString(value, showTime));
|
|
92
|
+
}, [showTime, value]);
|
|
93
|
+
|
|
94
|
+
const handleChange = (property: keyof DateObject, nextValue: any) => {
|
|
95
|
+
const nextState = {
|
|
96
|
+
...state,
|
|
97
|
+
[property]: typeof nextValue === 'undefined' ? -1 : nextValue,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
if (readyForChange(nextState)) {
|
|
101
|
+
onChange(toDateString(nextState, showTime));
|
|
102
|
+
} else {
|
|
103
|
+
setState(nextState);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const handleNow = (event: MouseEvent<HTMLButtonElement>) => {
|
|
108
|
+
event.preventDefault();
|
|
109
|
+
if (disabled || readonly) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const nextState = parseDateString(new Date().toJSON(), showTime);
|
|
113
|
+
onChange(toDateString(nextState, showTime));
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const handleClear = (event: MouseEvent<HTMLButtonElement>) => {
|
|
117
|
+
event.preventDefault();
|
|
118
|
+
if (disabled || readonly) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
onChange(undefined);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const renderDateElement = (elemProps: DateElementProps<T, S, F>) => (
|
|
125
|
+
<SelectWidget
|
|
126
|
+
autofocus={elemProps.autofocus}
|
|
127
|
+
className='form-control'
|
|
128
|
+
disabled={elemProps.disabled}
|
|
129
|
+
id={elemProps.id}
|
|
130
|
+
name={elemProps.name}
|
|
131
|
+
onBlur={elemProps.onBlur}
|
|
132
|
+
onChange={(elemValue) => elemProps.select(elemProps.type as keyof DateObject, elemValue)}
|
|
133
|
+
onFocus={elemProps.onFocus}
|
|
134
|
+
options={{
|
|
135
|
+
enumOptions: rangeOptions(elemProps.range[0], elemProps.range[1]),
|
|
136
|
+
}}
|
|
137
|
+
placeholder={elemProps.type}
|
|
138
|
+
readonly={elemProps.readonly}
|
|
139
|
+
schema={{ type: 'integer' } as S}
|
|
140
|
+
value={elemProps.value}
|
|
141
|
+
registry={registry}
|
|
142
|
+
label=''
|
|
143
|
+
aria-describedby={ariaDescribedByIds<T>(id)}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<Row gutter={[Math.floor(rowGutter / 2), Math.floor(rowGutter / 2)]}>
|
|
149
|
+
{dateElementProps(state, showTime, options.yearsRange as [number, number] | undefined).map((elemProps, i) => {
|
|
150
|
+
const elemId = id + '_' + elemProps.type;
|
|
151
|
+
return (
|
|
152
|
+
<Col flex='88px' key={elemId}>
|
|
153
|
+
{renderDateElement({
|
|
154
|
+
...elemProps,
|
|
155
|
+
autofocus: autofocus && i === 0,
|
|
156
|
+
disabled,
|
|
157
|
+
id: elemId,
|
|
158
|
+
name: id,
|
|
159
|
+
onBlur,
|
|
160
|
+
onFocus,
|
|
161
|
+
readonly,
|
|
162
|
+
registry,
|
|
163
|
+
select: handleChange,
|
|
164
|
+
// NOTE: antd components accept -1 rather than issue a warning
|
|
165
|
+
// like material-ui, so we need to convert -1 to undefined here.
|
|
166
|
+
value: elemProps.value < 0 ? undefined : elemProps.value,
|
|
167
|
+
})}
|
|
168
|
+
</Col>
|
|
169
|
+
);
|
|
170
|
+
})}
|
|
171
|
+
{!options.hideNowButton && (
|
|
172
|
+
<Col flex='88px'>
|
|
173
|
+
<Button block className='btn-now' onClick={handleNow} type='primary'>
|
|
174
|
+
{translateString(TranslatableString.NowLabel)}
|
|
175
|
+
</Button>
|
|
176
|
+
</Col>
|
|
177
|
+
)}
|
|
178
|
+
{!options.hideClearButton && (
|
|
179
|
+
<Col flex='88px'>
|
|
180
|
+
<Button block className='btn-clear' danger onClick={handleClear} type='primary'>
|
|
181
|
+
{translateString(TranslatableString.ClearLabel)}
|
|
182
|
+
</Button>
|
|
183
|
+
</Col>
|
|
184
|
+
)}
|
|
185
|
+
</Row>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
AltDateWidget.defaultProps = {
|
|
190
|
+
autofocus: false,
|
|
191
|
+
disabled: false,
|
|
192
|
+
options: {
|
|
193
|
+
yearsRange: [1900, new Date().getFullYear() + 2],
|
|
194
|
+
},
|
|
195
|
+
readonly: false,
|
|
196
|
+
showTime: false,
|
|
197
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { FocusEvent } from 'react';
|
|
2
|
+
import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox';
|
|
3
|
+
import {
|
|
4
|
+
ariaDescribedByIds,
|
|
5
|
+
labelValue,
|
|
6
|
+
FormContextType,
|
|
7
|
+
RJSFSchema,
|
|
8
|
+
StrictRJSFSchema,
|
|
9
|
+
WidgetProps,
|
|
10
|
+
GenericObjectType,
|
|
11
|
+
} from '@rjsf/utils';
|
|
12
|
+
|
|
13
|
+
/** The `CheckBoxWidget` is a widget for rendering boolean properties.
|
|
14
|
+
* It is typically used to represent a boolean.
|
|
15
|
+
*
|
|
16
|
+
* @param props - The `WidgetProps` for this component
|
|
17
|
+
*/
|
|
18
|
+
export default function CheckboxWidget<
|
|
19
|
+
T = any,
|
|
20
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
21
|
+
F extends FormContextType = any
|
|
22
|
+
>(props: WidgetProps<T, S, F>) {
|
|
23
|
+
const { autofocus, disabled, formContext, id, label, hideLabel, onBlur, onChange, onFocus, readonly, value } = props;
|
|
24
|
+
const { readonlyAsDisabled = true } = formContext as GenericObjectType;
|
|
25
|
+
|
|
26
|
+
const handleChange = ({ target }: CheckboxChangeEvent) => onChange(target.checked);
|
|
27
|
+
|
|
28
|
+
const handleBlur = ({ target }: FocusEvent<HTMLInputElement>) => onBlur(id, target.checked);
|
|
29
|
+
|
|
30
|
+
const handleFocus = ({ target }: FocusEvent<HTMLInputElement>) => onFocus(id, target.checked);
|
|
31
|
+
|
|
32
|
+
// Antd's typescript definitions do not contain the following props that are actually necessary and, if provided,
|
|
33
|
+
// they are used, so hacking them in via by spreading `extraProps` on the component to avoid typescript errors
|
|
34
|
+
const extraProps = {
|
|
35
|
+
onBlur: !readonly ? handleBlur : undefined,
|
|
36
|
+
onFocus: !readonly ? handleFocus : undefined,
|
|
37
|
+
};
|
|
38
|
+
return (
|
|
39
|
+
<Checkbox
|
|
40
|
+
autoFocus={autofocus}
|
|
41
|
+
checked={typeof value === 'undefined' ? false : value}
|
|
42
|
+
disabled={disabled || (readonlyAsDisabled && readonly)}
|
|
43
|
+
id={id}
|
|
44
|
+
name={id}
|
|
45
|
+
onChange={!readonly ? handleChange : undefined}
|
|
46
|
+
{...extraProps}
|
|
47
|
+
aria-describedby={ariaDescribedByIds<T>(id)}
|
|
48
|
+
>
|
|
49
|
+
{labelValue(label, hideLabel, '')}
|
|
50
|
+
</Checkbox>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { FocusEvent } from 'react';
|
|
2
|
+
import Checkbox from 'antd/lib/checkbox';
|
|
3
|
+
import {
|
|
4
|
+
ariaDescribedByIds,
|
|
5
|
+
enumOptionsIndexForValue,
|
|
6
|
+
enumOptionsValueForIndex,
|
|
7
|
+
optionId,
|
|
8
|
+
FormContextType,
|
|
9
|
+
WidgetProps,
|
|
10
|
+
RJSFSchema,
|
|
11
|
+
StrictRJSFSchema,
|
|
12
|
+
GenericObjectType,
|
|
13
|
+
} from '@rjsf/utils';
|
|
14
|
+
|
|
15
|
+
/** The `CheckboxesWidget` is a widget for rendering checkbox groups.
|
|
16
|
+
* It is typically used to represent an array of enums.
|
|
17
|
+
*
|
|
18
|
+
* @param props - The `WidgetProps` for this component
|
|
19
|
+
*/
|
|
20
|
+
export default function CheckboxesWidget<
|
|
21
|
+
T = any,
|
|
22
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
23
|
+
F extends FormContextType = any
|
|
24
|
+
>({ autofocus, disabled, formContext, id, onBlur, onChange, onFocus, options, readonly, value }: WidgetProps<T, S, F>) {
|
|
25
|
+
const { readonlyAsDisabled = true } = formContext as GenericObjectType;
|
|
26
|
+
|
|
27
|
+
const { enumOptions, enumDisabled, inline, emptyValue } = options;
|
|
28
|
+
|
|
29
|
+
const handleChange = (nextValue: any) => onChange(enumOptionsValueForIndex<S>(nextValue, enumOptions, emptyValue));
|
|
30
|
+
|
|
31
|
+
const handleBlur = ({ target }: FocusEvent<HTMLInputElement>) =>
|
|
32
|
+
onBlur(id, enumOptionsValueForIndex<S>(target.value, enumOptions, emptyValue));
|
|
33
|
+
|
|
34
|
+
const handleFocus = ({ target }: FocusEvent<HTMLInputElement>) =>
|
|
35
|
+
onFocus(id, enumOptionsValueForIndex<S>(target.value, enumOptions, emptyValue));
|
|
36
|
+
|
|
37
|
+
// Antd's typescript definitions do not contain the following props that are actually necessary and, if provided,
|
|
38
|
+
// they are used, so hacking them in via by spreading `extraProps` on the component to avoid typescript errors
|
|
39
|
+
const extraProps = {
|
|
40
|
+
id,
|
|
41
|
+
onBlur: !readonly ? handleBlur : undefined,
|
|
42
|
+
onFocus: !readonly ? handleFocus : undefined,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const selectedIndexes = enumOptionsIndexForValue<S>(value, enumOptions, true) as string[];
|
|
46
|
+
|
|
47
|
+
return Array.isArray(enumOptions) && enumOptions.length > 0 ? (
|
|
48
|
+
<>
|
|
49
|
+
<Checkbox.Group
|
|
50
|
+
disabled={disabled || (readonlyAsDisabled && readonly)}
|
|
51
|
+
name={id}
|
|
52
|
+
onChange={!readonly ? handleChange : undefined}
|
|
53
|
+
value={selectedIndexes}
|
|
54
|
+
{...extraProps}
|
|
55
|
+
aria-describedby={ariaDescribedByIds<T>(id)}
|
|
56
|
+
>
|
|
57
|
+
{Array.isArray(enumOptions) &&
|
|
58
|
+
enumOptions.map((option, i) => (
|
|
59
|
+
<span key={i}>
|
|
60
|
+
<Checkbox
|
|
61
|
+
id={optionId(id, i)}
|
|
62
|
+
name={id}
|
|
63
|
+
autoFocus={i === 0 ? autofocus : false}
|
|
64
|
+
disabled={Array.isArray(enumDisabled) && enumDisabled.indexOf(value) !== -1}
|
|
65
|
+
value={String(i)}
|
|
66
|
+
>
|
|
67
|
+
{option.label}
|
|
68
|
+
</Checkbox>
|
|
69
|
+
{!inline && <br />}
|
|
70
|
+
</span>
|
|
71
|
+
))}
|
|
72
|
+
</Checkbox.Group>
|
|
73
|
+
</>
|
|
74
|
+
) : null;
|
|
75
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import {
|
|
3
|
+
ariaDescribedByIds,
|
|
4
|
+
FormContextType,
|
|
5
|
+
GenericObjectType,
|
|
6
|
+
RJSFSchema,
|
|
7
|
+
StrictRJSFSchema,
|
|
8
|
+
WidgetProps,
|
|
9
|
+
} from '@rjsf/utils';
|
|
10
|
+
|
|
11
|
+
import DatePicker from '../../components/DatePicker';
|
|
12
|
+
|
|
13
|
+
const DATE_PICKER_STYLE = {
|
|
14
|
+
width: '100%',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** The `DateTimeWidget` component uses the `BaseInputTemplate` changing the type to `datetime-local` and transforms
|
|
18
|
+
* the value to/from utc using the appropriate utility functions.
|
|
19
|
+
*
|
|
20
|
+
* @param props - The `WidgetProps` for this component
|
|
21
|
+
*/
|
|
22
|
+
export default function DateTimeWidget<
|
|
23
|
+
T = any,
|
|
24
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
25
|
+
F extends FormContextType = any
|
|
26
|
+
>(props: WidgetProps<T, S, F>) {
|
|
27
|
+
const { disabled, formContext, id, onBlur, onChange, onFocus, placeholder, readonly, value } = props;
|
|
28
|
+
const { readonlyAsDisabled = true } = formContext as GenericObjectType;
|
|
29
|
+
|
|
30
|
+
const handleChange = (nextValue: any) => onChange(nextValue && nextValue.toISOString());
|
|
31
|
+
|
|
32
|
+
const handleBlur = () => onBlur(id, value);
|
|
33
|
+
|
|
34
|
+
const handleFocus = () => onFocus(id, value);
|
|
35
|
+
|
|
36
|
+
const getPopupContainer = (node: any) => node.parentNode;
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<DatePicker
|
|
40
|
+
disabled={disabled || (readonlyAsDisabled && readonly)}
|
|
41
|
+
getPopupContainer={getPopupContainer}
|
|
42
|
+
id={id}
|
|
43
|
+
name={id}
|
|
44
|
+
onBlur={!readonly ? handleBlur : undefined}
|
|
45
|
+
onChange={!readonly ? handleChange : undefined}
|
|
46
|
+
onFocus={!readonly ? handleFocus : undefined}
|
|
47
|
+
placeholder={placeholder}
|
|
48
|
+
showTime
|
|
49
|
+
style={DATE_PICKER_STYLE}
|
|
50
|
+
value={value && dayjs(value)}
|
|
51
|
+
aria-describedby={ariaDescribedByIds<T>(id)}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import {
|
|
3
|
+
ariaDescribedByIds,
|
|
4
|
+
FormContextType,
|
|
5
|
+
RJSFSchema,
|
|
6
|
+
StrictRJSFSchema,
|
|
7
|
+
WidgetProps,
|
|
8
|
+
GenericObjectType,
|
|
9
|
+
} from '@rjsf/utils';
|
|
10
|
+
|
|
11
|
+
import DatePicker from '../../components/DatePicker';
|
|
12
|
+
|
|
13
|
+
const DATE_PICKER_STYLE = {
|
|
14
|
+
width: '100%',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** The `DateWidget` component uses the `BaseInputTemplate` changing the type to `date` and transforms
|
|
18
|
+
* the value to undefined when it is falsy during the `onChange` handling.
|
|
19
|
+
*
|
|
20
|
+
* @param props - The `WidgetProps` for this component
|
|
21
|
+
*/
|
|
22
|
+
export default function DateWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
|
|
23
|
+
props: WidgetProps<T, S, F>
|
|
24
|
+
) {
|
|
25
|
+
const { disabled, formContext, id, onBlur, onChange, onFocus, placeholder, readonly, value } = props;
|
|
26
|
+
const { readonlyAsDisabled = true } = formContext as GenericObjectType;
|
|
27
|
+
|
|
28
|
+
const handleChange = (nextValue: any) => onChange(nextValue && nextValue.format('YYYY-MM-DD'));
|
|
29
|
+
|
|
30
|
+
const handleBlur = () => onBlur(id, value);
|
|
31
|
+
|
|
32
|
+
const handleFocus = () => onFocus(id, value);
|
|
33
|
+
|
|
34
|
+
const getPopupContainer = (node: any) => node.parentNode;
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<DatePicker
|
|
38
|
+
disabled={disabled || (readonlyAsDisabled && readonly)}
|
|
39
|
+
getPopupContainer={getPopupContainer}
|
|
40
|
+
id={id}
|
|
41
|
+
name={id}
|
|
42
|
+
onBlur={!readonly ? handleBlur : undefined}
|
|
43
|
+
onChange={!readonly ? handleChange : undefined}
|
|
44
|
+
onFocus={!readonly ? handleFocus : undefined}
|
|
45
|
+
placeholder={placeholder}
|
|
46
|
+
showTime={false}
|
|
47
|
+
style={DATE_PICKER_STYLE}
|
|
48
|
+
value={value && dayjs(value)}
|
|
49
|
+
aria-describedby={ariaDescribedByIds<T>(id)}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|