@inseefr/lunatic 0.3.2-experimental → 0.3.3-experimental
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/lib/index.js +36 -80
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/declarations/wrappers/input-declarations-wrapper.js +7 -6
- package/src/components/dropdown/commons/components/dropdown.js +21 -0
- package/src/components/dropdown/dropdown-edit/dropdown-edit.js +4 -1
- package/src/components/dropdown/dropdown-simple/dropdown.js +3 -1
- package/src/components/suggester/components/suggester-content.js +42 -42
- package/src/components/suggester/components/suggester.js +43 -3
- package/src/components/suggester/idb-suggester.js +7 -1
- package/src/components/suggester/lunatic-suggester.js +1 -0
- package/src/components/suggester/suggester-wrapper.js +6 -0
- package/src/stories/questionnaire/logement-queen.json +23390 -23390
- package/src/stories/questionnaire/logement-s2.json +46028 -44537
- package/src/stories/questionnaire/questionnaire.stories.js +2 -2
- package/src/stories/utils/orchestrator-split.js +4 -2
- package/src/stories/utils/orchestrator.js +4 -2
- package/src/tests/utils/to-expose/handler/results/res-input-edited.json +158 -158
- package/src/utils/lib/splitting.js +55 -23
- package/src/utils/to-expose/hooks/lunatic-split.js +39 -25
- package/src/utils/to-expose/hooks/lunatic.js +7 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inseefr/lunatic",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3-experimental",
|
|
4
4
|
"workersVersion": "0.2.1-experimental",
|
|
5
5
|
"description": "Library of questionnaire components",
|
|
6
6
|
"repository": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"library"
|
|
51
51
|
],
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@inseefr/trevas": "^0.1.
|
|
53
|
+
"@inseefr/trevas": "^0.1.12",
|
|
54
54
|
"date-fns": "^2.25.0",
|
|
55
55
|
"lodash.camelcase": "^4.3.0",
|
|
56
56
|
"lodash.debounce": "^4.0.8",
|
|
@@ -172,6 +172,7 @@ const InputDeclarationsWrapper = ({
|
|
|
172
172
|
aria-required={mandatory}
|
|
173
173
|
onChange={(e) => {
|
|
174
174
|
const v = e.target.value;
|
|
175
|
+
const valueToFire = v === '' ? null : v;
|
|
175
176
|
if (
|
|
176
177
|
(([null, ''].includes(v) && value.length > 0) ||
|
|
177
178
|
([null, ''].includes(value) && v.length > 0)) &&
|
|
@@ -179,7 +180,7 @@ const InputDeclarationsWrapper = ({
|
|
|
179
180
|
) {
|
|
180
181
|
setValue(v);
|
|
181
182
|
handleChange({
|
|
182
|
-
[U.getResponseName(response)]:
|
|
183
|
+
[U.getResponseName(response)]: valueToFire,
|
|
183
184
|
});
|
|
184
185
|
} else if (
|
|
185
186
|
// Chrome
|
|
@@ -187,11 +188,11 @@ const InputDeclarationsWrapper = ({
|
|
|
187
188
|
'Event' &&
|
|
188
189
|
roleType !== 'datepicker') ||
|
|
189
190
|
// FF hack: impossible to handle arrow events
|
|
190
|
-
(Math.abs(v - value)
|
|
191
|
+
(Math.abs(v - value) !== 0 && isInputNumber)
|
|
191
192
|
) {
|
|
192
|
-
setValue(
|
|
193
|
+
setValue(valueToFire);
|
|
193
194
|
handleChange({
|
|
194
|
-
[U.getResponseName(response)]:
|
|
195
|
+
[U.getResponseName(response)]: valueToFire,
|
|
195
196
|
});
|
|
196
197
|
} else {
|
|
197
198
|
if (isInputNumber) {
|
|
@@ -205,8 +206,8 @@ const InputDeclarationsWrapper = ({
|
|
|
205
206
|
return null;
|
|
206
207
|
} else validate(v);
|
|
207
208
|
}
|
|
208
|
-
if (management) setValue(
|
|
209
|
-
else setValue(
|
|
209
|
+
if (management) setValue(valueToFire);
|
|
210
|
+
else setValue(valueToFire);
|
|
210
211
|
}
|
|
211
212
|
}}
|
|
212
213
|
onBlur={handleChangeOnBlur}
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import classnames from 'classnames';
|
|
4
4
|
import Label from './label';
|
|
5
5
|
import * as U from '../../../../utils/lib';
|
|
6
|
+
import * as C from '../../../../constants';
|
|
6
7
|
import * as CLEAN from '../cleaner-callbacks';
|
|
7
8
|
import * as actions from '../actions';
|
|
8
9
|
import DropdownField from './dropdown-field';
|
|
@@ -65,9 +66,19 @@ function Dropdown({
|
|
|
65
66
|
state,
|
|
66
67
|
dispatch,
|
|
67
68
|
refs,
|
|
69
|
+
logFunction,
|
|
68
70
|
}) {
|
|
69
71
|
const { visible, focused, id, disabled } = state;
|
|
70
72
|
|
|
73
|
+
const createEventFocus = (focusIn = true) =>
|
|
74
|
+
U.createObjectEvent(
|
|
75
|
+
id,
|
|
76
|
+
C.INPUT_CATEGORY,
|
|
77
|
+
focusIn ? C.EVENT_FOCUS_IN : C.EVENT_FOCUS_OUT,
|
|
78
|
+
U.getResponseName(response),
|
|
79
|
+
valueFromProps
|
|
80
|
+
);
|
|
81
|
+
|
|
71
82
|
CLEAN.add(id, function () {
|
|
72
83
|
dispatch(actions.hidePanel());
|
|
73
84
|
dispatch(actions.setFocused(false));
|
|
@@ -130,6 +141,16 @@ function Dropdown({
|
|
|
130
141
|
[state, dispatch, onSelect]
|
|
131
142
|
);
|
|
132
143
|
|
|
144
|
+
// log info when focus change
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (id && focused && U.isFunction(logFunction))
|
|
147
|
+
logFunction(createEventFocus());
|
|
148
|
+
if (id && !focused && U.isFunction(logFunction))
|
|
149
|
+
logFunction(createEventFocus(false));
|
|
150
|
+
|
|
151
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
152
|
+
}, [focused, id]);
|
|
153
|
+
|
|
133
154
|
return (
|
|
134
155
|
<DropdownContainer
|
|
135
156
|
className={classnames(className, U.getLabelPositionClass(labelPosition), {
|
|
@@ -37,6 +37,7 @@ const createOnSelect = (_, dispatch, onSelect) => (option) => {
|
|
|
37
37
|
* @param {props}
|
|
38
38
|
*/
|
|
39
39
|
function Dropdown({
|
|
40
|
+
id: initId,
|
|
40
41
|
widthAuto,
|
|
41
42
|
options = [],
|
|
42
43
|
onSelect,
|
|
@@ -52,10 +53,11 @@ function Dropdown({
|
|
|
52
53
|
disabled,
|
|
53
54
|
focused: initFocused,
|
|
54
55
|
DeclarationAfterLabel,
|
|
56
|
+
logFunction,
|
|
55
57
|
}) {
|
|
56
58
|
const [state, dispatch] = useReducer(reducer, {
|
|
57
59
|
...initial,
|
|
58
|
-
id: `dropdown-${new Date().getMilliseconds()}`,
|
|
60
|
+
id: `dropdown-${initId || new Date().getMilliseconds()}`,
|
|
59
61
|
disabled,
|
|
60
62
|
focused: initFocused,
|
|
61
63
|
});
|
|
@@ -98,6 +100,7 @@ function Dropdown({
|
|
|
98
100
|
value={valueFromProps}
|
|
99
101
|
zIndex={zIndex}
|
|
100
102
|
management={management}
|
|
103
|
+
logFunction={logFunction}
|
|
101
104
|
>
|
|
102
105
|
<DeclarationAfterLabel />
|
|
103
106
|
<span
|
|
@@ -26,11 +26,12 @@ const Dropdown = ({
|
|
|
26
26
|
className,
|
|
27
27
|
zIndex,
|
|
28
28
|
DeclarationAfterLabel,
|
|
29
|
+
logFunction,
|
|
29
30
|
}) => {
|
|
30
31
|
const containerEl = useRef();
|
|
31
32
|
const [state, dispatch] = useReducer(reducer, {
|
|
32
33
|
...initial,
|
|
33
|
-
id: `dropdown-${initId
|
|
34
|
+
id: `dropdown-${initId || new Date().getMilliseconds()}`,
|
|
34
35
|
disabled,
|
|
35
36
|
focused: initFocused,
|
|
36
37
|
});
|
|
@@ -59,6 +60,7 @@ const Dropdown = ({
|
|
|
59
60
|
onSelect={onSelect_}
|
|
60
61
|
value={value}
|
|
61
62
|
zIndex={zIndex}
|
|
63
|
+
logFunction={logFunction}
|
|
62
64
|
>
|
|
63
65
|
<DeclarationAfterLabel />
|
|
64
66
|
<span className={classnames('lunatic-dropdown-input', { focused })}>
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import React, { useRef, useCallback } from 'react';
|
|
2
|
-
import classnames from 'classnames';
|
|
3
|
-
import useDocumentAddEventListener from '../../../utils/to-expose/hooks/use-document-add-event-listener';
|
|
4
|
-
|
|
5
|
-
function SuggesterContent({
|
|
6
|
-
children,
|
|
7
|
-
id,
|
|
8
|
-
focused,
|
|
9
|
-
onFocus,
|
|
10
|
-
onBlur,
|
|
11
|
-
onKeyDown,
|
|
12
|
-
}) {
|
|
13
|
-
const ref = useRef();
|
|
14
|
-
const onClick = useCallback(
|
|
15
|
-
function (e) {
|
|
16
|
-
const { current } = ref;
|
|
17
|
-
if (!current.contains(e.target)) {
|
|
18
|
-
onBlur();
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
[ref, onBlur]
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
useDocumentAddEventListener('mousedown', onClick);
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div
|
|
28
|
-
className={classnames('lunatic-suggester', {
|
|
29
|
-
focused,
|
|
30
|
-
})}
|
|
31
|
-
onFocus={onFocus}
|
|
32
|
-
onKeyDown={onKeyDown}
|
|
33
|
-
ref={ref}
|
|
34
|
-
>
|
|
35
|
-
<div className={classnames('lunatic-suggester-content', { focused })}>
|
|
36
|
-
{children}
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export default SuggesterContent;
|
|
1
|
+
import React, { useRef, useCallback } from 'react';
|
|
2
|
+
import classnames from 'classnames';
|
|
3
|
+
import useDocumentAddEventListener from '../../../utils/to-expose/hooks/use-document-add-event-listener';
|
|
4
|
+
|
|
5
|
+
function SuggesterContent({
|
|
6
|
+
children,
|
|
7
|
+
id,
|
|
8
|
+
focused,
|
|
9
|
+
onFocus,
|
|
10
|
+
onBlur,
|
|
11
|
+
onKeyDown,
|
|
12
|
+
}) {
|
|
13
|
+
const ref = useRef();
|
|
14
|
+
const onClick = useCallback(
|
|
15
|
+
function (e) {
|
|
16
|
+
const { current } = ref;
|
|
17
|
+
if (!current.contains(e.target) && focused) {
|
|
18
|
+
onBlur();
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
[ref, focused, onBlur]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
useDocumentAddEventListener('mousedown', onClick);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
className={classnames('lunatic-suggester', {
|
|
29
|
+
focused,
|
|
30
|
+
})}
|
|
31
|
+
onFocus={onFocus}
|
|
32
|
+
onKeyDown={onKeyDown}
|
|
33
|
+
ref={ref}
|
|
34
|
+
>
|
|
35
|
+
<div className={classnames('lunatic-suggester-content', { focused })}>
|
|
36
|
+
{children}
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default SuggesterContent;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useContext,
|
|
4
|
+
useRef,
|
|
5
|
+
useMemo,
|
|
6
|
+
useEffect,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
2
9
|
import classnames from 'classnames';
|
|
3
10
|
import { actions, SuggesterContext } from '../state-management';
|
|
4
11
|
import SuggesterContent from './suggester-content';
|
|
@@ -6,6 +13,8 @@ import Selection from './selection';
|
|
|
6
13
|
import Panel from './panel';
|
|
7
14
|
import createOnKeyDownCallback from './create-on-keydown-callback';
|
|
8
15
|
import Delete from './selection/delete';
|
|
16
|
+
import * as C from '../../../constants';
|
|
17
|
+
import * as U from '../../../utils/lib';
|
|
9
18
|
import './suggester.scss';
|
|
10
19
|
|
|
11
20
|
function Suggester({
|
|
@@ -16,23 +25,54 @@ function Suggester({
|
|
|
16
25
|
labelRenderer,
|
|
17
26
|
onSelect,
|
|
18
27
|
value,
|
|
28
|
+
focused: initFocused,
|
|
29
|
+
response,
|
|
30
|
+
logFunction,
|
|
19
31
|
}) {
|
|
20
32
|
const inputEl = useRef();
|
|
21
33
|
const [state, dispatch] = useContext(SuggesterContext);
|
|
22
34
|
const { focused, id, messageError, search, disabled } = state;
|
|
23
35
|
|
|
36
|
+
const [init, setInit] = useState(false);
|
|
37
|
+
|
|
38
|
+
const createEventFocus = (focusIn = true) =>
|
|
39
|
+
U.createObjectEvent(
|
|
40
|
+
`suggester-${id}`,
|
|
41
|
+
C.INPUT_CATEGORY,
|
|
42
|
+
focusIn ? C.EVENT_FOCUS_IN : C.EVENT_FOCUS_OUT,
|
|
43
|
+
U.getResponseName(response),
|
|
44
|
+
value
|
|
45
|
+
);
|
|
46
|
+
|
|
24
47
|
const onFocus = useCallback(
|
|
25
48
|
function () {
|
|
26
|
-
if (!disabled) {
|
|
49
|
+
if (!focused && !disabled) {
|
|
27
50
|
if (inputEl.current !== document.activeElement) {
|
|
28
51
|
}
|
|
29
52
|
inputEl.current.focus();
|
|
30
53
|
dispatch(actions.onFocus());
|
|
31
54
|
}
|
|
32
55
|
},
|
|
33
|
-
[dispatch,
|
|
56
|
+
[disabled, dispatch, focused]
|
|
34
57
|
);
|
|
35
58
|
|
|
59
|
+
// Handle focused props of Component
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (!init && id) {
|
|
62
|
+
if (initFocused && !focused) onFocus();
|
|
63
|
+
setInit(true);
|
|
64
|
+
}
|
|
65
|
+
}, [focused, init, initFocused, onFocus, id]);
|
|
66
|
+
|
|
67
|
+
// log info when focus change
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (init && id && focused && U.isFunction(logFunction))
|
|
70
|
+
logFunction(createEventFocus());
|
|
71
|
+
if (init && id && !focused && U.isFunction(logFunction))
|
|
72
|
+
logFunction(createEventFocus(false));
|
|
73
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
74
|
+
}, [focused, id, init]);
|
|
75
|
+
|
|
36
76
|
const onDelete = useCallback(
|
|
37
77
|
function () {
|
|
38
78
|
dispatch(actions.onDeleteSearch());
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import SuggesterWrapper from './suggester-wrapper';
|
|
4
4
|
import createSearching from './searching';
|
|
@@ -15,6 +15,9 @@ function IDBSuggester({
|
|
|
15
15
|
onSelect,
|
|
16
16
|
disabled,
|
|
17
17
|
value,
|
|
18
|
+
focused,
|
|
19
|
+
response,
|
|
20
|
+
logFunction,
|
|
18
21
|
}) {
|
|
19
22
|
const [store, setStore] = useState(undefined);
|
|
20
23
|
const searching = useMemo(
|
|
@@ -44,6 +47,9 @@ function IDBSuggester({
|
|
|
44
47
|
storeName={storeName}
|
|
45
48
|
disabled={disabled}
|
|
46
49
|
value={value}
|
|
50
|
+
focused={focused}
|
|
51
|
+
response={response}
|
|
52
|
+
logFunction={logFunction}
|
|
47
53
|
/>
|
|
48
54
|
</CheckStore>
|
|
49
55
|
);
|
|
@@ -30,6 +30,9 @@ function SuggesterWrapper({
|
|
|
30
30
|
labelRenderer,
|
|
31
31
|
disabled,
|
|
32
32
|
value,
|
|
33
|
+
focused,
|
|
34
|
+
response,
|
|
35
|
+
logFunction,
|
|
33
36
|
}) {
|
|
34
37
|
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
|
|
35
38
|
const { search, selectedIndex, options, expended } = state;
|
|
@@ -82,6 +85,9 @@ function SuggesterWrapper({
|
|
|
82
85
|
labelRenderer={labelRenderer}
|
|
83
86
|
onSelect={onSelect}
|
|
84
87
|
value={value}
|
|
88
|
+
focused={focused}
|
|
89
|
+
response={response}
|
|
90
|
+
logFunction={logFunction}
|
|
85
91
|
/>
|
|
86
92
|
</SuggesterContext.Provider>
|
|
87
93
|
);
|