@inseefr/lunatic 3.4.8-rc.0 → 3.4.9

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 (205) hide show
  1. package/components/CheckboxGroup/CheckboxGroup.js +3 -1
  2. package/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
  3. package/components/CheckboxGroup/CustomCheckboxGroup.d.ts +1 -1
  4. package/components/CheckboxGroup/CustomCheckboxGroup.js +2 -5
  5. package/components/CheckboxGroup/CustomCheckboxGroup.js.map +1 -1
  6. package/components/CheckboxOne/CheckboxOne.js +3 -1
  7. package/components/CheckboxOne/CheckboxOne.js.map +1 -1
  8. package/components/Datepicker/Datepicker.js +7 -1
  9. package/components/Datepicker/Datepicker.js.map +1 -1
  10. package/components/Input/Input.js +3 -1
  11. package/components/Input/Input.js.map +1 -1
  12. package/components/InputNumber/InputNumber.spec.js +12 -0
  13. package/components/InputNumber/InputNumber.spec.js.map +1 -1
  14. package/components/InputNumber/InputNumberThousand.js +3 -1
  15. package/components/InputNumber/InputNumberThousand.js.map +1 -1
  16. package/components/Radio/Radio.d.ts +1 -0
  17. package/components/Radio/Radio.js +3 -1
  18. package/components/Radio/Radio.js.map +1 -1
  19. package/components/library.d.ts +1 -0
  20. package/components/shared/Checkbox/CheckboxOption.d.ts +4 -0
  21. package/components/shared/Checkbox/CheckboxOption.js +4 -2
  22. package/components/shared/Checkbox/CheckboxOption.js.map +1 -1
  23. package/components/shared/Checkbox/CheckboxOption.spec.js +14 -0
  24. package/components/shared/Checkbox/CheckboxOption.spec.js.map +1 -1
  25. package/components/shared/Radio/RadioGroup.d.ts +1 -1
  26. package/components/shared/Radio/RadioGroup.js +2 -2
  27. package/components/shared/Radio/RadioGroup.js.map +1 -1
  28. package/components/shared/Radio/RadioOption.d.ts +1 -0
  29. package/components/shared/Radio/RadioOption.js +2 -2
  30. package/components/shared/Radio/RadioOption.js.map +1 -1
  31. package/components/shared/Radio/RadioOption.spec.js +12 -0
  32. package/components/shared/Radio/RadioOption.spec.js.map +1 -1
  33. package/components/type.d.ts +3 -0
  34. package/esm/components/CheckboxGroup/CheckboxGroup.js +3 -1
  35. package/esm/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
  36. package/esm/components/CheckboxGroup/CustomCheckboxGroup.d.ts +1 -1
  37. package/esm/components/CheckboxGroup/CustomCheckboxGroup.js +2 -6
  38. package/esm/components/CheckboxGroup/CustomCheckboxGroup.js.map +1 -1
  39. package/esm/components/CheckboxOne/CheckboxOne.js +3 -1
  40. package/esm/components/CheckboxOne/CheckboxOne.js.map +1 -1
  41. package/esm/components/Datepicker/Datepicker.js +7 -1
  42. package/esm/components/Datepicker/Datepicker.js.map +1 -1
  43. package/esm/components/Input/Input.js +3 -1
  44. package/esm/components/Input/Input.js.map +1 -1
  45. package/esm/components/InputNumber/InputNumber.spec.js +12 -0
  46. package/esm/components/InputNumber/InputNumber.spec.js.map +1 -1
  47. package/esm/components/InputNumber/InputNumberThousand.js +3 -1
  48. package/esm/components/InputNumber/InputNumberThousand.js.map +1 -1
  49. package/esm/components/Radio/Radio.d.ts +1 -0
  50. package/esm/components/Radio/Radio.js +3 -1
  51. package/esm/components/Radio/Radio.js.map +1 -1
  52. package/esm/components/library.d.ts +1 -0
  53. package/esm/components/shared/Checkbox/CheckboxOption.d.ts +4 -0
  54. package/esm/components/shared/Checkbox/CheckboxOption.js +4 -2
  55. package/esm/components/shared/Checkbox/CheckboxOption.js.map +1 -1
  56. package/esm/components/shared/Checkbox/CheckboxOption.spec.js +14 -0
  57. package/esm/components/shared/Checkbox/CheckboxOption.spec.js.map +1 -1
  58. package/esm/components/shared/Radio/RadioGroup.d.ts +1 -1
  59. package/esm/components/shared/Radio/RadioGroup.js +2 -2
  60. package/esm/components/shared/Radio/RadioGroup.js.map +1 -1
  61. package/esm/components/shared/Radio/RadioOption.d.ts +1 -0
  62. package/esm/components/shared/Radio/RadioOption.js +2 -2
  63. package/esm/components/shared/Radio/RadioOption.js.map +1 -1
  64. package/esm/components/shared/Radio/RadioOption.spec.js +12 -0
  65. package/esm/components/shared/Radio/RadioOption.spec.js.map +1 -1
  66. package/esm/components/type.d.ts +3 -0
  67. package/esm/index.d.ts +0 -1
  68. package/esm/index.js +0 -1
  69. package/esm/index.js.map +1 -1
  70. package/esm/main.css +5 -2
  71. package/esm/main.css.map +1 -1
  72. package/esm/type.source.d.ts +25 -40
  73. package/esm/type.source.js +1 -0
  74. package/esm/type.source.js.map +1 -1
  75. package/esm/use-lunatic/commons/fill-components/fill-components.d.ts +1 -0
  76. package/esm/use-lunatic/commons/fill-components/fill-components.js +1 -1
  77. package/esm/use-lunatic/commons/fill-components/fill-components.js.map +1 -1
  78. package/esm/use-lunatic/commons/page.js +4 -1
  79. package/esm/use-lunatic/commons/page.js.map +1 -1
  80. package/esm/use-lunatic/lunatic-context.d.ts +7 -1
  81. package/esm/use-lunatic/lunatic-context.js +7 -1
  82. package/esm/use-lunatic/lunatic-context.js.map +1 -1
  83. package/esm/use-lunatic/props/getComponentTypeProps.d.ts +3 -0
  84. package/esm/use-lunatic/props/propOptions.d.ts +1 -1
  85. package/esm/use-lunatic/props/propOptions.js.map +1 -1
  86. package/esm/use-lunatic/reducer/reducerInitializer.d.ts +2 -1
  87. package/esm/use-lunatic/reducer/reducerInitializer.js +3 -1
  88. package/esm/use-lunatic/reducer/reducerInitializer.js.map +1 -1
  89. package/esm/use-lunatic/type.d.ts +7 -0
  90. package/esm/use-lunatic/use-lunatic.js +6 -1
  91. package/esm/use-lunatic/use-lunatic.js.map +1 -1
  92. package/esm/utils/search/SearchMiniSearch.spec.d.ts +1 -0
  93. package/esm/utils/search/SearchMiniSearch.spec.js +51 -0
  94. package/esm/utils/search/SearchMiniSearch.spec.js.map +1 -0
  95. package/esm/utils/search/melauto.js +1 -1
  96. package/esm/utils/search/melauto.spec.d.ts +1 -0
  97. package/esm/utils/search/melauto.spec.js +67 -0
  98. package/esm/utils/search/melauto.spec.js.map +1 -0
  99. package/esm/utils/search/tokenizer.d.ts +7 -2
  100. package/esm/utils/search/tokenizer.js +23 -8
  101. package/esm/utils/search/tokenizer.js.map +1 -1
  102. package/esm/utils/search/tokenizer.spec.d.ts +1 -0
  103. package/esm/utils/search/tokenizer.spec.js +160 -0
  104. package/esm/utils/search/tokenizer.spec.js.map +1 -0
  105. package/index.d.ts +0 -1
  106. package/index.js +1 -4
  107. package/index.js.map +1 -1
  108. package/main.css +5 -2
  109. package/main.css.map +1 -1
  110. package/package.json +28 -1
  111. package/src/components/CheckboxGroup/CheckboxGroup.tsx +3 -0
  112. package/src/components/CheckboxGroup/CustomCheckboxGroup.tsx +3 -14
  113. package/src/components/CheckboxOne/CheckboxOne.tsx +3 -0
  114. package/src/components/Datepicker/Datepicker.tsx +8 -1
  115. package/src/components/Input/Input.tsx +4 -0
  116. package/src/components/Input/__snapshots__/Input.spec.tsx.snap +2 -0
  117. package/src/components/InputNumber/InputNumber.spec.tsx +20 -0
  118. package/src/components/InputNumber/InputNumberThousand.tsx +4 -0
  119. package/src/components/InputNumber/__snapshots__/InputNumber.spec.tsx.snap +2 -0
  120. package/src/components/Radio/Radio.tsx +3 -0
  121. package/src/components/RosterForLoop/__snapshots__/RosterForLoop.spec.tsx.snap +2 -0
  122. package/src/components/shared/Checkbox/CheckboxOption.spec.tsx +21 -0
  123. package/src/components/shared/Checkbox/CheckboxOption.tsx +19 -0
  124. package/src/components/shared/Radio/RadioGroup.tsx +3 -0
  125. package/src/components/shared/Radio/RadioOption.spec.tsx +36 -0
  126. package/src/components/shared/Radio/RadioOption.tsx +5 -1
  127. package/src/components/type.ts +3 -0
  128. package/src/css/components/CheckboxOne.scss +1 -1
  129. package/src/css/components/CheckboxOption.scss +14 -18
  130. package/src/css/components/Combobox.scss +3 -2
  131. package/src/css/components/Datepicker.scss +8 -8
  132. package/src/css/components/Declarations.scss +1 -1
  133. package/src/css/components/Dragger.scss +6 -6
  134. package/src/css/components/Duration.scss +4 -4
  135. package/src/css/components/IconButton.scss +4 -2
  136. package/src/css/components/Input.scss +3 -0
  137. package/src/css/components/Missing.scss +1 -1
  138. package/src/css/components/Roundabout.scss +3 -3
  139. package/src/css/components/Suggester.scss +2 -2
  140. package/src/css/components/Table.scss +9 -7
  141. package/src/css/main.scss +167 -167
  142. package/src/index.ts +0 -2
  143. package/src/stories/behaviour/filter/dataLoop.json +22 -0
  144. package/src/stories/behaviour/filter/filter.stories.jsx +36 -0
  145. package/src/stories/behaviour/filter/source.json +238 -0
  146. package/src/stories/behaviour/filter/sourceLoop.json +372 -0
  147. package/src/stories/behaviour/missing/missing.stories.jsx +9 -0
  148. package/src/stories/behaviour/paste/test.stories.jsx +5 -0
  149. package/src/stories/checkbox-group/checkbox-group.stories.jsx +25 -6
  150. package/src/stories/checkbox-one/checkboxOne.stories.jsx +24 -2
  151. package/src/stories/overview/overview.stories.jsx +8 -1
  152. package/src/stories/radio/radio.stories.jsx +46 -6
  153. package/src/stories/utils/default-arg-types.js +12 -1
  154. package/src/stories/utils/default-args.js +3 -0
  155. package/src/stories/utils/orchestrator.jsx +11 -1
  156. package/src/stories/utils/orchestrator.scss +9 -7
  157. package/src/stories/utils/overview.scss +0 -1
  158. package/src/type.source.ts +93 -108
  159. package/src/use-lunatic/commons/fill-components/fill-components.ts +4 -1
  160. package/src/use-lunatic/commons/page.ts +4 -1
  161. package/src/use-lunatic/lunatic-context.tsx +9 -0
  162. package/src/use-lunatic/props/propOptions.ts +2 -1
  163. package/src/use-lunatic/reducer/reducerInitializer.tsx +4 -0
  164. package/src/use-lunatic/type.ts +5 -0
  165. package/src/use-lunatic/use-lunatic.test.ts +52 -0
  166. package/src/use-lunatic/use-lunatic.ts +7 -0
  167. package/src/utils/search/SearchMiniSearch.spec.ts +58 -0
  168. package/src/utils/search/melauto.spec.ts +75 -0
  169. package/src/utils/search/melauto.ts +1 -1
  170. package/src/utils/search/tokenizer.spec.ts +205 -0
  171. package/src/utils/search/tokenizer.ts +27 -8
  172. package/tsconfig.build.tsbuildinfo +1 -1
  173. package/type.source.d.ts +25 -40
  174. package/type.source.js +1 -0
  175. package/type.source.js.map +1 -1
  176. package/use-lunatic/commons/fill-components/fill-components.d.ts +1 -0
  177. package/use-lunatic/commons/fill-components/fill-components.js +1 -1
  178. package/use-lunatic/commons/fill-components/fill-components.js.map +1 -1
  179. package/use-lunatic/commons/page.js +4 -1
  180. package/use-lunatic/commons/page.js.map +1 -1
  181. package/use-lunatic/lunatic-context.d.ts +7 -1
  182. package/use-lunatic/lunatic-context.js +9 -2
  183. package/use-lunatic/lunatic-context.js.map +1 -1
  184. package/use-lunatic/props/getComponentTypeProps.d.ts +3 -0
  185. package/use-lunatic/props/propOptions.d.ts +1 -1
  186. package/use-lunatic/props/propOptions.js.map +1 -1
  187. package/use-lunatic/reducer/reducerInitializer.d.ts +2 -1
  188. package/use-lunatic/reducer/reducerInitializer.js +3 -1
  189. package/use-lunatic/reducer/reducerInitializer.js.map +1 -1
  190. package/use-lunatic/type.d.ts +7 -0
  191. package/use-lunatic/use-lunatic.js +6 -1
  192. package/use-lunatic/use-lunatic.js.map +1 -1
  193. package/utils/search/SearchMiniSearch.spec.d.ts +1 -0
  194. package/utils/search/SearchMiniSearch.spec.js +51 -0
  195. package/utils/search/SearchMiniSearch.spec.js.map +1 -0
  196. package/utils/search/melauto.js +1 -1
  197. package/utils/search/melauto.spec.d.ts +1 -0
  198. package/utils/search/melauto.spec.js +69 -0
  199. package/utils/search/melauto.spec.js.map +1 -0
  200. package/utils/search/tokenizer.d.ts +7 -2
  201. package/utils/search/tokenizer.js +24 -8
  202. package/utils/search/tokenizer.js.map +1 -1
  203. package/utils/search/tokenizer.spec.d.ts +1 -0
  204. package/utils/search/tokenizer.spec.js +162 -0
  205. package/utils/search/tokenizer.spec.js.map +1 -0
