@arquimedes.co/eureka-forms 3.0.59-new-steps → 3.0.59-test

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 (133) hide show
  1. package/dist/@Types/FormStep.d.ts +2 -7
  2. package/dist/@Types/FormStep.js +1 -2
  3. package/dist/@Types/GenericFormSteps.d.ts +7 -0
  4. package/dist/App/App.cbr.test.js +78 -0
  5. package/dist/App/App.d.ts +6 -1
  6. package/dist/App/AppHooks.js +2 -2
  7. package/dist/FormSteps/@Construction/CBRIncidentsStep/MaterialCBRIncidentsStep/Incident/Incident.js +2 -1
  8. package/dist/FormSteps/@Construction/CBRIncidentsStep/MaterialCBRIncidentsStep/Incident/Incident.module.css +1 -2
  9. package/dist/FormSteps/CheckBoxStep/CheckBoxStep.mobileLabel.test.js +123 -0
  10. package/dist/FormSteps/CheckBoxStep/MaterialCheckBoxStep/MaterialCheckBoxStep.js +34 -7
  11. package/dist/FormSteps/CheckBoxStep/MaterialCheckBoxStep/MaterialCheckBoxStep.module.css +30 -0
  12. package/dist/FormSteps/MapperStep/MaterialMapperStep/Element/MapperElementComponent.js +1 -1
  13. package/dist/FormSteps/MapperStep/MaterialMapperStep/Element/PagedMapperElement/PagedMapperElement.js +2 -1
  14. package/dist/FormSteps/MapperStep/MaterialMapperStep/Element/PagedMapperElement/PagedMapperElement.module.css +1 -2
  15. package/dist/FormSteps/MapperStep/MaterialMapperStep/Element/PillMapperElement/PillMapperElement.js +2 -0
  16. package/dist/FormSteps/MapperStep/MaterialMapperStep/Element/PillMapperElement/PillMapperElement.module.css +1 -2
  17. package/dist/FormSteps/PhoneInputStep/MaterialTextInputStep/MaterialPhoneInputStep.js +5 -4
  18. package/dist/FormSteps/Step.js +4 -19
  19. package/dist/FormSteps/StepFunctions.d.ts +16 -1
  20. package/dist/FormSteps/StepFunctions.js +58 -14
  21. package/dist/FormSteps/StepFunctions.test.js +32 -55
  22. package/dist/FormSteps/TextInputStep/MaterialTextInputStep/MaterialTextInputStep.js +5 -4
  23. package/dist/FormSteps/TitleStep/MaterialTitleStep/MaterialTitleStep.js +4 -4
  24. package/dist/FormSteps/Utils/@StepFiller/StepFiller.js +5 -4
  25. package/dist/FormSteps/Utils/MaterialInputContainer/MaterialInputContainer.js +5 -4
  26. package/dist/Shared/ErkDatePicker/ErkDatePicker.js +10 -8
  27. package/dist/Shared/ErkDateRangePicker/ErkDateRangePicker.d.ts +3 -2
  28. package/dist/Shared/ErkDateRangePicker/ErkDateRangePicker.js +7 -6
  29. package/dist/Shared/ErkTimePicker/ErkTimePicker.js +1 -0
  30. package/dist/Shared/ErkTimePicker/ErkTimePicker.module.css +0 -1
  31. package/dist/Utils/CBRFunctions.js +4 -2
  32. package/dist/Utils/CBRFunctions.test.d.ts +1 -0
  33. package/dist/Utils/CBRFunctions.test.js +123 -0
  34. package/dist/Utils/MaterialProviders.js +6 -0
  35. package/dist/Utils/SurfaceStyle.d.ts +11 -0
  36. package/dist/Utils/SurfaceStyle.js +14 -0
  37. package/dist/constants/FormStepTypes.d.ts +1 -5
  38. package/dist/constants/FormStepTypes.js +0 -4
  39. package/dist/hooks.d.ts +1 -0
  40. package/dist/hooks.js +1 -0
  41. package/dist/index.lib.d.ts +2 -4
  42. package/dist/index.lib.js +1 -3
  43. package/package.json +7 -8
  44. package/dist/@Types/AvailabilityFormStep.d.ts +0 -48
  45. package/dist/@Types/AvailabilityFormStep.js +0 -24
  46. package/dist/@Types/BankAccountFormStep.d.ts +0 -67
  47. package/dist/@Types/BankAccountFormStep.js +0 -14
  48. package/dist/@Types/BookingFormStep.d.ts +0 -166
  49. package/dist/@Types/BookingFormStep.js +0 -44
  50. package/dist/@Types/CalendarFormStep.d.ts +0 -209
  51. package/dist/@Types/CalendarFormStep.js +0 -55
  52. package/dist/@Types/CommunicationChannelFormStep.d.ts +0 -51
  53. package/dist/@Types/CommunicationChannelFormStep.js +0 -15
  54. package/dist/@Types/ConsentFormStep.d.ts +0 -36
  55. package/dist/@Types/ConsentFormStep.js +0 -8
  56. package/dist/@Types/EntityFormFormStep.d.ts +0 -66
  57. package/dist/@Types/EntityFormFormStep.js +0 -20
  58. package/dist/@Types/EventFormStep.d.ts +0 -52
  59. package/dist/@Types/EventFormStep.js +0 -13
  60. package/dist/@Types/ExternalReferenceFormStep.d.ts +0 -74
  61. package/dist/@Types/ExternalReferenceFormStep.js +0 -20
  62. package/dist/@Types/LocationFormStep.d.ts +0 -159
  63. package/dist/@Types/LocationFormStep.js +0 -46
  64. package/dist/@Types/NumericFormSteps.d.ts +0 -108
  65. package/dist/@Types/NumericFormSteps.js +0 -20
  66. package/dist/@Types/PredefinedSelectorFormStep.d.ts +0 -51
  67. package/dist/@Types/PredefinedSelectorFormStep.js +0 -39
  68. package/dist/@Types/StepRef.d.ts +0 -135
  69. package/dist/@Types/StepRef.js +0 -49
  70. package/dist/FormSteps/AvailabilityStep/AvailabilityStep.d.ts +0 -7
  71. package/dist/FormSteps/AvailabilityStep/AvailabilityStep.js +0 -14
  72. package/dist/FormSteps/AvailabilityStep/MaterialAvailabilityStep/MaterialAvailabilityStep.d.ts +0 -8
  73. package/dist/FormSteps/AvailabilityStep/MaterialAvailabilityStep/MaterialAvailabilityStep.js +0 -32
  74. package/dist/FormSteps/BookingStep/BookingStep.d.ts +0 -17
  75. package/dist/FormSteps/BookingStep/BookingStep.js +0 -14
  76. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.d.ts +0 -7
  77. package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.js +0 -32
  78. package/dist/FormSteps/LocationStep/LocationStep.d.ts +0 -10
  79. package/dist/FormSteps/LocationStep/LocationStep.js +0 -14
  80. package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.d.ts +0 -3
  81. package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.js +0 -54
  82. package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.module.css +0 -18
  83. package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.d.ts +0 -3
  84. package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.js +0 -168
  85. package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.module.css +0 -94
  86. package/dist/FormSteps/NumberStep/NumberStep.d.ts +0 -10
  87. package/dist/FormSteps/NumberStep/NumberStep.js +0 -14
  88. package/dist/Icons/AddIcon.d.ts +0 -3
  89. package/dist/Icons/AddIcon.js +0 -7
  90. package/dist/Icons/EditIcon.d.ts +0 -3
  91. package/dist/Icons/EditIcon.js +0 -7
  92. package/dist/Icons/RemoveIcon.d.ts +0 -3
  93. package/dist/Icons/RemoveIcon.js +0 -7
  94. package/dist/Icons/ViewDayIcon.d.ts +0 -3
  95. package/dist/Icons/ViewDayIcon.js +0 -7
  96. package/dist/Icons/ViewWeekIcon.d.ts +0 -3
  97. package/dist/Icons/ViewWeekIcon.js +0 -7
  98. package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.d.ts +0 -19
  99. package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.js +0 -80
  100. package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.module.css +0 -88
  101. package/dist/Shared/ErkAddressAutocomplete/googlePlaces.d.ts +0 -29
  102. package/dist/Shared/ErkAddressAutocomplete/googlePlaces.js +0 -139
  103. package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.d.ts +0 -25
  104. package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.js +0 -112
  105. package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.module.css +0 -88
  106. package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.test.js +0 -75
  107. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.d.ts +0 -31
  108. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.js +0 -223
  109. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.module.css +0 -608
  110. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.d.ts +0 -28
  111. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.js +0 -117
  112. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.test.js +0 -49
  113. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.test.d.ts +0 -1
  114. package/dist/Shared/ErkBookingPicker/ErkBookingPicker.test.js +0 -107
  115. package/dist/Shared/ErkIconButton/ErkIconButton.d.ts +0 -17
  116. package/dist/Shared/ErkIconButton/ErkIconButton.js +0 -11
  117. package/dist/Shared/ErkIconButton/ErkIconButton.module.css +0 -41
  118. package/dist/Shared/ErkLocationField/ErkLocationField.d.ts +0 -24
  119. package/dist/Shared/ErkLocationField/ErkLocationField.js +0 -128
  120. package/dist/Shared/ErkLocationField/ErkLocationField.module.css +0 -164
  121. package/dist/Shared/ErkLocationField/ErkLocationField.test.d.ts +0 -1
  122. package/dist/Shared/ErkLocationField/ErkLocationField.test.js +0 -82
  123. package/dist/Shared/ErkLocationField/addressFields.d.ts +0 -12
  124. package/dist/Shared/ErkLocationField/addressFields.js +0 -34
  125. package/dist/Shared/ErkLocationField/locationRestrictions.d.ts +0 -6
  126. package/dist/Shared/ErkLocationField/locationRestrictions.js +0 -51
  127. package/dist/Shared/ErkLocationInput/ErkLocationInput.d.ts +0 -15
  128. package/dist/Shared/ErkLocationInput/ErkLocationInput.js +0 -502
  129. package/dist/Shared/ErkLocationInput/ErkLocationInput.module.css +0 -115
  130. package/dist/Shared/ErkNumberField/ErkNumberField.d.ts +0 -42
  131. package/dist/Shared/ErkNumberField/ErkNumberField.js +0 -170
  132. /package/dist/{Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.test.d.ts → App/App.cbr.test.d.ts} +0 -0
  133. /package/dist/{Shared/ErkBookingPicker/ErkBookingPicker.stories.test.d.ts → FormSteps/CheckBoxStep/CheckBoxStep.mobileLabel.test.d.ts} +0 -0
