@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/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
- trueRef: React.RefObject<any>;
21
- falseRef: React.RefObject<any>;
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
- onButtonGroupChange: (value: any) => void;
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.rmInputTabIndices = () => {
48
- [this.trueRef, this.falseRef, this.undefinedRef].forEach(node => {
49
- const domNode = (0, react_dom_1.findDOMNode)(node.current);
50
- if (!domNode) {
51
- return;
52
- }
53
- const input = domNode.getElementsByTagName("input")[0];
54
- if (!input) {
55
- return;
56
- }
57
- input.setAttribute("tabindex", -1);
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.onButtonGroupChange = (value) => {
67
- if (value === "undefined") {
68
- value = undefined;
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, id } = this.props;
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
- // "undefined" for silencing ToggleButton warning.
127
- const _value = value === undefined
128
- ? "undefined"
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 selectedValueGlyph = React.createElement("span", { className: "laji-form-checkbox-selected-value-glyph" });
142
- const unselectedValueGlyph = React.createElement("span", { className: "laji-form-checkbox-unselected-value-glyph" });
143
- const checkbox = (React.createElement(ButtonToolbar, { className: (0, utils_1.classNames)("laji-form-checkbox-buttons", toggleMode && "desktop-layout") },
144
- React.createElement(ToggleButtonGroup, Object.assign({ ref: this.groupRef, type: "radio", value: [_value], name: this.props.id, onChange: this.onButtonGroupChange, onKeyDown: this.onGroupKeyDown, className: (0, utils_1.classNames)(toggleMode && tabTargetClass) }, commonProps, { tabIndex: (toggleMode && !_disabled) ? 0 : undefined }),
145
- React.createElement(ToggleButton, Object.assign({ id: `${id}-true`, ref: this.trueRef, value: true, onClick: toggleMode ? this.toggle : undefined, className: (0, utils_1.classNames)(_value === true && tabTargetClass), onKeyDown: this.onTrueKeyDown }, commonProps),
146
- _value === true ? selectedValueGlyph : unselectedValueGlyph,
147
- trueLabel),
148
- React.createElement(ToggleButton, Object.assign({ id: `${id}-false`, ref: this.falseRef, value: false, onClick: toggleMode ? this.toggle : undefined, className: (0, utils_1.classNames)(_value === false && tabTargetClass), onKeyDown: this.onFalseKeyDown }, commonProps),
149
- _value === false ? selectedValueGlyph : unselectedValueGlyph,
150
- falseLabel),
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 SWITCH_CLASS = "laji-form-checkbox-widget-tab-target";
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
- `.${SWITCH_CLASS}`,
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
- ].map(type => `${type}:not([type="hidden"]):not(:disabled):not([readonly]):not([type="file"]):not(.leaflet-control-layers-selector):not(.laji-map-input)`);
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(SWITCH_CLASS)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luomus/laji-form",
3
- "version": "15.1.72",
3
+ "version": "15.1.74",
4
4
  "description": "React module capable of building dynamic forms from Laji form json schemas",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -228,14 +228,14 @@ class Form {
228
228
  });
229
229
  }
230
230
  getBooleanWidget(str) {
231
- const $container = this.$locate(str).locator(".btn-toolbar");
231
+ const $container = this.$locate(str).locator(".checkbox-container");
232
232
  return {
233
233
  $container,
234
- $true: $container.locator(".btn").nth(0), // eslint-disable-line protractor/use-first-last
235
- $false: $container.locator(".btn").nth(1),
236
- $undefined: this.$locate(str).locator(".btn").nth(2),
237
- $active: $container.locator(".btn.active"),
238
- $nonactive: $container.locator(".btn:not(.active)").first()
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) {