Skip to content

Commit 9ed69f7

Browse files
Scheduler: Add form customization stories (#31634)
1 parent cd767d5 commit 9ed69f7

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import React from "react";
3+
import dxScheduler from "devextreme/ui/scheduler";
4+
import type { dxSchedulerOptions } from "devextreme/ui/scheduler";
5+
import { wrapDxWithReact } from "../utils";
6+
import { data, resources } from "./data";
7+
import "./form-customization.css";
8+
9+
const Scheduler = wrapDxWithReact<dxSchedulerOptions>(dxScheduler);
10+
11+
const meta: Meta<typeof Scheduler> = {
12+
title: "Components/Scheduler/Form Customization",
13+
component: Scheduler,
14+
parameters: {
15+
layout: "padded",
16+
},
17+
};
18+
19+
export default meta;
20+
21+
type Story = StoryObj<typeof Scheduler>;
22+
23+
const baseConfig = {
24+
height: 600,
25+
views: ["day", "week", "workWeek", "month"],
26+
currentView: "week",
27+
startHour: 9,
28+
currentDate: new Date(2021, 3, 29),
29+
dataSource: data,
30+
};
31+
32+
export const DefaultForm: Story = {
33+
args: {
34+
...baseConfig,
35+
resources,
36+
} as dxSchedulerOptions,
37+
};
38+
39+
interface ShowOnlySpecificItemsArgs extends dxSchedulerOptions {
40+
showSubjectGroup?: boolean;
41+
showDateGroup?: boolean;
42+
showDescriptionGroup?: boolean;
43+
showResourcesGroup?: boolean;
44+
showRecurrenceGroup?: boolean;
45+
}
46+
47+
export const ShowOnlySpecificItems: Story = {
48+
args: {
49+
showSubjectGroup: true,
50+
showDateGroup: true,
51+
showRecurrenceGroup: false,
52+
showDescriptionGroup: false,
53+
showResourcesGroup: true,
54+
...baseConfig,
55+
resources,
56+
} as ShowOnlySpecificItemsArgs,
57+
argTypes: {
58+
showSubjectGroup: {
59+
control: "boolean",
60+
},
61+
showDateGroup: {
62+
control: "boolean",
63+
},
64+
showRecurrenceGroup: {
65+
control: "boolean",
66+
},
67+
showDescriptionGroup: {
68+
control: "boolean",
69+
},
70+
showResourcesGroup: {
71+
control: "boolean",
72+
},
73+
} as Record<string, unknown>,
74+
render: (args: ShowOnlySpecificItemsArgs) => {
75+
const items: unknown[] = [];
76+
if (args.showSubjectGroup) items.push("subjectGroup");
77+
if (args.showDateGroup) items.push("dateGroup");
78+
if (args.showDescriptionGroup) items.push("descriptionGroup");
79+
if (args.showResourcesGroup) items.push("resourcesGroup");
80+
if (args.showRecurrenceGroup) items.push("recurrenceGroup");
81+
82+
return (
83+
<Scheduler
84+
{...(baseConfig as dxSchedulerOptions)}
85+
resources={resources}
86+
editing={{ form: { items } } as dxSchedulerOptions['editing']}
87+
/>
88+
);
89+
},
90+
};
91+
92+
const positions = [1, 2, 3, 4, 5];
93+
94+
interface ReorderItemsArgs extends dxSchedulerOptions {
95+
subjectGroupPosition: number;
96+
dateGroupPosition: number;
97+
descriptionGroupPosition: number;
98+
resourcesGroupPosition: number;
99+
recurrenceGroupPosition: number;
100+
}
101+
102+
export const ReorderItems: Story = {
103+
args: {
104+
subjectGroupPosition: 3,
105+
dateGroupPosition: 2,
106+
descriptionGroupPosition: 1,
107+
resourcesGroupPosition: 4,
108+
recurrenceGroupPosition: 5,
109+
...baseConfig,
110+
resources,
111+
} as ReorderItemsArgs,
112+
argTypes: {
113+
subjectGroupPosition: {
114+
control: { type: "select" },
115+
options: positions,
116+
},
117+
dateGroupPosition: {
118+
control: { type: "select" },
119+
options: positions,
120+
},
121+
descriptionGroupPosition: {
122+
control: { type: "select" },
123+
options: positions,
124+
},
125+
resourcesGroupPosition: {
126+
control: { type: "select" },
127+
options: positions,
128+
},
129+
recurrenceGroupPosition: {
130+
control: { type: "select" },
131+
options: positions,
132+
},
133+
} as Record<string, unknown>,
134+
render: (args: ReorderItemsArgs) => {
135+
const groups = [
136+
{ name: "subjectGroup", position: args.subjectGroupPosition },
137+
{ name: "dateGroup", position: args.dateGroupPosition },
138+
{ name: "descriptionGroup", position: args.descriptionGroupPosition },
139+
{ name: "resourcesGroup", position: args.resourcesGroupPosition },
140+
{ name: "recurrenceGroup", position: args.recurrenceGroupPosition },
141+
];
142+
143+
groups.sort((a, b) => a.position - b.position);
144+
const items: unknown[] = groups.map(g => g.name);
145+
146+
return (
147+
<Scheduler
148+
{...(baseConfig as dxSchedulerOptions)}
149+
resources={resources}
150+
editing={{ form: { items } } as dxSchedulerOptions['editing']}
151+
/>
152+
);
153+
},
154+
};
155+
156+
export const AddCustomItems: Story = {
157+
args: {
158+
...baseConfig,
159+
resources,
160+
"editing.form.items": [
161+
"subjectGroup",
162+
"dateGroup",
163+
{
164+
name: "likeGroup",
165+
itemType: "group",
166+
caption: "Feedback",
167+
items: [
168+
{
169+
name: "commentIcon",
170+
template: () => {
171+
const element = document.createElement("div");
172+
element.classList.add("dx-icon", "dx-icon-comment");
173+
return element;
174+
},
175+
},
176+
{
177+
itemType: "simple",
178+
editorType: "dxTextArea",
179+
name: "comments",
180+
editorOptions: {
181+
placeholder: "Your comments...",
182+
height: 100
183+
}
184+
},
185+
{
186+
name: "likeButton",
187+
itemType: "button",
188+
buttonOptions: {
189+
icon: "like",
190+
type: "success",
191+
text: "Like",
192+
onClick: () => {
193+
alert("You liked this appointment!");
194+
},
195+
},
196+
},
197+
],
198+
},
199+
],
200+
} as Record<string, unknown>,
201+
};
202+
203+
export const CustomizeExistingItems: Story = {
204+
args: {
205+
...baseConfig,
206+
resources,
207+
"editing.form.items": [
208+
{
209+
name: "subjectGroup",
210+
items: [
211+
{
212+
name: "subjectIcon",
213+
itemType: "button",
214+
buttonOptions: {
215+
elementAttr: { id: 'customize-subjectIcon', class: "scheduler-form-custom-icon-button" },
216+
icon: "floppy",
217+
stylingMode: "text",
218+
onClick: () => {
219+
alert("Subject icon clicked!");
220+
},
221+
},
222+
},
223+
{
224+
name: "subject",
225+
label: { text: "Event Title" },
226+
editorOptions: {
227+
placeholder: "Enter event title..."
228+
}
229+
},
230+
],
231+
},
232+
{
233+
name: "dateGroup",
234+
items: [
235+
{
236+
name: "startDate",
237+
label: { text: "From" },
238+
editorOptions: {
239+
width: "100%"
240+
}
241+
},
242+
{
243+
name: "endDate",
244+
label: { text: "To" },
245+
editorOptions: {
246+
width: "100%"
247+
}
248+
},
249+
{
250+
colSpan: 2,
251+
name: "allDay",
252+
label: { text: "All day event" }
253+
},
254+
],
255+
},
256+
{
257+
name: "descriptionGroup",
258+
items: [
259+
{
260+
colSpan: 2,
261+
name: "description",
262+
label: { text: "Notes" },
263+
editorOptions: {
264+
height: 120,
265+
placeholder: "Add notes about this event..."
266+
}
267+
}
268+
]
269+
},
270+
],
271+
} as Record<string, unknown>,
272+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#customize-subjectIcon,
2+
.scheduler-form-custom-icon-button {
3+
width: 18px;
4+
height: 18px;
5+
border: 0 !important;
6+
}
7+
8+
#customize-subjectIcon *,
9+
.scheduler-form-custom-icon-button * {
10+
padding: 0 !important;
11+
}

0 commit comments

Comments
 (0)