Skip to content

Commit a6910f3

Browse files
authored
CardView: add playground story for card (AYjGnfon) (DevExpress#29757)
1 parent 686a960 commit a6910f3

File tree

4 files changed

+192
-0
lines changed

4 files changed

+192
-0
lines changed
7.14 KB
Loading
314 KB
Loading
191 KB
Loading
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import type {Meta, StoryObj} from "@storybook/react";
2+
3+
import dxCardView from "devextreme/ui/card_view";
4+
import {wrapDxWithReact} from "../utils";
5+
import Button from "devextreme/ui/button";
6+
7+
const CardView = wrapDxWithReact(dxCardView);
8+
9+
const imageTypes = ['none', 'placeholder', 'small', 'wide', 'tall'] as const
10+
type ImageType = typeof imageTypes[number];
11+
12+
interface HumanReadableProps {
13+
headerShowCheckBox: boolean;
14+
headerShowEditingButton: boolean;
15+
headerShowDeleteButton: boolean;
16+
headerShowCardTitle: boolean;
17+
image: ImageType;
18+
cardFields: Record<string, string>,
19+
showCardFooterTemplate: boolean,
20+
}
21+
22+
const DEFAULT_PROPS = {
23+
keyExpr: 'id',
24+
toolbar: {
25+
visible: false,
26+
},
27+
headerPanel: {
28+
visible: false,
29+
},
30+
}
31+
32+
const CARD_TEXT_TITLE_TEMPLATE = () => {
33+
const container = document.createElement('div');
34+
35+
container.innerText = 'Card Header';
36+
container.style.fontWeight = '600';
37+
container.style.fontSize = '16px';
38+
container.style.lineHeight = '20px';
39+
40+
return container;
41+
}
42+
43+
const CARD_FOOTER_TEMPLATE = () => {
44+
const container = document.createElement('div');
45+
container.style.display = 'flex';
46+
container.style.justifyContent = 'space-evenly';
47+
container.style.padding = '8px';
48+
container.style.gap = '8px';
49+
50+
const button1 = document.createElement('div');
51+
const button2 = document.createElement('div');
52+
53+
container.append(button1, button2);
54+
55+
new Button(button1, {text: 'button 1', type: 'default', width: '100%'});
56+
new Button(button2, {text: 'button 2', type: 'default', width: '100%'});
57+
58+
return container;
59+
};
60+
61+
const setImageProps = (
62+
props: Record<string, any>,
63+
image: ImageType,
64+
): void => {
65+
switch (image) {
66+
case 'placeholder':
67+
props.cardCover = {imageExpr: 'image'};
68+
return;
69+
case 'small':
70+
props.cardCover = {imageExpr: () => 'images/card_view/cat_small_crop.jpg'};
71+
return;
72+
case 'wide':
73+
props.cardCover = {
74+
imageExpr: () => 'images/card_view/cat_wide.jpg',
75+
};
76+
return;
77+
case 'tall':
78+
props.cardCover = {imageExpr: () => 'images/card_view/cat_tall.jpg'};
79+
return;
80+
case 'none':
81+
default:
82+
props.cardCover = undefined;
83+
return;
84+
}
85+
}
86+
87+
const mergeProps = (
88+
humanReadableProps: HumanReadableProps,
89+
defaultProps: Record<PropertyKey, any>,
90+
): Record<PropertyKey, any> => {
91+
const result = {...defaultProps};
92+
const {
93+
headerShowCheckBox,
94+
headerShowEditingButton,
95+
headerShowDeleteButton,
96+
headerShowCardTitle,
97+
image,
98+
cardFields,
99+
showCardFooterTemplate
100+
} = humanReadableProps;
101+
102+
result.dataSource = [cardFields];
103+
104+
result.selection = {
105+
mode: headerShowCheckBox ? 'multiple' : 'none'
106+
}
107+
108+
result.editing = {
109+
allowUpdating: headerShowEditingButton,
110+
allowDeleting: headerShowDeleteButton,
111+
}
112+
113+
result.cardHeader = headerShowCardTitle
114+
? {
115+
items: [
116+
{
117+
location: 'before',
118+
template: CARD_TEXT_TITLE_TEMPLATE,
119+
},
120+
]
121+
}
122+
: undefined;
123+
124+
setImageProps(result, image);
125+
126+
result.cardFooterTemplate = showCardFooterTemplate
127+
? CARD_FOOTER_TEMPLATE
128+
: undefined;
129+
130+
return result;
131+
}
132+
133+
const CardViewHumanReadableWrapper = (
134+
humanReadableProps: HumanReadableProps,
135+
) => {
136+
const props = mergeProps(humanReadableProps, DEFAULT_PROPS);
137+
return CardView(props);
138+
}
139+
140+
const meta: Meta<typeof CardView> = {
141+
title: "Grids/CardView/Card",
142+
component: CardViewHumanReadableWrapper,
143+
argTypes: {
144+
headerShowCheckBox: {
145+
control: 'boolean',
146+
},
147+
headerShowEditingButton: {
148+
control: 'boolean'
149+
},
150+
headerShowDeleteButton: {
151+
control: 'boolean',
152+
},
153+
headerShowCardTitle: {
154+
control: 'boolean',
155+
},
156+
image: {
157+
control: 'select',
158+
options: imageTypes,
159+
},
160+
cardFields: {
161+
control: 'object',
162+
},
163+
showCardFooterTemplate: {
164+
control: 'boolean',
165+
},
166+
}
167+
};
168+
169+
export default meta;
170+
171+
type Story = StoryObj<typeof CardView>;
172+
173+
export const Playground: Story = {
174+
args: {
175+
headerShowCheckBox: true,
176+
headerShowEditingButton: true,
177+
headerShowDeleteButton: true,
178+
headerShowCardTitle: true,
179+
image: 'none',
180+
cardFields: {
181+
id: 0,
182+
firstName: 'John',
183+
lastName: 'Smith',
184+
185+
gender: 'Male',
186+
birthDate: '1983/11/07',
187+
},
188+
// TODO: Check, template rendered twice on first render
189+
showCardFooterTemplate: false,
190+
}
191+
}
192+

0 commit comments

Comments
 (0)