diff --git a/src/sub-blocks/BackgroundCard/BackgroundCard.scss b/src/sub-blocks/BackgroundCard/BackgroundCard.scss
index 6f45ee0c9..62862fab5 100644
--- a/src/sub-blocks/BackgroundCard/BackgroundCard.scss
+++ b/src/sub-blocks/BackgroundCard/BackgroundCard.scss
@@ -55,14 +55,6 @@ $block: '.#{$ns}background-card';
object-position: left;
}
}
-
- &__footer {
- margin-top: 0px;
- }
- &__links,
- &__buttons {
- margin-top: $indentXS;
- }
}
a#{$block} {
diff --git a/src/sub-blocks/BackgroundCard/BackgroundCard.tsx b/src/sub-blocks/BackgroundCard/BackgroundCard.tsx
index d22416631..66dc63467 100644
--- a/src/sub-blocks/BackgroundCard/BackgroundCard.tsx
+++ b/src/sub-blocks/BackgroundCard/BackgroundCard.tsx
@@ -1,12 +1,14 @@
-import React from 'react';
+import React, {useMemo} 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';
+import renderContentControls from '../../utils/renderContentControls/renderContentControls';
import Content from '../Content/Content';
+import renderCardFooterControlsContainer from '../renderCardFooterControlsContainer/renderCardFooterControlsContainer';
import './BackgroundCard.scss';
@@ -37,6 +39,20 @@ const BackgroundCard = (props: BackgroundCardProps) => {
const borderType = hasBackgroundColor ? 'none' : border;
const areControlsInFooter = !paddingBottom && controlPosition === 'footer';
+ const footerControls = useMemo(
+ () =>
+ renderContentControls(
+ {
+ links: areControlsInFooter ? links : undefined,
+ buttons: areControlsInFooter ? buttons : undefined,
+ size: 's',
+ titleId,
+ },
+ renderCardFooterControlsContainer,
+ ),
+ [areControlsInFooter, links, buttons, titleId],
+ );
+
return (
{
analyticsEvents={analyticsEvents}
urlTitle={urlTitle}
>
-
+
{
colSizes={{all: 12, md: 12}}
/>
- {areControlsInFooter && (links || buttons) && (
-
-
-
-
- )}
+ {footerControls}
);
};
diff --git a/src/sub-blocks/BackgroundCard/__stories__/BackgroundCard.stories.tsx b/src/sub-blocks/BackgroundCard/__stories__/BackgroundCard.stories.tsx
index bfd32e0e3..282638255 100644
--- a/src/sub-blocks/BackgroundCard/__stories__/BackgroundCard.stories.tsx
+++ b/src/sub-blocks/BackgroundCard/__stories__/BackgroundCard.stories.tsx
@@ -107,7 +107,7 @@ const ControlPositionTemplate: StoryFn = (args) => (
-
+
{data.cardLayout.items.map((item, index) => (
= (args) => (
{data.cardLayout.items.map((item, index) => (
diff --git a/src/sub-blocks/BackgroundCard/__stories__/data.json b/src/sub-blocks/BackgroundCard/__stories__/data.json
index cb1224255..ec729e6a1 100644
--- a/src/sub-blocks/BackgroundCard/__stories__/data.json
+++ b/src/sub-blocks/BackgroundCard/__stories__/data.json
@@ -119,6 +119,9 @@
]
},
"cardLayout": {
+ "contentTitle": "With controlPosition = content",
+ "footerTitle": "With controlPosition = footer",
+ "footerDescription": "Please note that the controlPosition prop manages the position of buttons and links only when paddingBottom = default.",
"items": [
{
"title": "Lorem ipsumt",
diff --git a/src/sub-blocks/BasicCard/BasicCard.scss b/src/sub-blocks/BasicCard/BasicCard.scss
index 80367eb71..70f51003d 100644
--- a/src/sub-blocks/BasicCard/BasicCard.scss
+++ b/src/sub-blocks/BasicCard/BasicCard.scss
@@ -7,12 +7,4 @@ $block: '.#{$ns}basic-card';
@include add-specificity(&) {
min-height: auto;
}
-
- &__footer {
- margin-top: 0px;
- }
- &__links,
- &__buttons {
- margin-top: $indentXS;
- }
}
diff --git a/src/sub-blocks/BasicCard/BasicCard.tsx b/src/sub-blocks/BasicCard/BasicCard.tsx
index 2507386ac..342adbcdd 100644
--- a/src/sub-blocks/BasicCard/BasicCard.tsx
+++ b/src/sub-blocks/BasicCard/BasicCard.tsx
@@ -1,12 +1,14 @@
-import React from 'react';
+import React, {useMemo} 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';
+import renderContentControls from '../../utils/renderContentControls/renderContentControls';
import Content from '../Content/Content';
+import renderCardFooterControlsContainer from '../renderCardFooterControlsContainer/renderCardFooterControlsContainer';
import './BasicCard.scss';
@@ -28,6 +30,19 @@ const BasicCard = (props: BasicCardProps) => {
const titleId = useUniqId();
const descriptionId = useUniqId();
const areControlsInFooter = controlPosition === 'footer';
+ const footerControls = useMemo(
+ () =>
+ renderContentControls(
+ {
+ links: areControlsInFooter ? links : undefined,
+ buttons: areControlsInFooter ? buttons : undefined,
+ size: 's',
+ titleId,
+ },
+ renderCardFooterControlsContainer,
+ ),
+ [areControlsInFooter, links, buttons, titleId],
+ );
return (
{
{...cardParams}
extraProps={{'aria-describedby': descriptionId, 'aria-labelledby': titleId}}
>
-
+
{
/>
- {areControlsInFooter && (links || buttons) && (
-
-
-
-
- )}
+ {footerControls}
);
};
diff --git a/src/sub-blocks/BasicCard/__stories__/BasicCard.stories.tsx b/src/sub-blocks/BasicCard/__stories__/BasicCard.stories.tsx
index 623ef97b7..a384f52af 100644
--- a/src/sub-blocks/BasicCard/__stories__/BasicCard.stories.tsx
+++ b/src/sub-blocks/BasicCard/__stories__/BasicCard.stories.tsx
@@ -118,7 +118,7 @@ const ControlPositionTemplate: StoryFn = (args) => (
-
+
{data.cardLayout.items.map((item, index) => (
= (args) => (
-
+
{data.cardLayout.items.map((item, index) => (
{
const defaultTitleId = useUniqId();
const titleId = titleIdFromProps || defaultTitleId;
+ const controls = useMemo(
+ () =>
+ renderContentControls({
+ size,
+ links,
+ buttons,
+ titleId,
+ qa: qaAttributes,
+ }),
+ [size, links, buttons, titleId, qa],
+ );
+
return (
{
/>
)}
-
-
+ {controls}
);
};
diff --git a/src/sub-blocks/LayoutItem/LayoutItem.scss b/src/sub-blocks/LayoutItem/LayoutItem.scss
index 222a7d5c6..8370360b3 100644
--- a/src/sub-blocks/LayoutItem/LayoutItem.scss
+++ b/src/sub-blocks/LayoutItem/LayoutItem.scss
@@ -30,9 +30,4 @@ $block: '.#{$ns}layout-item';
margin: 0;
}
}
-
- &__links,
- &__buttons {
- margin-top: $indentXS;
- }
}
diff --git a/src/sub-blocks/LayoutItem/LayoutItem.tsx b/src/sub-blocks/LayoutItem/LayoutItem.tsx
index d279e45c9..f26b054e5 100644
--- a/src/sub-blocks/LayoutItem/LayoutItem.tsx
+++ b/src/sub-blocks/LayoutItem/LayoutItem.tsx
@@ -1,10 +1,11 @@
-import React, {Fragment, useMemo} from 'react';
+import React, {useMemo} from 'react';
import {useUniqId} from '@gravity-ui/uikit';
-import {Buttons, FullscreenMedia, IconWrapper, Links, Media, MetaInfo} from '../../components';
+import {FullscreenMedia, IconWrapper, Media, MetaInfo} from '../../components';
import {ContentBlockProps, LayoutItemProps} from '../../models';
import {block} from '../../utils';
+import renderContentControls from '../../utils/renderContentControls/renderContentControls';
import Content from '../Content/Content';
import {getLayoutItemLinks, hasFullscreen, showFullscreenIcon} from './utils';
@@ -34,7 +35,16 @@ const LayoutItem = ({
colSizes: {all: 12, md: 12},
};
const titleId = useUniqId();
-
+ const footerControls = useMemo(
+ () =>
+ renderContentControls({
+ links: areControlsInFooter ? links : undefined,
+ buttons: areControlsInFooter ? buttons : undefined,
+ size: 's',
+ titleId,
+ }),
+ [areControlsInFooter, links, buttons, titleId],
+ );
const renderMedia = () => {
if (!media) {
return null;
@@ -67,22 +77,7 @@ const LayoutItem = ({
- {areControlsInFooter && (links || buttons) && (
-
-
-
-
- )}
+ {footerControls}
);
};
diff --git a/src/sub-blocks/LayoutItem/__stories__/LayoutItem.stories.tsx b/src/sub-blocks/LayoutItem/__stories__/LayoutItem.stories.tsx
index 006be6512..716a4dfc9 100644
--- a/src/sub-blocks/LayoutItem/__stories__/LayoutItem.stories.tsx
+++ b/src/sub-blocks/LayoutItem/__stories__/LayoutItem.stories.tsx
@@ -40,7 +40,7 @@ const ControlPositionTemplate: StoryFn = (args) => (
-
+
{data.cardLayout.items.map((item, index) => (
= (args) => (
-
+
{data.cardLayout.items.map((item, index) => (
(
+ {children}
+);
+
+export default renderCardFooterControlsContainer;
diff --git a/src/utils/renderContentControls/ContentControls.scss b/src/utils/renderContentControls/ContentControls.scss
new file mode 100644
index 000000000..299cd924d
--- /dev/null
+++ b/src/utils/renderContentControls/ContentControls.scss
@@ -0,0 +1,17 @@
+@import '../../../styles/variables.scss';
+
+$block: '.#{$ns}content-controls';
+
+#{$block} {
+ &__links,
+ &__buttons {
+ &_size {
+ &_s {
+ margin-top: $indentXS;
+ }
+ &_l {
+ margin-top: $indentSM;
+ }
+ }
+ }
+}
diff --git a/src/utils/renderContentControls/renderContentControls.tsx b/src/utils/renderContentControls/renderContentControls.tsx
new file mode 100644
index 000000000..860aa3a6c
--- /dev/null
+++ b/src/utils/renderContentControls/renderContentControls.tsx
@@ -0,0 +1,48 @@
+import React, {Fragment} from 'react';
+
+import {Buttons, Links} from '../../components';
+import {ButtonProps, ContentSize, LinkProps} from '../../models';
+import {block} from '../../utils';
+
+import './ContentControls.scss';
+
+const b = block('content-controls');
+
+type ContentControlsArgs = {
+ links?: LinkProps[];
+ buttons?: ButtonProps[];
+ titleId?: string;
+ size?: ContentSize;
+ qa?: Record;
+};
+const renderContentControls = (
+ {links, buttons, titleId, size = 's', qa = {}}: ContentControlsArgs,
+ renderContainer: (children: React.ReactElement) => React.ReactElement = (children) => children,
+) => {
+ const {links: linksQa, link: linkQa, buttons: buttonsQa, button: buttonQa} = qa;
+
+ return links || buttons
+ ? renderContainer(
+
+
+
+ ,
+ )
+ : null;
+};
+
+export default renderContentControls;