|
1 | 1 | import React, {Fragment, useContext, useState} from 'react'; |
2 | | -import {Tabs} from '@gravity-ui/uikit'; |
3 | 2 |
|
4 | 3 | import {block, getThemedValue} from '../../utils'; |
5 | 4 | import {Row, Col, GridColumnOrderClasses} from '../../grid'; |
6 | | -import YFMWrapper from '../../components/YFMWrapper/YFMWrapper'; |
7 | 5 | import {TabsBlockProps} from '../../models'; |
8 | 6 | import AnimateBlock from '../../components/AnimateBlock/AnimateBlock'; |
9 | 7 | import BlockHeader from '../../components/BlockHeader/BlockHeader'; |
10 | 8 | import FullScreenImage from '../../components/FullscreenImage/FullscreenImage'; |
11 | 9 | import Media from '../../components/Media/Media'; |
12 | | -import Links from '../../components/Link/Links'; |
13 | 10 | import {ThemeValueContext} from '../../context/theme/ThemeValueContext'; |
14 | 11 | import {getMediaImage} from '../../components/Media/Image/utils'; |
| 12 | +import ButtonTabs, {ButtonTabsItemProps} from '../../components/ButtonTabs/ButtonTabs'; |
| 13 | +import {Content} from '../../sub-blocks'; |
15 | 14 |
|
16 | 15 | import './Tabs.scss'; |
17 | 16 |
|
18 | | -const b = block('TabsBlock'); |
| 17 | +const b = block('tabs-block'); |
19 | 18 |
|
20 | | -export const TabsBlock = ({items, title, description, animated}: TabsBlockProps) => { |
| 19 | +export const TabsBlock = ({ |
| 20 | + items, |
| 21 | + title, |
| 22 | + description, |
| 23 | + animated, |
| 24 | + tabsColSizes, |
| 25 | + centered, |
| 26 | + direction = 'media-content', |
| 27 | +}: TabsBlockProps) => { |
21 | 28 | const [activeTab, setActiveTab] = useState(items[0].tabName); |
22 | 29 | const [play, setPlay] = useState<boolean>(false); |
23 | 30 | const {themeValue: theme} = useContext(ThemeValueContext); |
24 | | - const tabs = items.map(({tabName}) => ({title: tabName, id: tabName})); |
| 31 | + const tabs: ButtonTabsItemProps[] = items.map(({tabName}) => ({title: tabName, id: tabName})); |
25 | 32 | const activeTabData = items.find(({tabName}) => tabName === activeTab); |
| 33 | + const isReverse = direction === 'content-media'; |
26 | 34 |
|
27 | 35 | let imageProps; |
28 | 36 |
|
29 | 37 | if (activeTabData) { |
30 | 38 | const themedImage = getThemedValue(activeTabData.image, theme); |
| 39 | + |
31 | 40 | imageProps = themedImage && getMediaImage(themedImage); |
32 | 41 | } |
33 | 42 |
|
34 | 43 | const showMedia = Boolean(activeTabData?.media || imageProps); |
| 44 | + const showText = Boolean(activeTabData?.text); |
| 45 | + |
| 46 | + const textContent = activeTabData && showText && ( |
| 47 | + <Col |
| 48 | + sizes={{all: 12, md: showMedia ? 4 : 8}} |
| 49 | + className={b('content', {centered: centered})} |
| 50 | + > |
| 51 | + <div |
| 52 | + className={b('content-wrapper', { |
| 53 | + margin: Boolean((activeTabData?.media || imageProps) && !isReverse), |
| 54 | + })} |
| 55 | + > |
| 56 | + <Content |
| 57 | + title={activeTabData.title} |
| 58 | + text={activeTabData.text} |
| 59 | + additionalInfo={activeTabData.additionalInfo} |
| 60 | + size="s" |
| 61 | + links={[ |
| 62 | + ...(activeTabData.link ? [activeTabData.link] : []), |
| 63 | + ...(activeTabData.links || []), |
| 64 | + ]} |
| 65 | + buttons={activeTabData.buttons} |
| 66 | + colSizes={{all: 12}} |
| 67 | + /> |
| 68 | + </div> |
| 69 | + </Col> |
| 70 | + ); |
| 71 | + |
| 72 | + const mediaContent = showMedia && ( |
| 73 | + <Col |
| 74 | + sizes={{all: 12, md: 8}} |
| 75 | + orders={{ |
| 76 | + all: GridColumnOrderClasses.Last, |
| 77 | + md: GridColumnOrderClasses.First, |
| 78 | + }} |
| 79 | + className={b('col', {centered: centered})} |
| 80 | + > |
| 81 | + {activeTabData?.media && ( |
| 82 | + <Media |
| 83 | + {...getThemedValue(activeTabData.media, theme)} |
| 84 | + key={activeTab} |
| 85 | + className={b('media')} |
| 86 | + playVideo={play} |
| 87 | + /> |
| 88 | + )} |
| 89 | + {imageProps && ( |
| 90 | + <Fragment> |
| 91 | + <FullScreenImage {...imageProps} imageClassName={b('image')} /> |
| 92 | + {activeTabData?.caption && ( |
| 93 | + <p className={b('caption')}>{activeTabData.caption}</p> |
| 94 | + )} |
| 95 | + </Fragment> |
| 96 | + )} |
| 97 | + </Col> |
| 98 | + ); |
35 | 99 |
|
36 | 100 | return ( |
37 | 101 | <AnimateBlock className={b()} onScroll={() => setPlay(true)} animate={animated}> |
38 | | - <BlockHeader title={title} description={description} className={b('block-title')} /> |
39 | | - <Tabs |
40 | | - className={b('tabs')} |
41 | | - items={tabs} |
42 | | - activeTab={activeTab} |
43 | | - onSelectTab={setActiveTab} |
44 | | - size="l" |
| 102 | + <BlockHeader |
| 103 | + title={title} |
| 104 | + description={description} |
| 105 | + className={b('block-title', {centered: centered})} |
45 | 106 | /> |
| 107 | + <Row> |
| 108 | + <Col sizes={tabsColSizes}> |
| 109 | + <ButtonTabs |
| 110 | + items={tabs} |
| 111 | + onSelectTab={setActiveTab} |
| 112 | + activeTab={activeTab} |
| 113 | + className={b('tabs', {centered: centered})} |
| 114 | + /> |
| 115 | + </Col> |
| 116 | + </Row> |
46 | 117 | {activeTabData && ( |
47 | | - <Row> |
48 | | - {showMedia && ( |
49 | | - <Col |
50 | | - sizes={{all: 12, md: 8}} |
51 | | - orders={{ |
52 | | - all: GridColumnOrderClasses.Last, |
53 | | - md: GridColumnOrderClasses.First, |
54 | | - }} |
55 | | - > |
56 | | - {activeTabData?.media && ( |
57 | | - <Media |
58 | | - {...getThemedValue(activeTabData.media, theme)} |
59 | | - key={activeTab} |
60 | | - className={b('media')} |
61 | | - playVideo={play} |
62 | | - /> |
63 | | - )} |
64 | | - {imageProps && ( |
65 | | - <Fragment> |
66 | | - <FullScreenImage {...imageProps} imageClassName={b('image')} /> |
67 | | - {activeTabData && ( |
68 | | - <p className={b('caption')}>{activeTabData.caption}</p> |
69 | | - )} |
70 | | - </Fragment> |
71 | | - )} |
72 | | - </Col> |
73 | | - )} |
74 | | - <Col sizes={{all: 12, md: showMedia ? 4 : 8}} className={b('content')}> |
75 | | - <div |
76 | | - className={b('content-wrapper', { |
77 | | - margin: Boolean(activeTabData?.media || imageProps), |
78 | | - })} |
79 | | - > |
80 | | - <h4 className={b('content-title')}> |
81 | | - <YFMWrapper |
82 | | - content={activeTabData.title} |
83 | | - modifiers={{constructor: true}} |
84 | | - /> |
85 | | - </h4> |
86 | | - <YFMWrapper |
87 | | - content={activeTabData.text} |
88 | | - modifiers={{constructor: true}} |
89 | | - /> |
90 | | - <Links |
91 | | - links={[ |
92 | | - ...(activeTabData.link ? [activeTabData.link] : []), |
93 | | - ...(activeTabData.links || []), |
94 | | - ]} |
95 | | - className={b('link')} |
96 | | - /> |
97 | | - </div> |
98 | | - </Col> |
| 118 | + <Row className={b('row', {reverse: isReverse})}> |
| 119 | + {mediaContent} |
| 120 | + {textContent} |
99 | 121 | </Row> |
100 | 122 | )} |
101 | 123 | </AnimateBlock> |
|
0 commit comments