forked from rjsf-team/react-jsonschema-form
/
CheckboxesWidget.tsx
107 lines (96 loc) · 2.99 KB
/
CheckboxesWidget.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React from "react";
import { Checkbox, Label } from "@fluentui/react";
import {
FormContextType,
RJSFSchema,
StrictRJSFSchema,
WidgetProps,
} from "@rjsf/utils";
import { allowedProps } from "../CheckboxWidget";
import _pick from "lodash/pick";
const styles_red = {
// TODO: get this color from theme.
color: "rgb(164, 38, 44)",
fontSize: 12,
fontWeight: "normal" as any,
fontFamily: `"Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;`,
};
const selectValue = (value: any, selected: any, all: any) => {
const at = all.indexOf(value);
const updated = selected.slice(0, at).concat(value, selected.slice(at));
// As inserting values at predefined index positions doesn't work with empty
// arrays, we need to reorder the updated selection to match the initial order
return updated.sort((a: any, b: any) => all.indexOf(a) > all.indexOf(b));
};
const deselectValue = (value: any, selected: any) => {
return selected.filter((v: any) => v !== value);
};
export default function CheckboxesWidget<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>({
schema,
label,
id,
disabled,
options,
value,
autofocus,
readonly,
required,
onChange,
onBlur,
onFocus,
rawErrors = [],
}: WidgetProps<T, S, F>) {
const { enumOptions, enumDisabled } = options;
const _onChange =
(option: any) =>
(_ev?: React.FormEvent<HTMLElement>, checked?: boolean) => {
const all = (enumOptions as any).map(({ value }: any) => value);
if (checked) {
onChange(selectValue(option.value, value, all));
} else {
onChange(deselectValue(option.value, value));
}
};
const _onBlur = ({
target: { value },
}: React.FocusEvent<HTMLButtonElement>) => onBlur(id, value);
const _onFocus = ({
target: { value },
}: React.FocusEvent<HTMLButtonElement>) => onFocus(id, value);
const uiProps = _pick((options.props as object) || {}, allowedProps);
return (
<>
<Label>
{label || schema.title}
{required && <span style={styles_red}> *</span>}
</Label>
{Array.isArray(enumOptions) &&
enumOptions.map((option, index: number) => {
const checked = value.indexOf(option.value) !== -1;
const itemDisabled =
Array.isArray(enumDisabled) &&
enumDisabled.indexOf(option.value) !== -1;
return (
<Checkbox
id={`${id}-${option.value}`}
name={id}
checked={checked}
label={option.label}
disabled={disabled || itemDisabled || readonly}
autoFocus={autofocus && index === 0}
onChange={_onChange(option)}
onBlur={_onBlur}
onFocus={_onFocus}
key={option.value}
{...uiProps}
/>
);
})}
<span style={styles_red}>{(rawErrors || []).join("\n")}</span>
</>
);
}