Skip to content

Commit 86b5523

Browse files
authored
feat: add background for card-layout-block (#754)
* feat: add background for card-layout-block * fix: update card layout storybook data
1 parent e4519c2 commit 86b5523

File tree

7 files changed

+234
-34
lines changed

7 files changed

+234
-34
lines changed

src/blocks/CardLayout/CardLayout.scss

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,28 @@ $block: '.#{$ns}card-layout-block';
88
margin-top: $indentSM;
99
}
1010

11+
&__content {
12+
position: relative;
13+
14+
&_with-background {
15+
padding: $indentXXXS $indentM $indentL;
16+
margin-top: $indentSM;
17+
}
18+
}
19+
20+
&__image {
21+
position: absolute;
22+
top: 0;
23+
left: 0;
24+
width: 100%;
25+
height: 100%;
26+
border-radius: 40px;
27+
28+
img {
29+
object-fit: cover;
30+
object-position: left;
31+
}
32+
}
33+
1134
@include animate-slides(#{$block}__item);
1235
}

src/blocks/CardLayout/CardLayout.tsx

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React from 'react';
22

3-
import {AnimateBlock, Title} from '../../components';
3+
import isEmpty from 'lodash/isEmpty';
4+
5+
import {AnimateBlock, BackgroundImage, Title} from '../../components';
46
import {Col, GridColumnSizesType, Row} from '../../grid';
57
import {
68
CardLayoutBlockProps as CardLayoutBlockParams,
@@ -29,19 +31,29 @@ const CardLayout: React.FC<CardLayoutBlockProps> = ({
2931
children,
3032
className,
3133
titleClassName,
32-
}) => (
33-
<AnimateBlock className={b(null, className)} animate={animated}>
34-
{(title || description) && (
35-
<Title title={title} subtitle={description} className={titleClassName} />
36-
)}
37-
<Row>
38-
{React.Children.map(children, (child, index) => (
39-
<Col key={index} sizes={colSizes} className={b('item')}>
40-
{child}
41-
</Col>
42-
))}
43-
</Row>
44-
</AnimateBlock>
45-
);
34+
background,
35+
}) => {
36+
return (
37+
<AnimateBlock className={b(null, className)} animate={animated}>
38+
{(title || description) && (
39+
<Title title={title} subtitle={description} className={titleClassName} />
40+
)}
41+
<div
42+
className={b('content', {
43+
'with-background': !isEmpty(background),
44+
})}
45+
>
46+
<BackgroundImage className={b('image')} {...background} />
47+
<Row>
48+
{React.Children.map(children, (child, index) => (
49+
<Col key={index} sizes={colSizes} className={b('item')}>
50+
{child}
51+
</Col>
52+
))}
53+
</Row>
54+
</div>
55+
</AnimateBlock>
56+
);
57+
};
4658

4759
export default CardLayout;

src/blocks/CardLayout/__stories__/CardLayout.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ import * as CardLayoutStories from './CardLayout.stories.tsx';
1515

