Skip to content

Commit

Permalink
feat: add section for templates
Browse files Browse the repository at this point in the history
  • Loading branch information
Raubzeug committed Dec 13, 2023
1 parent 8ccf7c0 commit 29855b3
Show file tree
Hide file tree
Showing 13 changed files with 240 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/assets/icons/cra-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/assets/icons/next-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/icons/vite-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions src/blocks/TemplatesBlock/TemplatesBlock.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@use '~@gravity-ui/page-constructor/styles/styles.scss' as pcStyles;
@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables;
@use '../../variables.scss';

$block: '.#{variables.$ns}templates-block';

#{$block} {
@include pcStyles.animate();

&__title {
@include pcStyles.heading2();
margin-bottom: pcVariables.$indentM;
}
}
33 changes: 33 additions & 0 deletions src/blocks/TemplatesBlock/TemplatesBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {Animatable, AnimateBlock, HTML} from '@gravity-ui/page-constructor';
import React from 'react';

import {Templates} from '../../components/Templates';
import type {Tab} from '../../components/Templates';
import {block} from '../../utils';
import {CustomBlock} from '../constants';

import './TemplatesBlock.scss';

const b = block('templates-block');

export type TemplatesProps = Animatable & {
title: string;
tabs: Tab[];
};

export type TemplatesModel = TemplatesProps & {
type: CustomBlock.Templates;
};

export const TemplatesBlock: React.FC<TemplatesProps> = ({animated, title, tabs}) => {
return (
<AnimateBlock className={b()} animate={animated}>
<h2 className={b('title')} data-section="templates">
<HTML>{title}</HTML>
</h2>
<Templates tabs={tabs} />
</AnimateBlock>
);
};

export default TemplatesBlock;
1 change: 1 addition & 0 deletions src/blocks/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export enum CustomBlock {
CustomBanner = 'custom-banner',
Examples = 'examples',
Roadmap = 'roadmap',
Templates = 'templates',
}
4 changes: 3 additions & 1 deletion src/blocks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import {CustomExtendedFeaturesModel} from './CustomExtendedFeatures/CustomExtend
import {CustomHeaderModel} from './CustomHeader/CustomHeader';
import {ExamplesModel} from './Examples/Examples';
import {RoadmapModel} from './RoadmapBlock/RoadmapBlock';
import {TemplatesModel} from './TemplatesBlock/TemplatesBlock';

export type CustomBlockModel =
| CustomHeaderModel
| CustomExtendedFeaturesModel
| CustomBannerModel
| ExamplesModel
| RoadmapModel;
| RoadmapModel
| TemplatesModel;
2 changes: 2 additions & 0 deletions src/components/Landing/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {CustomExtendedFeatures} from '../../blocks/CustomExtendedFeatures/Custom
import {CustomHeader} from '../../blocks/CustomHeader/CustomHeader';
import {Examples} from '../../blocks/Examples/Examples';
import {RoadmapBlock} from '../../blocks/RoadmapBlock/RoadmapBlock';
import TemplatesBlock from '../../blocks/TemplatesBlock/TemplatesBlock';
import {CustomBlock} from '../../blocks/constants';
import {landing} from '../../content/landing';
import {useSectionScroll} from '../../hooks/useSectionScroll';
Expand All @@ -23,6 +24,7 @@ export const Landing: React.FC = () => {
[CustomBlock.CustomBanner]: CustomBanner,
[CustomBlock.Examples]: Examples,
[CustomBlock.Roadmap]: RoadmapBlock,
[CustomBlock.Templates]: TemplatesBlock,
},
}}
/>
Expand Down
37 changes: 37 additions & 0 deletions src/components/Templates/Templates.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@use '~@gravity-ui/page-constructor/styles/styles.scss' as pcStyles;
@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables;
@use '../../variables.scss';

$block: '.#{variables.$ns}templates';

#{$block} {
background: #251b25;
border-radius: pcVariables.$borderRadius;
padding: 12px 32px 24px;
display: flex;
flex-direction: column;
gap: 20px;

&__commands-wrapper {
width: 100%;
padding: 16px;
background: #160d1b;
border-radius: 16px;

@media (max-width: map-get(pcVariables.$gridBreakpoints, 'lg') - 1) {
width: inherit;
}
}

&__commands {
overflow-x: auto;
white-space: nowrap;
position: relative;
}

&__copy {
position: absolute;
top: 0;
right: 0;
}
}
74 changes: 74 additions & 0 deletions src/components/Templates/Templates.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {Button, ClipboardButton, Icon, Tabs, Text} from '@gravity-ui/uikit';
import React from 'react';

import {block} from '../../utils';

import './Templates.scss';
import type {Tab} from './types';

const b = block('templates');

interface CommandsProps {
commands: string[];
}

const Commands: React.FC<CommandsProps> = ({commands}) => {
return (
<div className={b('commands-wrapper')}>
<div className={b('commands')}>
{commands.map((item, index) => {
return (
<Text as="div" key={index} variant="body-3">
{item}
</Text>
);
})}
<ClipboardButton text={commands.join(' && ')} className={b('copy')} size={16} />
</div>
</div>
);
};

interface TabContentProps {
data?: Pick<Tab, 'button' | 'commands'>;
}

const TabContent: React.FC<TabContentProps> = ({data}) => {
if (!data) {
return null;
}

return (
<>
{data.commands && <Commands commands={data.commands} />}
{data.button?.href && (
<div>
<Button {...data.button} pin="circle-circle" view="outlined-action" size="xl">
{data.button.title}
</Button>
</div>
)}
</>
);
};

interface TemplatesProps {
tabs: Tab[];
}

export const Templates: React.FC<TemplatesProps> = ({tabs}) => {
const [activeTab, setActiveTab] = React.useState(() => tabs[0]?.title);
const tabsItems = tabs.map(({title, icon}) => ({
id: title,
title,
icon: icon ? <Icon data={icon} size={24} /> : undefined,
}));
const activeTabData = tabs.find((el) => el.title === activeTab);

return (
<section className={b()}>
<Tabs size="xl" items={tabsItems} activeTab={activeTab} onSelectTab={setActiveTab} />
<TabContent data={activeTabData} />
</section>
);
};
3 changes: 3 additions & 0 deletions src/components/Templates/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type {Tab} from './types';

export {Templates} from './Templates';
12 changes: 12 additions & 0 deletions src/components/Templates/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {SVGIconData} from '@gravity-ui/uikit/build/esm/components/Icon/types';

export interface Tab {
title: string;
icon?: SVGIconData;
commands?: string[];
button?: {
title: string;
href?: string;
target?: string;
};
}
Loading

0 comments on commit 29855b3

Please sign in to comment.