@inseefr/lunatic 3.4.10-rc.0 → 3.4.10

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.
Files changed (85) hide show
  1. package/README.md +6 -4
  2. package/components/LunaticComponents.d.ts +10 -1
  3. package/components/LunaticComponents.js +3 -1
  4. package/components/LunaticComponents.js.map +1 -1
  5. package/components/shared/HOC/slottableComponent.d.ts +3 -3
  6. package/components/shared/HOC/slottableComponent.js +2 -2
  7. package/components/shared/Radio/RadioOption.js +5 -1
  8. package/components/shared/Radio/RadioOption.js.map +1 -1
  9. package/components/shared/Radio/RadioOption.spec.js +21 -0
  10. package/components/shared/Radio/RadioOption.spec.js.map +1 -1
  11. package/esm/components/LunaticComponents.d.ts +10 -1
  12. package/esm/components/LunaticComponents.js +3 -1
  13. package/esm/components/LunaticComponents.js.map +1 -1
  14. package/esm/components/shared/HOC/slottableComponent.d.ts +3 -3
  15. package/esm/components/shared/HOC/slottableComponent.js +2 -2
  16. package/esm/components/shared/Radio/RadioOption.js +5 -1
  17. package/esm/components/shared/Radio/RadioOption.js.map +1 -1
  18. package/esm/components/shared/Radio/RadioOption.spec.js +21 -0
  19. package/esm/components/shared/Radio/RadioOption.spec.js.map +1 -1
  20. package/esm/use-lunatic/commons/compile-controls.d.ts +1 -1
  21. package/esm/use-lunatic/commons/compile-controls.js +4 -3
  22. package/esm/use-lunatic/commons/compile-controls.js.map +1 -1
  23. package/esm/use-lunatic/commons/variables/lunatic-variables-store.d.ts +16 -0
  24. package/esm/use-lunatic/commons/variables/lunatic-variables-store.js +6 -6
  25. package/esm/use-lunatic/commons/variables/lunatic-variables-store.js.map +1 -1
  26. package/esm/use-lunatic/hooks/use-loop-variables.d.ts +1 -1
  27. package/esm/use-lunatic/hooks/use-loop-variables.js +1 -1
  28. package/esm/use-lunatic/hooks/use-page-has-response.d.ts +1 -1
  29. package/esm/use-lunatic/hooks/use-page-has-response.js +6 -6
  30. package/esm/use-lunatic/hooks/useOverview.d.ts +1 -1
  31. package/esm/use-lunatic/hooks/useOverview.js +4 -4
  32. package/esm/use-lunatic/hooks/useWarnDepChange.d.ts +3 -2
  33. package/esm/use-lunatic/hooks/useWarnDepChange.js +3 -2
  34. package/esm/use-lunatic/hooks/useWarnDepChange.js.map +1 -1
  35. package/esm/use-lunatic/lunatic-context.d.ts +5 -2
  36. package/esm/use-lunatic/lunatic-context.js +5 -2
  37. package/esm/use-lunatic/lunatic-context.js.map +1 -1
  38. package/esm/use-lunatic/props/propOptions.d.ts +2 -0
  39. package/esm/use-lunatic/props/propOptions.js +4 -0
  40. package/esm/use-lunatic/props/propOptions.js.map +1 -1
  41. package/esm/use-lunatic/type.d.ts +152 -2
  42. package/esm/use-lunatic/use-lunatic.d.ts +13 -36
  43. package/esm/use-lunatic/use-lunatic.js +13 -2
  44. package/esm/use-lunatic/use-lunatic.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/components/LunaticComponents.tsx +10 -8
  47. package/src/components/shared/HOC/slottableComponent.tsx +3 -3
  48. package/src/components/shared/Radio/RadioOption.spec.tsx +55 -0
  49. package/src/components/shared/Radio/RadioOption.tsx +5 -0
  50. package/src/use-lunatic/commons/compile-controls.ts +4 -3
  51. package/src/use-lunatic/commons/variables/lunatic-variables-store.ts +18 -18
  52. package/src/use-lunatic/hooks/use-loop-variables.ts +1 -1
  53. package/src/use-lunatic/hooks/use-page-has-response.ts +6 -6
  54. package/src/use-lunatic/hooks/useOverview.ts +4 -4
  55. package/src/use-lunatic/hooks/useWarnDepChange.ts +3 -2
  56. package/src/use-lunatic/lunatic-context.tsx +5 -2
  57. package/src/use-lunatic/props/propOptions.ts +5 -0
  58. package/src/use-lunatic/type.ts +153 -17
  59. package/src/use-lunatic/use-lunatic.ts +11 -2
  60. package/tsconfig.build.tsbuildinfo +1 -1
  61. package/use-lunatic/commons/compile-controls.d.ts +1 -1
  62. package/use-lunatic/commons/compile-controls.js +4 -3
  63. package/use-lunatic/commons/compile-controls.js.map +1 -1
  64. package/use-lunatic/commons/variables/lunatic-variables-store.d.ts +16 -0
  65. package/use-lunatic/commons/variables/lunatic-variables-store.js +13 -13
  66. package/use-lunatic/commons/variables/lunatic-variables-store.js.map +1 -1
  67. package/use-lunatic/hooks/use-loop-variables.d.ts +1 -1
  68. package/use-lunatic/hooks/use-loop-variables.js +1 -1
  69. package/use-lunatic/hooks/use-page-has-response.d.ts +1 -1
  70. package/use-lunatic/hooks/use-page-has-response.js +6 -6
  71. package/use-lunatic/hooks/useOverview.d.ts +1 -1
  72. package/use-lunatic/hooks/useOverview.js +4 -4
  73. package/use-lunatic/hooks/useWarnDepChange.d.ts +3 -2
  74. package/use-lunatic/hooks/useWarnDepChange.js +3 -2
  75. package/use-lunatic/hooks/useWarnDepChange.js.map +1 -1
  76. package/use-lunatic/lunatic-context.d.ts +5 -2
  77. package/use-lunatic/lunatic-context.js +5 -2
  78. package/use-lunatic/lunatic-context.js.map +1 -1
  79. package/use-lunatic/props/propOptions.d.ts +2 -0
  80. package/use-lunatic/props/propOptions.js +4 -0
  81. package/use-lunatic/props/propOptions.js.map +1 -1
  82. package/use-lunatic/type.d.ts +152 -2
  83. package/use-lunatic/use-lunatic.d.ts +13 -36
  84. package/use-lunatic/use-lunatic.js +13 -2
  85. package/use-lunatic/use-lunatic.js.map +1 -1
