@luomus/laji-form 15.1.72 → 15.1.74
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/laji-form.js +1 -1
- package/dist/styles.css +25 -19
- package/lib/components/widgets/CheckboxWidget.d.ts +5 -15
- package/lib/components/widgets/CheckboxWidget.js +29 -97
- package/lib/themes/bs3.js +2 -1
- package/lib/utils.js +8 -6
- package/package.json +1 -1
- package/test-export/test-utils.js +6 -6
package/dist/styles.css
CHANGED
|
@@ -2899,25 +2899,6 @@ body .laji-form {
|
|
|
2899
2899
|
.laji-form .hidden {
|
|
2900
2900
|
display: none;
|
|
2901
2901
|
}
|
|
2902
|
-
.laji-form .checkbox-container {
|
|
2903
|
-
display: table;
|
|
2904
|
-
}
|
|
2905
|
-
|
|
2906
|
-
.laji-form-checkbox-selected-value-glyph, .laji-form-checkbox-unselected-value-glyph {
|
|
2907
|
-
pointer-events: none;
|
|
2908
|
-
}
|
|
2909
|
-
.laji-form-checkbox-selected-value-glyph:before, .laji-form-checkbox-unselected-value-glyph:before {
|
|
2910
|
-
content: "•";
|
|
2911
|
-
margin-right: 6px;
|
|
2912
|
-
height: 0;
|
|
2913
|
-
font-weight: 900;
|
|
2914
|
-
color: #9e9e9e;
|
|
2915
|
-
font-size: 18px;
|
|
2916
|
-
vertical-align: -2px;
|
|
2917
|
-
}
|
|
2918
|
-
.laji-form-checkbox-unselected-value-glyph:before {
|
|
2919
|
-
visibility: hidden;
|
|
2920
|
-
}
|
|
2921
2902
|
|
|
2922
2903
|
.laji-form.map-dialog .modal-content, .laji-form.map-dialog .modal-body {
|
|
2923
2904
|
width: auto;
|
|
@@ -3931,3 +3912,28 @@ body .laji-form {
|
|
|
3931
3912
|
margin-left: -20px !important;
|
|
3932
3913
|
}
|
|
3933
3914
|
|
|
3915
|
+
.laji-form .checkbox-container label {
|
|
3916
|
+
font-weight: initial;
|
|
3917
|
+
margin-right: 5px;
|
|
3918
|
+
}
|
|
3919
|
+
.laji-form input[type="radio"] {
|
|
3920
|
+
margin-right: 5px;
|
|
3921
|
+
margin-top: -2px;
|
|
3922
|
+
vertical-align: middle;
|
|
3923
|
+
accent-color: #7d7d7d;
|
|
3924
|
+
}
|
|
3925
|
+
.laji-form .has-error input[type="radio"] {
|
|
3926
|
+
accent-color: #a94442 !important;
|
|
3927
|
+
}
|
|
3928
|
+
|
|
3929
|
+
.laji-form .checkbox-container label input:focus {
|
|
3930
|
+
outline-offset: 0;
|
|
3931
|
+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 5px 2px rgb(0 142 255);
|
|
3932
|
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 5px 2px rgb(0 142 255);
|
|
3933
|
+
}
|
|
3934
|
+
.laji-form .checkbox-container label input:focus-within {
|
|
3935
|
+
outline-offset: 0;
|
|
3936
|
+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 5px 2px rgb(0 142 255);
|
|
3937
|
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 5px 2px rgb(0 142 255);
|
|
3938
|
+
}
|
|
3939
|
+
|
|
@@ -17,24 +17,14 @@ export default class CheckboxWidget extends React.Component<any, any, any> {
|
|
|
17
17
|
value: PropTypes.Requireable<boolean>;
|
|
18
18
|
};
|
|
19
19
|
constructor(props: any);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
undefinedRef: React.RefObject<any>;
|
|
23
|
-
groupRef: React.RefObject<any>;
|
|
24
|
-
componentDidMount(): void;
|
|
25
|
-
componentDidUpdate(): void;
|
|
26
|
-
rmInputTabIndices: () => void;
|
|
20
|
+
containerRef: React.RefObject<any>;
|
|
21
|
+
onKeyDown: (e: any) => void;
|
|
27
22
|
onChange: (value: any) => void;
|
|
28
|
-
|
|
23
|
+
onChangeTrue: () => void;
|
|
24
|
+
onChangeFalse: () => void;
|
|
25
|
+
onChangeUndefined: () => void;
|
|
29
26
|
getOptions: (props: any) => any;
|
|
30
27
|
render(): JSX.Element;
|
|
31
|
-
getToggleMode: (props: any) => boolean;
|
|
32
|
-
onGroupKeyDown: any;
|
|
33
|
-
onTrueKeyDown: any;
|
|
34
|
-
onFalseKeyDown: any;
|
|
35
|
-
onUndefinedKeyDown: any;
|
|
36
|
-
toggle: (e: any) => void;
|
|
37
|
-
formatValue(value: any, options: any, props: any): any;
|
|
38
28
|
}
|
|
39
29
|
import * as React from "react";
|
|
40
30
|
import * as PropTypes from "prop-types";
|
|
@@ -37,25 +37,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
const React = __importStar(require("react"));
|
|
40
|
-
const react_dom_1 = require("react-dom");
|
|
41
40
|
const PropTypes = __importStar(require("prop-types"));
|
|
42
41
|
const utils_1 = require("../../utils");
|
|
43
42
|
const ReactContext_1 = __importDefault(require("../../ReactContext"));
|
|
44
43
|
class CheckboxWidget extends React.Component {
|
|
45
44
|
constructor(props) {
|
|
46
45
|
super(props);
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
46
|
+
this.containerRef = React.createRef();
|
|
47
|
+
this.onKeyDown = (e) => {
|
|
48
|
+
if (!e.key.startsWith("Arrow")) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const inputs = this.containerRef.current.querySelectorAll("input");
|
|
52
|
+
if (["ArrowRight", "ArrowDown"].includes(e.key) && document.activeElement === inputs[inputs.length - 1]) {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
}
|
|
55
|
+
else if (["ArrowLeft", "ArrowUp"].includes(e.key) && document.activeElement === inputs[0]) {
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
}
|
|
59
58
|
};
|
|
60
59
|
this.onChange = (value) => {
|
|
61
60
|
if (value !== undefined && this.getOptions(this.props).invert) {
|
|
@@ -63,107 +62,40 @@ class CheckboxWidget extends React.Component {
|
|
|
63
62
|
}
|
|
64
63
|
this.props.onChange(value);
|
|
65
64
|
};
|
|
66
|
-
this.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
this.onChange(value);
|
|
71
|
-
};
|
|
65
|
+
this.onChangeTrue = () => this.onChange(true);
|
|
66
|
+
this.onChangeFalse = () => this.onChange(false);
|
|
67
|
+
this.onChangeUndefined = () => this.onChange(undefined);
|
|
72
68
|
this.getOptions = (props) => {
|
|
73
69
|
const { Yes, No, Unknown } = props.registry.formContext.translations;
|
|
74
70
|
return Object.assign({ allowUndefined: true, showUndefined: true, invert: false, trueLabel: Yes, falseLabel: No, unknownLabel: Unknown, required: this.props.required }, (0, utils_1.getUiOptions)(props));
|
|
75
71
|
};
|
|
76
|
-
this.getToggleMode = (props) => {
|
|
77
|
-
const { allowUndefined, showUndefined } = this.getOptions(props);
|
|
78
|
-
const displayUndefined = (allowUndefined && showUndefined);
|
|
79
|
-
return !displayUndefined;
|
|
80
|
-
};
|
|
81
|
-
this.onGroupKeyDown = this.props.formContext.utils.keyboardClick((e) => {
|
|
82
|
-
this.getToggleMode(this.props) && this.toggle(e);
|
|
83
|
-
});
|
|
84
|
-
this.onTrueKeyDown = this.props.formContext.utils.keyboardClick((e) => {
|
|
85
|
-
this.onChange(true);
|
|
86
|
-
e.preventDefault();
|
|
87
|
-
e.stopPropagation();
|
|
88
|
-
});
|
|
89
|
-
this.onFalseKeyDown = this.props.formContext.utils.keyboardClick((e) => {
|
|
90
|
-
this.onChange(false);
|
|
91
|
-
e.preventDefault();
|
|
92
|
-
e.stopPropagation();
|
|
93
|
-
});
|
|
94
|
-
this.onUndefinedKeyDown = this.props.formContext.utils.keyboardClick((e) => {
|
|
95
|
-
this.onChange(undefined);
|
|
96
|
-
e.preventDefault();
|
|
97
|
-
e.stopPropagation();
|
|
98
|
-
});
|
|
99
|
-
this.toggle = (e) => {
|
|
100
|
-
if (this.props.disabled || this.props.readonly) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const nodes = [this.trueRef, this.falseRef, this.groupRef].map(r => (0, react_dom_1.findDOMNode)(r.current));
|
|
104
|
-
if (!nodes.includes(e.target)) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
e.preventDefault();
|
|
108
|
-
this.props.onChange(!this.props.value);
|
|
109
|
-
};
|
|
110
|
-
this.trueRef = React.createRef();
|
|
111
|
-
this.falseRef = React.createRef();
|
|
112
|
-
this.undefinedRef = React.createRef();
|
|
113
|
-
this.groupRef = React.createRef();
|
|
114
|
-
}
|
|
115
|
-
componentDidMount() {
|
|
116
|
-
this.rmInputTabIndices();
|
|
117
|
-
}
|
|
118
|
-
componentDidUpdate() {
|
|
119
|
-
this.rmInputTabIndices();
|
|
120
72
|
}
|
|
121
73
|
render() {
|
|
122
|
-
const { value, disabled, readonly, label
|
|
74
|
+
const { value, disabled, readonly, label } = this.props;
|
|
123
75
|
const options = this.getOptions(this.props);
|
|
124
76
|
const { allowUndefined, showUndefined, invert, trueLabel, falseLabel, unknownLabel, required, label: uiOptionsLabel } = options;
|
|
125
77
|
const hasLabel = !(0, utils_1.isEmptyString)(label) && uiOptionsLabel !== false;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
: invert
|
|
130
|
-
? !value
|
|
131
|
-
: value;
|
|
132
|
-
const { ButtonToolbar, ToggleButton, ToggleButtonGroup } = this.context.theme;
|
|
78
|
+
const _value = invert
|
|
79
|
+
? !value
|
|
80
|
+
: value;
|
|
133
81
|
const displayUndefined = (allowUndefined && showUndefined);
|
|
134
|
-
const toggleMode = this.getToggleMode(this.props);
|
|
135
82
|
const _disabled = disabled || readonly;
|
|
136
|
-
const commonProps = {
|
|
137
|
-
disabled: _disabled,
|
|
138
|
-
tabIndex: (toggleMode || _disabled) ? undefined : 0
|
|
139
|
-
};
|
|
140
83
|
const tabTargetClass = "laji-form-checkbox-widget-tab-target";
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
(displayUndefined ?
|
|
152
|
-
React.createElement(ToggleButton, Object.assign({ id: `${id}-undefined`, ref: this.undefinedRef, value: "undefined", className: (0, utils_1.classNames)(value === undefined && tabTargetClass) }, commonProps, { onKeyDown: this.onUndefinedKeyDown }),
|
|
153
|
-
_value === "undefined" ? selectedValueGlyph : unselectedValueGlyph,
|
|
154
|
-
unknownLabel) : null))));
|
|
84
|
+
const checkbox = (React.createElement("div", { ref: this.containerRef, className: "checkbox-container" },
|
|
85
|
+
React.createElement("label", null,
|
|
86
|
+
React.createElement("input", { type: "radio", value: "true", checked: _value === true, onChange: this.onChangeTrue, className: tabTargetClass, onKeyDown: this.onKeyDown, disabled: _disabled }),
|
|
87
|
+
trueLabel),
|
|
88
|
+
React.createElement("label", null,
|
|
89
|
+
React.createElement("input", { type: "radio", value: "false", checked: _value === false, onChange: this.onChangeFalse, onKeyDown: this.onKeyDown, disabled: _disabled }),
|
|
90
|
+
falseLabel),
|
|
91
|
+
displayUndefined && (React.createElement("label", null,
|
|
92
|
+
React.createElement("input", { type: "radio", value: "undefined", checked: _value === undefined, onChange: this.onChangeUndefined, onKeyDown: this.onKeyDown, disabled: _disabled }),
|
|
93
|
+
unknownLabel))));
|
|
155
94
|
const { Label } = this.props.formContext;
|
|
156
95
|
return !hasLabel ? checkbox : React.createElement(React.Fragment, null,
|
|
157
96
|
React.createElement(Label, { label: label, required: required, uiSchema: this.props.uiSchema, registry: this.props.registry, id: this.props.id }),
|
|
158
97
|
checkbox);
|
|
159
98
|
}
|
|
160
|
-
formatValue(value, options, props) {
|
|
161
|
-
return value === undefined
|
|
162
|
-
? ""
|
|
163
|
-
: value === true
|
|
164
|
-
? props.formContext.translations.Yes
|
|
165
|
-
: props.formContext.translations.No;
|
|
166
|
-
}
|
|
167
99
|
}
|
|
168
100
|
CheckboxWidget.contextType = ReactContext_1.default;
|
|
169
101
|
CheckboxWidget.propTypes = {
|
package/lib/themes/bs3.js
CHANGED
|
@@ -164,6 +164,7 @@ const theme = {
|
|
|
164
164
|
ControlLabel: ControlLabel_1.default,
|
|
165
165
|
Checkbox: Checkbox_1.default,
|
|
166
166
|
ToggleButton: ToggleButton_1.default,
|
|
167
|
-
ToggleButtonGroup: ToggleButtonGroup_1.default
|
|
167
|
+
ToggleButtonGroup: ToggleButtonGroup_1.default,
|
|
168
|
+
// Radio
|
|
168
169
|
};
|
|
169
170
|
exports.default = theme;
|
package/lib/utils.js
CHANGED
|
@@ -292,16 +292,18 @@ function isMultiSelect(schema, uiSchema) {
|
|
|
292
292
|
function isSelect(schema) {
|
|
293
293
|
return (0, utils_1.isSelect)(validator_ajv6_1.default, schema);
|
|
294
294
|
}
|
|
295
|
-
const
|
|
295
|
+
const CHECKBOX_CLASS = "laji-form-checkbox-widget-tab-target";
|
|
296
296
|
const IMG_ADD_CLASS = "laji-form-drop-zone";
|
|
297
297
|
const tabbableSelectors = [
|
|
298
298
|
"input",
|
|
299
299
|
"select",
|
|
300
|
-
"textarea"
|
|
301
|
-
|
|
300
|
+
"textarea"
|
|
301
|
+
].map(type => `${type}:not([type="hidden"]):not(:disabled):not([readonly]):not([type="file"]):not(.leaflet-control-layers-selector):not(.laji-map-input):not([type="radio"])`);
|
|
302
|
+
const tabbableSelectorsQuery = [
|
|
303
|
+
...tabbableSelectors,
|
|
304
|
+
`.${CHECKBOX_CLASS}`,
|
|
302
305
|
`.${IMG_ADD_CLASS}`
|
|
303
|
-
].
|
|
304
|
-
const tabbableSelectorsQuery = tabbableSelectors.join(", ");
|
|
306
|
+
].join(", ");
|
|
305
307
|
function getTabbableFields(elem, reverse) {
|
|
306
308
|
const fieldsNodeList = elem.querySelectorAll(tabbableSelectorsQuery);
|
|
307
309
|
let fields = Array.from(fieldsNodeList).filter(node => node.tabIndex !== -1);
|
|
@@ -312,7 +314,7 @@ function getTabbableFields(elem, reverse) {
|
|
|
312
314
|
function isTabbableInput(elem) {
|
|
313
315
|
return elem.id.match(/^_laji-form_/)
|
|
314
316
|
|| ["input", "select", "textarea"].includes(elem.tagName.toLowerCase())
|
|
315
|
-
|| elem.className.includes(
|
|
317
|
+
|| elem.className.includes(CHECKBOX_CLASS)
|
|
316
318
|
|| elem.className.includes(IMG_ADD_CLASS);
|
|
317
319
|
}
|
|
318
320
|
function canFocusNextInput(root, inputElem) {
|
package/package.json
CHANGED
|
@@ -228,14 +228,14 @@ class Form {
|
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
getBooleanWidget(str) {
|
|
231
|
-
const $container = this.$locate(str).locator(".
|
|
231
|
+
const $container = this.$locate(str).locator(".checkbox-container");
|
|
232
232
|
return {
|
|
233
233
|
$container,
|
|
234
|
-
$true: $container.locator("
|
|
235
|
-
$false: $container.locator("
|
|
236
|
-
$undefined: this.$locate(str).locator("
|
|
237
|
-
$active: $container.locator("
|
|
238
|
-
$nonactive: $container.locator("
|
|
234
|
+
$true: $container.locator("input").nth(0), // eslint-disable-line protractor/use-first-last
|
|
235
|
+
$false: $container.locator("input").nth(1),
|
|
236
|
+
$undefined: this.$locate(str).locator("input").nth(2),
|
|
237
|
+
$active: $container.locator("input[checked]"),
|
|
238
|
+
$nonactive: $container.locator("input:not([checked])").first()
|
|
239
239
|
};
|
|
240
240
|
}
|
|
241
241
|
$getInputWidget(str) {
|