Skip to content

Commit

Permalink
fix: add custom height to images in Tabs (#650)
Browse files Browse the repository at this point in the history
  • Loading branch information
Juli Ovechkina authored Nov 17, 2023
1 parent 4c3ed84 commit 6ab3d04
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 99 deletions.
42 changes: 1 addition & 41 deletions src/blocks/Tabs/Tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ $block: '.#{$ns}tabs-block';
#{$block} {
$class: &;

&__block-title {
&__title {
margin-bottom: $indentSM;

@include centerable-title();
Expand All @@ -20,10 +20,6 @@ $block: '.#{$ns}tabs-block';

&__row_reverse {
flex-direction: row-reverse;

#{$class}__content-wrapper {
margin: $indentSM $indentM 0 0;
}
}

&__image {
Expand All @@ -45,51 +41,15 @@ $block: '.#{$ns}tabs-block';
color: var(--g-color-text-secondary);
}

&__content {
display: flex;
flex-direction: column;

&_centered {
margin: 0 auto;
}
}

&__col {
&_centered {
margin: 0 auto;
}
}

&__content-wrapper {
&_margin {
margin: $indentSM 0 0 $contentMargin;
}
}

&__content-title {
margin: 0 auto $indentXXS;

@include add-specificity(&) {
& > * {
@include heading4();
}
}
}

@media (max-width: map-get($gridBreakpoints, 'md')) {
&__content-wrapper {
&_margin {
margin: 0 0 $contentMargin 0;
}
}

&__row_reverse {
flex-direction: column-reverse;

#{$class}__content > * {
margin-top: $indentM;
padding-bottom: 0;
}
}
}

Expand Down
88 changes: 43 additions & 45 deletions src/blocks/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {Fragment, useRef, useState} from 'react';
import React, {Fragment, useCallback, useRef, useState} from 'react';

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

Expand All @@ -12,9 +12,10 @@ import {getHeight} from '../../components/VideoBlock/VideoBlock';
import {useTheme} from '../../context/theme';
import {Col, GridColumnOrderClasses, Row} from '../../grid';
import {TabsBlockProps} from '../../models';
import {Content} from '../../sub-blocks';
import {block, getThemedValue} from '../../utils';

import TabsTextContent from './TabsTextContent/TabsTextContent';

import './Tabs.scss';

const b = block('tabs-block');
Expand All @@ -37,15 +38,32 @@ export const TabsBlock = ({
const isReverse = direction === 'content-media';
const ref = useRef<HTMLDivElement>(null);
const mediaWidth = ref?.current?.offsetWidth;
const mediaHeight = mediaWidth && getHeight(mediaWidth);
const captionId = useUniqId();

const themedMedia = getThemedValue(activeTabData?.media, theme);
const hasNoImage = !themedMedia?.image || !activeTabData?.image;
const mediaVideoHeight = hasNoImage && mediaWidth && getHeight(mediaWidth);
const [minImageHeight, setMinImageHeight] = useState(ref?.current?.offsetHeight);
// TODO remove property support activeTabData?.image. Use only activeTabData?.media?.image
let imageProps;

const handleImageHeight = useCallback(() => {
setMinImageHeight(ref?.current?.offsetHeight);
}, []);

const onSelectTab = (
id: string | null,
e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>,
) => {
setActiveTab(id);
handleImageHeight();
e.currentTarget.scrollIntoView({inline: 'center', behavior: 'smooth', block: 'nearest'});
};

if (activeTabData) {
const themedImage = getThemedValue(activeTabData.image, theme);
const themedImage = getThemedValue(activeTabData?.image, theme);

imageProps = themedImage && getMediaImage(themedImage);

if (activeTabData.caption && imageProps) {
Object.assign(imageProps, {
'aria-describedby': captionId,
Expand All @@ -57,29 +75,14 @@ export const TabsBlock = ({
const showText = Boolean(activeTabData?.text);

const textContent = activeTabData && showText && (
<Col
sizes={{all: 12, md: showMedia ? 4 : 8}}
className={b('content', {centered: centered})}
>
<div
className={b('content-wrapper', {
margin: Boolean((activeTabData?.media || imageProps) && !isReverse),
})}
>
<Content
title={activeTabData.title}
text={activeTabData.text}
additionalInfo={activeTabData.additionalInfo}
size={contentSize}
links={[
...(activeTabData.link ? [activeTabData.link] : []),
...(activeTabData.links || []),
]}
buttons={activeTabData.buttons}
colSizes={{all: 12}}
/>
</div>
</Col>
<TabsTextContent
showMedia={showMedia}
data={activeTabData}
imageProps={imageProps ? imageProps : undefined}
isReverse={isReverse}
contentSize={contentSize}
centered={centered}
/>
);

const mediaContent = showMedia && (
Expand All @@ -91,15 +94,18 @@ export const TabsBlock = ({
}}
className={b('col', {centered: centered})}
>
<div ref={ref}>
<div style={{minHeight: mediaVideoHeight || minImageHeight}}>
{activeTabData?.media && (
<Media
{...getThemedValue(activeTabData.media, theme)}
key={activeTab}
className={b('media')}
playVideo={play}
height={mediaHeight}
/>
<div ref={ref}>
<Media
{...getThemedValue(activeTabData.media, theme)}
key={activeTab}
className={b('media')}
playVideo={play}
height={mediaVideoHeight || undefined}
onImageLoad={handleImageHeight}
/>
</div>
)}
</div>
{imageProps && (
Expand All @@ -115,20 +121,12 @@ export const TabsBlock = ({
</Col>
);

const onSelectTab = (
id: string | null,
e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>,
) => {
setActiveTab(id);
e.currentTarget.scrollIntoView({inline: 'center', behavior: 'smooth', block: 'nearest'});
};

return (
<AnimateBlock className={b()} onScroll={() => setPlay(true)} animate={animated}>
<Title
title={title}
subtitle={description}
className={b('block-title', {centered: centered})}
className={b('title', {centered: centered})}
/>
<Row>
<Col sizes={tabsColSizes}>
Expand Down
36 changes: 36 additions & 0 deletions src/blocks/Tabs/TabsTextContent/TabsTextContent.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@import '../../../../styles/mixins';
@import '../../../../styles/variables';

$block: '.#{$ns}tabs-block-text-content';

#{$block} {
display: flex;
flex-direction: column;

&_centered {
margin: 0 auto;
}

&__wrapper {
margin: $indentSM 0 0 $contentMargin;

&_reverse {
margin: $indentSM $indentM 0 0;
}

&_no-image {
margin: 0;
}
}

@media (max-width: map-get($gridBreakpoints, 'md')) {
&__wrapper {
margin: 0 0 $contentMargin 0;

&_reverse {
margin-top: $indentM;
padding-bottom: 0;
}
}
}
}
51 changes: 51 additions & 0 deletions src/blocks/Tabs/TabsTextContent/TabsTextContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';

import {Col} from '../../../grid';
import {ImageDeviceProps, ImageObjectProps, TabsBlockItem, TabsBlockProps} from '../../../models';
import {Content} from '../../../sub-blocks';
import {block} from '../../../utils';

import './TabsTextContent.scss';

const b = block('tabs-block-text-content');

interface TextContentProps extends Pick<TabsBlockProps, 'centered' | 'contentSize'> {
showMedia: boolean;
isReverse: boolean;
data: TabsBlockItem;
centered?: boolean;
imageProps?: ImageObjectProps | ImageDeviceProps;
}

export const TabsTextContent = ({
centered,
contentSize = 's',
showMedia,
data,
imageProps,
isReverse,
}: TextContentProps) => {
const isImage = data?.media || imageProps;
return (
<Col sizes={{all: 12, md: showMedia ? 4 : 8}} className={b({centered: centered})}>
<div
className={b('wrapper', {
reverse: isReverse,
'no-image': !isImage,
})}
>
<Content
title={data.title}
text={data.text}
additionalInfo={data.additionalInfo}
size={contentSize}
links={[...(data.link ? [data.link] : []), ...(data.links || [])]}
buttons={data.buttons}
colSizes={{all: 12}}
/>
</div>
</Col>
);
};

export default TabsTextContent;
Loading

0 comments on commit 6ab3d04

Please sign in to comment.