@@ -5,13 +5,7 @@ import { EurekaDraft } from './Draft/Draft';
5
5
  import { ErkValue } from './ErkValue';
6
6
  import * as GSteps from './GenericFormSteps';
7
7
  import { Time } from './Time';
8
- import { LocationStep } from './LocationFormStep';
9
- import { NumberStep, NumberStepType } from './NumericFormSteps';
10
- import { BookingStep } from './BookingFormStep';
11
- import { CalendarStep } from './CalendarFormStep';
12
- export type { LocationStep, NumberStep, BookingStep, CalendarStep };
13
- export { NumberStepType };
14
- export type FormStep = Title | TimePicker | Rating | CheckBox | TextArea | TextInput | DatePicker | FileUpload | Separator | FormSelector | ClassifierSelector | Collapsible | EntityValuePicker | ApiSelector | Mapper | DatePickerRange | LocationStep | NumberStep | BookingStep | CalendarStep;
8
+ export type FormStep = Title | TimePicker | Rating | CheckBox | TextArea | TextInput | DatePicker | FileUpload | Separator | FormSelector | ClassifierSelector | Collapsible | EntityValuePicker | ApiSelector | Mapper | DatePickerRange;
15
9
  export interface Title extends GSteps.GBaseStep {
16
10
  type: FormStepTypes.TITLE;
17
11
  title?: EurekaDraft;
@@ -238,3 +232,4 @@ export interface Mapper extends GSteps.GBaseStep {
238
232
  deletable?: boolean;
239
233
  max?: number;
240
234
  }
235
+ export {};
@@ -1,2 +1 @@
1
- import { NumberStepType } from './NumericFormSteps';
2
- export { NumberStepType };
1
+ export {};
@@ -9,6 +9,13 @@ export interface GBaseStep {
9
9
  clientInfoType?: string;
10
10
  dependencies?: string[];
11
11
  condition?: Condition;
12
+ /**
13
+ * Per-screen column-span overrides (tablet/mobile) written by the form editor. Desktop's
14
+ * source of truth stays the step's legacy `size`, and a missing entry falls back to the span
15
+ * derived from it (see `resolveStepSpan` in FormSteps/StepFunctions), so a form with no
16
+ * explicit overrides renders exactly like the legacy shape.
17
+ */
18
+ sizes?: Partial<Record<'tablet' | 'mobile', 1 | 2 | 3 | 4>>;
12
19
  }
13
20
  export interface GTitle extends GBaseStep {
14
21
  title: string;
@@ -0,0 +1,78 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render, screen, waitFor } from '@testing-library/react';
3
+ import { describe, expect, it } from 'vitest';
4
+ import '@testing-library/jest-dom';
5
+ import App from './App';
6
+ import CBRFormStepTypes from '../constants/CBRFormStepTypes';
7
+ const INCIDENT = {
8
+ idSpaceStep: 'CBR_TIPO_ESPACIO-PYDqn',
9
+ idElementStep: 'CBR_LOCATIVAS-fp6xL',
10
+ idCommentStep: 'CBR_COMENTARIO-sQjpP',
11
+ num: 1,
12
+ };
13
+ const ID_SUB_ELEMENT_STEP = 'CBR_LOCATIVAS-G4S0r';
14
+ /** Shaped after a real posventa ticket: incidents are stored flat, keyed by generated step ids. */
15
+ const POSVENTA_VALUES = {
16
+ CBR_INCIDENCIAS: [INCIDENT],
17
+ [INCIDENT.idSpaceStep]: { id: '35365', label: 'Zona de Oficios' },
18
+ [INCIDENT.idCommentStep]: 'GRAN HUMEDAD!!!',
19
+ [INCIDENT.idElementStep]: { id: '06', label: 'CIELOS', subStep: ID_SUB_ELEMENT_STEP },
20
+ [ID_SUB_ELEMENT_STEP]: { id: '0601', label: 'Cielo Falso' },
21
+ };
22
+ const POSVENTA_FORM = {
23
+ name: 'Formulario PosVenta',
24
+ firstSection: 'FIRST',
25
+ sections: {
26
+ FIRST: { id: 'FIRST', name: '', nextSection: null, steps: ['CBR_INCIDENCIAS'] },
27
+ },
28
+ steps: {
29
+ CBR_INCIDENCIAS: {
30
+ id: 'CBR_INCIDENCIAS',
31
+ type: CBRFormStepTypes.CBR_INCIDENCIAS,
32
+ label: 'Incidencias',
33
+ description: null,
34
+ addBtnLabel: 'Agregar Incidencia',
35
+ required: true,
36
+ unitLabel: 'Incidencia',
37
+ dependencies: ['CBR_PROYECTO'],
38
+ spaceStep: {
39
+ label: 'Espacio',
40
+ description: null,
41
+ size: 1,
42
+ required: true,
43
+ showIcon: true,
44
+ searchable: true,
45
+ },
46
+ commentStep: { label: 'Comentario', description: null, size: 1, required: true },
47
+ elementStep: {
48
+ label: 'Elemento',
49
+ description: null,
50
+ size: 1,
51
+ required: true,
52
+ showIcon: true,
53
+ searchable: true,
54
+ subStep: {
55
+ label: 'Elemento Hijo',
56
+ description: null,
57
+ size: 1,
58
+ required: true,
59
+ showIcon: true,
60
+ searchable: true,
61
+ },
62
+ },
63
+ },
64
+ },
65
+ size: { blockNum: 4, blockSize: 210, spacingSize: 20 },
66
+ };
67
+ describe('CBR posventa postview', () => {
68
+ it('renders the submitted incidents read-only', async () => {
69
+ const { container } = render(_jsx(App, { formData: POSVENTA_FORM, valuesData: POSVENTA_VALUES, idOrganization: 'melendez', postview: true, internal: true, isWidget: true, editable: false }));
70
+ await waitFor(() => {
71
+ expect(container.textContent).toContain('Incidencia 1');
72
+ });
73
+ expect(container.textContent).toContain('GRAN HUMEDAD!!!');
74
+ expect(screen.getByDisplayValue('Zona de Oficios')).toBeInTheDocument();
75
+ expect(screen.getByDisplayValue('CIELOS')).toBeInTheDocument();
76
+ expect(screen.getByDisplayValue('Cielo Falso')).toBeInTheDocument();
77
+ });
78
+ });
package/dist/App/App.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Classifier, Form } from '../@Types/Form';
1
+ import { Classifier, Form, FormStyle } from '../@Types/Form';
2
2
  import './App.css';
