Skip to content

Commit

Permalink
feat(ImageCard): add contentPosition (#919)
Browse files Browse the repository at this point in the history
+ generalize contentPosition behavior for all cards
  • Loading branch information
DC-RomanKarpov authored Apr 15, 2024
1 parent 3caa964 commit 7df0d3a
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 83 deletions.
10 changes: 4 additions & 6 deletions src/components/IconWrapper/IconWrapper.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ $block: '.#{$ns}icon-wrapper';
}
}

&_content {
&_left {
@include add-specificity(&) {
flex: 1 0 0;
}
}
&__content {
display: flex;
flex-direction: column;
flex: 1 0 auto;
}
}
10 changes: 5 additions & 5 deletions src/components/IconWrapper/IconWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {Fragment, PropsWithChildren} from 'react';

import {IconWrapperProps} from '../../models';
import type {ClassNameProps, IconWrapperProps} from '../../models';
import {block} from '../../utils';
import Image from '../Image/Image';
import {getMediaImage} from '../Media/Image/utils';
Expand All @@ -9,8 +9,8 @@ import './IconWrapper.scss';

const b = block('icon-wrapper');

const IconWrapper = (props: PropsWithChildren<IconWrapperProps>) => {
const {icon, children} = props;
const IconWrapper = (props: PropsWithChildren<IconWrapperProps> & ClassNameProps) => {
const {icon, children, className} = props;
if (!icon) {
return <Fragment>{children}</Fragment>;
}
Expand All @@ -19,15 +19,15 @@ const IconWrapper = (props: PropsWithChildren<IconWrapperProps>) => {
const iconPosition = icon?.position;

return (
<div className={b({['icon-position']: iconPosition})}>
<div className={b({['icon-position']: iconPosition}, className)}>
{iconProps && (
<Image
{...iconProps}
containerClassName={b('icon-container')}
className={b('icon', {['icon-position']: iconPosition})}
/>
)}
<div className={b({['content']: iconPosition})}>{children}</div>
<div className={b('content')}>{children}</div>
</div>
);
};
Expand Down
1 change: 1 addition & 0 deletions src/models/constructor-items/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ export interface ContentBlockProps {
centered?: boolean;
theme?: ContentTheme;
list?: ContentItemProps[];
controlPosition?: 'default' | 'bottom';
}

export enum PCShareSocialNetwork {
Expand Down
6 changes: 3 additions & 3 deletions src/models/constructor-items/sub-blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export interface BackgroundCardProps
extends CardBaseProps,
AnalyticsEventsBase,
CardLayoutProps,
Omit<ContentBlockProps, 'colSizes' | 'centered'> {
Omit<ContentBlockProps, 'colSizes' | 'centered' | 'controlPosition'> {
url?: string;
urlTitle?: string;
background?: ThemeSupporting<ImageObjectProps>;
Expand All @@ -146,7 +146,7 @@ export interface BasicCardProps
extends CardBaseProps,
AnalyticsEventsBase,
CardLayoutProps,
Omit<ContentBlockProps, 'colSizes' | 'centered' | 'size' | 'theme'> {
Omit<ContentBlockProps, 'colSizes' | 'centered' | 'size' | 'theme' | 'controlPosition'> {
url: string;
urlTitle?: string;
icon?: ImageProps;
Expand Down Expand Up @@ -191,7 +191,7 @@ export interface LayoutItemProps extends ClassNameProps, CardLayoutProps, Analyt
export interface ImageCardProps
extends CardBaseProps,
CardLayoutProps,
Omit<ContentBlockProps, 'colSizes' | 'centered'> {
Omit<ContentBlockProps, 'colSizes' | 'centered' | 'controlPosition'> {
image: ImageProps;
enableImageBorderRadius?: boolean;
margins?: ImageCardMargins;
Expand Down
7 changes: 7 additions & 0 deletions src/schema/validators/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ export const BaseProps = {
},
};

export const CardLayoutProps = {
controlPosition: {
type: 'string',
enum: ['content', 'footer'],
},
};

export const containerSizesObject = {
type: 'object',
additionalProperties: false,
Expand Down
13 changes: 4 additions & 9 deletions src/sub-blocks/BackgroundCard/BackgroundCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ $block: '.#{$ns}background-card';
border: none;
}

&__content {
display: flex;
}

&__image {
position: absolute;
top: 0;
Expand All @@ -55,15 +59,6 @@ $block: '.#{$ns}background-card';
object-position: left;
}
}

&__footer {
margin-top: 0px;
}

&__links,
&__buttons {
margin-top: $indentXS;
}
}

a#{$block} {
Expand Down
19 changes: 5 additions & 14 deletions src/sub-blocks/BackgroundCard/BackgroundCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import {useUniqId} from '@gravity-ui/uikit';

import {BackgroundImage, Buttons, CardBase, Links} from '../../components/';
import {BackgroundImage, CardBase} from '../../components/';
import {useTheme} from '../../context/theme';
import {BackgroundCardProps} from '../../models';
import {block, getThemedValue} from '../../utils';
Expand Down Expand Up @@ -41,6 +41,7 @@ const BackgroundCard = (props: BackgroundCardProps) => {
return (
<CardBase
className={b({padding: paddingBottom, theme: cardTheme})}
contentClassName={b('content')}
url={url}
border={borderType}
analyticsEvents={analyticsEvents}
Expand All @@ -59,23 +60,13 @@ const BackgroundCard = (props: BackgroundCardProps) => {
additionalInfo={additionalInfo}
size="s"
theme={cardTheme}
links={areControlsInFooter ? undefined : links}
buttons={areControlsInFooter ? undefined : buttons}
links={links}
buttons={buttons}
list={list}
colSizes={{all: 12, md: 12}}
controlPosition={areControlsInFooter ? 'bottom' : 'default'}
/>
</CardBase.Content>
{areControlsInFooter && (links || buttons) && (
<CardBase.Footer>
<Links className={b('links')} size="s" links={links} titleId={titleId} />
<Buttons
className={b('buttons')}
size="s"
buttons={buttons}
titleId={titleId}
/>
</CardBase.Footer>
)}
</CardBase>
);
};
Expand Down
5 changes: 3 additions & 2 deletions src/sub-blocks/BackgroundCard/schema.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import omit from 'lodash/omit';

import {ImageObjectProps} from '../../components/Image/schema';
import {BaseProps, CardBase, withTheme} from '../../schema/validators/common';
import {BaseProps, CardBase, CardLayoutProps, withTheme} from '../../schema/validators/common';
import {AnalyticsEventSchema} from '../../schema/validators/event';
import {ContentBase} from '../Content/schema';

const BackgroundCardContentProps = omit(ContentBase, ['size']);
const BackgroundCardContentProps = omit(ContentBase, ['size', 'controlPosition']);

export const BackgroundCard = {
'background-card': {
Expand All @@ -14,6 +14,7 @@ export const BackgroundCard = {
properties: {
...BaseProps,
...CardBase,
...CardLayoutProps,
...BackgroundCardContentProps,
url: {
type: 'string',
Expand Down
9 changes: 4 additions & 5 deletions src/sub-blocks/BasicCard/BasicCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ $block: '.#{$ns}basic-card';
min-height: auto;
}

&__footer {
margin-top: 0px;
&__content {
display: flex;
}

&__links,
&__buttons {
margin-top: $indentXS;
&__wrapper {
flex: auto;
}
}
24 changes: 9 additions & 15 deletions src/sub-blocks/BasicCard/BasicCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import {useUniqId} from '@gravity-ui/uikit';

import {Buttons, CardBase, IconWrapper, Links} from '../../components';
import {CardBase, IconWrapper} from '../../components';
import {BasicCardProps} from '../../models';
import {IconPosition} from '../../models/constructor-items/sub-blocks';
import {block} from '../../utils';
Expand Down Expand Up @@ -32,36 +32,30 @@ const BasicCard = (props: BasicCardProps) => {
return (
<CardBase
className={b()}
contentClassName={b('content')}
{...cardParams}
extraProps={{'aria-describedby': descriptionId, 'aria-labelledby': titleId}}
>
<CardBase.Content>
<IconWrapper icon={icon ? {value: icon, position: iconPosition} : undefined}>
<IconWrapper
icon={icon ? {value: icon, position: iconPosition} : undefined}
className={b('wrapper')}
>
<Content
title={title}
titleId={titleId}
text={text}
textId={descriptionId}
additionalInfo={additionalInfo}
links={areControlsInFooter ? undefined : links}
links={links}
list={list}
buttons={areControlsInFooter ? undefined : buttons}
buttons={buttons}
size="s"
colSizes={{all: 12, md: 12}}
controlPosition={areControlsInFooter ? 'bottom' : 'default'}
/>
</IconWrapper>
</CardBase.Content>
{areControlsInFooter && (buttons || links) && (
<CardBase.Footer className={b('footer')}>
<Links className={b('links')} size="s" links={links} titleId={titleId} />
<Buttons
className={b('buttons')}
size="s"
buttons={buttons}
titleId={titleId}
/>
</CardBase.Footer>
)}
</CardBase>
);
};
Expand Down
5 changes: 3 additions & 2 deletions src/sub-blocks/BasicCard/schema.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import omit from 'lodash/omit';

import {ImageProps} from '../../components/Image/schema';
import {BaseProps, CardBase} from '../../schema/validators/common';
import {BaseProps, CardBase, CardLayoutProps} from '../../schema/validators/common';
import {ContentBase} from '../Content/schema';

const BasicCardContentProps = omit(ContentBase, ['size', 'theme']);
const BasicCardContentProps = omit(ContentBase, ['size', 'theme', 'controlPosition']);

export const BasicCard = {
'basic-card': {
Expand All @@ -13,6 +13,7 @@ export const BasicCard = {
properties: {
...BaseProps,
...CardBase,
...CardLayoutProps,
...BasicCardContentProps,
url: {
type: 'string',
Expand Down
17 changes: 17 additions & 0 deletions src/sub-blocks/Content/Content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ $darkSecondary: var(--g-color-text-dark-secondary);
--pc-monochrome-button-background-color-hover: #393939;
--pc-monochrome-button-color: var(--g-color-text-light-primary);

display: flex;
flex-direction: column;

&__notice,
&__text {
.yfm ol,
Expand Down Expand Up @@ -189,4 +192,18 @@ $darkSecondary: var(--g-color-text-dark-secondary);
}
}
}

&_control-position {
&_bottom {
#{$block}__notice,
#{$block}__list,
#{$block}__text,
#{$block}__title {
&:has(+ #{$block}__buttons),
&:has(+ #{$block}__link) {
margin-bottom: auto;
}
}
}
}
}
3 changes: 2 additions & 1 deletion src/sub-blocks/Content/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const Content = (props: ContentProps) => {
className,
list,
qa,
controlPosition,
} = props;
const qaAttributes = getQaAttrubutes(qa, ['links', 'link', 'buttons', 'button', 'list']);

Expand All @@ -55,7 +56,7 @@ const Content = (props: ContentProps) => {

return (
<Col
className={b({size, centered, theme}, className)}
className={b({size, centered, theme, 'control-position': controlPosition}, className)}
reset
sizes={colSizes}
qa={qaAttributes.container}
Expand Down
4 changes: 4 additions & 0 deletions src/sub-blocks/Content/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export const ContentBase = {
enum: contentThemes,
},
list: filteredArray(ContentItem),
controlPosition: {
type: 'string',
enum: ['default', 'bottom'],
},
};

export const ContentBlock = {
Expand Down
4 changes: 4 additions & 0 deletions src/sub-blocks/ImageCard/ImageCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ $block: '.#{$ns}image-card';
$content: #{&}__content;

#{$content} {
display: flex;

padding: $indentM;

flex: auto;
}

#{$image} {
Expand Down
7 changes: 6 additions & 1 deletion src/sub-blocks/ImageCard/ImageCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import {Link, useUniqId} from '@gravity-ui/uikit';

import {Image} from '../../components';
import {getMediaImage} from '../../components/Media/Image/utils';
import {GridColumnSizesType} from '../../grid';
import {ImageCardDirection, ImageCardProps} from '../../models';
import {block} from '../../utils';
import Content from '../Content/Content';

import './ImageCard.scss';

const b = block('image-card');
const CONTENT_COL_SIZES: GridColumnSizesType = {all: 12, md: 12};

const ImageCard = (props: ImageCardProps) => {
const {
Expand All @@ -31,8 +33,10 @@ const ImageCard = (props: ImageCardProps) => {
list,
theme: cardTheme = 'default',
size = 's',
controlPosition = 'content',
} = props;

const areControlsInFooter = controlPosition === 'footer';
const hasContent = Boolean(text || title || buttons || links || list);
const imageProps = getMediaImage(image);
const titleId = useUniqId();
Expand All @@ -57,7 +61,8 @@ const ImageCard = (props: ImageCardProps) => {
theme={cardTheme}
additionalInfo={additionalInfo}
size={size}
colSizes={{all: 12, md: 12}}
colSizes={CONTENT_COL_SIZES}
controlPosition={areControlsInFooter ? 'bottom' : 'default'}
/>
</div>
)}
Expand Down
Loading

0 comments on commit 7df0d3a

Please sign in to comment.