1616
`colSizes?: Object` — more info [here](?path=/docs/documentation-types--docs#colsizes).
1717

18+
`background?: BackgroundImage` — See [background](?path=/story/components-pics-video-datalens-backgroundimage--docs&viewMode=docs) properties.
19+
1820
`children:[]` — You can add an array of any available cards here.
1921

2022
The following blocks are currently supported:
2123

2224
- [`BasicCard` — Basic card](?path=/story/components-cards-basiccard--default&viewMode=docs)
2325
- [`Price Detailed` — Pricing](?path=/story/components-cards-pricedetailed--marked-list&viewMode=docs)
2426
- [`BackgroundCard` — Background card](?path=/story/components-cards-backgroundcard--default&viewMode=docs)
27+
- [`PriceCard` — Price card](?path=/story/components-cards-pricecard--default&viewMode=docs)
2528
- [`LayoutItem` — Component part of `Layout` component, consists with `Media` and `Content`](?path=/story/components-cards-layoutitem--default&viewMode=docs)
2629
</StoryTemplate>

src/blocks/CardLayout/__stories__/CardLayout.stories.tsx

Lines changed: 124 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,7 @@ import React, {Fragment} from 'react';
33
import {Meta, StoryFn} from '@storybook/react';
44

55
import {PageConstructor} from '../../../containers/PageConstructor';
6-
import {
7-
CardLayoutBlockModel,
8-
CardLayoutBlockProps,
9-
LayoutItemModel,
10-
LayoutItemProps,
11-
SubBlockModels,
12-
} from '../../../models';
6+
import {CardLayoutBlockModel, CardLayoutBlockProps, SubBlockModels} from '../../../models';
137
import CardLayout from '../CardLayout';
148

159
import data from './data.json';
@@ -19,13 +13,72 @@ export default {
1913
component: CardLayout,
2014
} as Meta;
2115

22-
const createCardArray: (count: number, shared: LayoutItemProps) => SubBlockModels[] = (
23-
count,
24-
shared,
25-
) => Array.from({length: count}, () => ({...shared} as LayoutItemModel));
16+
const createCardArray: (
17+
count: number,
18+
shared: Omit<SubBlockModels, 'type'> & {type: string},
19+
) => SubBlockModels[] = (count, shared) =>
20+
Array.from({length: count}, () => ({...shared} as SubBlockModels));
2621

2722
const DefaultTemplate: StoryFn<CardLayoutBlockModel> = (args) => (
28-
<PageConstructor content={{blocks: [args]}} />
23+
<PageConstructor
24+
content={{
25+
blocks: [
26+
{
27+
...args,
28+
children: createCardArray(6, data.cards.basicCard),
29+
},
30+
{
31+
...args,
32+
title: 'Card layout with layout items',
33+
children: createCardArray(3, data.cards.layoutItem),
34+
},
35+
{
36+
...args,
37+
title: 'Card layout with background cards',
38+
children: createCardArray(3, data.cards.backgroundCard),
39+
},
40+
{
41+
...args,
42+
title: 'Card layout with price cards',
43+
children: [
44+
{
45+
...data.cards.priceCard,
46+
buttons: [
47+
{
48+
text: 'Button',
49+
url: 'https://example.com',
50+
width: 'max',
51+
theme: 'outlined',
52+
},
53+
],
54+
},
55+
{
56+
...data.cards.priceCard,
57+
buttons: [
58+
{
59+
text: 'Button',
60+
url: 'https://example.com',
61+
width: 'max',
62+
theme: 'action',
63+
},
64+
],
65+
},
66+
{
67+
...data.cards.priceCard,
68+
buttons: [
69+
{
70+
text: 'Button',
71+
url: 'https://example.com',
72+
width: 'max',
73+
theme: 'monochrome',
74+
},
75+
],
76+
},
77+
],
78+
},
79+
],
80+
}}
81+
/>
2982
);
3083

3184
const ColSizeTemplate: StoryFn<CardLayoutBlockModel> = (args) => (
@@ -109,13 +162,66 @@ const WithCustomIndentsTemplate: StoryFn<CardLayoutBlockModel> = ({title, ...res
109162
</Fragment>
110163
);
111164

165+
const WithBackgroundTemplate: StoryFn<CardLayoutBlockModel> = (args) => (
166+
<PageConstructor
167+
content={{
168+
blocks: [
169+
{
170+
...args,
171+
background: {
172+
src: 'https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/content-bg-img_light.png',
173+
disableCompress: true,
174+
},
175+
children: createCardArray(8, data.cards.basicCard),
176+
},
177+
{
178+
...args,
179+
title: 'Card layout with background color (basic cards)',
180+
background: {
181+
style: {
182+
backgroundColor: '#EEF2F8',
183+
},
184+
},
185+
children: createCardArray(4, data.cards.basicCard),
186+
},
187+
{
188+
...args,
189+
background: {
190+
style: {
191+
backgroundColor: '#7CCEA0',
192+
},
193+
},
194+
title: 'Card layout with background color and shadow (layout items)',
195+
description:
196+
'Three cards in a row on the desktop, three cards in a row on a tablet, one card in a row on a mobile phone.',
197+
colSizes: {
198+
all: 12,
199+
sm: 4,
200+
md: 4,
201+
},
202+
children: createCardArray(3, data.cards.layoutItem),
203+
},
204+
{
205+
...args,
206+
title: 'Card layout with background image (price cards)',
207+
background: {
208+
src: 'https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/content-bg-img_light.png',
209+
disableCompress: true,
210+
},
211+
children: createCardArray(4, data.cards.priceCard),
212+
},
213+
],
214+
}}
215+
/>
216+
);
217+
112218
export const Default = DefaultTemplate.bind({});
113219
export const ColSize = ColSizeTemplate.bind({});
114220
export const WithCustomIndents = WithCustomIndentsTemplate.bind({});
221+
export const WithBackground = WithBackgroundTemplate.bind({});
115222

116223
Default.args = {
117224
...data.default.content,
118-
children: createCardArray(6, data.default.card),
119225
} as CardLayoutBlockProps;
120226

121227
ColSize.args = {
@@ -125,5 +231,9 @@ ColSize.args = {
125231

126232
WithCustomIndents.args = {
127233
...data.default.content,
128-
children: createCardArray(3, data.default.card),
234+
children: createCardArray(3, data.cards.layoutItem),
235+
} as CardLayoutBlockProps;
236+
237+
WithBackground.args = {
238+
...data.withBackground.content,
129239
} as CardLayoutBlockProps;

src/blocks/CardLayout/__stories__/data.json

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,54 @@
11
{
2-
"default": {
3-
"card": {
2+
"cards": {
3+
"basicCard": {
4+
"type": "basic-card",
5+
"title": "Tell a story and build a narrative",
6+
"text": "We are all storytellers. Stories are a powerful way to communicate ideas and share information. The right story can lead to a better understanding of a situation, make us laugh, or even inspire us to do something in the future.",
7+
"icon": "https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/icon_1_light.svg"
8+
},
9+
"layoutItem": {
410
"type": "layout-item",
511
"media": {
612
"image": "https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/img-mini_4-12_light.png"
713
},
814
"content": {
9-
"title": "Lorem&nbsp;ipsum",
10-
"text": "Dolor sit amet"
15+
"title": "Tell a story and build a narrative",
16+
"text": "We are all storytellers. Stories are a powerful way to communicate ideas and share information. The right story can lead to a better understanding of a situation, make us laugh, or even inspire us to do something in the future."
17+
}
18+
},
19+
"backgroundCard": {
20+
"type": "background-card",
21+
"title": "Tell a story and build a narrative",
22+
"text": "We are all storytellers. Stories are a powerful way to communicate ideas and share information. The right story can lead to a better understanding of a situation, make us laugh, or even inspire us to do something in the future.",
23+
"background": {
24+
"light": {
25+
"src": "https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/img-bg_nopadding_4-12_light.png",
26+
"alt": "Lorem ipsumt",
27+
"disableCompress": true
28+
},
29+
"dark": {
30+
"src": "https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/img-bg_nopadding_4-12_dark.png",
31+
"alt": "Lorem ipsumt"
32+
}
1133
}
1234
},
35+
"priceCard": {
36+
"type": "price-card",
37+
"title": "Lorem ipsum",
38+
"price": "299.99 $",
39+
"pricePeriod": "month",
40+
"priceDetails": "plan details",
41+
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
42+
"list": [
43+
"Ut enim ad minim veniam exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
44+
"Ut enim ad minim veniam exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
45+
]
46+
}
47+
},
48+
"default": {
1349
"content": {
1450
"type": "card-layout-block",
15-
"title": "Card Layout",
51+
"title": "Card layout with basic cards",
1652
"description": "Three cards in a row on the desktop, two cards in a row on a tablet, one card in a row on a mobile phone."
1753
}
1854
},
@@ -51,5 +87,18 @@
5187
"all": 6
5288
}
5389
}
90+
},
91+
"withBackground": {
92+
"content": {
93+
"type": "card-layout-block",
94+
"title": "Card layout with background image (basic cards)",
95+
"description": "Four cards in a row on the desktop, three cards in a row on the mini-desktop, two cards in a row on a tablet, one card in a row on a mobile phone.",
96+
"colSizes": {
97+
"all": 12,
98+
"sm": 6,
99+
"md": 4,
100+
"lg": 3
101+
}
102+
}
54103
}
55104
}

src/blocks/CardLayout/schema.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {ImageObjectProps} from '../../components/Image/schema';
12
import {
23
AnimatableProps,
34
BlockBaseProps,
@@ -14,6 +15,7 @@ export const CardLayoutProps = {
1415
...AnimatableProps,
1516
...BlockHeaderProps,
1617
colSizes: containerSizesObject,
18+
background: ImageObjectProps,
1719
children: ChildrenCardsProps,
1820
},
1921
};

src/models/constructor-items/blocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ export interface CardLayoutBlockProps extends Childable, Animatable, LoadableChi
305305
titleClassName?: string;
306306
description?: string;
307307
colSizes?: GridColumnSizesType;
308+
background?: BackgroundImageProps;
308309
}
309310

310311
export type FilterTag = {

0 commit comments

Comments
 (0)