@@ -1,6 +1,7 @@
1
1
  import { RadioGroup } from '../shared/Radio/RadioGroup';
2
2
  import type { LunaticComponentProps } from '../type';
3
3
  import { getComponentErrors } from '../shared/ComponentErrors/ComponentErrors';
4
+ import { useLunaticComponentsOptions } from '../../use-lunatic/lunatic-context';
4
5
 
5
6
  /**
6
7
  * Checkbox acting as a radio (only one option can be checked at a time)
@@ -18,6 +19,7 @@ export function CheckboxOne({
18
19
  declarations,
19
20
  orientation,
20
21
  }: LunaticComponentProps<'CheckboxOne'>) {
22
+ const { detailAlwaysDisplayed } = useLunaticComponentsOptions();
21
23
  return (
22
24
  <RadioGroup
23
25
  id={id}
@@ -33,6 +35,7 @@ export function CheckboxOne({
33
35
  shortcut={shortcut}
34
36
  declarations={declarations}
35
37
  orientation={orientation ?? 'vertical'}
38
+ detailAlwaysDisplayed={detailAlwaysDisplayed}
36
39
  clearable
37
40
  />
38
41
  );
@@ -153,9 +153,16 @@ function numbersFromDateString(s?: string): [number, number, number] {
153
153
  ];
154
154
  }
155
155
 
156
+ /**
157
+ * Check if the date provided by the user is valid (e.g. not 2001/02/29)
158
+ */
156
159
  function isDateValid(dateArray: [number, number, number]) {
157
160
  const [year, month, day] = dateArray;
158
- const date = new Date(year, month - 1, day);
161
+
162
+ // do not set the date directly on new Date(), to avoid transformation on year between 0 and 99.
163
+ //See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#year
164
+ const date = new Date();
165
+ date.setFullYear(year, month - 1, day);
159
166
 
160
167
  return (
161
168
  date.getFullYear() === year &&
@@ -65,11 +65,15 @@ export const CustomInput = slottableComponent<CustomProps>('Input', (props) => {
65
65
  disabled={disabled}
66
66
  readOnly={readOnly}
67
67
  value={(value ?? '').toString()}
68
+ title={value ?? ''}
68
69
  onChange={(e) => onChange(e.target.value)}
69
70
  aria-required={required}
70
71
  required={required}
71
72
  maxLength={maxLength}
72
73
  aria-invalid={!!errors}
74
+ onBlur={(e) => {
75
+ e.target.setSelectionRange(0, 0);
76
+ }}
73
77
  />
74
78
  <ComponentErrors errors={errors} />
75
79
  </div>
@@ -10,6 +10,7 @@ exports[`Input > renders without crashing 1`] = `
10
10
  aria-labelledby="label-input"
11
11
  autocomplete="off"
12
12
  id="input"
13
+ title="input"
13
14
  type="text"
14
15
  value="input"
15
16
  />
@@ -28,6 +29,7 @@ exports[`Input > should handle readOnly 1`] = `
28
29
  autocomplete="off"
29
30
  id="number"
30
31
  readonly=""
32
+ title="toto"
31
33
  type="text"
32
34
  value="toto"
33
35
  />
@@ -112,4 +112,24 @@ describe('InputNumber', () => {
112
112
  const unit = container.querySelector('span');
113
113
  expect(unit).toHaveTextContent('kg');
114
114
  });
115
+
116
+ it('should display the input value from the start', () => {
117
+ const setSelectionRangeMock = vi.fn();
118
+ const { container } = render(
119
+ <InputNumber
120
+ {...baseProps}
121
+ value={100000000000000000000000000000000000}
122
+ />
123
+ );
124
+
125
+ const input = container.querySelector('input[type="text"]');
126
+
127
+ fireEvent.blur(input!, {
128
+ target: {
129
+ ...input,
130
+ setSelectionRange: setSelectionRangeMock,
131
+ },
132
+ });
133
+ expect(setSelectionRangeMock).toHaveBeenCalledWith(0, 0);
134
+ });
115
135
  });
@@ -55,6 +55,7 @@ export const InputNumberThousand = ({
55
55
  className={classNames({ disabled })}
56
56
  onValueChange={handleChange}
57
57
  value={value ?? ''}
58
+ title={value ? value.toString() : ''}
58
59
  aria-labelledby={labelId}
59
60
  disabled={disabled}
60
61
  readOnly={readOnly}
@@ -68,6 +69,9 @@ export const InputNumberThousand = ({
68
69
  thousandSeparator={inputNumberPropsI18N.thousandSeparator}
69
70
  inputMode={decimals ? 'decimal' : 'numeric'}
70
71
  aria-invalid={invalid}
72
+ onBlur={(e) => {
73
+ e.target.setSelectionRange(0, 0);
74
+ }}
71
75
  />
72
76
  );
73
77
  };
@@ -12,6 +12,7 @@ exports[`InputNumber > renders without crashing 1`] = `
12
12
  id="number"
13
13
  inputmode="numeric"
14
14
  lang="en"
15
+ title="10"
15
16
  type="text"
16
17
  value="10"
17
18
  />
@@ -32,6 +33,7 @@ exports[`InputNumber > should handle readOnly 1`] = `
32
33
  inputmode="numeric"
33
34
  lang="en"
34
35
  readonly=""
36
+ title="123"
35
37
  type="text"
36
38
  value="123"
37
39
  />
@@ -2,6 +2,7 @@ import type { LunaticComponentProps } from '../type';
2
2
  import { getComponentErrors } from '../shared/ComponentErrors/ComponentErrors';
3
3
  import { RadioGroup } from '../shared/Radio/RadioGroup';
4
4
  import { slottableComponent } from '../shared/HOC/slottableComponent';
5
+ import { useLunaticComponentsOptions } from '../../use-lunatic/lunatic-context';
5
6
 
6
7
  function LunaticRadio(props: LunaticComponentProps<'Radio'>) {
7
8
  const {
@@ -19,6 +20,7 @@ function LunaticRadio(props: LunaticComponentProps<'Radio'>) {
19
20
  declarations,
20
21
  orientation,
21
22
  } = props;
23
+ const { detailAlwaysDisplayed } = useLunaticComponentsOptions();
22
24
  return (
23
25
  <RadioGroup
24
26
  id={id}
@@ -34,6 +36,7 @@ function LunaticRadio(props: LunaticComponentProps<'Radio'>) {
34
36
  readOnly={readOnly}
35
37
  declarations={declarations}
36
38
  orientation={orientation ?? 'vertical'}
39
+ detailAlwaysDisplayed={detailAlwaysDisplayed}
37
40
  />
38
41
  );
39
42
  }
@@ -37,6 +37,7 @@ exports[`RosterForLoop > renders the right number of columns 1`] = `
37
37
  autocomplete="off"
38
38
  id="jrc3ye5q-QOP-lo6tcvvx-0"
39
39
  maxlength="249"
40
+ title="azeaze"
40
41
  type="text"
41
42
  value="azeaze"
42
43
  />
@@ -66,6 +67,7 @@ exports[`RosterForLoop > renders the right number of columns 1`] = `
66
67
  autocomplete="off"
67
68
  id="jrc3ye5q-QOP-lo6tcvvx-1"
68
69
  maxlength="249"
70
+ title="azeaze"
69
71
  type="text"
70
72
  value="azeaze"
71
73
  />
@@ -17,6 +17,8 @@ describe('CheckboxOption', () => {
17
17
  id: 'test-checkbox',
18
18
  onCheck: vi.fn(),
19
19
  label: 'Test checkbox',
20
+ detailLabel: 'My detail',
21
+ onDetailChange: () => {},
20
22
  };
21
23
 
22
24
  it('renders the component correctly', () => {
@@ -55,4 +57,23 @@ describe('CheckboxOption', () => {
55
57
  fireEvent.keyDown(checkbox, { code: 'Space' });
56
58
  expect(defaultProps.onCheck).toHaveBeenCalledWith(true);
57
59
  });
60
+
61
+ it('renders the detail when checked', () => {
62
+ const { getByText } = render(
63
+ <CheckboxOption {...defaultProps} checked={true} />
64
+ );
65
+ expect(getByText(defaultProps.detailLabel)).toBeInTheDocument();
66
+ });
67
+ it('does not render the detail when unchecked', () => {
68
+ const { queryByText } = render(
69
+ <CheckboxOption {...defaultProps} checked={false} />
70
+ );
71
+ expect(queryByText(defaultProps.detailLabel)).toBeNull();
72
+ });
73
+ it('renders the details when unchecked with the detail always displayed attribute', () => {
74
+ const { getByText } = render(
75
+ <CheckboxOption {...defaultProps} checked={false} detailAlwaysDisplayed />
76
+ );
77
+ expect(getByText(defaultProps.detailLabel)).toBeInTheDocument();
78
+ });
58
79
  });
@@ -3,6 +3,7 @@ import type { LunaticBaseProps } from '../../type';
3
3
  import { slottableComponent } from '../HOC/slottableComponent';
4
4
  import { Label } from '../Label/Label';
5
5
  import { useKeyboardKey } from '../../../hooks/useKeyboardKey';
6
+ import { CustomInput } from '../../Input/Input';
6
7
 
7
8
  export type CheckboxOptionProps = {
8
9
  disabled?: boolean;
@@ -15,6 +16,10 @@ export type CheckboxOptionProps = {
15
16
  codeModality?: string;
16
17
  shortcut?: boolean;
17
18
  invalid?: boolean;
19
+ detailAlwaysDisplayed?: boolean;
20
+ detailLabel?: ReactNode;
21
+ detailValue?: string | null;
22
+ onDetailChange?: (value: string) => void;
18
23
  };
19
24
 
20
25
  function LunaticCheckboxOption({
@@ -25,11 +30,16 @@ function LunaticCheckboxOption({
25
30
  onCheck,
26
31
  label,
27
32
  description,
33
+ detailAlwaysDisplayed,
34
+ detailLabel,
35
+ detailValue,
36
+ onDetailChange,
28
37
  codeModality,
29
38
  shortcut,
30
39
  invalid,
31
40
  }: CheckboxOptionProps) {
32
41
  const isEnabled = !readOnly && !disabled;
42
+ const hasDetail = !!onDetailChange;
33
43
  const hasKeyboardShortcut = Boolean(shortcut && codeModality && isEnabled);
34
44
  const onClickOption = () => {
35
45
  if (isEnabled) {
@@ -88,6 +98,15 @@ function LunaticCheckboxOption({
88
98
  )}{' '}
89
99
  {label}
90
100
  </Label>
101
+ {hasDetail && (checked || detailAlwaysDisplayed) && (
102
+ <CustomInput
103
+ id="detailId"
104
+ label={detailLabel ?? 'Précisez :'}
105
+ value={typeof detailValue === 'string' ? detailValue : ''}
106
+ onChange={onDetailChange}
107
+ disabled={disabled}
108
+ />
109
+ )}
91
110
  </div>
92
111
  );
93
112
  }
@@ -22,6 +22,7 @@ export type RadioGroupProps = Pick<
22
22
  | 'description'
23
23
  | 'declarations'
24
24
  | 'orientation'
25
+ | 'detailAlwaysDisplayed'
25
26
  > & {
26
27
  errors?: LunaticError[];
27
28
  clearable?: boolean;
@@ -44,6 +45,7 @@ function LunaticRadioGroup({
44
45
  readOnly,
45
46
  declarations,
46
47
  orientation,
48
+ detailAlwaysDisplayed,
47
49
  }: RadioGroupProps) {
48
50
  const onKeyDown = useListKeyboardHandler(options);
49
51
  const maxIndex = options.length;
@@ -61,6 +63,7 @@ function LunaticRadioGroup({
61
63
  id={radioId}
62
64
  index={index}
63
65
  checked={value === option.value}
66
+ detailAlwaysDisplayed={detailAlwaysDisplayed}
64
67
  onKeyDown={onKeyDown}
65
68
  checkboxStyle={checkboxStyle}
66
69
  codeModality={shortcut ? codeModality : undefined}
@@ -73,4 +73,40 @@ describe('RadioOption', () => {
73
73
  fireEvent.keyDown(option, { key: 'Enter', code: 'Enter' });
74
74
  expect(onKeyDownMock).toHaveBeenCalled();
75
75
  });
76
+
77
+ it('renders the detail when checked', () => {
78
+ const { getByText } = render(
79
+ <RadioOption
80
+ id="radio-option"
81
+ label="Test Option"
82
+ onDetailChange={() => {}}
83
+ detailLabel="My detail"
84
+ checked
85
+ />
86
+ );
87
+ expect(getByText('My detail')).toBeInTheDocument();
88
+ });
89
+ it('does not render the detail when unchecked', () => {
90
+ const { queryByText } = render(
91
+ <RadioOption
92
+ id="radio-option"
93
+ label="Test Option"
94
+ onDetailChange={() => {}}
95
+ detailLabel="My detail"
96
+ />
97
+ );
98
+ expect(queryByText('My detail')).toBeNull();
99
+ });
100
+ it('renders the details when unchecked with the detail always displayed attribute', () => {
101
+ const { getByText } = render(
102
+ <RadioOption
103
+ id="radio-option"
104
+ label="Test Option"
105
+ onDetailChange={() => {}}
106
+ detailLabel="My detail"
107
+ detailAlwaysDisplayed
108
+ />
109
+ );
110
+ expect(getByText('My detail')).toBeInTheDocument();
111
+ });
76
112
  });
@@ -17,6 +17,7 @@ export type Props = {
17
17
  labelledBy?: string;
18
18
  codeModality?: string;
19
19
  invalid?: boolean;
20
+ detailAlwaysDisplayed?: boolean;
20
21
  } & InterpretedOption;
21
22
 
22
23
  function LunaticRadioOption({
@@ -30,10 +31,12 @@ function LunaticRadioOption({
30
31
  shortcut,
31
32
  codeModality,
32
33
  id,
34
+ invalid,
33
35
  labelledBy,
34
36
  description,
35
37
  label,
36
38
  onDetailChange,
39
+ detailAlwaysDisplayed,
37
40
  detailLabel,
38
41
  detailValue,
39
42
  onCheck,
@@ -80,6 +83,7 @@ function LunaticRadioOption({
80
83
  <div
81
84
  id={id}
82
85
  role="radio"
86
+ aria-invalid={invalid}
83
87
  aria-disabled={disabled}
84
88
  className={classnames(
85
89
  'lunatic-input-checkbox',
@@ -113,7 +117,7 @@ function LunaticRadioOption({
113
117
  {label}
114
118
  </Label>
115
119
  </div>
116
- {hasDetail && checked && (
120
+ {hasDetail && (checked || detailAlwaysDisplayed) && (
117
121
  <CustomInput
118
122
  id="detailId"
119
123
  label={detailLabel ?? 'Précisez :'}
@@ -191,6 +191,7 @@ export type ComponentPropsByType = {
191
191
  detailLabel?: ReactNode;
192
192
  }[];
193
193
  orientation?: 'horizontal' | 'vertical';
194
+ detailAlwaysDisplayed?: boolean;
194
195
  componentType?: 'CheckboxGroup';
195
196
  };
196
197
  CheckboxOne: LunaticBaseProps<string | null> &
@@ -198,6 +199,7 @@ export type ComponentPropsByType = {
198
199
  options: Array<InterpretedOption>;
199
200
  componentType?: 'CheckboxOne';
200
201
  orientation?: 'horizontal' | 'vertical';
202
+ detailAlwaysDisplayed?: boolean;
201
203
  };
202
204
  Switch: LunaticBaseProps<boolean> &
203
205
  LunaticExtraProps & {
@@ -217,6 +219,7 @@ export type ComponentPropsByType = {
217
219
  response: { name: string };
218
220
  componentType?: 'Radio';
219
221
  orientation?: 'horizontal' | 'vertical';
222
+ detailAlwaysDisplayed?: boolean;
220
223
  };
221
224
  Roundabout: LunaticBaseProps<string> &
222
225
  LunaticExtraProps & {
@@ -9,7 +9,7 @@
9
9
 
10
10
  label {
11
11
  display: flex;
12
- gap:0.5em;
12
+ gap: 0.5em;
13
13
  align-items: center;
14
14
  .label-description {
15
15
  font-weight: lighter;
@@ -12,12 +12,12 @@
12
12
  display: flex;
13
13
  align-items: center;
14
14
  cursor: pointer;
15
- gap: .5rem;
16
- padding: .3rem 0;
15
+ gap: 0.5rem;
16
+ padding: 0.3rem 0;
17
17
 
18
18
  label {
19
19
  display: flex;
20
- gap: .5em;
20
+ gap: 0.5em;
21
21
  cursor: inherit;
22
22
  margin: 0;
23
23
  font-weight: normal;
@@ -31,33 +31,30 @@
31
31
  height: 18px;
32
32
  flex: none;
33
33
  border-radius: 2px;
34
- color: #FFF;
34
+ color: #fff;
35
35
  border: 2px solid var(--color-primary-dark);
36
36
 
37
37
  svg {
38
- transform: scale(.9);
38
+ transform: scale(0.9);
39
39
  }
40
40
  }
41
41
 
42
- .lunatic-input-checkbox[aria-checked="true"] .lunatic-input-checkbox__icon {
42
+ .lunatic-input-checkbox[aria-checked='true'] .lunatic-input-checkbox__icon {
43
43
  background-color: var(--color-primary-dark);
44
44
  }
45
45
 
46
- .lunatic-input-checkbox[aria-disabled="true"],
47
- .lunatic-input-checkbox[aria-readonly="true"] {
46
+ .lunatic-input-checkbox[aria-disabled='true'],
47
+ .lunatic-input-checkbox[aria-readonly='true'] {
48
48
  cursor: default;
49
49
 
50
- .lunatic-input-checkbox__icon
51
- {
50
+ .lunatic-input-checkbox__icon {
52
51
  border-color: var(--color-primary-light);
53
52
  background-color: var(--color-disabled);
54
53
  }
55
54
  }
56
55
 
57
- .lunatic-input-checkbox[aria-disabled="true"][aria-checked="true"],
58
- .lunatic-input-checkbox[aria-readonly="true"][aria-checked="true"]
59
- {
60
-
56
+ .lunatic-input-checkbox[aria-disabled='true'][aria-checked='true'],
57
+ .lunatic-input-checkbox[aria-readonly='true'][aria-checked='true'] {
61
58
  .lunatic-input-checkbox__icon {
62
59
  color: var(--color-primary-light);
63
60
  }
@@ -71,15 +68,14 @@
71
68
  svg {
72
69
  display: none;
73
70
  }
74
-
75
71
  }
76
72
 
77
- .lunatic-input-radio[aria-checked="true"] .lunatic-input-checkbox__icon {
73
+ .lunatic-input-radio[aria-checked='true'] .lunatic-input-checkbox__icon {
78
74
  background: transparent;
79
75
  }
80
76
 
81
- .lunatic-input-radio[aria-checked="true"] .lunatic-input-checkbox__icon::after {
82
- content:'';
77
+ .lunatic-input-radio[aria-checked='true'] .lunatic-input-checkbox__icon::after {
78
+ content: '';
83
79
  width: 10px;
84
80
  height: 10px;
85
81
  border-radius: 10px;
@@ -86,13 +86,14 @@
86
86
  height: 0;
87
87
  opacity: 0;
88
88
  background-color: var(--color-combo-box-background);
89
- transition: opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
89
+ transition:
90
+ opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
90
91
  transform 178ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
91
92
 
92
93
  &.expanded {
93
94
  display: flex;
94
95
  flex-direction: column;
95
- gap: .2rem;
96
+ gap: 0.2rem;
96
97
  border: solid 1px var(--color-primary-light);
97
98
  opacity: 1;
98
99
  min-height: 30px;
@@ -1,19 +1,19 @@
1
1
  .lunaticDatepickerFields {
2
- display: flex;
3
- align-items: flex-end;
4
- gap: 1rem;
2
+ display: flex;
3
+ align-items: flex-end;
4
+ gap: 1rem;
5
5
  }
6
6
 
7
7
  .lunaticDatepickerField input {
8
- width: 3.5em;
8
+ width: 3.5em;
9
9
  }
10
10
 
11
11
  .lunaticDatepickerFieldLarge input {
12
- width: 4.5em;
12
+ width: 4.5em;
13
13
  }
14
14
 
15
15
  .lunaticDatepickerHint {
16
- display: block;
17
- font-weight: 400;
18
- font-size: .9em;
16
+ display: block;
17
+ font-weight: 400;
18
+ font-size: 0.9em;
19
19
  }
@@ -28,7 +28,7 @@
28
28
  width: fit-content;
29
29
  padding: 1em;
30
30
  &:before {
31
- content: ""
31
+ content: '';
32
32
  }
33
33
  }
34
34
 
@@ -1,8 +1,8 @@
1
1
  .lunatic-dragger {
2
- display: inline-block;
3
- width: 100%;
4
- height: 100%;
5
- -moz-user-select: -moz-none;
6
- -khtml-user-select: none;
7
- -webkit-user-select: none;
2
+ display: inline-block;
3
+ width: 100%;
4
+ height: 100%;
5
+ -moz-user-select: -moz-none;
6
+ -khtml-user-select: none;
7
+ -webkit-user-select: none;
8
8
  }
@@ -1,9 +1,9 @@
1
1
  .duration-fields,
2
2
  .duration-field {
3
- display: flex;
4
- align-items: center;
5
- gap: 1rem;
3
+ display: flex;
4
+ align-items: center;
5
+ gap: 1rem;
6
6
  }
7
7
  .duration-field {
8
- gap: .5rem;
8
+ gap: 0.5rem;
9
9
  }
@@ -13,8 +13,10 @@
13
13
  outline: inherit;
14
14
  border: none;
15
15
  background-color: royalblue;
16
- box-shadow: 0px 3px 5px -1px rgb(0 0 0 / 20%),
17
- 0px 6px 10px 0px rgb(0 0 0 / 14%), 0px 1px 18px 0px rgb(0 0 0 / 12%);
16
+ box-shadow:
17
+ 0px 3px 5px -1px rgb(0 0 0 / 20%),
18
+ 0px 6px 10px 0px rgb(0 0 0 / 14%),
19
+ 0px 1px 18px 0px rgb(0 0 0 / 12%);
18
20
 
19
21
  &:hover {
20
22
  cursor: pointer;
@@ -21,6 +21,9 @@
21
21
  min-width: 0;
22
22
  box-sizing: content-box;
23
23
  background: none;
24
+ overflow: hidden;
25
+ text-overflow: ellipsis;
26
+ white-space: nowrap;
24
27
  &:focus {
25
28
  outline: none;
26
29
  border-bottom: 0.125rem solid var(--color-primary-main);
@@ -15,7 +15,7 @@
15
15
  color: var(--color-primary-main);
16
16
  }
17
17
  .missing-buttons .button-lunatic:disabled {
18
- opacity: .5;
18
+ opacity: 0.5;
19
19
  }
20
20
  .missing-button-active .button-lunatic {
21
21
  background-color: var(--color-primary-dark);
@@ -8,7 +8,7 @@
8
8
  display: grid;
9
9
  grid-template-columns: 1fr max-content;
10
10
  justify-content: space-between;
11
- gap: .5rem;
11
+ gap: 0.5rem;
12
12
  }
13
13
 
14
14
  .lunatic-roundabout__item .lunatic-errors {
@@ -17,7 +17,7 @@
17
17
 
18
18
  .lunatic-roundabout__item + .lunatic-roundabout__item {
19
19
  border-top: 1px solid var(--color-secondary-dark);
20
- padding-top: .5rem;
20
+ padding-top: 0.5rem;
21
21
  margin-top: 1rem;
22
22
  }
23
23
 
@@ -27,5 +27,5 @@
27
27
  }
28
28
  .lunatic-roundabout__button-progress,
29
29
  .lunatic-roundabout__button-progress:focus {
30
- background-color: var(--color-primary-main)
30
+ background-color: var(--color-primary-main);
31
31
  }
@@ -53,7 +53,6 @@
53
53
  min-width: 260px;
54
54
  width: 100%;
55
55
  .lunatic-suggester-content {
56
-
57
56
  &.focused {
58
57
  .lunatic-suggester-selection {
59
58
  }
@@ -107,7 +106,8 @@
107
106
  height: 0;
108
107
  opacity: 0;
109
108
  background-color: white;
110
- transition: opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
109
+ transition:
110
+ opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
111
111
  transform 178ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
112
112
  &.expended {
113
113
  border: solid 1px var(--color-primary-light);
@@ -21,10 +21,12 @@
21
21
  top: 0;
22
22
  z-index: 2;
23
23
  border-collapse: separate;
24
- background-color: #FFF;
24
+ background-color: #fff;
25
25
  // Borders does not work on position sticky element, use box-shadow to imitate border
26
- border-top: none!important;
27
- box-shadow: inset 0 1px 0 var(--color-primary-dark), inset 0 -1px 0 var(--color-primary-dark);
26
+ border-top: none !important;
27
+ box-shadow:
28
+ inset 0 1px 0 var(--color-primary-dark),
29
+ inset 0 -1px 0 var(--color-primary-dark);
28
30
  }
29
31
 
30
32
  td {
@@ -37,7 +39,7 @@
37
39
  }
38
40
  }
39
41
 
40
- .lunatic-component .table-lunatic .tooltip-lunatic img {
41
- height: 20px;
42
- width: 20px;
43
- }
42
+ .lunatic-component .table-lunatic .tooltip-lunatic img {
43
+ height: 20px;
44
+ width: 20px;
45
+ }