Skip to content

Commit 7ae06d4

Browse files
Scheduler New Form — Fix slide animation overlapping items outside mainGroup
1 parent 5edd04b commit 7ae06d4

6 files changed

Lines changed: 87 additions & 2 deletions

File tree

apps/react-storybook/stories/scheduler/SchedulerFormCustomization.stories.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,40 @@ export const ResourcesColumnLayout: Story = {
383383
},
384384
};
385385

386+
export const CustomItemBeforeMainGroup: Story = {
387+
args: {
388+
...baseConfig,
389+
resources,
390+
},
391+
argTypes: iconsShowModeArgType,
392+
render: (args) => {
393+
return (
394+
<Scheduler
395+
{...baseConfig}
396+
resources={resources}
397+
editing={{
398+
form: {
399+
items: [
400+
{
401+
name: "customNotice",
402+
template: () => {
403+
const element = document.createElement("div");
404+
element.className = "custom-form-notice";
405+
element.textContent = "This is a custom element placed before mainGroup. The slide animation should not overlap this area.";
406+
return element;
407+
},
408+
},
409+
"mainGroup",
410+
"recurrenceGroup",
411+
],
412+
iconsShowMode: args["editing.form.iconsShowMode"],
413+
},
414+
} as Properties["editing"]}
415+
/>
416+
);
417+
},
418+
};
419+
386420
export const RTL: Story = {
387421
args: {
388422
...baseConfig,

apps/react-storybook/stories/scheduler/form-customization.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,13 @@
99
.scheduler-form-custom-icon-button * {
1010
padding: 0 !important;
1111
}
12+
13+
.custom-form-notice {
14+
background: #fce4e4;
15+
border: 1px solid #e0a0a0;
16+
border-radius: 4px;
17+
padding: 8px 12px;
18+
color: #8b3a3a;
19+
font-size: 13px;
20+
line-height: 1.4;
21+
}

packages/devextreme-scss/scss/widgets/base/scheduler/_index.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ $scheduler-appointment-form-label-padding: 20px;
486486
&.dx-scheduler-form-main-group-hidden {
487487
transform: translateX(-110%);
488488
position: absolute;
489-
top: 0;
489+
top: var(--dx-scheduler-animation-top, 0);
490490
}
491491
}
492492

@@ -499,7 +499,7 @@ $scheduler-appointment-form-label-padding: 20px;
499499
&.dx-scheduler-form-recurrence-group-hidden {
500500
transform: translateX(110%);
501501
position: absolute;
502-
top: 0;
502+
top: var(--dx-scheduler-animation-top, 0);
503503
}
504504
}
505505

packages/devextreme/js/__internal/scheduler/__tests__/__mock__/m_mock_scheduler.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ export const setupSchedulerTestEnvironment = ({
5858
y: 0,
5959
toJSON: (): void => {},
6060
};
61+
case classList.includes('dx-scheduler-form-main-group'):
62+
return {
63+
width: 0,
64+
height: 0,
65+
top: 50,
66+
left: 0,
67+
bottom: 50,
68+
right: 0,
69+
x: 0,
70+
y: 50,
71+
toJSON: (): void => {},
72+
};
6173
default:
6274
return {
6375
width: 0,

packages/devextreme/js/__internal/scheduler/appointment_popup/appointment_popup.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,18 @@ describe('Appointment Form', () => {
15941594
expect(document.activeElement).toBe(frequencyEditorInputElement);
15951595
});
15961596
});
1597+
1598+
it('should set animation offset CSS variable when switching to recurrence form', async () => {
1599+
const { scheduler, POM } = await createScheduler(getDefaultConfig());
1600+
1601+
scheduler.showAppointmentPopup();
1602+
1603+
POM.popup.selectRepeatValue('weekly');
1604+
1605+
const formElement = POM.popup.dxForm.$element()[0];
1606+
const animationTop = formElement.style.getPropertyValue('--dx-scheduler-animation-top');
1607+
expect(animationTop).toBe('50px');
1608+
});
15971609
});
15981610

15991611
describe('firstDayOfWeek', () => {

packages/devextreme/js/__internal/scheduler/appointment_popup/m_form.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ export class AppointmentForm {
927927
}
928928

929929
this._popup.updateToolbarForRecurrenceGroup();
930+
this.updateAnimationOffset();
930931

931932
const currentHeight = this.dxPopup.option('height') as string | number | undefined;
932933

@@ -1065,6 +1066,22 @@ export class AppointmentForm {
10651066
this.dxForm.endUpdate();
10661067
}
10671068

1069+
private updateAnimationOffset(): void {
1070+
if (!this._$mainGroup) {
1071+
return;
1072+
}
1073+
1074+
const formElement = this.dxForm.$element()[0];
1075+
const mainGroupElement = this._$mainGroup[0];
1076+
1077+
if (formElement && mainGroupElement) {
1078+
const formRect = formElement.getBoundingClientRect();
1079+
const groupRect = mainGroupElement.getBoundingClientRect();
1080+
const topOffset = groupRect.top - formRect.top;
1081+
formElement.style.setProperty('--dx-scheduler-animation-top', `${topOffset}px`);
1082+
}
1083+
}
1084+
10681085
private focusFirstFocusableInGroup($group: dxElementWrapper): void {
10691086
const focusTarget = $group.find(`.${CLASSES.fieldItemContent} [tabindex]`).first().get(0) as HTMLElement;
10701087
focusTarget?.focus({ preventScroll: true });

0 commit comments

Comments
 (0)