Skip to content

Commit 83617c9

Browse files
authored
feat: add an icon position on the left side of a basic-card (#481)
* feat: add an icon position on the left side of a basic-card
1 parent ef5f194 commit 83617c9

File tree

6 files changed

+86
-17
lines changed

6 files changed

+86
-17
lines changed

src/models/constructor-items/sub-blocks.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export enum SubBlockType {
4040
Card = 'card',
4141
}
4242

43+
export enum IconPosition {
44+
Top = 'top',
45+
Left = 'left',
46+
}
47+
4348
export const SubBlockTypes = Object.values(SubBlockType);
4449

4550
export interface DividerProps {
@@ -108,6 +113,7 @@ export interface BasicCardProps
108113
url: string;
109114
icon?: ImageProps;
110115
target?: string;
116+
iconPosition?: IconPosition;
111117
}
112118

113119
export interface BannerCardProps {

src/sub-blocks/BasicCard/BasicCard.scss

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,45 @@
44
$block: '.#{$ns}basic-card';
55

66
#{$block} {
7+
$iconSizePositionTop: 32px;
8+
$iconSizePositionLeft: 22px;
9+
710
@include add-specificity(&) {
811
min-height: auto;
912
}
1013

1114
&__icon {
1215
max-width: 100%;
1316
margin-bottom: $indentXXS;
14-
height: 32px;
17+
height: $iconSizePositionTop;
1518
object-fit: contain;
1619
display: block;
20+
21+
&_icon-position {
22+
&_left {
23+
height: $iconSizePositionLeft;
24+
width: $iconSizePositionLeft;
25+
margin: 1px $indentXXS 1px 0px;
26+
}
27+
}
28+
}
29+
30+
&__content {
31+
display: flex;
32+
flex-direction: column;
33+
34+
&_icon-position {
35+
&_left {
36+
flex-direction: row;
37+
}
38+
}
39+
}
40+
41+
&_content-layout {
42+
&_left {
43+
@include add-specificity(&) {
44+
flex: 1 0 0;
45+
}
46+
}
1747
}
1848
}

src/sub-blocks/BasicCard/BasicCard.tsx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,47 @@ import CardBase from '../../components/CardBase/CardBase';
55
import Image from '../../components/Image/Image';
66
import {getMediaImage} from '../../components/Media/Image/utils';
77
import {BasicCardProps} from '../../models';
8+
import {IconPosition} from '../../models/constructor-items/sub-blocks';
89
import {block} from '../../utils';
910

1011
import './BasicCard.scss';
1112

1213
const b = block('basic-card');
1314

1415
const BasicCard = (props: BasicCardProps) => {
15-
const {title, text, icon, additionalInfo, links, buttons, ...cardParams} = props;
16+
const {
17+
title,
18+
text,
19+
icon,
20+
additionalInfo,
21+
links,
22+
buttons,
23+
iconPosition = IconPosition.Top,
24+
...cardParams
25+
} = props;
1626
const iconProps = icon && getMediaImage(icon);
1727

1828
return (
1929
<CardBase className={b()} {...cardParams}>
2030
<CardBase.Content>
21-
{iconProps && <Image {...iconProps} className={b('icon')} />}
22-
<Content
23-
title={title}
24-
text={text}
25-
additionalInfo={additionalInfo}
26-
links={links}
27-
buttons={buttons}
28-
colSizes={{all: 12, md: 12}}
29-
size="s"
30-
/>
31+
<div className={b('content', {['icon-position']: iconPosition})}>
32+
{iconProps && (
33+
<Image
34+
{...iconProps}
35+
className={b('icon', {['icon-position']: iconPosition})}
36+
/>
37+
)}
38+
<Content
39+
title={title}
40+
text={text}
41+
additionalInfo={additionalInfo}
42+
links={links}
43+
buttons={buttons}
44+
colSizes={{all: 12, md: 12}}
45+
size="s"
46+
className={b({['content-layout']: iconPosition})}
47+
/>
48+
</div>
3149
</CardBase.Content>
3250
</CardBase>
3351
);

src/sub-blocks/BasicCard/__stories__/BasicCard.stories.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ import yfm from '@doc-tools/transform';
44
import {Meta, StoryFn} from '@storybook/react';
55

66
import {BasicCardProps} from '../../../models';
7+
import {IconPosition} from '../../../models/constructor-items/sub-blocks';
78
import BasicCard from '../BasicCard';
89

910
import data from './data.json';
1011

1112
const getCardWithBorderTitle = (border: string) =>
1213
data.withBorder.title.replace('{{border}}', border);
1314

15+
const getCardWithIconTitle = (border: string) =>
16+
data.withIcon.title.replace('{{position}}', border);
17+
1418
export default {
1519
component: BasicCard,
1620
title: 'Components/Cards/BasicCard',
@@ -25,13 +29,19 @@ const DefaultTemplate: StoryFn<BasicCardProps> = (args) => (
2529
const WithIconTemplate: StoryFn<BasicCardProps> = (args) => (
2630
<div style={{display: 'flex'}}>
2731
<div style={{maxWidth: '400px', padding: '0 8px'}}>
28-
<BasicCard {...args} icon={data.withIcon.icons[0]} />
29-
</div>
30-
<div style={{maxWidth: '400px', padding: '0 8px'}}>
31-
<BasicCard {...args} icon={data.withIcon.icons[1]} />
32+
<BasicCard
33+
{...args}
34+
icon={data.withIcon.icons[0]}
35+
title={getCardWithIconTitle('top')}
36+
/>
3237
</div>
3338
<div style={{maxWidth: '400px', padding: '0 8px'}}>
34-
<BasicCard {...args} icon={data.withIcon.icons[2]} />
39+
<BasicCard
40+
{...args}
41+
icon={data.withIcon.icons[1]}
42+
iconPosition={IconPosition.Left}
43+
title={getCardWithIconTitle('left')}
44+
/>
3545
</div>
3646
</div>
3747
);

src/sub-blocks/BasicCard/__stories__/data.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"withIcon": {
3+
"title": "Card with icon on {{position}}",
34
"icons": [
45
"https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/icon_1_light.svg",
56
"https://storage.yandexcloud.net/cloud-www-assets/constructor/storybook/images/icon_2_light.svg",

src/sub-blocks/BasicCard/schema.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ export const BasicCard = {
2222
type: 'string',
2323
enum: ['_blank', '_parent', '_top', '_self'],
2424
},
25+
iconPosition: {
26+
type: 'string',
27+
enum: ['top', 'left'],
28+
},
2529
},
2630
},
2731
};

0 commit comments

Comments
 (0)