@@ -45,7 +45,7 @@ import type { MarkdownLink } from '../MDLabel/MarkdownLink';
45
45
  import type { Accordion } from '../../Accordion/Accordion';
46
46
 
47
47
  /**
48
- * Contains the type of every customizable component
48
+ * Contain the type of every customizable components.
49
49
  */
50
50
  export type LunaticSlotComponents = {
51
51
  // Components
@@ -130,9 +130,9 @@ export const SlotsProvider = ({
130
130
  };
131
131
 
132
132
  /**
133
- * Create a replaceable version of a component
133
+ * Create a replaceable version of a component.
134
134
  *
135
- * The component can be replaced using the "slots" props on <LunaticComponents>
135
+ * The component can be replaced through the `slots` props on `LunaticComponents`.
136
136
  */
137
137
  export function slottableComponent<T>(
138
138
  name: keyof LunaticSlotComponents,
@@ -25,6 +25,61 @@ describe('RadioOption', () => {
25
25
  expect(onClickMock).toHaveBeenCalled();
26
26
  });
27
27
 
28
+ it('does not allow to uncheck modality if checkboxStyle is not defined', () => {
29
+ const onClickMock = vi.fn();
30
+ render(
31
+ <RadioOption
32
+ id="radio-option"
33
+ label="Test Option"
34
+ onCheck={onClickMock}
35
+ onUncheck={onClickMock}
36
+ checked
37
+ />
38
+ );
39
+
40
+ const option = screen.getByRole('radio');
41
+ fireEvent.click(option);
42
+ expect(onClickMock).not.toHaveBeenCalled();
43
+ });
44
+
45
+ it('does not allow to uncheck modality if checkboxStyle is false', () => {
46
+ const onClickMock = vi.fn();
47
+
48
+ render(
49
+ <RadioOption
50
+ id="radio-option"
51
+ label="Test Option"
52
+ onCheck={onClickMock}
53
+ onUncheck={onClickMock}
54
+ checkboxStyle={false}
55
+ checked
56
+ />
57
+ );
58
+
59
+ const option = screen.getByRole('radio');
60
+ fireEvent.click(option);
61
+ expect(onClickMock).not.toHaveBeenCalled();
62
+ });
63
+
64
+ it('allows to uncheck modality if checkboxStyle = true and onUncheck', () => {
65
+ const onClickMock = vi.fn();
66
+
67
+ render(
68
+ <RadioOption
69
+ id="radio-option"
70
+ label="Test Option"
71
+ onCheck={onClickMock}
72
+ onUncheck={onClickMock}
73
+ checkboxStyle={true}
74
+ checked
75
+ />
76
+ );
77
+
78
+ const option = screen.getByRole('radio');
79
+ fireEvent.click(option);
80
+ expect(onClickMock).toHaveBeenCalled();
81
+ });
82
+
28
83
  it('sets the tabIndex to 0 when unchecked', () => {
29
84
  const { getByRole } = render(
30
85
  <RadioOption id="radio-option" label="Test Option" checked={false} />
@@ -40,6 +40,7 @@ function LunaticRadioOption({
40
40
  detailLabel,
41
41
  detailValue,
42
42
  onCheck,
43
+ onUncheck,
43
44
  }: Props) {
44
45
  const divEl = useRef<HTMLDivElement>(null);
45
46
  const isEnabled = !disabled && !readOnly;
@@ -48,6 +49,10 @@ function LunaticRadioOption({
48
49
 
49
50
  const onClickOption = () => {
50
51
  if (!isEnabled || !onCheck || checked) {
52
+ // for checkboxStyle=true (only used by CheckboxOne) , we allow uncheck
53
+ if (checkboxStyle && onUncheck) {
54
+ onUncheck();
55
+ }
51
56
  return;
52
57
  }
53
58
  onCheck();
@@ -35,7 +35,8 @@ const isLoopComponent = (
35
35
  };
36
36
 
37
37
  /**
38
- * Check if components of the current page have errors, and return a map of error (indexed by component ID)
38
+ * Check if components of the current page have errors, and return a map of
39
+ * errors (indexed by component ID).
39
40
  */
40
41
  function checkComponents(
41
42
  state: StateForControls,
@@ -93,7 +94,7 @@ function checkControls(
93
94
  }
94
95
 
95
96
  /**
96
- * Figure out the number of iterations of a component
97
+ * Figure out the number of iterations of a component.
97
98
  */
98
99
  function computeIterations(
99
100
  component: InterpretedComponent | ComponentDefinition,
@@ -210,7 +211,7 @@ function hasCriticalError(errors?: Record<string, LunaticError[]>): boolean {
210
211
  }
211
212
 
212
213
  /**
213
- * Check controls for currently visible components and output errors
214
+ * Check controls for currently visible components and output errors.
214
215
  */
215
216
  export function compileControls(state: StateForControls) {
216
217
  const components = replaceComponentSequence(getComponentsFromState(state));
@@ -19,23 +19,23 @@ import {
19
19
  VTLMissingDependency,
20
20
  } from './errors';
21
21
 
22
- // Interpret counter, used for testing purpose
22
+ /** Interpret counter. Used for testing purpose. */
23
23
  let interpretCount = 0;
24
- // Special variable that will take the current iteration value
24
+ /** Special variable that will take the current iteration value. */
25
25
  const iterationVariableName = 'GLOBAL_ITERATION_INDEX';
26
26
 
27
27
  type IterationLevel = number[];
28
28
  export type EventArgs = {
29
29
  change: {
30
- // Name of the changed variable
30
+ /** Name of the changed variable. */
31
31
  name: string;
32
- // New value for the variable
32
+ /** New value for the variable. */
33
33
  value: unknown;
34
- // Iteration changed (for array)
34
+ /** Iteration changed (for array). */
35
35
  iteration?: IterationLevel | undefined;
36
- // What triggered this change
36
+ /** What triggered this change. */
37
37
  cause?: 'resizing' | 'cleaning';
38
- // Extra sent when setting the variable
38
+ /** Extra sent when setting the variable. */
39
39
  [extra: string]: unknown;
40
40
  };
41
41
  };
@@ -220,7 +220,7 @@ export class LunaticVariablesStore {
220
220
  this.eventTarget.removeEventListener(eventName, cb as EventListener);
221
221
  }
222
222
 
223
- // Retrieve the number of interpret() run (used in testing only)
223
+ /** Retrieve the number of interpret() run (used in testing only). */
224
224
  get interpretCount() {
225
225
  return interpretCount;
226
226
  }
@@ -249,25 +249,25 @@ export class LunaticVariablesStore {
249
249
  }
250
250
 
251
251
  class LunaticVariable {
252
- // Last time the value was updated (changed)
252
+ /** Last time the value was updated (changed). */
253
253
  public updatedAt = new Map<undefined | string, number>();
254
- // Last time "calculation" was run (for calculated variable)
254
+ /** Last time "calculation" was run (for calculated variable). */
255
255
  private calculatedAt = new Map<undefined | string, number>();
256
- // Internal value for the variable
256
+ /** Internal value for the variable. */
257
257
  private value: unknown;
258
- // List of dependencies, ex: ['FIRSTNAME', 'LASTNAME']
258
+ /** List of dependencies, ex: ['FIRSTNAME', 'LASTNAME']. */
259
259
  private dependencies?: string[];
260
- // Expression for calculated variable
260
+ /** Expression for calculated variable. */
261
261
  public readonly expression?: string;
262
- // Dictionary holding all the available variables
262
+ /** Dictionary holding all the available variables. */
263
263
  private readonly dictionary?: Map<string, LunaticVariable>;
264
- // Specific iteration depth to get value from dependencies (used for yAxis for instance)
264
+ /** Specific iteration depth to get value from dependencies (used for yAxis for instance). */
265
265
  private readonly iterationDepth?: number;
266
- // For calculated variable, shape is copied from another variable
266
+ /** For calculated variable, shape is copied from another variable. */
267
267
  private readonly shapeFrom?: string[];
268
- // Keep a record of variable name (optional, used for debug)
268
+ /** Keep a record of variable name (optional, used for debug). */
269
269
  public readonly name?: string;
270
- // Count the number of calculation
270
+ /** Count the number of calculation. */
271
271
  public calculatedCount = 0;
272
272
 
273
273
  constructor(
@@ -2,7 +2,7 @@ import type { LunaticComponentDefinition, LunaticReducerState } from '../type';
2
2
  import { useMemo } from 'react';
3
3
 
4
4
  /**
5
- * Extract the list of variables used for the current loop
5
+ * Extract the list of variables used for the current loop.
6
6
  */
7
7
  export function useLoopVariables(
8
8
  pager: LunaticReducerState['pager'],
@@ -4,7 +4,7 @@ import type { LunaticComponentDefinition, LunaticReducerState } from '../type';
4
4
  import type { LunaticComponentProps } from '../../components/type';
5
5
 
6
6
  /**
7
- * Check if a page has one response (value is filled for at least one field)
7
+ * Check if a page has one response (value is filled for at least one field).
8
8
  */
9
9
  export function usePageHasResponse(
10
10
  components: LunaticComponentProps[],
@@ -67,10 +67,10 @@ export function usePageHasResponse(
67
67
  }
68
68
 
69
69
  /**
70
- * Check if a value is empty
71
- * - null ou undefined ou ''
72
- * - for arrays, every item must be empty
73
- * - for objects, every value must be empty
70
+ * Check if a value is empty.
71
+ * - `null`, `undefined` or `''`.
72
+ * - for arrays, every item must be empty.
73
+ * - for objects, every value must be empty.
74
74
  */
75
75
  function isEmpty(value: unknown): boolean {
76
76
  // Array is empty if all items are empty
@@ -86,7 +86,7 @@ function isEmpty(value: unknown): boolean {
86
86
  }
87
87
 
88
88
  /**
89
- * For complex component we need to inspect child components, interpret the response value
89
+ * For complex component we need to inspect child components, interpret the response value.
90
90
  */
91
91
  function isSubComponentsEmpty(
92
92
  components: (LunaticComponentProps | LunaticComponentDefinition)[],
@@ -18,7 +18,7 @@ export type InterpretedLunaticOverviewItem = {
18
18
  };
19
19
 
20
20
  /**
21
- * Hook to build a filled overview everytime the deps change
21
+ * Build a filled overview everytime the deps change.
22
22
  */
23
23
  export const useOverview = (
24
24
  {
@@ -36,7 +36,7 @@ export const useOverview = (
36
36
  };
37
37
 
38
38
  /**
39
- * Use lunatic data to interpret the static overview (calculated on init) with the real data
39
+ * Use Lunatic data to interpret the static overview (calculated on init) with the real data.
40
40
  */
41
41
  const interpretOverview = (
42
42
  overviewItems: LunaticOverviewItem[],
@@ -71,7 +71,7 @@ const interpretOverview = (
71
71
  };
72
72
 
73
73
  /**
74
- * Interpret expression inside an item (label & condition)
74
+ * Interpret expression inside an item (label & condition).
75
75
  */
76
76
  const interpretOverviewItem = (
77
77
  items: InterpretedLunaticOverviewItem[],
@@ -127,7 +127,7 @@ const interpretOverviewItem = (
127
127
  };
128
128
 
129
129
  /**
130
- * Set the current property in the correct overview item
130
+ * Set the current property in the correct overview item.
131
131
  */
132
132
  const applyCurrentPage = (
133
133
  items: InterpretedLunaticOverviewItem[],
@@ -3,8 +3,9 @@ import type { LunaticLogger } from '../logger/type';
3
3
  import { useRefSync } from '../../hooks/useRefSync';
4
4
 
5
5
  /**
6
- * Log a warning when the variable change
7
- * ensure that we received a memoized value and help debug
6
+ * Log a warning when the variable change.
7
+ *
8
+ * Ensure that we received a memoized value and help debug.
8
9
  */
9
10
  export function useWarnDepChange(
10
11
  variable: unknown,
@@ -17,8 +17,11 @@ const LunaticContext = createContext({
17
17
  refusedButton: D.RF,
18
18
  componentsOptions: { detailAlwaysDisplayed: false },
19
19
  });
20
- /** Provide `missing` `missingStrategy`, `shortcut` and `missingShortcut`, `dontKnowButton`, `refusedButton` to Missing component
21
- * to manage non-response buttons and shortcut */
20
+ /**
21
+ * Provide `missing`, `missingStrategy`, `shortcut` and `missingShortcut`,
22
+ * `dontKnowButton`, `refusedButton` to `Missing` component to manage
23
+ * non-response buttons and shortcut.
24
+ */
22
25
  export const useLunaticMissing = () => {
23
26
  const {
24
27
  missing,
@@ -18,6 +18,7 @@ export type InterpretedOption = {
18
18
  detailValue?: string | null;
19
19
  onDetailChange?: (value: string) => void;
20
20
  onCheck?: () => void;
21
+ onUncheck?: () => void;
21
22
  };
22
23
 
23
24
  /**
@@ -86,6 +87,10 @@ export function getOptionsProp(
86
87
  { name: definition.response.name, value: option.value },
87
88
  ]);
88
89
  },
90
+ // for CheckboxOne, we allow uncheck
91
+ onUncheck: () => {
92
+ handleChanges([{ name: definition.response.name, value: null }]);
93
+ },
89
94
  detailValue:
90
95
  'detail' in option && option.detail
91
96
  ? variables.get(option.detail.response.name, iteration)
@@ -35,6 +35,7 @@ export type LunaticOverviewItem = {
35
35
 
36
36
  export type LunaticSuggester = SuggesterDefinition;
37
37
 
38
+ /** Survey data. */
38
39
  export type LunaticData = Partial<
39
40
  Record<Exclude<VariableType, 'COLLECTED'>, Record<string, unknown>> & {
40
41
  COLLECTED: Record<string, LunaticCollectedValue>;
@@ -45,6 +46,10 @@ export type LunaticValues = {
45
46
  [variableName: string]: unknown;
46
47
  };
47
48
 
49
+ /**
50
+ * Errors returned by `useLunatic` hook when an input check is made with their
51
+ * id, criticity, type and the message to display to the user.
52
+ */
48
53
  export type LunaticError = Pick<
49
54
  ControlDefinition,
50
55
  'id' | 'criticality' | 'typeOfControl'
@@ -55,8 +60,17 @@ export type LunaticError = Pick<
55
60
  export type VariableType = 'COLLECTED' | 'EXTERNAL' | 'CALCULATED';
56
61
  export type LunaticExpression = VTLExpression | VTLScalarExpression;
57
62
 
63
+ /**
64
+ * Page numerotation.
65
+ *
66
+ * String representing a location in the survey. It has one of the following
67
+ * format:
68
+ * - [page].[sous-page]#[iteration], when we are in a loop or a roundabount
69
+ * - [page]
70
+ */
58
71
  export type PageTag = `${number}.${number}#${number}` | `${number}`;
59
72
 
73
+ /** Variables provided to Lunatic through the source and used internally in a store. */
60
74
  export type LunaticVariable = Variable;
61
75
  export type LunaticCollectedValue = Partial<{
62
76
  COLLECTED: unknown;
@@ -76,16 +90,52 @@ export type LunaticStateVariable = {
76
90
  };
77
91
  }[LunaticVariable['variableType']];
78
92
 
93
+ /**
94
+ * Contains informations about navigation (last page reached, number of pages, subpages, etc.).
95
+ *
96
+ * This is the object used internally to determine where we are in the navigation.
97
+ *
98
+ * When we are in a loop, the pager will have additional properties.
99
+ */
79
100
  export type LunaticPager = {
101
+ /** Last page reached. */
80
102
  lastReachedPage?: PageTag;
103
+ /** Last page of the survey. */
81
104
  maxPage: number;
82
- nbSubPages?: number;
105
+ /** Current page. */
83
106
  page: number;
107
+
108
+ /**
109
+ * Current subpage.
110
+ *
111
+ * Only in a loop.
112
+ */
84
113
  subPage?: number;
85
- // Iteration index (starting at 0)
114
+ /**
115
+ * Number of pages in a loop.
116
+ *
117
+ * Only in a loop.
118
+ */
119
+ nbSubPages?: number;
120
+ /**
121
+ * Iteration index (starts at 0).
122
+ *
123
+ * Only in a loop.
124
+ */
86
125
  iteration?: number;
126
+ /**
127
+ * Number of iterations (i.e. number of people).
128
+ *
129
+ * Only in a loop.
130
+ */
87
131
  nbIterations?: number;
132
+ /**
133
+ * Only in a loop.
134
+ */
88
135
  shallowIteration?: number;
136
+ /**
137
+ * Only in a loop.
138
+ */
89
139
  linksIterations?: number[];
90
140
  };
91
141
 
@@ -107,25 +157,25 @@ export type LunaticReducerState = {
107
157
  components: LunaticSource['components'];
108
158
  isLoop: true;
109
159
  iterations: VTLScalarExpression;
110
- // Variables affecting this loop
160
+ /** Variables affecting this loop. */
111
161
  loopDependencies: string[];
112
- // List of child pages (ex: ['20.1', '20.2']
162
+ /** List of child pages (ex: ['20.1', '20.2'] */
113
163
  subPages: string[];
114
164
  };
115
165
  };
116
- // Run and expression using the value from the state
166
+ /** Run an expression using the value from the state. */
117
167
  executeExpression: <T = unknown>(
118
168
  expression: VTLExpression,
119
169
  args?: {
120
170
  iteration?: number | number[];
121
- // @deprecated
171
+ /** @deprecated */
122
172
  bindingDependencies?: string[];
123
173
  deps?: string[];
124
174
  }
125
175
  ) => T;
126
176
  isInLoop: boolean;
127
177
  updatedAt: number;
128
- // Update the value collected for the variable
178
+ /** Update the value collected for the variable. */
129
179
  updateBindings: (
130
180
  variableName: string,
131
181
  value: unknown,
@@ -136,78 +186,164 @@ export type LunaticReducerState = {
136
186
  };
137
187
  };
138
188
 
189
+ /** Specific behaviour options defined in the {@link useLunatic} hook. */
139
190
  export type LunaticOptions = {
191
+ /** Ignore filters. (default: `false`) */
140
192
  disableFilters?: boolean;
193
+ /** Enable VTL and Markdown support. */
141
194
  features?: ('MD' | 'VTL')[];
142
195
  preferences?: ['COLLECTED'];
196
+ /** Key in which the data is saved. (default: `"COLLECTED"`) */
143
197
  savingType?: 'COLLECTED';
198
+ /** Function called when a variable is changed by a user input (must be memoized as it is used in dependency of a `useCallback` by the library). */
144
199
  onChange?: LunaticChangesHandler;
145
200
  onVariableChange?: (event: LunaticVariablesStoreEvents['change']) => void;
201
+ /**
202
+ * Not yet implemented.
203
+ *
204
+ * Enable management mode which allow to handle multiple states of the same variable (used by recovery positions).
205
+ *
206
+ * The administrator can switch between `COLLECTED`, `EDITED`, `INPUTTED` modes. (default: `false`)
207
+ */
146
208
  management?: boolean;
147
- // enable shortcut on radio/checkbox/missing buttons
209
+ /** Enable keyboard shortcuts for checkboxes, radio buttons and missing buttons (default: `false`). */
148
210
  shortcut?: boolean;
211
+ /** Starting page at launch. (default: `"1"`) */
149
212
  initialPage?: PageTag;
213
+ /** Furthest page the user ever reached. */
150
214
  lastReachedPage?: PageTag;
215
+ /** Enable the preemptive loading of suggester data on Lunatic initialization. (default: `false`) */
151
216
  autoSuggesterLoading?: boolean;
217
+ /** Function called to fetch nomenclatures used by the suggesters. */
152
218
  getReferentiel?: (name: string) => Promise<Array<IndexEntry>>;
153
- // Enable controls for data (form validation)
219
+ /** Enable data controls (form validation). (default: `false`) */
154
220
  activeControls?: boolean;
221
+ /** Enable overview system. (default: `false`) */
155
222
  withOverview?: boolean;
223
+ /** Enable missing system. (default: `false`) */
156
224
  missing?: boolean;
225
+ /** Function triggered when a missing button is clicked. */
157
226
  missingStrategy?: () => void;
227
+ /** Keyboard shortcut that triggers missing buttons. */
158
228
  missingShortcut?: { dontKnow: string; refused: string };
229
+ /** "Don't know" button label. */
159
230
  dontKnowButton?: string;
231
+ /** "Refused" button label. */
160
232
  refusedButton?: string;
161
- // Enable change tracking to keep a track of what variable changed (allow using getChangedData())
233
+ /** Enable change tracking to keep a track of what variable changed (allow using getChangedData()). (default: `false`) */
162
234
  trackChanges?: boolean;
163
235
  logger?: LunaticLogger;
164
236
  componentsOptions?: { detailAlwaysDisplayed?: boolean };
165
237
  };
166
238
 
167
- // Type representing the return type of "useLunatic()"
239
+ /**
240
+ * Return type of {@link useLunatic}.
241
+ *
242
+ * Allow to operate the survey.
243
+ */
168
244
  export type LunaticState = {
245
+ /** Current pager. */
169
246
  pager: LunaticPager;
170
247
  overview: InterpretedLunaticOverviewItem[];
248
+ /** Current page numerotation. */
171
249
  pageTag: PageTag;
250
+ /** Date of the last `handleChange` function call. */
172
251
  updatedAt: number;
252
+ /** Necessary component that must wraps `LunaticComponents` to make the library works. */
173
253
  Provider: FunctionComponent<PropsWithChildren>;
254
+ /** Whether or not we're in a loop. */
174
255
  isInLoop: boolean;
256
+ /** Current loop's variables. */
175
257
  loopVariables: string[];
258
+ /** Whether or not we're on the survey first page. */
176
259
  isFirstPage: boolean;
260
+ /** Whether or not we're on the survey last page (we reached `maxPage`). */
177
261
  isLastPage: boolean;
178
- // Errors for the form
262
+ /** Errors in the survey. */
179
263
  errors?: { [page: string]: { [id: string]: LunaticError[] } };
180
- // Contains the errors for the current page / iteration
264
+ /** Errors in the current page / iteration. */
181
265
  currentErrors?: { [id: string]: LunaticError[] };
182
- // Errors
266
+ /** Errors in modal. */
183
267
  modalErrors?: Record<string, LunaticError[]>;
268
+ /** Navigate to a specific page. */
184
269
  goToPage: (page: {
185
270
  page: PageTag | number;
186
271
  iteration?: number;
187
272
  nbIterations?: number;
188
273
  subPage?: number;
189
274
  }) => void;
190
- // Enable components to independently navigate next/previous
275
+ /** Navigate to the next page. */
191
276
  goNextPage: () => void;
277
+ /** Navigate to the previous page. */
192
278
  goPreviousPage: () => void;
279
+ /** Allow to fetch controls. */
193
280
  compileControls: () => {
194
281
  currentErrors: Record<string, LunaticError[]> | undefined;
195
282
  isCritical: boolean;
196
283
  };
284
+ /**
285
+ * Components to display in the current page.
286
+ *
287
+ * Return an array with the various components' properties. The orchestrator
288
+ * has to handle how they are displayed, using the `componentType` property to
289
+ * select the appropriate component.
290
+ *
291
+ * @example
292
+ * // using `LunaticComponents`
293
+ * import { useLunatic, LunaticComponents } from '@inseefr/lunatic';
294
+ *
295
+ * function App({ source, data }) {
296
+ * const { getComponents, Provider } = useLunatic(source, data, {});
297
+ * const components = getComponents();
298
+ *
299
+ * return (
300
+ * <Provider>
301
+ * <LunaticComponents components={components} />
302
+ * </Provider>
303
+ * );
304
+ * }
305
+ *
306
+ * @example
307
+ * // using custom components
308
+ * import { useLunatic, LunaticComponents } from '@inseefr/lunatic';
309
+ *
310
+ * const customCompoonents = {
311
+ * Input: MyCustomInput,
312
+ * InputNumber: MyCustomInputNumber,
313
+ * };
314
+ *
315
+ * function App({ source, data }) {
316
+ * const { getComponents, Provider } = useLunatic(source, data, {});
317
+ * const components = getComponents();
318
+ *
319
+ * return (
320
+ * <Provider>
321
+ * <LunaticComponents components={components} slots={customComponents} />
322
+ * </Provider>
323
+ * );
324
+ * }
325
+ *
326
+ * @see {@link LunaticComponents}
327
+ */
197
328
  getComponents: () => LunaticComponentProps[];
329
+ /** Get data collected by the survey. */
198
330
  getData: (
199
331
  withRefreshedCalculated: boolean,
200
332
  variableNames?: string[]
201
333
  ) => LunaticData;
202
- getChangedData: (reset: boolean) => LunaticData;
334
+ /** Get data that have changed since last reset. Returns the same thing as `getData()`. */
335
+ getChangedData: (reset?: boolean) => LunaticData;
336
+ /** Empty the store of changed variables. */
203
337
  resetChangedData: () => void;
338
+ /** Return `true` as soon as the current page has at least one answer. */
204
339
  hasPageResponse: () => boolean;
205
- // This is used for testing purpose only
340
+ /** Used for testing purpose only. */
206
341
  testing: {
207
342
  handleChanges: LunaticChangesHandler;
208
343
  };
209
344
  };
210
345
 
346
+ /** Function taking as arguments the various changes the user has made. */
211
347
  export type LunaticChangesHandler = (
212
348
  args: {
213
349
  name: string;
@@ -66,11 +66,19 @@ const defaultOptions = {
66
66
  componentsOptions: { detailAlwaysDisplayed: false },
67
67
  } satisfies LunaticOptions;
68
68
 
69
+ /** The first library entrypoint is the `useLunatic` hook. */
69
70
  export function useLunatic(
71
+ /**
72
+ * JSON representation of our survey unit in the Lunatic Model.
73
+ *
74
+ * {@link https://github.com/InseeFr/Lunatic-Model}
75
+ */
70
76
  source: LunaticSource,
77
+ /** Initial survey data (i.e. if it has been partially filled). */
71
78
  data: LunaticData = DEFAULT_DATA,
79
+ /** Specific behaviour options. */
72
80
  argOptions: LunaticOptions = empty
73
- ) {
81
+ ): LunaticState {
74
82
  const options = mergeDefault(argOptions, defaultOptions);
75
83
  const {
76
84
  disableFilters,
@@ -106,7 +114,7 @@ export function useLunatic(
106
114
  reducerInitializer
107
115
  );
108
116
 
109
- // Required context provider: cleaner than prop drilling through every component
117
+ /** Required context provider: cleaner than prop drilling through every component */
110
118
  const Provider = useMemo(
111
119
  () =>
112
120
  createLunaticProvider({
@@ -157,6 +165,7 @@ export function useLunatic(
157
165
  },
158
166
  [dispatch]
159
167
  );
168
+
160
169
  const handleChanges = useCallback<LunaticChangesHandler>(
161
170
  (responses) => {
162
171
  dispatch(handleChangesAction(responses));