diff --git a/public/locales/en/themes.json b/public/locales/en/themes.json index 8a9ba664f597..16377960527b 100644 --- a/public/locales/en/themes.json +++ b/public/locales/en/themes.json @@ -23,6 +23,9 @@ "is_everything_set": "Is everything set?", "cancel": "Cancel", "export_theme_config": "Export theme config", + "export_theme_cancel_btn": "Cancel", + "export_theme_apply_btn": "Save custom.svs", + "export_theme_apply-theme-alert-title": "How to apply the theme", "radius": "Radius", "radius_regular": "Regular", "radius_circled": "Circled", diff --git a/public/locales/ru/themes.json b/public/locales/ru/themes.json index 6c017a5d3c5d..dfc9755b16e6 100644 --- a/public/locales/ru/themes.json +++ b/public/locales/ru/themes.json @@ -23,6 +23,9 @@ "is_everything_set": "Все настроили?", "cancel": "Закрыть", "export_theme_config": "Экспорт конфигурации темы", + "export_theme_cancel_btn": "Закрыть", + "export_theme_apply_btn": "Сохранить custom.svs", + "export_theme_apply-theme-alert-title": "Как применить выбранную тему", "radius": "Радиус", "radius_regular": "Стандартный", "radius_circled": "Круглый", diff --git a/src/components/Themes/Themes.scss b/src/components/Themes/Themes.scss index d90e078ac465..b319e87fe830 100644 --- a/src/components/Themes/Themes.scss +++ b/src/components/Themes/Themes.scss @@ -4,13 +4,40 @@ $block: '.#{variables.$ns}themes'; +@mixin sticky() { + z-index: 150; + padding-block: var(--g-spacing-2); + background-color: var(--g-color-base-float); + border-bottom: 1px solid var(--g-color-line-generic); +} + +@mixin gridContainerOffsets() { + max-width: calc(1232px + 16px + 80px); + padding-inline: var(--g-spacing-10); + margin-inline: auto; +} + #{$block} { - position: relative; - z-index: 1; - margin-block-start: calc(var(--g-spacing-base) * 16); + &__grid { + position: relative; + z-index: 1; + + &__content { + padding: calc(var(--g-spacing-base) * 12) 0; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + padding: calc(var(--g-spacing-base) * 6) 0; + } + } + } &__title { + @include gridContainerOffsets(); + margin-block-start: calc(var(--g-spacing-base) * 12); margin-block-end: var(--g-spacing-6); + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + padding-inline: var(--g-spacing-4); + } &__text { @include ukitMixins.text-display-4(); @@ -21,17 +48,49 @@ $block: '.#{variables.$ns}themes'; } } - &__header-actions { + &__header-actions-wrapper { + position: sticky; + top: 0; + margin-block-end: calc(var(--g-spacing-base) * 8); + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md')) { + margin-block-end: 0; + } + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + padding-inline: var(--g-spacing-4); + } + + &_sticky { + @include sticky(); + } + } + + &__header-actions { justify-content: space-between; + @include gridContainerOffsets(); @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md') - 1) { flex-direction: column; justify-content: flex-start; } + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + margin: 0 -16px; + padding-inline: 16px; + } + } + + &__header-action-buttons { + padding-inline: 40px; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + padding-inline: 16px; + } } - & &__tabs { + &__tags { display: flex; overflow: auto; flex-wrap: wrap; @@ -46,26 +105,15 @@ $block: '.#{variables.$ns}themes'; &__export-theme-btn { --g-button-border-radius: 8px; + border-radius: var(--g-border-radius-m); width: fit-content; @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md') - 1) { - margin-top: var(--g-spacing-6); + margin-block: var(--g-spacing-6) var(--g-spacing-8); } @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { width: 100%; } } - - &__export-theme-btn { - border-radius: var(--g-border-radius-m); - } - - &__content { - padding: calc(var(--g-spacing-base) * 12) 0; - - @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { - padding: calc(var(--g-spacing-base) * 6) 0; - } - } } diff --git a/src/components/Themes/Themes.tsx b/src/components/Themes/Themes.tsx index 84e2bcac2756..480b76fdd1f9 100644 --- a/src/components/Themes/Themes.tsx +++ b/src/components/Themes/Themes.tsx @@ -1,8 +1,9 @@ -import {Col, Grid, Row} from '@gravity-ui/page-constructor'; +import {BREAKPOINTS, Grid, useWindowBreakpoint} from '@gravity-ui/page-constructor'; import {ArrowUpFromSquare} from 'landing-icons'; import {Button, Flex, Icon, Text} from 'landing-uikit'; import {useTranslation} from 'next-i18next'; -import React, {useMemo, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import {ThemeExport} from 'src/components/Themes/ui/ThemeExport/ThemeExport'; import {block} from '../../utils'; import {TagItem, Tags} from '../Tags/Tags'; @@ -13,7 +14,6 @@ import {BorderRadiusTab} from './ui/BorderRadiusTab/BorderRadiusTab'; import {ColorsTab} from './ui/ColorsTab/ColorsTab'; import {PreviewTab} from './ui/PreviewTab/PreviewTab'; import {ThemeCreatorContextProvider} from './ui/ThemeCreatorContextProvider'; -import {ThemeExportDialog} from './ui/ThemeExportDialog/ThemeExportDialog'; import {TypographyTab} from './ui/TypographyTab/TypographyTab'; const b = block('themes'); @@ -34,6 +34,9 @@ const tabToComponent: Record = { export const Themes = () => { const {t} = useTranslation('themes'); + const breakpoint = useWindowBreakpoint(); + + const headerRef = useRef(null); const [isExportDialogVisible, toggleExportDialog] = React.useReducer( (isOpen) => !isOpen, @@ -62,41 +65,76 @@ export const Themes = () => { [t], ); + useEffect(() => { + const contentEl = document.getElementsByClassName( + 'gravity-ui-landing-layout__wrapper', + )?.[0]; + + if (!contentEl) { + return; + } + + const onScroll = () => { + if (headerRef?.current?.offsetTop && headerRef.current.offsetTop > 136) { + headerRef.current?.classList.add(b('header-actions-wrapper_sticky')); + } else { + headerRef.current?.classList.remove(b('header-actions-wrapper_sticky')); + } + }; + + contentEl.addEventListener('scroll', onScroll); + + return () => { + contentEl.removeEventListener('scroll', onScroll); + }; + }, []); + const [activeTab, setActiveTab] = useState(ThemeTab.Colors); const TabComponent = tabToComponent[activeTab]; + const ExportBtn = useCallback( + () => ( + + ), + [toggleExportDialog], + ); + return ( - - - - {t('title')} - - +
+ {t('title')} +
+
- + {breakpoint >= BREAKPOINTS.md && } +
- - {TabComponent ? : null} - + {breakpoint < BREAKPOINTS.md && ( +
+ +
+ )} + +
{TabComponent ? : null}
- + +
); }; diff --git a/src/components/Themes/lib/constants.ts b/src/components/Themes/lib/constants.ts index 86b28a1aefb0..b87717c2fae3 100644 --- a/src/components/Themes/lib/constants.ts +++ b/src/components/Themes/lib/constants.ts @@ -96,7 +96,7 @@ export const DEFAULT_COLORS: ThemeOptions['colors'] = { 'text-brand-heavy': 'private.brand.700-solid', 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.black, 'text-link': 'private.brand.600-solid', - 'text-link-hover': 'private.orange.800-solid', + 'text-link-hover': 'private.brand.800-solid', 'text-link-visited': 'private.purple.550-solid', 'text-link-visited-hover': 'private.purple.800-solid', }, @@ -145,7 +145,7 @@ export const BRAND_COLORS_PRESETS: BrandPreset[] = [ 'text-brand-heavy': 'private.brand.700-solid', 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.black, 'text-link': 'private.brand.600-solid', - 'text-link-hover': 'private.orange.800-solid', + 'text-link-hover': 'private.brand.800-solid', 'text-link-visited': 'private.purple.550-solid', 'text-link-visited-hover': 'private.purple.800-solid', }, @@ -178,7 +178,7 @@ export const BRAND_COLORS_PRESETS: BrandPreset[] = [ 'text-brand-heavy': 'private.brand.700-solid', 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, 'text-link': 'private.brand.600-solid', - 'text-link-hover': 'private.orange.800-solid', + 'text-link-hover': 'private.brand.800-solid', 'text-link-visited': 'private.purple.550-solid', 'text-link-visited-hover': 'private.purple.800-solid', }, @@ -211,7 +211,7 @@ export const BRAND_COLORS_PRESETS: BrandPreset[] = [ 'text-brand-heavy': 'private.brand.700-solid', 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, 'text-link': 'private.brand.600-solid', - 'text-link-hover': 'private.orange.800-solid', + 'text-link-hover': 'private.brand.800-solid', 'text-link-visited': 'private.purple.550-solid', 'text-link-visited-hover': 'private.purple.800-solid', }, @@ -244,7 +244,7 @@ export const BRAND_COLORS_PRESETS: BrandPreset[] = [ 'text-brand-heavy': 'private.brand.700-solid', 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, 'text-link': 'private.brand.600-solid', - 'text-link-hover': 'private.orange.800-solid', + 'text-link-hover': 'private.brand.800-solid', 'text-link-visited': 'private.purple.550-solid', 'text-link-visited-hover': 'private.purple.800-solid', }, @@ -277,7 +277,7 @@ export const BRAND_COLORS_PRESETS: BrandPreset[] = [ 'text-brand-heavy': 'private.brand.700-solid', 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.black, 'text-link': 'private.brand.600-solid', - 'text-link-hover': 'private.orange.800-solid', + 'text-link-hover': 'private.brand.800-solid', 'text-link-visited': 'private.purple.550-solid', 'text-link-visited-hover': 'private.purple.800-solid', }, @@ -310,7 +310,7 @@ export const BRAND_COLORS_PRESETS: BrandPreset[] = [ 'text-brand-heavy': 'private.brand.700-solid', 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, 'text-link': 'private.brand.600-solid', - 'text-link-hover': 'private.orange.800-solid', + 'text-link-hover': 'private.brand.800-solid', 'text-link-visited': 'private.purple.550-solid', 'text-link-visited-hover': 'private.purple.800-solid', }, diff --git a/src/components/Themes/lib/themeCreatorExport.ts b/src/components/Themes/lib/themeCreatorExport.ts index 67838e081b0d..d5e47fbcace6 100644 --- a/src/components/Themes/lib/themeCreatorExport.ts +++ b/src/components/Themes/lib/themeCreatorExport.ts @@ -40,6 +40,16 @@ ${FONTS_TEMPLATE_NAME} } `.trim(); +export const APPLY_THEME_TEMPLATE = ` + Create custom.scss file with the styles created in the Themer (from the section below) and import it after the default UIKit styles. + + // Import default UIKit styles + import '@gravity-ui/uikit/styles/styles.css'; + + // Styles from the Themer + import './custom.scss'; +`; + export type ExportFormat = 'scss' | 'json'; type ExportThemeParams = { diff --git a/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx b/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx index ee69d733e22f..caed3a76d40c 100644 --- a/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx +++ b/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx @@ -94,6 +94,15 @@ export const ColorPickerInput = ({ validateAndChangeExternal(inputValue); }, [inputValue, validateAndChangeExternal]); + const onKeyPress = useCallback( + (event: React.KeyboardEvent) => { + if (event.key === 'Enter') { + validateAndChangeExternal(inputValue); + } + }, + [inputValue, validateAndChangeExternal], + ); + useEffect(() => { // Dont validate if not initial value if (!value && !defaultValue) { @@ -109,6 +118,7 @@ export const ColorPickerInput = ({ className={b('text-input')} name={name} value={inputValue} + onKeyPress={onKeyPress} errorPlacement="inside" errorMessage={errorMessage || t('color-input_validation-format-error')} validationState={validationError} diff --git a/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx b/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx index 170a01ebdec7..bb3980968937 100644 --- a/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx +++ b/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx @@ -4,7 +4,7 @@ import {useTranslation} from 'next-i18next'; import React from 'react'; import {block} from '../../../../utils'; -import {ThemeExportDialog} from '../ThemeExportDialog/ThemeExportDialog'; +import {ThemeExport} from '../ThemeExport/ThemeExport'; import {ThemeSection} from '../ThemeSection'; import './ExportThemeSection.scss'; @@ -21,7 +21,7 @@ export const ExportThemeSection = () => { {t('btn_export_theme')} - + ); }; diff --git a/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx b/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx index 10d420d6ccac..83547c681de1 100644 --- a/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx +++ b/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx @@ -52,7 +52,7 @@ export const DashboardPreview = ({justify}: {justify: string}) => { {[barXDashboardData, linesDashboardData, areaDashboardData].map( (data, index) => ( - +
@@ -64,7 +64,7 @@ export const DashboardPreview = ({justify}: {justify: string}) => { {[pieDashboardData, dotsDashboardData].map((data, index) => ( - +
diff --git a/src/components/Themes/ui/ThemableSettings/ThemableSettings.scss b/src/components/Themes/ui/ThemableSettings/ThemableSettings.scss index f7c1eb2f2000..9dffdf50ab6f 100644 --- a/src/components/Themes/ui/ThemableSettings/ThemableSettings.scss +++ b/src/components/Themes/ui/ThemableSettings/ThemableSettings.scss @@ -4,9 +4,11 @@ $block: '.#{variables.$ns}themable-settings'; #{$block} { + width: calc(100% + var(--g-spacing-4)); + &__columns { - width: 380px; - max-width: 380px; + width: 400px; + max-width: 400px; @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md')) { display: none; diff --git a/src/components/Themes/ui/ThemableSettings/ThemableSettings.tsx b/src/components/Themes/ui/ThemableSettings/ThemableSettings.tsx index 888c8b1e0be8..51375edfa2bb 100644 --- a/src/components/Themes/ui/ThemableSettings/ThemableSettings.tsx +++ b/src/components/Themes/ui/ThemableSettings/ThemableSettings.tsx @@ -1,5 +1,5 @@ import {BREAKPOINTS, useWindowBreakpoint} from '@gravity-ui/page-constructor'; -import {Col, Flex} from 'landing-uikit'; +import {Col, Flex, Row} from 'landing-uikit'; import React from 'react'; import {block} from '../../../../utils'; @@ -27,14 +27,12 @@ export const ThemableSettings: React.FC = ({title, rows, return ( - - - + + + + + + = ({title, rows, /> {isMobile && addButton} - + - + ); }; diff --git a/src/components/Themes/ui/ThemeExport/ThemeExport.scss b/src/components/Themes/ui/ThemeExport/ThemeExport.scss new file mode 100644 index 000000000000..7205b85a9c4c --- /dev/null +++ b/src/components/Themes/ui/ThemeExport/ThemeExport.scss @@ -0,0 +1,38 @@ +@use '../../../../variables.scss'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; + +$block: '.#{variables.$ns}theme-export'; + +#{$block} { + &__dialog { + --g-border-radius-l: 8px; + } + + &__sheet { + --g-sheet-content-padding: var(--g-spacing-5); + + &__save-btn { + --g-border-radius-xl: 8px; + left: 0; + right: 0; + margin-inline: auto; + width: calc(100% - var(--g-spacing-4)); + position: absolute; + bottom: var(--g-spacing-2); + } + } + + &__code { + --code-example-max-height: 620px; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + --code-example-max-height: auto; + } + + border-radius: 8px; + } + + &__apply-theme-message { + white-space: pre-line; + } +} diff --git a/src/components/Themes/ui/ThemeExport/ThemeExport.tsx b/src/components/Themes/ui/ThemeExport/ThemeExport.tsx new file mode 100644 index 000000000000..da1ca217d19d --- /dev/null +++ b/src/components/Themes/ui/ThemeExport/ThemeExport.tsx @@ -0,0 +1,83 @@ +import {BREAKPOINTS, useWindowBreakpoint} from '@gravity-ui/page-constructor'; +import {Alert, Flex, Text} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React, {useCallback, useMemo, useState} from 'react'; + +import {block} from '../../../../utils'; +import {CodeExample} from '../../../CodeExample/CodeExample'; +import {useThemeCreator} from '../../hooks'; +import { + APPLY_THEME_TEMPLATE, + type ExportFormat, + exportThemeForDialog, +} from '../../lib/themeCreatorExport'; + +import './ThemeExport.scss'; +import {ThemeExportDialog} from './ThemeExportDialog'; +import {ThemeExportSheet} from './ThemeExportSheet'; + +const b = block('theme-export'); + +export interface ThemeExportProps { + isOpen: boolean; + onClose: () => void; +} + +export const ThemeExport = ({isOpen, onClose}: ThemeExportProps) => { + const {t} = useTranslation('themes'); + + const themeState = useThemeCreator(); + const breakpoint = useWindowBreakpoint(); + + //TODO: add more formats to import + const [format] = useState('scss'); + + const themeStyles = useMemo( + () => exportThemeForDialog({themeState, format}), + [themeState, format], + ); + + const onSaveThemeClick = useCallback(() => { + const blob = new Blob([themeStyles]); + + const url = URL.createObjectURL(blob); + + const link = document.createElement('a'); + link.setAttribute('href', url); + link.setAttribute('download', 'styles.scss'); + + link.click(); + }, [themeStyles]); + + const ExportContent = useCallback(() => { + return ( + + + {APPLY_THEME_TEMPLATE} + + } + /> + + + ); + }, [themeStyles]); + + return breakpoint >= BREAKPOINTS.sm ? ( + + + + ) : ( + + + + ); +}; diff --git a/src/components/Themes/ui/ThemeExport/ThemeExportDialog.tsx b/src/components/Themes/ui/ThemeExport/ThemeExportDialog.tsx new file mode 100644 index 000000000000..060c583323be --- /dev/null +++ b/src/components/Themes/ui/ThemeExport/ThemeExportDialog.tsx @@ -0,0 +1,51 @@ +import {BREAKPOINTS} from '@gravity-ui/page-constructor'; +import {Dialog, DialogFooter} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React, {PropsWithChildren} from 'react'; + +import {block} from '../../../../utils'; + +import type {ThemeExportProps} from './ThemeExport'; +import './ThemeExport.scss'; + +const b = block('theme-export'); + +interface ThemeExportDialogProps extends PropsWithChildren, ThemeExportProps { + onSaveThemeClick: () => void; + breakpoint: number; +} + +const breakpointToSize = { + [BREAKPOINTS.xl]: 'l' as const, + [BREAKPOINTS.lg]: 'l' as const, + [BREAKPOINTS.md]: 'm' as const, + [BREAKPOINTS.sm]: 's' as const, +}; + +export const ThemeExportDialog: React.FC = ({ + isOpen, + onClose, + onSaveThemeClick, + breakpoint, + children, +}) => { + const {t} = useTranslation('themes'); + + return ( + + + {children} + + + ); +}; diff --git a/src/components/Themes/ui/ThemeExport/ThemeExportSheet.tsx b/src/components/Themes/ui/ThemeExport/ThemeExportSheet.tsx new file mode 100644 index 000000000000..70c6bdb8232b --- /dev/null +++ b/src/components/Themes/ui/ThemeExport/ThemeExportSheet.tsx @@ -0,0 +1,39 @@ +import {Button, Flex, Sheet, Text} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React, {type PropsWithChildren} from 'react'; + +import {block} from '../../../../utils'; + +import type {ThemeExportProps} from './ThemeExport'; +import './ThemeExport.scss'; + +export interface ThemeExportSheetProps extends ThemeExportProps, PropsWithChildren { + onSaveThemeClick: () => void; +} + +const b = block('theme-export__sheet'); + +export const ThemeExportSheet = ({ + isOpen, + onClose, + children, + onSaveThemeClick, +}: ThemeExportSheetProps) => { + const {t} = useTranslation('themes'); + + return ( + + + {children} + + + + ); +}; diff --git a/src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.scss b/src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.scss deleted file mode 100644 index a1cb4d3236f4..000000000000 --- a/src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.scss +++ /dev/null @@ -1,9 +0,0 @@ -@use '../../../../variables.scss'; - -$block: '.#{variables.$ns}theme-export-dialog'; - -#{$block} { - &__code { - --code-example-max-height: max(100px, calc(100vh - 60px - 54px - 92px - 56px)); - } -} diff --git a/src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.tsx b/src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.tsx deleted file mode 100644 index 6cf084f6707c..000000000000 --- a/src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import {Dialog, Flex} from 'landing-uikit'; -import {useTranslation} from 'next-i18next'; -import React from 'react'; - -import {block} from '../../../../utils'; -import {CodeExample} from '../../../CodeExample/CodeExample'; -import {useThemeCreator} from '../../hooks'; -import {ExportFormat, exportThemeForDialog} from '../../lib/themeCreatorExport'; - -import './ThemeExportDialog.scss'; - -const b = block('theme-export-dialog'); - -interface ThemeExportDialogProps { - isOpen: boolean; - onClose: () => void; -} - -export const ThemeExportDialog: React.FC = ({isOpen, onClose}) => { - const {t} = useTranslation('themes'); - const themeState = useThemeCreator(); - - const [format] = React.useState('scss'); - - const themeStyles = React.useMemo( - () => exportThemeForDialog({themeState, format}), - [themeState, format], - ); - - return ( - - - - - - - -
-
- ); -}; diff --git a/src/components/Themes/ui/TypographyTab/AdvanceTypographySettings.tsx b/src/components/Themes/ui/TypographyTab/AdvanceTypographySettings.tsx index 96e233001cb5..1115876cbe69 100644 --- a/src/components/Themes/ui/TypographyTab/AdvanceTypographySettings.tsx +++ b/src/components/Themes/ui/TypographyTab/AdvanceTypographySettings.tsx @@ -31,7 +31,7 @@ export const AdvanceTypographySettings = () => { return ( {Object.entries(advanced).map(([key, setting]) => ( - + diff --git a/src/components/Themes/ui/TypographyTab/FontFamilyPicker.tsx b/src/components/Themes/ui/TypographyTab/FontFamilyPicker.tsx index 95f3e2f0a008..5fdf0c41afe0 100644 --- a/src/components/Themes/ui/TypographyTab/FontFamilyPicker.tsx +++ b/src/components/Themes/ui/TypographyTab/FontFamilyPicker.tsx @@ -274,6 +274,57 @@ const CustomFontFamily = ({ ); }; +const DeleteAdditionalFontButton = ({ + getFontUsages, + removeFontFamilyType, + fType, + mobile, +}: { + getFontUsages: (fontType: string) => string[]; + fType: {value: string; content: string}; + removeFontFamilyType: ReturnType['removeFontFamilyType']; + mobile?: boolean; +}) => { + return ( + + + This font is currently in use in blocks:{' '} + {getFontUsages(fType.value).join(', ')}. If you delete it, we'll + replace it with a default font. + + + + } + disabled={getFontUsages(fType.value).length === 0} + > + + + ); +}; + export const FontFamilyPicker = () => { const { typography: { @@ -301,7 +352,12 @@ export const FontFamilyPicker = () => { Fonts {FONT_FAMILIES_OPTION.map((option) => ( - + {option.name} @@ -378,61 +434,42 @@ export const FontFamilyPicker = () => { ))} {customFontFamilyType.map((fType) => ( - - - { - const value = event.target.value; + + + + { + const value = event.target.value; - updateFontFamilyTypeTitle({title: value, familyType: fType.value}); - }} - placeholder="Enter font alias" - className={b('additional-font-input')} - /> + updateFontFamilyTypeTitle({ + title: value, + familyType: fType.value, + }); + }} + placeholder="Enter font alias" + className={b('additional-font-input')} + /> + + - - This font is currently in use in blocks:{' '} - {getFontUsages(fType.value).join(', ')}. If - you delete it, we'll replace it with a default font. - - - - } - disabled={getFontUsages(fType.value).length === 0} - > - - + } /> diff --git a/src/components/Themes/ui/TypographyTab/Preview.tsx b/src/components/Themes/ui/TypographyTab/Preview.tsx index 7da0d1f544b1..fa6a511289bc 100644 --- a/src/components/Themes/ui/TypographyTab/Preview.tsx +++ b/src/components/Themes/ui/TypographyTab/Preview.tsx @@ -164,7 +164,11 @@ export const Preview = () => { {title} {variants.map((variant) => ( - + {variant.title} ))} diff --git a/src/components/Themes/ui/TypographyTab/TypographyTab.scss b/src/components/Themes/ui/TypographyTab/TypographyTab.scss index d1512102478f..7fc44341f0b6 100644 --- a/src/components/Themes/ui/TypographyTab/TypographyTab.scss +++ b/src/components/Themes/ui/TypographyTab/TypographyTab.scss @@ -17,8 +17,6 @@ $block: '.#{variables.$ns}typography-tab'; &__font { &__additional-font-input { - width: 380px; - @media (max-width: map-get(pcVariables.$gridBreakpoints, 'lg')) { width: 100%; } @@ -30,6 +28,30 @@ $block: '.#{variables.$ns}typography-tab'; } } + &__additional-font-label { + padding-inline-end: var(--g-spacing-4); + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'lg')) { + padding-inline-end: 0; + margin-block-end: var(--g-spacing-4); + } + } + + &__additional-font-delete-btn { + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + display: none; + } + + &_mobile { + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'lg')) { + display: none; + } + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + display: block; + } + } + } + &__font-card { &__text { @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md')) { @@ -65,6 +87,10 @@ $block: '.#{variables.$ns}typography-tab'; &__custom-font-radio-button { --g-border-radius-xl: 8px; align-self: flex-start; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + width: 100%; + } } &__custom-font-textarea { @@ -83,7 +109,7 @@ $block: '.#{variables.$ns}typography-tab'; --g-text-display-4-line-height: 52px !important; &__wrapper { - padding: 80px; + padding: 60px; margin-block-start: 0 !important; @media (max-width: map-get(pcVariables.$gridBreakpoints, 'lg')) { @@ -136,16 +162,14 @@ $block: '.#{variables.$ns}typography-tab'; } &__setting-input { - width: 225px; - - @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md')) { - width: 210px; - } - @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { width: 100%; } } + + &__row { + width: calc(100% + var(--g-spacing-8)); + } } &__advanced-button {