diff --git a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts
index e2508a69..b29f610b 100644
--- a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts
+++ b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts
@@ -10,8 +10,6 @@ test.describe('Header', () => {
test('checks all the elements are visible', async ({ page }) => {
const header = page.locator('header').first();
- await expect(header.getByAltText('Gouvernement Logo')).toBeVisible();
-
await expect(header.getByAltText('Docs Logo')).toBeVisible();
await expect(header.locator('h2').getByText('Docs')).toHaveCSS(
'color',
@@ -67,6 +65,42 @@ test.describe('Header', () => {
});
});
+test.describe('Header mobile', () => {
+ test.use({ viewport: { width: 500, height: 1200 } });
+
+ test.beforeEach(async ({ page }) => {
+ await page.goto('/');
+ });
+
+ test('it checks the header when mobile', async ({ page }) => {
+ const header = page.locator('header').first();
+
+ await expect(
+ header.getByRole('button', {
+ name: 'Les services de La Suite numérique',
+ }),
+ ).toBeVisible();
+
+ await expect(
+ page.getByRole('button', {
+ name: 'Logout',
+ }),
+ ).toBeHidden();
+
+ await expect(page.getByAltText('Language Icon')).toBeHidden();
+
+ await header.getByLabel('Open the header menu').click();
+
+ await expect(
+ page.getByRole('button', {
+ name: 'Logout',
+ }),
+ ).toBeVisible();
+
+ await expect(page.getByAltText('Language Icon')).toBeVisible();
+ });
+});
+
test.describe('Header: Log out', () => {
test.use({ storageState: { cookies: [], origins: [] } });
diff --git a/src/frontend/apps/impress/src/core/auth/AccountDropdown.tsx b/src/frontend/apps/impress/src/core/auth/ButtonLogin.tsx
similarity index 94%
rename from src/frontend/apps/impress/src/core/auth/AccountDropdown.tsx
rename to src/frontend/apps/impress/src/core/auth/ButtonLogin.tsx
index 43344d4b..f54fab32 100644
--- a/src/frontend/apps/impress/src/core/auth/AccountDropdown.tsx
+++ b/src/frontend/apps/impress/src/core/auth/ButtonLogin.tsx
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
import { useAuthStore } from '@/core/auth';
-export const AccountDropdown = () => {
+export const ButtonLogin = () => {
const { t } = useTranslation();
const { logout, authenticated, login } = useAuthStore();
diff --git a/src/frontend/apps/impress/src/core/auth/index.ts b/src/frontend/apps/impress/src/core/auth/index.ts
index abae4bc5..e45c9a64 100644
--- a/src/frontend/apps/impress/src/core/auth/index.ts
+++ b/src/frontend/apps/impress/src/core/auth/index.ts
@@ -1,4 +1,4 @@
-export * from './AccountDropdown';
export * from './api/types';
export * from './Auth';
+export * from './ButtonLogin';
export * from './useAuthStore';
diff --git a/src/frontend/apps/impress/src/features/header/components/Burger/Burger.module.css b/src/frontend/apps/impress/src/features/header/components/Burger/Burger.module.css
new file mode 100644
index 00000000..506ecfbe
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/header/components/Burger/Burger.module.css
@@ -0,0 +1,32 @@
+.burgerIcon {
+ cursor: pointer;
+ transform: translate(-20%, 0%);
+}
+
+.burgerIcon path {
+ stroke-width: 40;
+ stroke-linecap: round;
+ fill: none;
+ transition: all 0.5s ease-in-out;
+}
+
+/* In menu form */
+.burgerIcon path:first-child,
+.burgerIcon path:last-child {
+ stroke-dasharray: 240px 910px;
+}
+
+.burgerIcon .middle_bar {
+ stroke-dasharray: 240px 240px;
+}
+
+/* In cross form */
+.open path:first-child,
+.open path:last-child {
+ stroke-dashoffset: -650px;
+}
+
+.open :nth-child(2) {
+ stroke-dasharray: 0 220px;
+ stroke-dashoffset: -120px;
+}
diff --git a/src/frontend/apps/impress/src/features/header/components/Burger/Burger.spec.tsx b/src/frontend/apps/impress/src/features/header/components/Burger/Burger.spec.tsx
new file mode 100644
index 00000000..dcf7c10f
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/header/components/Burger/Burger.spec.tsx
@@ -0,0 +1,18 @@
+import { render, screen } from '@testing-library/react';
+import React from 'react';
+
+import { Burger } from './Burger';
+
+describe('', () => {
+ test('Burger interactions', () => {
+ const { rerender } = render();
+
+ const burger = screen.getByRole('img');
+ expect(burger).toBeInTheDocument();
+ expect(burger.classList.contains('open')).toBeTruthy();
+
+ rerender();
+
+ expect(burger.classList.contains('open')).not.toBeTruthy();
+ });
+});
diff --git a/src/frontend/apps/impress/src/features/header/components/Burger/Burger.tsx b/src/frontend/apps/impress/src/features/header/components/Burger/Burger.tsx
new file mode 100644
index 00000000..c5941f81
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/header/components/Burger/Burger.tsx
@@ -0,0 +1,31 @@
+import { SVGProps } from 'react';
+
+import { Box } from '@/components';
+import { useCunninghamTheme } from '@/cunningham';
+
+import styles from './Burger.module.css';
+import BurgerIcon from './burger.svg';
+
+type BurgerProps = SVGProps & {
+ isOpen: boolean;
+};
+
+export const Burger = ({ isOpen, ...props }: BurgerProps) => {
+ const { colorsTokens } = useCunninghamTheme();
+
+ return (
+
+
+
+ );
+};
+
+export default Burger;
diff --git a/src/frontend/apps/impress/src/features/header/components/Burger/burger.svg b/src/frontend/apps/impress/src/features/header/components/Burger/burger.svg
new file mode 100644
index 00000000..ac1d6e3a
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/header/components/Burger/burger.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/frontend/apps/impress/src/features/header/components/DropdownMenu.tsx b/src/frontend/apps/impress/src/features/header/components/DropdownMenu.tsx
new file mode 100644
index 00000000..1b17fc9e
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/header/components/DropdownMenu.tsx
@@ -0,0 +1,46 @@
+import { useState } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import { Box, DropButton } from '@/components';
+import { ButtonLogin } from '@/core';
+import { useCunninghamTheme } from '@/cunningham';
+import { LanguagePicker } from '@/features/language';
+
+import { Burger } from './Burger/Burger';
+
+export const DropdownMenu = () => {
+ const { colorsTokens } = useCunninghamTheme();
+ const [isDropOpen, setIsDropOpen] = useState(false);
+ const { t } = useTranslation();
+
+ return (
+
+ }
+ onOpenChange={(isOpen) => setIsDropOpen(isOpen)}
+ isOpen={isDropOpen}
+ >
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/frontend/apps/impress/src/features/header/Header.tsx b/src/frontend/apps/impress/src/features/header/components/Header.tsx
similarity index 50%
rename from src/frontend/apps/impress/src/features/header/Header.tsx
rename to src/frontend/apps/impress/src/features/header/components/Header.tsx
index f5802b3d..7e022e5d 100644
--- a/src/frontend/apps/impress/src/features/header/Header.tsx
+++ b/src/frontend/apps/impress/src/features/header/components/Header.tsx
@@ -1,59 +1,40 @@
import Image from 'next/image';
import React from 'react';
import { useTranslation } from 'react-i18next';
-import styled from 'styled-components';
import { Box, StyledLink, Text } from '@/components/';
-import { AccountDropdown } from '@/core/auth';
-import { useCunninghamTheme } from '@/cunningham';
+import { ButtonLogin } from '@/core/auth';
+import { LanguagePicker } from '@/features/language';
+import { useResponsiveStore } from '@/stores';
-import { LanguagePicker } from '../language/';
+import { default as IconDocs } from '../assets/icon-docs.svg?url';
+import { DropdownMenu } from './DropdownMenu';
import { LaGaufre } from './LaGaufre';
-import { default as IconDocs } from './assets/icon-docs.svg?url';
-
-export const HEADER_HEIGHT = '100px';
-
-const RedStripe = styled.div`
- position: absolute;
- height: 5px;
- width: 100%;
- background: var(--c--theme--colors--danger-500);
- top: 0;
-`;
export const Header = () => {
const { t } = useTranslation();
- const { themeTokens } = useCunninghamTheme();
- const logo = themeTokens().logo;
+ const { isSmallMobile } = useResponsiveStore();
return (
-
-
- {logo && (
-
- )}
+
{
$height="fit-content"
$margin={{ top: 'auto' }}
>
-
+
BETA
-
+
{t('Docs')}
-
-
-
-
-
+ {isSmallMobile ? (
+
+
+
+
+ ) : (
+
+
+
+
+
+ )}
);
diff --git a/src/frontend/apps/impress/src/features/header/LaGaufre.tsx b/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx
similarity index 63%
rename from src/frontend/apps/impress/src/features/header/LaGaufre.tsx
rename to src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx
index 58dbdefa..627ac8ee 100644
--- a/src/frontend/apps/impress/src/features/header/LaGaufre.tsx
+++ b/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx
@@ -2,6 +2,13 @@ import { Gaufre } from '@gouvfr-lasuite/integration';
import '@gouvfr-lasuite/integration/dist/css/gaufre.css';
import Script from 'next/script';
import React from 'react';
+import { createGlobalStyle } from 'styled-components';
+
+const GaufreStyle = createGlobalStyle`
+ .lasuite-gaufre-btn{
+ box-shadow: inset 0 0 0 0 !important;
+ }
+`;
export const LaGaufre = () => (
<>
@@ -10,6 +17,7 @@ export const LaGaufre = () => (
strategy="lazyOnload"
id="lasuite-gaufre-script"
/>
-
+
+
>
);
diff --git a/src/frontend/apps/impress/src/features/header/index.ts b/src/frontend/apps/impress/src/features/header/index.ts
index 266dec8a..428157f9 100644
--- a/src/frontend/apps/impress/src/features/header/index.ts
+++ b/src/frontend/apps/impress/src/features/header/index.ts
@@ -1 +1 @@
-export * from './Header';
+export * from './components/Header';
diff --git a/src/frontend/apps/impress/src/features/language/LanguagePicker.tsx b/src/frontend/apps/impress/src/features/language/LanguagePicker.tsx
index 990cd772..e40a8475 100644
--- a/src/frontend/apps/impress/src/features/language/LanguagePicker.tsx
+++ b/src/frontend/apps/impress/src/features/language/LanguagePicker.tsx
@@ -10,12 +10,12 @@ import IconLanguage from './assets/icon-language.svg?url';
const SelectStyled = styled(Select)<{ $isSmall?: boolean }>`
flex-shrink: 0;
- width: 5.5rem;
+ width: auto;
.c__select__wrapper {
min-height: 2rem;
height: auto;
- border-color: #ddd;
+ border-color: transparent;
padding: 0 0.15rem 0 0.45rem;
border-radius: 1px;
@@ -28,7 +28,7 @@ const SelectStyled = styled(Select)<{ $isSmall?: boolean }>`
}
&:hover {
- border-color: var(--c--theme--colors--primary-500);
+ box-shadow: var(--c--theme--colors--primary-100) 0 0 0 2px !important;
}
}
`;
diff --git a/src/frontend/apps/impress/src/layouts/MainLayout.tsx b/src/frontend/apps/impress/src/layouts/MainLayout.tsx
index db050df1..5176557e 100644
--- a/src/frontend/apps/impress/src/layouts/MainLayout.tsx
+++ b/src/frontend/apps/impress/src/layouts/MainLayout.tsx
@@ -1,6 +1,6 @@
import { Box } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
-import { HEADER_HEIGHT, Header } from '@/features/header';
+import { Header } from '@/features/header';
export function MainLayout({ children }: { children: React.ReactNode }) {
const { colorsTokens } = useCunninghamTheme();
@@ -12,7 +12,7 @@ export function MainLayout({ children }: { children: React.ReactNode }) {
diff --git a/src/frontend/apps/impress/src/pages/_app.tsx b/src/frontend/apps/impress/src/pages/_app.tsx
index 48b8a2d0..6af42f45 100644
--- a/src/frontend/apps/impress/src/pages/_app.tsx
+++ b/src/frontend/apps/impress/src/pages/_app.tsx
@@ -28,6 +28,7 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) {
)}
/>
+
{getLayout()}
>