diff --git a/public/locales/en/home.json b/public/locales/en/home.json
index 5b3eee9395b..4f16d07a9fb 100644
--- a/public/locales/en/home.json
+++ b/public/locales/en/home.json
@@ -31,5 +31,7 @@
"roadmap_items_item10": "UIKit: extended mobile support",
"roadmap_items_item11": "Page constructor: footer block",
"templates_title": "Start creating with Gravity UI",
- "companies_title": "Trusted by"
+ "companies_title": "Trusted by",
+ "github_stars-text": "Do you 💖 Gravity UI? Give us",
+ "github_stars-button": "Star"
}
diff --git a/public/locales/ru/home.json b/public/locales/ru/home.json
index d4b117379e9..88496df3c1f 100644
--- a/public/locales/ru/home.json
+++ b/public/locales/ru/home.json
@@ -31,5 +31,7 @@
"roadmap_items_item10": "UIKit: Расширенная поддержка мобильных устройств",
"roadmap_items_item11": "Page constructor: блок футера",
"templates_title": "Начните создавать проекты с Gravity UI",
- "companies_title": "Нам доверяют"
+ "companies_title": "Нам доверяют",
+ "github_stars-text": "Вам нравится 💖 Gravity UI? Поставьте нам",
+ "github_stars-button": "Звезду"
}
diff --git a/src/blocks/GithubStarsBlock/GithubStarsBlock.scss b/src/blocks/GithubStarsBlock/GithubStarsBlock.scss
new file mode 100644
index 00000000000..9bfe96a55bb
--- /dev/null
+++ b/src/blocks/GithubStarsBlock/GithubStarsBlock.scss
@@ -0,0 +1,73 @@
+@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}github-stars-promotion';
+
+.pc-block-base.pc-block-base.pc-block-base.pc-constructor-block_type_github-stars-promotion {
+ position: unset;
+ margin: 0;
+ padding: 0;
+}
+
+#{$block} {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--g-spacing-2);
+ padding: var(--g-spacing-1) var(--g-spacing-1) var(--g-spacing-1) var(--g-spacing-4);
+ border-radius: var(--g-border-radius-m);
+ text-decoration: none;
+ background: #cda2e7;
+
+ @media (min-width: map-get(pcVariables.$gridBreakpoints, 'sm')) {
+ transform: translateX(calc(100% + 2 * var(--g-spacing-2)));
+ animation: leftBlockAnimation 250ms ease-out forwards;
+ animation-delay: 500ms;
+ }
+
+ &__wrapper {
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+
+ padding-top: var(--g-spacing-2);
+
+ @media (min-width: map-get(pcVariables.$gridBreakpoints, 'sm')) {
+ position: absolute;
+ overflow: hidden;
+ left: 0;
+ right: 0;
+ z-index: 9;
+
+ padding-left: var(--g-spacing-2);
+ padding-right: var(--g-spacing-2);
+
+ &[data-hide='true'] {
+ display: none;
+ }
+
+ &[data-device='mobile'] {
+ display: none;
+ }
+ }
+
+ @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm') - 1) {
+ justify-content: center;
+
+ &[data-device='desktop'] {
+ display: none;
+ }
+ }
+ }
+
+ @keyframes leftBlockAnimation {
+ from {
+ transform: translateX(100%);
+ }
+
+ to {
+ transform: translateX(0%);
+ }
+ }
+}
diff --git a/src/blocks/GithubStarsBlock/GithubStarsBlock.tsx b/src/blocks/GithubStarsBlock/GithubStarsBlock.tsx
new file mode 100644
index 00000000000..906ee4fa819
--- /dev/null
+++ b/src/blocks/GithubStarsBlock/GithubStarsBlock.tsx
@@ -0,0 +1,58 @@
+import {Star} from '@gravity-ui/icons';
+import {Animatable, HTML} from '@gravity-ui/page-constructor';
+import {Button, Icon, Text} from '@gravity-ui/uikit';
+import {useTranslation} from 'next-i18next';
+import {useRouter} from 'next/router';
+import React, {useEffect, useState} from 'react';
+import {GITHUB_UI_KIT_URL} from 'src/constants';
+
+import {block} from '../../utils';
+import {CustomBlock} from '../constants';
+
+import './GithubStarsBlock.scss';
+
+const b = block('github-stars-promotion');
+const LOCAL_STORAGE_KEY = 'gravity-landing-hide-stars-promotion';
+
+type GithubStarsBlockProps = Animatable & {
+ device: 'desktop' | 'mobile';
+};
+
+export type GithubStarsModel = GithubStarsBlockProps & {
+ type: CustomBlock.GithubStars;
+};
+
+export const GithubStarsBlock: React.FC = ({device}) => {
+ const {t} = useTranslation();
+ const {pathname} = useRouter();
+ const [hide, setHide] = useState(true);
+
+ useEffect(() => {
+ setHide(Boolean(localStorage.getItem(LOCAL_STORAGE_KEY)));
+ }, []);
+
+ const hideBlock = () => {
+ localStorage.setItem(LOCAL_STORAGE_KEY, 'true');
+ };
+
+ if (pathname !== '/') {
+ return null;
+ }
+
+ return (
+
+ );
+};
+
+export default GithubStarsBlock;
diff --git a/src/blocks/constants.ts b/src/blocks/constants.ts
index 2fafdac5d4d..77dd757aeb5 100644
--- a/src/blocks/constants.ts
+++ b/src/blocks/constants.ts
@@ -4,4 +4,5 @@ export enum CustomBlock {
Examples = 'examples',
Roadmap = 'roadmap',
Templates = 'templates',
+ GithubStars = 'github-stars-promotion',
}
diff --git a/src/blocks/types.ts b/src/blocks/types.ts
index 459fbe01c07..0c451e2280c 100644
--- a/src/blocks/types.ts
+++ b/src/blocks/types.ts
@@ -1,6 +1,7 @@
import {CustomExtendedFeaturesModel} from './CustomExtendedFeatures/CustomExtendedFeatures';
import {CustomHeaderModel} from './CustomHeader/CustomHeader';
import {ExamplesModel} from './Examples/Examples';
+import {GithubStarsModel} from './GithubStarsBlock/GithubStarsBlock';
import {RoadmapModel} from './RoadmapBlock/RoadmapBlock';
import {TemplatesModel} from './TemplatesBlock/TemplatesBlock';
@@ -9,4 +10,5 @@ export type CustomBlockModel =
| CustomExtendedFeaturesModel
| ExamplesModel
| RoadmapModel
- | TemplatesModel;
+ | TemplatesModel
+ | GithubStarsModel;
diff --git a/src/components/Landing/Landing.tsx b/src/components/Landing/Landing.tsx
index dfc0b122340..5046edd44ea 100644
--- a/src/components/Landing/Landing.tsx
+++ b/src/components/Landing/Landing.tsx
@@ -6,6 +6,7 @@ import React from 'react';
import {CustomExtendedFeatures} from '../../blocks/CustomExtendedFeatures/CustomExtendedFeatures';
import {CustomHeader} from '../../blocks/CustomHeader/CustomHeader';
import {Examples} from '../../blocks/Examples/Examples';
+import {GithubStarsBlock} from '../../blocks/GithubStarsBlock/GithubStarsBlock';
import {RoadmapBlock} from '../../blocks/RoadmapBlock/RoadmapBlock';
import TemplatesBlock from '../../blocks/TemplatesBlock/TemplatesBlock';
import {CustomBlock} from '../../blocks/constants';
@@ -20,17 +21,21 @@ export const Landing: React.FC = () => {
useSectionScroll();
return (
-
+ <>
+
+
+ >
);
};
diff --git a/src/components/Layout/Layout.scss b/src/components/Layout/Layout.scss
index 8c277add665..95c923aa07d 100644
--- a/src/components/Layout/Layout.scss
+++ b/src/components/Layout/Layout.scss
@@ -24,6 +24,7 @@ $block: '.#{variables.$ns}layout';
}
&__content {
+ position: relative;
flex: 1;
}
}
diff --git a/src/constants.ts b/src/constants.ts
index 8d0862d0844..da45a994bde 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -15,3 +15,5 @@ export const TARGET_PROFILE = 'gravity-ui';
export const SCROLL_TO_TEMPLATES_EVENT = 'templates';
export const LOCALE_LOCAL_STORAGE_KEY = 'gravity-landing-locale-v3';
+
+export const GITHUB_UI_KIT_URL = 'https://github.com/gravity-ui/uikit';
diff --git a/src/content/landing.ts b/src/content/landing.ts
index f0686ddd6a4..067b3b98baf 100644
--- a/src/content/landing.ts
+++ b/src/content/landing.ts
@@ -35,6 +35,10 @@ export const getLanding = (t: TFunction): CustomPageContent => ({
},
},
blocks: [
+ {
+ type: CustomBlock.GithubStars,
+ device: 'mobile',
+ },
{
type: CustomBlock.CustomHeader,
title: t('home:header_title'),