diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e0046f64..95523d42d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to - ✨(y-provider) preserve callouts, PDFs, page breaks, interlinking links and commented text on HTML/markdown export #2296 - ✨(frontend) add a user menu #2463 +- ✨(frontend) new header and responsive harmonization #2471 - ✨(backend) add management command to reset a Document #1882 ### Changed diff --git a/src/backend/impress/configuration/theme/default.json b/src/backend/impress/configuration/theme/default.json index 453382079..3f87d89c7 100644 --- a/src/backend/impress/configuration/theme/default.json +++ b/src/backend/impress/configuration/theme/default.json @@ -142,7 +142,7 @@ "icon": { "src": "/assets/icon-docs.svg", "style": { - "width": "32px", + "width": "40px", "height": "auto" }, "alt": "", diff --git a/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts index 79b4be2ad..42fa5df12 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts @@ -3,7 +3,7 @@ import { expect, test } from '@playwright/test'; test.beforeEach(async ({ page }) => { await page.goto('/'); await expect( - page.locator('header').first().locator('h1').getByText('Docs'), + page.locator('nav').first().locator('h1').getByText('Docs'), ).toBeVisible(); await page.goto('unknown-page404'); }); diff --git a/src/frontend/apps/impress/public/assets/icon-docs-dsfr-v2.png b/src/frontend/apps/impress/public/assets/icon-docs-dsfr-v2.png index 34a5d7709..a11c7a63c 100644 Binary files a/src/frontend/apps/impress/public/assets/icon-docs-dsfr-v2.png and b/src/frontend/apps/impress/public/assets/icon-docs-dsfr-v2.png differ diff --git a/src/frontend/apps/impress/public/assets/icon-docs.svg b/src/frontend/apps/impress/public/assets/icon-docs.svg index 10af0f986..7845e6c66 100644 --- a/src/frontend/apps/impress/public/assets/icon-docs.svg +++ b/src/frontend/apps/impress/public/assets/icon-docs.svg @@ -1,4 +1,12 @@ - - - + + + diff --git a/src/frontend/apps/impress/src/features/header/components/Title.tsx b/src/frontend/apps/impress/src/components/Title.tsx similarity index 70% rename from src/frontend/apps/impress/src/features/header/components/Title.tsx rename to src/frontend/apps/impress/src/components/Title.tsx index 79789224b..f6ec1cf69 100644 --- a/src/frontend/apps/impress/src/features/header/components/Title.tsx +++ b/src/frontend/apps/impress/src/components/Title.tsx @@ -1,21 +1,21 @@ import { useTranslation } from 'react-i18next'; -import { Text } from '@/components/'; +import { Text, TextType } from '@/components/'; -type TitleSemanticsProps = { +type TitleSemanticsProps = TextType & { headingLevel?: 'h1' | 'h2' | 'h3'; className?: string; }; export const Title = ({ headingLevel = 'h2', - className, + ...props }: TitleSemanticsProps) => { const { t } = useTranslation(); return ( {t('Docs')} diff --git a/src/frontend/apps/impress/src/components/separators/SeparatedSection.tsx b/src/frontend/apps/impress/src/components/separators/SeparatedSection.tsx index 547b41772..026a76be7 100644 --- a/src/frontend/apps/impress/src/components/separators/SeparatedSection.tsx +++ b/src/frontend/apps/impress/src/components/separators/SeparatedSection.tsx @@ -1,25 +1,23 @@ import { PropsWithChildren } from 'react'; import { css } from 'styled-components'; -import { useCunninghamTheme } from '@/cunningham'; +import { Box, BoxType } from '../Box'; -import { Box } from '../Box'; - -type SeparatedSectionProps = { +type SeparatedSectionProps = BoxType & { showSeparator?: 'top' | 'bottom' | boolean; }; export const SeparatedSection = ({ showSeparator = true, children, + ...boxProps }: PropsWithChildren) => { - const { spacingsTokens } = useCunninghamTheme(); - return ( ; diff --git a/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx b/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx index dc4700d43..e55febc42 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx @@ -4,8 +4,11 @@ import { css } from 'styled-components'; import { Box, Text } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; import { DocsBlockNoteEditor } from '@/docs/doc-editor/types'; +import { getMainContentElement } from '@/layouts/utils'; import { useResponsiveStore } from '@/stores'; +const SCROLL_MARGIN_TOP = 50; + const leftPaddingMap: { [key: number]: string } = { 3: '1.5rem', 2: '0.9rem', @@ -57,11 +60,26 @@ export const Heading = ({ editor.setTextCursorPosition(headingId, 'end'); const blockEl = document.getElementById(headingId); - blockEl?.scrollIntoView({ - behavior: 'smooth', - inline: 'start', - block: 'start', - }); + + // Try to scroll the main content container instead of the block itself + // to avoid the block being hidden behind the header + const container = getMainContentElement(); + + if (blockEl && container) { + const top = + blockEl.getBoundingClientRect().top - + container.getBoundingClientRect().top + + container.scrollTop - + SCROLL_MARGIN_TOP; + + container.scrollTo({ top, behavior: 'smooth' }); + } else { + blockEl?.scrollIntoView({ + behavior: 'smooth', + inline: 'start', + block: 'start', + }); + } }} $radius="var(--c--globals--spacings--st)" $background={ diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx index b9618e9e7..d32e97407 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx @@ -79,12 +79,13 @@ export const DocsGrid = ({ return ( @@ -193,7 +193,7 @@ const DocGridTitleBar = ({ target }: { target: DocDefaultFilter }) => { { - const { t } = useTranslation(); - const { data: config } = useConfig(); - const { spacingsTokens } = useCunninghamTheme(); - const { isLargeScreen } = useResponsiveStore(); - - const icon = config?.theme_customization?.header?.icon; - - return ( - <> - - - {!isLargeScreen && } - - - {icon && ( - rest)(icon)} - /> - )} - - - - {isLargeScreen && ( - - - - )} - - - ); -}; diff --git a/src/frontend/apps/impress/src/features/header/components/index.ts b/src/frontend/apps/impress/src/features/header/components/index.ts index 127632913..f2a5d7552 100644 --- a/src/frontend/apps/impress/src/features/header/components/index.ts +++ b/src/frontend/apps/impress/src/features/header/components/index.ts @@ -1,2 +1 @@ -export * from './Header'; -export * from './Title'; +export * from './HeaderFloatingBar'; diff --git a/src/frontend/apps/impress/src/features/header/conf.ts b/src/frontend/apps/impress/src/features/header/conf.ts deleted file mode 100644 index b50057ad7..000000000 --- a/src/frontend/apps/impress/src/features/header/conf.ts +++ /dev/null @@ -1 +0,0 @@ -export const HEADER_HEIGHT = 52; diff --git a/src/frontend/apps/impress/src/features/header/index.ts b/src/frontend/apps/impress/src/features/header/index.ts index e32f9ebdb..ef6330a0f 100644 --- a/src/frontend/apps/impress/src/features/header/index.ts +++ b/src/frontend/apps/impress/src/features/header/index.ts @@ -1,3 +1 @@ export * from './components/'; -export * from './conf'; -export * from './types'; diff --git a/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx b/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx index 38cfafd8b..5374e6330 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx @@ -2,10 +2,10 @@ import { useTranslation } from 'react-i18next'; import IconDocs from '@/assets/icons/icon-docs.svg'; import { Box, Text } from '@/components'; +import { Title } from '@/components/Title'; import { useConfig } from '@/core/config'; import { useCunninghamTheme } from '@/cunningham'; import { ProConnectButton } from '@/features/auth'; -import { Title } from '@/features/header'; import { useResponsiveStore } from '@/stores'; export function HomeBottom() { diff --git a/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx b/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx index 5a516ab29..eec4e3fc5 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx @@ -4,7 +4,6 @@ import { css } from 'styled-components'; import { Box, Icon, Text } from '@/components'; import { Footer } from '@/features/footer'; -import { LeftPanel } from '@/features/left-panel'; import { MAIN_LAYOUT_ID } from '@/layouts/conf'; import { useResponsiveStore } from '@/stores'; @@ -50,11 +49,6 @@ export function HomeContent() { `} > - {isSmallMobile && ( - - - - )} { $align="center" $gap="2rem" $direction="row" - $width={isSmallMobile ? '100%' : 'auto'} + $width="auto" $justify="center" > - {isSmallMobile && ( - - - - )} {!isSmallMobile && logo?.src && ( { {icon?.withTitle && } - {!isSmallMobile && ( - - - - - )} + + + + ); }; diff --git a/src/frontend/apps/impress/src/features/language/components/LanguagePicker.tsx b/src/frontend/apps/impress/src/features/language/components/LanguagePicker.tsx index 75b219fff..1eba4ff33 100644 --- a/src/frontend/apps/impress/src/features/language/components/LanguagePicker.tsx +++ b/src/frontend/apps/impress/src/features/language/components/LanguagePicker.tsx @@ -14,6 +14,7 @@ import { getMatchingLocales, useSynchronizedLanguage, } from '@/features/language'; +import { useResponsiveStore } from '@/stores/useResponsiveStore'; /** * LanguagePickerLegacy component for selecting language. @@ -22,6 +23,7 @@ import { * @returns JSX.Element */ export const LanguagePickerLegacy = () => { + const { isSmallMobile } = useResponsiveStore(); const { t, i18n } = useTranslation(); const { data: conf } = useConfig(); const { data: user } = useAuthQuery(); @@ -87,7 +89,9 @@ export const LanguagePickerLegacy = () => { $gap="0.5rem" $align="center" > - + {!isSmallMobile && ( + + )} {currentLanguageLabel} diff --git a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFooter.tsx b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFooter.tsx index 54082afac..c26266183 100644 --- a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFooter.tsx +++ b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFooter.tsx @@ -21,7 +21,7 @@ export const LeftPanelFooter = () => { }; return ( - + { - const router = useRouter(); - const { authenticated } = useAuth(); - - const { togglePanel, closePanel } = useLeftPanelStore(); - - const goToHome = () => { - void router.push('/'); - togglePanel({ type: 'mobile' }); - }; +export const LeftPanelHeader = () => { + const { data: config } = useConfig(); + const { isMobile } = useResponsiveStore(); + const { closePanel } = useLeftPanelStore(); + const icon = config?.theme_customization?.header?.icon; return ( - - + - {authenticated && ( - closePanel({ type: 'mobile' })} /> - )} - - {router.pathname !== '/' && ( -