@arquimedes.co/eureka-forms 3.0.58-new-steps → 3.0.58-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.
- package/dist/@Types/FormStep.d.ts +2 -7
- package/dist/@Types/FormStep.js +1 -2
- package/dist/@Types/GenericFormSteps.d.ts +7 -0
- package/dist/App/App.cbr.test.js +78 -0
- package/dist/App/App.d.ts +6 -1
- package/dist/App/AppHooks.js +2 -2
- package/dist/FormSteps/CheckBoxStep/CheckBoxStep.mobileLabel.test.js +123 -0
- package/dist/FormSteps/CheckBoxStep/MaterialCheckBoxStep/MaterialCheckBoxStep.js +34 -7
- package/dist/FormSteps/CheckBoxStep/MaterialCheckBoxStep/MaterialCheckBoxStep.module.css +30 -0
- package/dist/FormSteps/MapperStep/MaterialMapperStep/Element/MapperElementComponent.js +1 -1
- package/dist/FormSteps/PhoneInputStep/MaterialTextInputStep/MaterialPhoneInputStep.js +5 -4
- package/dist/FormSteps/Step.js +4 -19
- package/dist/FormSteps/StepFunctions.d.ts +16 -1
- package/dist/FormSteps/StepFunctions.js +58 -14
- package/dist/FormSteps/StepFunctions.test.js +32 -55
- package/dist/FormSteps/TextInputStep/MaterialTextInputStep/MaterialTextInputStep.js +5 -4
- package/dist/FormSteps/TitleStep/MaterialTitleStep/MaterialTitleStep.js +4 -4
- package/dist/FormSteps/Utils/@StepFiller/StepFiller.js +5 -4
- package/dist/FormSteps/Utils/MaterialInputContainer/MaterialInputContainer.js +5 -4
- package/dist/Shared/ErkDatePicker/ErkDatePicker.js +10 -8
- package/dist/Shared/ErkDateRangePicker/ErkDateRangePicker.d.ts +3 -2
- package/dist/Shared/ErkDateRangePicker/ErkDateRangePicker.js +7 -6
- package/dist/Shared/ErkTimePicker/ErkTimePicker.js +1 -0
- package/dist/Shared/ErkTimePicker/ErkTimePicker.module.css +0 -1
- package/dist/Utils/CBRFunctions.js +4 -2
- package/dist/Utils/CBRFunctions.test.d.ts +1 -0
- package/dist/Utils/CBRFunctions.test.js +123 -0
- package/dist/Utils/MaterialProviders.js +6 -0
- package/dist/constants/FormStepTypes.d.ts +1 -5
- package/dist/constants/FormStepTypes.js +0 -4
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.js +1 -0
- package/dist/index.lib.d.ts +2 -4
- package/dist/index.lib.js +1 -3
- package/package.json +7 -8
- package/dist/@Types/AvailabilityFormStep.d.ts +0 -48
- package/dist/@Types/AvailabilityFormStep.js +0 -24
- package/dist/@Types/BankAccountFormStep.d.ts +0 -67
- package/dist/@Types/BankAccountFormStep.js +0 -14
- package/dist/@Types/BookingFormStep.d.ts +0 -166
- package/dist/@Types/BookingFormStep.js +0 -44
- package/dist/@Types/CalendarFormStep.d.ts +0 -209
- package/dist/@Types/CalendarFormStep.js +0 -55
- package/dist/@Types/CommunicationChannelFormStep.d.ts +0 -51
- package/dist/@Types/CommunicationChannelFormStep.js +0 -15
- package/dist/@Types/ConsentFormStep.d.ts +0 -36
- package/dist/@Types/ConsentFormStep.js +0 -8
- package/dist/@Types/EntityFormFormStep.d.ts +0 -66
- package/dist/@Types/EntityFormFormStep.js +0 -20
- package/dist/@Types/EventFormStep.d.ts +0 -52
- package/dist/@Types/EventFormStep.js +0 -13
- package/dist/@Types/ExternalReferenceFormStep.d.ts +0 -74
- package/dist/@Types/ExternalReferenceFormStep.js +0 -20
- package/dist/@Types/LocationFormStep.d.ts +0 -159
- package/dist/@Types/LocationFormStep.js +0 -46
- package/dist/@Types/NumericFormSteps.d.ts +0 -108
- package/dist/@Types/NumericFormSteps.js +0 -20
- package/dist/@Types/PredefinedSelectorFormStep.d.ts +0 -51
- package/dist/@Types/PredefinedSelectorFormStep.js +0 -39
- package/dist/@Types/StepRef.d.ts +0 -135
- package/dist/@Types/StepRef.js +0 -49
- package/dist/FormSteps/AvailabilityStep/AvailabilityStep.d.ts +0 -7
- package/dist/FormSteps/AvailabilityStep/AvailabilityStep.js +0 -14
- package/dist/FormSteps/AvailabilityStep/MaterialAvailabilityStep/MaterialAvailabilityStep.d.ts +0 -8
- package/dist/FormSteps/AvailabilityStep/MaterialAvailabilityStep/MaterialAvailabilityStep.js +0 -32
- package/dist/FormSteps/BookingStep/BookingStep.d.ts +0 -17
- package/dist/FormSteps/BookingStep/BookingStep.js +0 -14
- package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.d.ts +0 -7
- package/dist/FormSteps/BookingStep/MaterialBookingStep/MaterialBookingStep.js +0 -32
- package/dist/FormSteps/LocationStep/LocationStep.d.ts +0 -10
- package/dist/FormSteps/LocationStep/LocationStep.js +0 -14
- package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.d.ts +0 -3
- package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.js +0 -54
- package/dist/FormSteps/LocationStep/MaterialLocationStep/MaterialLocationStep.module.css +0 -18
- package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.d.ts +0 -3
- package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.js +0 -168
- package/dist/FormSteps/NumberStep/MaterialNumberStep/MaterialNumberStep.module.css +0 -94
- package/dist/FormSteps/NumberStep/NumberStep.d.ts +0 -10
- package/dist/FormSteps/NumberStep/NumberStep.js +0 -14
- package/dist/Icons/AddIcon.d.ts +0 -3
- package/dist/Icons/AddIcon.js +0 -7
- package/dist/Icons/EditIcon.d.ts +0 -3
- package/dist/Icons/EditIcon.js +0 -7
- package/dist/Icons/RemoveIcon.d.ts +0 -3
- package/dist/Icons/RemoveIcon.js +0 -7
- package/dist/Icons/ViewDayIcon.d.ts +0 -3
- package/dist/Icons/ViewDayIcon.js +0 -7
- package/dist/Icons/ViewWeekIcon.d.ts +0 -3
- package/dist/Icons/ViewWeekIcon.js +0 -7
- package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.d.ts +0 -19
- package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.js +0 -80
- package/dist/Shared/ErkAddressAutocomplete/ErkAddressAutocomplete.module.css +0 -82
- package/dist/Shared/ErkAddressAutocomplete/googlePlaces.d.ts +0 -29
- package/dist/Shared/ErkAddressAutocomplete/googlePlaces.js +0 -139
- package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.d.ts +0 -25
- package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.js +0 -112
- package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.module.css +0 -88
- package/dist/Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.test.js +0 -75
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.d.ts +0 -31
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.js +0 -223
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.module.css +0 -608
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.d.ts +0 -28
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.js +0 -117
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.stories.test.js +0 -49
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.test.d.ts +0 -1
- package/dist/Shared/ErkBookingPicker/ErkBookingPicker.test.js +0 -107
- package/dist/Shared/ErkIconButton/ErkIconButton.d.ts +0 -17
- package/dist/Shared/ErkIconButton/ErkIconButton.js +0 -11
- package/dist/Shared/ErkIconButton/ErkIconButton.module.css +0 -41
- package/dist/Shared/ErkLocationField/ErkLocationField.d.ts +0 -24
- package/dist/Shared/ErkLocationField/ErkLocationField.js +0 -126
- package/dist/Shared/ErkLocationField/ErkLocationField.module.css +0 -135
- package/dist/Shared/ErkLocationField/ErkLocationField.test.d.ts +0 -1
- package/dist/Shared/ErkLocationField/ErkLocationField.test.js +0 -82
- package/dist/Shared/ErkLocationField/addressFields.d.ts +0 -12
- package/dist/Shared/ErkLocationField/addressFields.js +0 -34
- package/dist/Shared/ErkLocationField/locationRestrictions.d.ts +0 -6
- package/dist/Shared/ErkLocationField/locationRestrictions.js +0 -51
- package/dist/Shared/ErkLocationInput/ErkLocationInput.d.ts +0 -15
- package/dist/Shared/ErkLocationInput/ErkLocationInput.js +0 -502
- package/dist/Shared/ErkLocationInput/ErkLocationInput.module.css +0 -115
- package/dist/Shared/ErkNumberField/ErkNumberField.d.ts +0 -42
- package/dist/Shared/ErkNumberField/ErkNumberField.js +0 -170
- /package/dist/{Shared/ErkAvailabilityPicker/ErkAvailabilityPicker.test.d.ts → App/App.cbr.test.d.ts} +0 -0
- /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
|
-
|
|
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 {};
|
package/dist/@Types/FormStep.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
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*/
|
package/dist/App/AppHooks.js
CHANGED
|
@@ -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 ?? {}),
|
|
@@ -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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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:
|
|
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:
|
|
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) {
|
|
@@ -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 {
|
|
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
|
|
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 <=
|
|
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
|
}
|
package/dist/FormSteps/Step.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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(
|
|
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 {};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NumberStepType, } from '../@Types/FormStep';
|
|
2
1
|
import FormStepTypes, { ApiSelectorOptionTypes, ClassifierOptionTypes, EntityValueDataTypes, EntityValueOptionTypes, OptionTypes, } from '../constants/FormStepTypes';
|
|
3
2
|
import CBRFormStepTypes from '../constants/CBRFormStepTypes';
|
|
4
3
|
import AYFFormStepTypes from '../constants/AYFFormStepTypes';
|
|
@@ -88,8 +87,6 @@ function recursivelyCheckOpenSize(idStep, steps, values) {
|
|
|
88
87
|
return size;
|
|
89
88
|
}
|
|
90
89
|
case FormStepTypes.DATEPICKER:
|
|
91
|
-
case FormStepTypes.LOCATION:
|
|
92
|
-
case FormStepTypes.NUMBER:
|
|
93
90
|
case FormStepTypes.TEXTINPUT: {
|
|
94
91
|
return step.size;
|
|
95
92
|
}
|
|
@@ -100,6 +97,64 @@ function recursivelyCheckOpenSize(idStep, steps, values) {
|
|
|
100
97
|
export const calcStepWidth = (stepSize, size) => {
|
|
101
98
|
return size.blockSize * stepSize + size.spacingSize * (stepSize - 1);
|
|
102
99
|
};
|
|
100
|
+
const clampSpan = (span, columns) => Math.max(1, Math.min(span, columns));
|
|
101
|
+
/**
|
|
102
|
+
* Columns the form grid has on each screen — the editor's model, mirrored so both sides agree on
|
|
103
|
+
* what fits: desktop uses the form's configured `blockNum`, tablet caps it at 2, and mobile is the
|
|
104
|
+
* single column this renderer has always collapsed to.
|
|
105
|
+
*/
|
|
106
|
+
function columnsForBreakpoint(formSize, breakpoint) {
|
|
107
|
+
switch (breakpoint) {
|
|
108
|
+
case 'desktop':
|
|
109
|
+
return formSize.blockNum;
|
|
110
|
+
case 'tablet':
|
|
111
|
+
return clampSpan(formSize.blockNum, 2);
|
|
112
|
+
case 'mobile':
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Span a step gets on a screen when it has no explicit override — the legacy model translated to
|
|
118
|
+
* the responsive one: desktop keeps the step's `size` (falling back to full width, as steps
|
|
119
|
+
* without one have always rendered), and the other screens shrink that span to fit their column
|
|
120
|
+
* count.
|
|
121
|
+
*/
|
|
122
|
+
function deriveDefaultSpan(step, breakpoint, formSize) {
|
|
123
|
+
const desktopSpan = clampSpan(step.size ?? formSize.blockNum, formSize.blockNum);
|
|
124
|
+
if (breakpoint === 'desktop')
|
|
125
|
+
return desktopSpan;
|
|
126
|
+
return clampSpan(desktopSpan, columnsForBreakpoint(formSize, breakpoint));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Maps the renderer's width model onto the editor's. The editor lays out exactly three screens,
|
|
130
|
+
* while `currentBreakPoint` counts how many columns currently fit, so the two need a bridge:
|
|
131
|
+
* `isMobile` is the editor's mobile screen, and because the editor's tablet layout is a 2-column
|
|
132
|
+
* grid (see `columnsForBreakpoint`) its overrides apply only once at most 2 columns fit.
|
|
133
|
+
* Reduced-but-wider states (e.g. 3 columns of a 4-column form) keep the desktop spans — the
|
|
134
|
+
* editor has no screen for them, and this keeps forms without overrides rendering exactly as
|
|
135
|
+
* they always have.
|
|
136
|
+
*/
|
|
137
|
+
function breakpointForWidthStats(widthStats, formSize) {
|
|
138
|
+
if (widthStats.isMobile)
|
|
139
|
+
return 'mobile';
|
|
140
|
+
if (widthStats.currentBreakPoint < formSize.blockNum && widthStats.currentBreakPoint <= 2)
|
|
141
|
+
return 'tablet';
|
|
142
|
+
return 'desktop';
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Effective column span of a step at the current width: its explicit `sizes` override for the
|
|
146
|
+
* screen when present (clamped to that screen's columns), the derived legacy default otherwise.
|
|
147
|
+
* Desktop never reads `sizes` — its source of truth stays the legacy `size` field.
|
|
148
|
+
*/
|
|
149
|
+
export function resolveStepSpan(step, widthStats, formSize) {
|
|
150
|
+
const breakpoint = breakpointForWidthStats(widthStats, formSize);
|
|
151
|
+
if (breakpoint !== 'desktop') {
|
|
152
|
+
const override = step.sizes?.[breakpoint];
|
|
153
|
+
if (override !== undefined)
|
|
154
|
+
return clampSpan(override, columnsForBreakpoint(formSize, breakpoint));
|
|
155
|
+
}
|
|
156
|
+
return deriveDefaultSpan(step, breakpoint, formSize);
|
|
157
|
+
}
|
|
103
158
|
export const calcDefaultValue = (step) => {
|
|
104
159
|
switch (step.type) {
|
|
105
160
|
case FormStepTypes.CHECKBOX:
|
|
@@ -120,17 +175,6 @@ export const calcDefaultValue = (step) => {
|
|
|
120
175
|
return getRawText();
|
|
121
176
|
else
|
|
122
177
|
return '';
|
|
123
|
-
case FormStepTypes.LOCATION:
|
|
124
|
-
return step.defaultValue ?? null;
|
|
125
|
-
case FormStepTypes.NUMBER: {
|
|
126
|
-
const numStep = step;
|
|
127
|
-
if (numStep.numberType === NumberStepType.MONEY ||
|
|
128
|
-
numStep.numberType === NumberStepType.MEASURE ||
|
|
129
|
-
numStep.numberType === NumberStepType.UNIT_PRICE) {
|
|
130
|
-
return numStep.defaultValue ?? null;
|
|
131
|
-
}
|
|
132
|
-
return numStep.defaultValue ?? '';
|
|
133
|
-
}
|
|
134
178
|
case FormStepTypes.RATING:
|
|
135
179
|
case FormStepTypes.DATEPICKER:
|
|
136
180
|
case FormStepTypes.DATEPICKER_RANGE:
|