3
3
  import { CustomStep, CustomStepProps } from '../FormSteps/CustomStep';
4
4
  import { EditorState } from 'draft-js';
@@ -17,6 +17,11 @@ export interface AppProps {
17
17
  formData?: Form;
18
18
  /** If the widget is usedInternally */
19
19
  internal?: boolean;
20
+ /**
21
+ * Overrides for the built-in internal style — only honored with `internal`, where the form's own
22
+ * style is ignored. Lets the host app (the admin) render the form in its color scheme, e.g. dark mode.
23
+ */
24
+ formStyle?: Partial<FormStyle>;
20
25
  /** If the widget is a postview (view what the user filled)*/
21
26
  postview?: boolean;
22
27
  /** If postview should only show steps with values*/
@@ -12,7 +12,7 @@ import { iterateNestedSteps } from '../FormSteps/StepFunctions';
12
12
  import { createNextState } from '@reduxjs/toolkit';
13
13
  import { BaseConfirmationMessage } from '../Contexts/FormContext';
14
14
  export const useSetupApp = (isEmbedded, props) => {
15
- const { preview, internal, postview, partial, editable, handleConfirmed, customSteps, valuesData, apiKey, formData, classifiers, idCurrentAgent, ...others } = props;
15
+ const { preview, internal, postview, partial, editable, handleConfirmed, customSteps, valuesData, apiKey, formData, classifiers, idCurrentAgent, formStyle: formStyleOverride, ...others } = props;
16
16
  const [form, setForm] = useState(undefined);
17
17
  const [organization, setOrganization] = useState(undefined);
18
18
  const dispatch = useAppDispatch();
@@ -112,7 +112,7 @@ export const useSetupApp = (isEmbedded, props) => {
112
112
  user,
113
113
  apiKey,
114
114
  formStyle: internal
115
- ? InternalFormStyle
115
+ ? { ...InternalFormStyle, ...(formStyleOverride ?? {}) }
116
116
  : {
117
117
  ...InternalFormStyle,
118
118
  ...(form?.style ?? {}),
@@ -6,6 +6,7 @@ import FormContext from '../../../../../Contexts/FormContext';
6
6
  import { useAppSelector } from '../../../../../hooks';
7
7
  import { useContext } from 'react';
8
8
  import DeleteIcon from '../../../../../Icons/DeleteIcon';
9
+ import { pillSurfaceStyle } from '../../../../../Utils/SurfaceStyle';
9
10
  function IncidentComponent({ step, incident, handleDelete, ...others }) {
10
11
  const { formStyle, postview } = useAppSelector((state) => state.global);
11
12
  const form = useContext(FormContext);
@@ -16,7 +17,7 @@ function IncidentComponent({ step, incident, handleDelete, ...others }) {
16
17
  if (incident.deleted) {
17
18
  return _jsx("div", {});
18
19
  }
19
- return (_jsx("div", { className: widthStats.isMobile || form.size.blockNum < 3 ? styles.mobileContainer : styles.container, children: _jsxs("div", { className: styles.contentContainer, style: {
20
+ return (_jsx("div", { className: widthStats.isMobile || form.size.blockNum < 3 ? styles.mobileContainer : styles.container, style: pillSurfaceStyle(formStyle), children: _jsxs("div", { className: styles.contentContainer, style: {
20
21
  width: (form.size.blockSize + form.size.spacingSize) * (form.size.blockNum - 1),
21
22
  }, children: [_jsxs("div", { className: styles.titleLbl, style: { color: formStyle.textColor }, children: [step.unitLabel + ' ' + incident.num, ":"] }), _jsx("div", { className: !others.editable || postview ? styles.disabledDeleteBtn : styles.deleteBtn, style: { color: formStyle.textColor }, onClick: () => {
22
23
  if (others.editable && !postview) {
@@ -1,7 +1,6 @@
1
1
  .container,
2
2
  .mobileContainer {
3
- background-color: #f0f0f0;
4
- border: 1px solid #d6d6d6;
3
+ border: 1px solid;
5
4
  width: fit-content;
6
5
  border-radius: 20px;
7
6
  margin-bottom: 10px;
@@ -0,0 +1,123 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import '@testing-library/jest-dom';
6
+ import { Provider } from 'react-redux';
7
+ import { useForm, FormProvider } from 'react-hook-form';
8
+ import { configureStore } from '@reduxjs/toolkit';
9
+ import { EurekaFormsReducer, defaultRootState } from '../../Utils/store';
10
+ import { RootApi } from '../../Utils/_api';
11
+ import FormStepTypes from '../../constants/FormStepTypes';
12
+ import { StoreContext } from '../../Utils/StoreContext';
13
+ import { IdFormContext } from '../../Contexts/FormContext';
14
+ import FormContext from '../../Contexts/FormContext';
15
+ import SectionContext from '../../Contexts/SectionContext';
16
+ import MaterialProviders from '../../Utils/MaterialProviders';
17
+ import InternalFormStyle from '../../constants/InternalFormStyle';
18
+ import CheckBoxStep from './CheckBoxStep';
19
+ import styles from './MaterialCheckBoxStep/MaterialCheckBoxStep.module.css';
20
+ const STORY_FORM_ID = 'STORY_FORM';
21
+ const LONG_LABEL = 'Cumplimiento de lo ofrecido frente a lo entregado en su vivienda';
22
+ const checkBoxStep = {
23
+ id: 'checkbox-step',
24
+ idSection: 'SECTION_1',
25
+ stepPath: ['checkbox-step'],
26
+ type: FormStepTypes.CHECKBOX,
27
+ label: LONG_LABEL,
28
+ description: null,
29
+ required: false,
30
+ size: 2,
31
+ };
32
+ const form = {
33
+ firstSection: 'SECTION_1',
34
+ sections: {
35
+ SECTION_1: { id: 'SECTION_1', name: 'Sección 1', steps: [], nextSection: null },
36
+ },
37
+ steps: { 'checkbox-step': { ...checkBoxStep } },
38
+ confirmationMessage: { blocks: [], entityMap: {} },
39
+ showLink: false,
40
+ size: { blockSize: 200, blockNum: 4, spacingSize: 10 },
41
+ };
42
+ function makeStore(currentBreakPoint) {
43
+ return configureStore({
44
+ reducer: { forms: EurekaFormsReducer, [RootApi.reducerPath]: RootApi.reducer },
45
+ preloadedState: {
46
+ forms: {
47
+ [STORY_FORM_ID]: {
48
+ ...defaultRootState,
49
+ widthStats: {
50
+ currentBreakPoint,
51
+ isMobile: currentBreakPoint <= checkBoxStep.size,
52
+ isResponsive: true,
53
+ },
54
+ },
55
+ },
56
+ },
57
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(RootApi.middleware),
58
+ });
59
+ }
60
+ function Harness({ currentBreakPoint }) {
61
+ const methods = useForm({ mode: 'onTouched' });
62
+ return (_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(Provider, { store: makeStore(currentBreakPoint), context: StoreContext, children: _jsx(IdFormContext.Provider, { value: STORY_FORM_ID, children: _jsx(FormContext.Provider, { value: form, children: _jsx(SectionContext.Provider, { value: "SECTION_1", children: _jsx(FormProvider, { ...methods, children: _jsx(CheckBoxStep, { step: checkBoxStep, editable: true }) }) }) }) }) }) }));
63
+ }
64
+ function getLabelDiv() {
65
+ // the leaf div holding only the label text (the wrapping column also matches by textContent)
66
+ return screen.getByText((_, element) => element?.tagName === 'DIV' &&
67
+ element.children.length === 0 &&
68
+ element.textContent === `${LONG_LABEL}:`);
69
+ }
70
+ /** Makes every element report a 2-line-clamped overflow (jsdom has no layout). */
71
+ function mockLabelOverflow() {
72
+ Object.defineProperty(HTMLElement.prototype, 'scrollHeight', {
73
+ configurable: true,
74
+ get() {
75
+ return 100;
76
+ },
77
+ });
78
+ Object.defineProperty(HTMLElement.prototype, 'clientHeight', {
79
+ configurable: true,
80
+ get() {
81
+ return 48;
82
+ },
83
+ });
84
+ }
85
+ afterEach(() => {
86
+ // remove the overflow mocks so other tests see jsdom defaults again
87
+ delete HTMLElement.prototype.scrollHeight;
88
+ delete HTMLElement.prototype.clientHeight;
89
+ });
90
+ describe('CheckBoxStep label on collapsed (mobile) breakpoints', () => {
91
+ it('wraps the label (2-line clamp) instead of single-line truncating it when the step collapses to 100% width', () => {
92
+ // breakpoint 1 <= size 2 → MaterialInputContainer renders the step at width: 100%
93
+ render(_jsx(Harness, { currentBreakPoint: 1 }));
94
+ const label = getLabelDiv();
95
+ expect(label.className).toBe(styles.clampLbl);
96
+ expect(label.className).not.toBe(styles.overflowLbl);
97
+ // the fixed desktop pixel maxWidth must not constrain the collapsed label
98
+ expect(label.style.maxWidth).toBe('');
99
+ });
100
+ it('keeps the single-line ellipsis label on desktop widths (control)', () => {
101
+ // breakpoint 4 > size 2 → the step keeps its fixed desktop width
102
+ render(_jsx(Harness, { currentBreakPoint: 4 }));
103
+ const label = getLabelDiv();
104
+ expect(label.className).toBe(styles.overflowLbl);
105
+ expect(label.style.maxWidth).not.toBe('');
106
+ expect(screen.queryByRole('button', { name: 'ver más' })).not.toBeInTheDocument();
107
+ });
108
+ it('shows no "ver más" toggle when the label fits in the clamp', () => {
109
+ // jsdom defaults: scrollHeight === clientHeight === 0 → nothing is clipped
110
+ render(_jsx(Harness, { currentBreakPoint: 1 }));
111
+ expect(screen.queryByRole('button', { name: 'ver más' })).not.toBeInTheDocument();
112
+ });
113
+ it('offers "ver más" when the clamp clips the label, and expands/collapses on click', async () => {
114
+ mockLabelOverflow();
115
+ render(_jsx(Harness, { currentBreakPoint: 1 }));
116
+ const toggle = await screen.findByRole('button', { name: 'ver más' });
117
+ await userEvent.click(toggle);
118
+ expect(getLabelDiv().className).toBe(styles.expandedLbl);
119
+ const collapseToggle = screen.getByRole('button', { name: 'ver menos' });
120
+ await userEvent.click(collapseToggle);
121
+ expect(getLabelDiv().className).toBe(styles.clampLbl);
122
+ });
123
+ });
@@ -1,14 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styles from './MaterialCheckBoxStep.module.css';
3
3
  import ErkCheckBox from '../../../Shared/ErkCheckbox/ErkCheckBox';
4
- import React, { useContext } from 'react';
4
+ import React, { useContext, useLayoutEffect, useRef, useState } from 'react';
5
5
  import StepComponent from '../../Step';
6
6
  import FormContext from '../../../Contexts/FormContext';
7
- import { useAppSelector } from '../../../hooks';
7
+ import { useAppSelector, selectWidthStats } from '../../../hooks';
8
8
  import { useFormStep } from '../../StepHooks';
9
9
  import StepFillerContainer from '../../Utils/@StepFiller/StepFiller';
10
10
  import MaterialInputContainer from '../../Utils/MaterialInputContainer/MaterialInputContainer';
11
- import { calcStepWidth } from '../../StepFunctions';
11
+ import { calcStepWidth, resolveStepSpan } from '../../StepFunctions';
12
12
  function CheckBoxStep({ step, editable }) {
13
13
  const { ref, value, onChange, error, field } = useFormStep(step, {
14
14
  defaultValue: step.defaultValue ?? false,
@@ -19,6 +19,26 @@ function CheckBoxStep({ step, editable }) {
19
19
  });
20
20
  const { formStyle, postview } = useAppSelector((state) => state.global);
21
21
  const form = useContext(FormContext);
22
+ const widthStats = useAppSelector(selectWidthStats);
23
+ const span = resolveStepSpan(step, widthStats, form.size);
24
+ // when the breakpoint collapses the step to width: 100% (see MaterialInputContainer),
25
+ // the fixed desktop pixel width no longer matches the real available space
26
+ const collapsed = widthStats.currentBreakPoint <= span;
27
+ const labelRef = useRef(null);
28
+ const [expanded, setExpanded] = useState(false);
29
+ const [clamped, setClamped] = useState(false);
30
+ useLayoutEffect(() => {
31
+ if (!collapsed || expanded)
32
+ return;
33
+ const measure = () => {
34
+ const label = labelRef.current;
35
+ if (label)
36
+ setClamped(label.scrollHeight > label.clientHeight);
37
+ };
38
+ measure();
39
+ window.addEventListener('resize', measure);
40
+ return () => window.removeEventListener('resize', measure);
41
+ }, [collapsed, expanded, step.label]);
22
42
  const renderNested = () => {
23
43
  const steps = value ? step.steps : step.uncheckedSteps;
24
44
  return (_jsx(React.Fragment, { children: steps?.map((idStep) => {
@@ -27,12 +47,19 @@ function CheckBoxStep({ step, editable }) {
27
47
  }) }));
28
48
  };
29
49
  const renderLabel = (colon = false) => {
30
- return (_jsxs("div", { className: step.size === 4 ? styles.checkboxLbl : styles.overflowLbl, style: {
31
- maxWidth: calcStepWidth(step.size, form.size) - 45,
32
- }, children: [step.label, step.required ? ' *' : '', colon ? ':' : ''] }));
50
+ const label = `${step.label}${step.required ? ' *' : ''}${colon ? ':' : ''}`;
51
+ if (!collapsed) {
52
+ return (_jsx("div", { className: span === 4 ? styles.checkboxLbl : styles.overflowLbl, style: {
53
+ maxWidth: calcStepWidth(span, form.size) - 45,
54
+ }, children: label }));
55
+ }
56
+ return (_jsxs("div", { className: styles.labelColumn, children: [_jsx("div", { ref: labelRef, className: expanded ? styles.expandedLbl : styles.clampLbl, children: label }), (clamped || expanded) && (_jsx("button", { type: "button", className: styles.toggleLbl, style: { color: formStyle.primaryColor }, onClick: (event) => {
57
+ event.stopPropagation();
58
+ setExpanded(!expanded);
59
+ }, children: expanded ? 'ver menos' : 'ver más' }))] }));
33
60
  };
34
61
  return (_jsxs(StepFillerContainer, { step: step, children: [_jsx(MaterialInputContainer, { step: step, editable: editable, maxHeight: step.size < 4, children: _jsxs("div", { className: styles.container, children: [_jsxs("div", { className: styles.labelCheckBoxContainer, style: {
35
- height: step.size < 4 ? 31 : undefined,
62
+ height: span < 4 && !collapsed ? 31 : undefined,
36
63
  minHeight: 31,
37
64
  alignItems: step.isList ? 'start' : 'center',
38
65
  }, children: [step.label && !step.isList && renderLabel(true), _jsx(ErkCheckBox, { ...field, padding: "0px", inputRef: ref, error: !!error, checked: value, onChange: onChange, "data-testid": step.id, readOnly: !editable || postview }), step.label && step.isList && renderLabel()] }), (step.description ?? !!error) && (_jsx("div", { className: styles.descriptionPar, style: {
@@ -14,6 +14,36 @@
14
14
  overflow: hidden;
15
15
  text-overflow: ellipsis;
16
16
  }
17
+ .labelColumn {
18
+ display: flex;
19
+ flex-direction: column;
20
+ align-items: flex-start;
21
+ flex: 1 1 auto;
22
+ min-width: 0;
23
+ margin-right: 10px;
24
+ margin-left: 10px;
25
+ }
26
+ .clampLbl,
27
+ .expandedLbl {
28
+ font-size: 18px;
29
+ }
30
+ .clampLbl {
31
+ display: -webkit-box;
32
+ -webkit-box-orient: vertical;
33
+ -webkit-line-clamp: 2;
34
+ line-clamp: 2;
35
+ overflow: hidden;
36
+ }
37
+ .toggleLbl {
38
+ background: none;
39
+ border: none;
40
+ padding: 0;
41
+ margin-top: 2px;
42
+ font-size: 13px;
43
+ font-weight: 700;
44
+ font-family: inherit;
45
+ cursor: pointer;
46
+ }
17
47
  .labelCheckBoxContainer {
18
48
  display: flex;
19
49
  align-items: center;
@@ -25,7 +25,7 @@ function MapperElementComponent(props) {
25
25
  const mapSubSteps = () => {
26
26
  return (_jsx(CustomContext.Provider, { value: nestedCustomContext, children: step.rootSteps.map((idSubStep) => {
27
27
  const subStep = form.steps[element.ids[idSubStep]];
28
- return (_createElement(StepComponent, { ...props, editable: editable ? (step.editable ?? true) : false, step: subStep, key: element.ids[idSubStep] }));
28
+ return (_createElement(StepComponent, { ...props, editable: editable ? (step.editable ?? true) : false, step: subStep, key: idSubStep }));
29
29
  }) }));
30
30
  };
31
31
  switch (step.style?.type) {
@@ -10,6 +10,7 @@ import DeleteIcon from '../../../../../Icons/DeleteIcon';
10
10
  import { MobileStepper, styled } from '@mui/material';
11
11
  import ArrowRightIcon from '../../../../../Icons/ArrowRightIcon';
12
12
  import ArrowLeftIcon from '../../../../../Icons/ArrowLeftIcon';
13
+ import { pillSurfaceStyle } from '../../../../../Utils/SurfaceStyle';
13
14
  function PagedMapperElement({ step, num, loading, element, children, editable, onChange, value, handleDelete, customElementModifiers, customElementRender, }) {
14
15
  const deletable = step.deletable ?? true;
15
16
  const { size } = useContext(FormContext);
@@ -77,7 +78,7 @@ function PagedMapperElement({ step, num, loading, element, children, editable, o
77
78
  const { calcName } = customElementModifiers ?? {};
78
79
  const name = calcName ? calcName(element) : step.unitLabel ? step.unitLabel + ' ' + (num + 1) : '';
79
80
  const renderElement = (renderElementButtons) => {
80
- return (_jsx("div", { className: widthStats.isMobile ? styles.mobileContainer : styles.container, ref: containerRef, children: _jsxs("div", { className: styles.contentContainer, style: {
81
+ return (_jsx("div", { className: widthStats.isMobile ? styles.mobileContainer : styles.container, style: pillSurfaceStyle(formStyle), ref: containerRef, children: _jsxs("div", { className: styles.contentContainer, style: {
81
82
  width: (size.blockSize + size.spacingSize) * (step.style?.size ?? size.blockNum - 1),
82
83
  }, children: [name && (_jsx("div", { className: styles.titleLbl, style: { color: formStyle.textColor }, children: loading ? 'Cargando...' : name + ':' })), _jsxs("div", { className: styles.btnsContainer, children: [renderElementButtons?.(element), (deletable || !element.isOriginal) && (_jsx("div", { className: !editable || postview ? styles.disabledDeleteBtn : styles.deleteBtn, style: { color: formStyle.textColor }, onClick: () => {
83
84
  if (editable && !postview) {
@@ -4,8 +4,7 @@
4
4
 
5
5
  .container,
6
6
  .mobileContainer {
7
- background-color: #f0f0f0;
8
- border: 1px solid #d6d6d6;
7
+ border: 1px solid;
9
8
  width: fit-content;
10
9
  border-radius: 20px;
11
10
  margin-bottom: 10px;
@@ -4,6 +4,7 @@ import styles from './PillMapperElement.module.css';
4
4
  import FormContext from '../../../../../Contexts/FormContext';
5
5
  import { useAppSelector } from '../../../../../hooks';
6
6
  import DeleteIcon from '../../../../../Icons/DeleteIcon';
7
+ import { pillSurfaceStyle } from '../../../../../Utils/SurfaceStyle';
7
8
  function PillMapperElement({ step, num, loading, element, children, editable, handleDelete, customElementModifiers, customElementRender, }) {
8
9
  const deletable = step.deletable ?? true;
9
10
  const { size } = useContext(FormContext);
@@ -16,6 +17,7 @@ function PillMapperElement({ step, num, loading, element, children, editable, ha
16
17
  const isDeleted = customElementModifiers?.isDeleted?.(element) ?? false;
17
18
  const renderElement = (renderElementButtons) => {
18
19
  return (_jsx("div", { className: widthStats.isMobile ? styles.mobileContainer : styles.container, style: {
20
+ ...pillSurfaceStyle(formStyle),
19
21
  opacity: isDeleted ? 0.5 : 1,
20
22
  }, children: _jsxs("div", { className: styles.contentContainer, style: {
21
23
  width: (size.blockSize + size.spacingSize) * (step.style?.size ?? size.blockNum - 1),
@@ -4,8 +4,7 @@
4
4
 
5
5
  .container,
6
6
  .mobileContainer {
7
- background-color: #f0f0f0;
8
- border: 1px solid #d6d6d6;
7
+ border: 1px solid;
9
8
  width: fit-content;
10
9
  border-radius: 20px;
11
10
  margin-bottom: 10px;
@@ -1,16 +1,17 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import styles from './MaterialPhoneInputStep.module.css';
3
- import { calcStepWidth } from '../../StepFunctions';
3
+ import { calcStepWidth, resolveStepSpan } from '../../StepFunctions';
4
4
  import { useContext } from 'react';
5
5
  import FormContext from '../../../Contexts/FormContext';
6
- import { selectBreakPoint, useAppSelector } from '../../../hooks';
6
+ import { selectWidthStats, useAppSelector } from '../../../hooks';
7
7
  import { useFormStep } from '../../StepHooks';
8
8
  import ErkPhoneInput from '../../../Shared/ErkPhoneInput/EkrPhoneInput';
9
9
  import { isEmptyPhoneNumber, isValidPhoneNumber } from '../../../Utils/PhoneFunctions';
10
10
  function PhoneInputStep({ step, editable, defaultValue = step.defaultValue }) {
11
- const currentBreakPoint = useAppSelector(selectBreakPoint);
11
+ const widthStats = useAppSelector(selectWidthStats);
12
12
  const postview = useAppSelector((state) => state.global.postview);
13
13
  const form = useContext(FormContext);
14
+ const span = resolveStepSpan(step, widthStats, form.size);
14
15
  const { ref, value, onChange, error, field } = useFormStep(step, {
15
16
  defaultValue: defaultValue ?? '',
16
17
  debounce: true,
@@ -26,7 +27,7 @@ function PhoneInputStep({ step, editable, defaultValue = step.defaultValue }) {
26
27
  },
27
28
  });
28
29
  return (_jsx("div", { className: styles.container, style: {
29
- width: currentBreakPoint <= step.size ? '100%' : calcStepWidth(step.size, form.size),
30
+ width: widthStats.currentBreakPoint <= span ? '100%' : calcStepWidth(span, form.size),
30
31
  minHeight: step.description || (!postview && editable) ? '55px' : '43px',
31
32
  }, children: _jsx(ErkPhoneInput, { ...field, value: value, inputRef: ref, error: !!error, labelMargin: 0, label: step.label, onChange: onChange, "data-testid": step.id, required: step.required, readOnly: !editable || postview, helperText: error?.message ?? step.description }) }));
32
33
  }
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import FormStepTypes from '../constants/FormStepTypes';
3
3
  import SelectorStep from './SelectorStep/SelectorStep';
4
4
  import SeparatorStep from './SeparatorStep/SeparatorStep';
@@ -24,18 +24,15 @@ import CustomContext from '../Contexts/CustomContext';
24
24
  import { selectOriginalValue, useCondition } from './StepHooks';
25
25
  import TimePickerStep from './TimePickerStep/TimePickerStep';
26
26
  import PhoneInputStep from './PhoneInputStep/PhoneInputStep';
27
- import LocationStepComponent from './LocationStep/LocationStep';
28
- import NumberStepComponent from './NumberStep/NumberStep';
29
- import BookingStepComponent from './BookingStep/BookingStep';
30
- import AvailabilityStepComponent from './AvailabilityStep/AvailabilityStep';
31
27
  function StepComponent({ step, ...props }) {
32
28
  const { postview, partial } = useAppSelector((state) => state.global);
33
29
  const { customSteps, customClientInfoStep } = useContext(CustomContext);
34
30
  const originalValue = useAppSelector((state) => selectOriginalValue(state, step));
35
- const showStep = useCondition(step.condition);
31
+ const showStep = useCondition(step?.condition);
32
+ /** A rootSteps entry with no matching step definition must not take the whole form down with it. */
36
33
  if (!step) {
37
34
  console.error('Step not found!', step);
38
- return _jsx("div", {});
35
+ return _jsx(_Fragment, {});
39
36
  }
40
37
  if (!showStep)
41
38
  return _jsx(_Fragment, {});
@@ -78,18 +75,6 @@ function StepComponent({ step, ...props }) {
78
75
  case FormStepTypes.DATEPICKER: {
79
76
  return _jsx(DatePickerStep, { ...props, step: step, editable: editable });
80
77
  }
81
- case FormStepTypes.LOCATION: {
82
- return _jsx(LocationStepComponent, { ...props, step: step, editable: editable });
83
- }
84
- case FormStepTypes.NUMBER: {
85
- return _jsx(NumberStepComponent, { ...props, step: step, editable: editable });
86
- }
87
- case FormStepTypes.BOOKING: {
88
- return _jsx(BookingStepComponent, { ...props, step: step, editable: editable });
89
- }
90
- case FormStepTypes.AVAILABILITY: {
91
- return _jsx(AvailabilityStepComponent, { ...props, step: step, editable: editable });
92
- }
93
78
  case FormStepTypes.DATEPICKER_RANGE: {
94
79
  return _jsx(DatePickerRangeStep, { ...props, step: step, editable: editable });
95
80
  }
@@ -3,11 +3,25 @@ import { ApiSelector, CheckBox, ClassifierSelector, EntityValuePicker, FormSelec
3
3
  import { AYFFormStep } from '../@Types/AYFFormStep';
4
4
  import { CBRFormStep } from '../@Types/CBRFormStep';
5
5
  import { Condition } from '../@Types/Condition';
6
- import { DependencyStore } from '../Form/Form';
6
+ import { DependencyStore, WidthStats } from '../Form/Form';
7
+ import { GBaseStep } from '../@Types/GenericFormSteps';
7
8
  import { Entity } from '../@Types/Entity';
8
9
  export type FillerSteps = FormSelector | ClassifierSelector | EntityValuePicker | ApiSelector | CheckBox;
9
10
  export declare function calcFillerSize(step: FillerSteps, steps: Record<string, FormStep>, values: Record<string, unknown>, size: FormSize): number;
10
11
  export declare const calcStepWidth: (stepSize: 1 | 2 | 3 | 4, size: FormSize) => number;
12
+ /** Column span of a step inside the form grid (the grid itself has at most 4 columns). */
13
+ export type FormSpan = 1 | 2 | 3 | 4;
14
+ /** Steps that occupy form-grid columns; content-only steps (e.g. titles) may omit `size`. */
15
+ interface SpannedStep {
16
+ size?: FormSpan;
17
+ sizes?: GBaseStep['sizes'];
18
+ }
19
+ /**
20
+ * Effective column span of a step at the current width: its explicit `sizes` override for the
21
+ * screen when present (clamped to that screen's columns), the derived legacy default otherwise.
22
+ * Desktop never reads `sizes` — its source of truth stays the legacy `size` field.
23
+ */
24
+ export declare function resolveStepSpan(step: SpannedStep, widthStats: Pick<WidthStats, 'currentBreakPoint' | 'isMobile'>, formSize: FormSize): FormSpan;
11
25
  export declare const calcDefaultValue: (step: FormStep | CBRFormStep) => any;
12
26
  export declare const iterateNestedSteps: (idStep: string, steps: Record<string, FormStep>, iteration: (step: FormStep, path: string[]) => void, path?: string[]) => void;
13
27
  /**
@@ -25,3 +39,4 @@ export declare const evaluateCondition: (condition: Condition, dependencies: Dep
25
39
  } & Record<string, any>;
26
40
  }) => boolean;
27
41
  export declare function getRelativeDate(nDays?: number, nHours?: number, nMinutes?: number, subtract?: boolean, date?: Date): Date;
42
+ export {};