From 36b0ff9f6322c7b90266000afacb7a44968c9a36 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 25 Mar 2025 13:01:48 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20create=20generic=20theme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default Docs will not be on the dsfr theme but on the generic theme. La Gaufre is part of the dsfr theme and is removed from the generic theme. Same for the "beta" keyword and the "proconnect" buttons. --- CHANGELOG.md | 1 + env.d/development/common.dist | 3 - .../e2e/__tests__/app-impress/404.spec.ts | 2 - .../apps/e2e/__tests__/app-impress/common.ts | 20 +- .../e2e/__tests__/app-impress/config.spec.ts | 41 ++-- .../__tests__/app-impress/doc-grid.spec.ts | 1 - .../app-impress/doc-visibility.spec.ts | 14 +- .../e2e/__tests__/app-impress/footer.spec.ts | 2 +- .../e2e/__tests__/app-impress/header.spec.ts | 48 ++++- .../e2e/__tests__/app-impress/home.spec.ts | 56 +++++ src/frontend/apps/impress/cunningham.ts | 197 +++++++++++++++++- src/frontend/apps/impress/package.json | 2 +- .../impress/src/assets/icons/icon-docs.svg | 4 +- .../impress/src/components/DropButton.tsx | 13 +- .../__tests__/useCunninghamTheme.spec.tsx | 8 +- .../src/cunningham/cunningham-style.css | 26 +++ .../src/cunningham/cunningham-tokens.css | 179 +++++++++++++++- .../src/cunningham/cunningham-tokens.ts | 172 ++++++++++++++- .../src/cunningham/useCunninghamTheme.tsx | 29 +-- .../docs/docs-grid/assets/pinned-document.svg | 179 ++++++++++++---- .../docs/docs-grid/assets/simple-document.svg | 144 ++++++++++--- .../docs-grid/components/SimpleDocItem.tsx | 12 +- .../src/features/header/assets/icon-cells.svg | 61 ------ .../src/features/header/components/Header.tsx | 6 +- .../features/header/components/LaGaufre.tsx | 2 +- .../src/features/header/components/Title.tsx | 48 +++-- .../features/home/components/HomeBanner.tsx | 13 +- .../features/home/components/HomeBottom.tsx | 13 +- .../features/home/components/HomeContent.tsx | 2 +- .../features/home/components/HomeHeader.tsx | 10 +- src/frontend/apps/impress/src/pages/404.tsx | 37 ++-- 31 files changed, 1050 insertions(+), 295 deletions(-) delete mode 100644 src/frontend/apps/impress/src/features/header/assets/icon-cells.svg diff --git a/CHANGELOG.md b/CHANGELOG.md index 1367bc1e..f02bbfa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to - ✨(backend) integrate maleware_detection from django-lasuite #936 - 🏗️(frontend) Footer configurable #959 - 🩺(CI) add lint spell mistakes #954 +- ✨(frontend) create generic theme #792 - 🛂(frontend) block edition to not connected users #945 - 🚸 Let loader during upload analyze #984 diff --git a/env.d/development/common.dist b/env.d/development/common.dist index 4b1389bf..bf1b4553 100644 --- a/env.d/development/common.dist +++ b/env.d/development/common.dist @@ -61,6 +61,3 @@ COLLABORATION_BACKEND_BASE_URL=http://app-dev:8000 COLLABORATION_SERVER_ORIGIN=http://localhost:3000 COLLABORATION_SERVER_SECRET=my-secret COLLABORATION_WS_URL=ws://localhost:4444/collaboration/ws/ - -# Frontend -FRONTEND_THEME=default 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 83b9b823..e55acfe5 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts @@ -10,8 +10,6 @@ test.beforeEach(async ({ page }) => { test.describe('404', () => { test('Checks all the elements are visible', async ({ page }) => { - await expect(page.getByLabel('Image 404')).toBeVisible(); - await expect(page.getByText('Ouch')).toBeVisible(); await expect( page.getByText( 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', diff --git a/src/frontend/apps/e2e/__tests__/app-impress/common.ts b/src/frontend/apps/e2e/__tests__/app-impress/common.ts index eadb609f..ee5f24de 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/common.ts @@ -7,7 +7,7 @@ export const CONFIG = { ENVIRONMENT: 'development', FRONTEND_CSS_URL: null, FRONTEND_HOMEPAGE_FEATURE_ENABLED: true, - FRONTEND_THEME: 'default', + FRONTEND_THEME: null, MEDIA_BASE_URL: 'http://localhost:8083', LANGUAGES: [ ['en-us', 'English'], @@ -20,7 +20,7 @@ export const CONFIG = { POSTHOG_KEY: {}, SENTRY_DSN: null, theme_customization: {}, -}; +} as const; export const overrideConfig = async ( page: Page, @@ -46,10 +46,7 @@ export const keyCloakSignIn = async ( fromHome: boolean = true, ) => { if (fromHome) { - await page - .getByRole('button', { name: 'Proconnect Login' }) - .first() - .click(); + await page.getByRole('button', { name: 'Start Writing' }).first().click(); } const login = `user-e2e-${browserName}`; @@ -109,9 +106,16 @@ export const createDoc = async ( }; export const verifyDocName = async (page: Page, docName: string) => { - const input = page.getByRole('textbox', { name: 'doc title input' }); + await expect( + page.getByLabel('It is the card information about the document.'), + ).toBeVisible({ + timeout: 10000, + }); + try { - await expect(input).toHaveText(docName); + await expect( + page.getByRole('textbox', { name: 'doc title input' }), + ).toHaveText(docName); } catch { await expect(page.getByRole('heading', { name: docName })).toBeVisible(); } diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts index 28379315..21bb085e 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -5,25 +5,6 @@ import { expect, test } from '@playwright/test'; import { CONFIG, createDoc, overrideConfig } from './common'; test.describe('Config', () => { - test('it checks the config api is called', async ({ page }) => { - const responsePromise = page.waitForResponse( - (response) => - response.url().includes('/config/') && response.status() === 200, - ); - - await page.goto('/'); - - const response = await responsePromise; - expect(response.ok()).toBeTruthy(); - - const json = (await response.json()) as typeof CONFIG; - const { theme_customization, ...configApi } = json; - expect(theme_customization).toBeDefined(); - const { theme_customization: _, ...CONFIG_LEFT } = CONFIG; - - expect(configApi).toStrictEqual(CONFIG_LEFT); - }); - test('it checks that sentry is trying to init from config endpoint', async ({ page, }) => { @@ -143,9 +124,7 @@ test.describe('Config', () => { test.describe('Config: Not loggued', () => { test.use({ storageState: { cookies: [], origins: [] } }); - test('it checks that theme is configured from config endpoint', async ({ - page, - }) => { + test('it checks the config api is called', async ({ page }) => { const responsePromise = page.waitForResponse( (response) => response.url().includes('/config/') && response.status() === 200, @@ -156,8 +135,22 @@ test.describe('Config: Not loggued', () => { const response = await responsePromise; expect(response.ok()).toBeTruthy(); - const jsonResponse = await response.json(); - expect(jsonResponse.FRONTEND_THEME).toStrictEqual('default'); + const json = (await response.json()) as typeof CONFIG; + const { theme_customization, ...configApi } = json; + expect(theme_customization).toBeDefined(); + const { theme_customization: _, ...CONFIG_LEFT } = CONFIG; + + expect(configApi).toStrictEqual(CONFIG_LEFT); + }); + + test('it checks that theme is configured from config endpoint', async ({ + page, + }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + + await page.goto('/'); const header = page.locator('header').first(); // alt 'Gouvernement Logo' comes from the theme diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts index 758c8712..12be84ce 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts @@ -208,7 +208,6 @@ test.describe('Documents filters', () => { // Initial state await expect(allDocs).toBeVisible(); - await expect(allDocs).toHaveCSS('background-color', 'rgb(238, 238, 238)'); await expect(allDocs).toHaveAttribute('aria-selected', 'true'); await expect(myDocs).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts index a28200b0..f28fb38d 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts @@ -101,6 +101,8 @@ test.describe('Doc Visibility: Restricted', () => { page, browserName, }) => { + test.slow(); + await page.goto('/'); await keyCloakSignIn(page, browserName); @@ -121,14 +123,16 @@ test.describe('Doc Visibility: Restricted', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); await expect( page.getByText('You do not have permission to view this document.'), - ).toBeVisible(); + ).toBeVisible({ + timeout: 10000, + }); }); test('A doc is accessible when member.', async ({ page, browserName }) => { @@ -173,7 +177,7 @@ test.describe('Doc Visibility: Restricted', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); @@ -430,7 +434,7 @@ test.describe('Doc Visibility: Authenticated', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); @@ -490,7 +494,7 @@ test.describe('Doc Visibility: Authenticated', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts index 93405911..221fbf82 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts @@ -20,7 +20,6 @@ test.describe('Footer', () => { await expect(footer.getByAltText('Docs Logo')).toBeVisible(); await expect(footer.getByRole('heading', { name: 'Docs' })).toBeVisible(); - await expect(footer.getByText('BETA')).toBeVisible(); await expect(footer.getByRole('link', { name: 'Github' })).toBeVisible(); await expect(footer.getByRole('link', { name: 'DINUM' })).toBeVisible(); @@ -57,6 +56,7 @@ test.describe('Footer', () => { test('checks the footer is correctly overrided', async ({ page }) => { await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', theme_customization: { footer: { default: { 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 7234b1fd..1abca24b 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts @@ -1,20 +1,39 @@ import { expect, test } from '@playwright/test'; -import { expectLoginPage, keyCloakSignIn } from './common'; +import { expectLoginPage, keyCloakSignIn, overrideConfig } from './common'; test.describe('Header', () => { - test.beforeEach(async ({ page }) => { - await page.goto('/'); - }); - test('checks all the elements are visible', async ({ page }) => { + await page.goto('/'); + const header = page.locator('header').first(); await expect(header.getByLabel('Docs Logo')).toBeVisible(); await expect(header.locator('h2').getByText('Docs')).toHaveCSS( - 'color', - 'rgb(0, 0, 145)', + 'font-family', + /Roboto/i, ); + + await expect( + header.getByRole('button', { + name: 'Logout', + }), + ).toBeVisible(); + + await expect(header.getByText('English')).toBeVisible(); + }); + + test('checks all the elements are visible with DSFR theme', async ({ + page, + }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + await page.goto('/'); + + const header = page.locator('header').first(); + + await expect(header.getByLabel('Docs Logo')).toBeVisible(); await expect(header.locator('h2').getByText('Docs')).toHaveCSS( 'font-family', /Marianne/i, @@ -36,6 +55,11 @@ test.describe('Header', () => { }); test('checks La Gauffre interaction', async ({ page }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + await page.goto('/'); + const header = page.locator('header').first(); await expect( @@ -68,11 +92,13 @@ 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 with DSFR theme', async ({ page }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + + await page.goto('/'); - test('it checks the header when mobile', async ({ page }) => { const header = page.locator('header').first(); await expect(header.getByLabel('Open the header menu')).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts index b3c7be40..63b74fae 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts @@ -9,6 +9,62 @@ test.beforeEach(async ({ page }) => { test.describe('Home page', () => { test.use({ storageState: { cookies: [], origins: [] } }); test('checks all the elements are visible', async ({ page }) => { + await page.goto('/docs/'); + + // Check header content + const header = page.locator('header').first(); + const footer = page.locator('footer').first(); + await expect(header).toBeVisible(); + await expect( + header.getByRole('button', { name: /Language/ }), + ).toBeVisible(); + await expect(header.getByRole('img', { name: 'Docs logo' })).toBeVisible(); + await expect(header.getByRole('heading', { name: 'Docs' })).toBeVisible(); + + // Check the titles + const h2 = page.locator('h2'); + await expect(h2.getByText('Govs ❤️ Open Source.')).toBeVisible(); + await expect( + h2.getByText('Collaborative writing, Simplified.'), + ).toBeVisible(); + await expect( + h2.getByText('An uncompromising writing experience.'), + ).toBeVisible(); + await expect( + h2.getByText('Simple and secure collaboration.'), + ).toBeVisible(); + await expect(h2.getByText('Flexible export.')).toBeVisible(); + await expect( + h2.getByText('A new way to organize knowledge.'), + ).toBeVisible(); + await expect( + page.getByRole('button', { name: 'Start Writing' }), + ).toBeVisible(); + + await expect(footer).toBeVisible(); + }); + + test('checks all the elements are visible with dsfr theme', async ({ + page, + }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + theme_customization: { + footer: { + default: { + externalLinks: [ + { + label: 'legifrance.gouv.fr', + href: '#', + }, + ], + }, + }, + }, + }); + + await page.goto('/docs/'); + // Check header content const header = page.locator('header').first(); const footer = page.locator('footer').first(); diff --git a/src/frontend/apps/impress/cunningham.ts b/src/frontend/apps/impress/cunningham.ts index 988d39f3..1bccd00e 100644 --- a/src/frontend/apps/impress/cunningham.ts +++ b/src/frontend/apps/impress/cunningham.ts @@ -3,6 +3,8 @@ import { cunninghamConfig as tokens } from '@gouvfr-lasuite/ui-kit'; const customColors = { 'primary-action': '#1212FF', 'primary-bg': '#FAFAFA', + 'primary-focus': '#0A76F6', + 'secondary-icon': 'var(--c--theme--colors--primary-text)', 'blue-400': '#7AB1E8', 'blue-500': '#417DC4', 'blue-600': '#3558A2', @@ -34,7 +36,6 @@ const customColors = { 'yellow-500': '#B7A73F', 'yellow-600': '#66673D', }; - tokens.themes.default.theme.colors = { ...tokens.themes.default.theme.colors, ...customColors, @@ -44,10 +45,10 @@ tokens.themes.default.theme = { ...tokens.themes.default.theme, ...{ logo: { - src: '/assets/logo-gouv.svg', - widthHeader: '110px', - widthFooter: '220px', - alt: 'Gouvernement Logo', + src: '', + alt: '', + widthHeader: '', + widthFooter: '', }, }, }; @@ -55,13 +56,189 @@ tokens.themes.default.theme = { tokens.themes.default.components = { ...tokens.themes.default.components, ...{ - 'la-gauffre': { - activated: true, + 'la-gaufre': false, + 'home-proconnect': false, + beta: false, + }, +}; + +const dsfrTheme = { + dsfr: { + theme: { + colors: { + 'secondary-icon': '#C9191E', + }, + logo: { + src: '/assets/logo-gouv.svg', + widthHeader: '110px', + widthFooter: '220px', + alt: 'Gouvernement Logo', + }, }, - 'home-proconnect': { - activated: true, + components: { + 'la-gaufre': true, + 'home-proconnect': true, + beta: true, }, }, }; -export default tokens; +const genericTheme = { + generic: { + theme: { + colors: { + 'primary-action': '#206EBD', + 'primary-focus': '#1E64BF', + 'primary-text': '#2E2C28', + 'primary-050': '#F8F8F7', + 'primary-100': '#F0EFEC', + 'primary-150': '#F4F4FD', + 'primary-200': '#E8E7E4', + 'primary-300': '#CFCDC9', + 'primary-400': '#979592', + 'primary-500': '#82807D', + 'primary-600': '#3F3D39', + 'primary-700': '#2E2C28', + 'primary-800': '#302E29', + 'primary-900': '#282622', + 'primary-950': '#201F1C', + 'secondary-text': '#fff', + 'secondary-50': '#F4F7FA', + 'secondary-100': '#D7E3EE', + 'secondary-200': '#B8CCE1', + 'secondary-300': '#99B4D3', + 'secondary-400': '#7595BE', + 'secondary-500': '#5874A0', + 'secondary-600': '#3A5383', + 'secondary-700': '#1E3462', + 'secondary-800': '#091B41', + 'secondary-900': '#08183B', + 'secondary-950': '#071636', + 'greyscale-text': '#3C3B38', + 'greyscale-000': '#fff', + 'greyscale-050': '#F8F7F7', + 'greyscale-100': '#F3F3F2', + 'greyscale-200': '#ECEBEA', + 'greyscale-250': '#E4E3E2', + 'greyscale-300': '#D3D2CF', + 'greyscale-350': '#eee', + 'greyscale-400': '#96948E', + 'greyscale-500': '#817E77', + 'greyscale-600': '#6A6862', + 'greyscale-700': '#3C3B38', + 'greyscale-750': '#383632', + 'greyscale-800': '#2D2B27', + 'greyscale-900': '#262522', + 'greyscale-950': '#201F1C', + 'greyscale-1000': '#181714', + 'success-text': '#234935', + 'success-50': '#F3FBF5', + 'success-100': '#E4F7EA', + 'success-200': '#CAEED4', + 'success-300': '#A0E0B5', + 'success-400': '#6CC88C', + 'success-500': '#6CC88C', + 'success-600': '#358D5C', + 'success-700': '#2D704B', + 'success-800': '#28583F', + 'success-900': '#234935', + 'success-950': '#0F281B', + 'info-text': '#212445', + 'info-50': '#F2F6FB', + 'info-100': '#E2E9F5', + 'info-200': '#CCD8EE', + 'info-300': '#A9C0E3', + 'info-400': '#809DD4', + 'info-500': '#617BC7', + 'info-600': '#4A5CBF', + 'info-700': '#3E49B2', + 'info-800': '#353C8F', + 'info-900': '#303771', + 'info-950': '#212445', + 'warning-text': '#D97C3A', + 'warning-50': '#FDF7F1', + 'warning-100': '#FBEDDC', + 'warning-200': '#F5D9B9', + 'warning-300': '#EDBE8C', + 'warning-400': '#E2985C', + 'warning-500': '#D97C3A', + 'warning-600': '#C96330', + 'warning-700': '#A34B32', + 'warning-800': '#813B2C', + 'warning-900': '#693327', + 'warning-950': '#381713', + 'danger-action': '#C0182A', + 'danger-text': '#FFF', + 'danger-050': '#FDF5F4', + 'danger-100': '#FBEBE8', + 'danger-200': '#F9E0DC', + 'danger-300': '#F3C3BD', + 'danger-400': '#E26552', + 'danger-500': '#C91F00', + 'danger-600': '#A71901', + 'danger-700': '#562C2B', + 'danger-800': '#392425', + 'danger-900': '#311F20', + 'danger-950': '#2A191A', + 'blue-400': '#8BAECC', + 'blue-500': '#567AA2', + 'blue-600': '#455784', + 'brown-400': '#E4C090', + 'brown-500': '#BA9977', + 'brown-600': '#735C45', + 'cyan-400': '#5CBEC9', + 'cyan-500': '#43A1B3', + 'cyan-600': '#39809B', + 'gold-400': '#ECBF50', + 'gold-500': '#DFA038', + 'gold-600': '#C17B31', + 'green-400': '#5DBD9A', + 'green-500': '#3AA183', + 'green-600': '#2A816D', + 'olive-400': '#AFD662', + 'olive-500': '#90BB4B', + 'olive-600': '#6E9441', + 'orange-400': '#E2985C', + 'orange-500': '#D97C3A', + 'orange-600': '#C96330', + 'pink-400': '#BE8FC8', + 'pink-500': '#A563B1', + 'pink-600': '#8B44A5', + 'purple-400': '#BE8FC8', + 'purple-500': '#A563B1', + 'purple-600': '#8B44A5', + 'yellow-400': '#EDC947', + 'yellow-500': '#DBB13A', + 'yellow-600': '#B88A34', + }, + font: { + families: { + base: 'Inter, Roboto Flex Variable, sans-serif', + accent: 'Inter, Roboto Flex Variable, sans-serif', + }, + }, + }, + components: { + button: { + primary: { + background: { + 'color-hover': 'var(--c--theme--colors--primary-focus)', + 'color-active': 'var(--c--theme--colors--primary-focus)', + 'color-focus': 'var(--c--theme--colors--primary-focus)', + }, + }, + }, + }, + }, +}; + +const docsTokens = { + ...tokens, + themes: { + ...tokens.themes, + ...dsfrTheme, + ...genericTheme, + }, +}; + +export default docsTokens; diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index dc1d0c59..416510f1 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -6,7 +6,7 @@ "dev": "next dev", "build": "prettier --check . && yarn stylelint && next build", "build:ci": "cp .env.development .env.local && yarn build", - "build-theme": "cunningham -g css,ts -o src/cunningham --utility-classes && yarn prettier", + "build-theme": "cunningham -g css,ts -o src/cunningham --utility-classes && yarn prettier && yarn stylelint --fix", "start": "npx -y serve@latest out", "lint": "tsc --noEmit && next lint", "prettier": "prettier --write .", diff --git a/src/frontend/apps/impress/src/assets/icons/icon-docs.svg b/src/frontend/apps/impress/src/assets/icons/icon-docs.svg index 05cf0436..882e92ef 100644 --- a/src/frontend/apps/impress/src/assets/icons/icon-docs.svg +++ b/src/frontend/apps/impress/src/assets/icons/icon-docs.svg @@ -1,12 +1,12 @@ diff --git a/src/frontend/apps/impress/src/components/DropButton.tsx b/src/frontend/apps/impress/src/components/DropButton.tsx index 5dfc1054..22f18f67 100644 --- a/src/frontend/apps/impress/src/components/DropButton.tsx +++ b/src/frontend/apps/impress/src/components/DropButton.tsx @@ -6,7 +6,9 @@ import { useState, } from 'react'; import { Button, Popover } from 'react-aria-components'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; + +import { useCunninghamTheme } from '@/cunningham'; import { BoxProps } from './Box'; @@ -27,11 +29,9 @@ const StyledButton = styled(Button)` background: none; outline: none; transition: all 0.2s ease-in-out; - font-family: Marianne, Arial, serif; font-weight: 500; font-size: 0.938rem; padding: 0; - text-wrap: nowrap; ${({ $css }) => $css}; `; @@ -51,6 +51,8 @@ export const DropButton = ({ children, label, }: PropsWithChildren) => { + const { themeTokens } = useCunninghamTheme(); + const font = themeTokens['font']?.['families']['base']; const [isLocalOpen, setIsLocalOpen] = useState(isOpen); const triggerRef = useRef(null); @@ -70,7 +72,10 @@ export const DropButton = ({ ref={triggerRef} onPress={() => onOpenChangeHandler(true)} aria-label={label} - $css={buttonCss} + $css={css` + font-family: ${font}; + ${buttonCss}; + `} className="--docs--drop-button" > {button} diff --git a/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx b/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx index 425781d6..208d8942 100644 --- a/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx +++ b/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx @@ -2,8 +2,12 @@ import { useCunninghamTheme } from '../useCunninghamTheme'; describe('', () => { it('has the logo correctly set', () => { - const { themeTokens, setTheme } = useCunninghamTheme.getState(); - setTheme('default'); + expect(useCunninghamTheme.getState().themeTokens.logo?.src).toBe(''); + + // Change theme + useCunninghamTheme.getState().setTheme('dsfr'); + + const { themeTokens } = useCunninghamTheme.getState(); const logo = themeTokens.logo; expect(logo?.src).toBe('/assets/logo-gouv.svg'); expect(logo?.widthHeader).toBe('110px'); diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-style.css b/src/frontend/apps/impress/src/cunningham/cunningham-style.css index f3d42853..b98989ac 100644 --- a/src/frontend/apps/impress/src/cunningham/cunningham-style.css +++ b/src/frontend/apps/impress/src/cunningham/cunningham-style.css @@ -43,3 +43,29 @@ .c__tooltip { padding: 4px 6px; } + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('https://fonts.gstatic.com/s/inter/v18/UcCm3FwrK3iLTcvnUwQT9g.woff2') + format('woff2'); + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, + U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, + U+2215, U+FEFF, U+FFFD; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('https://fonts.gstatic.com/s/inter/v18/UcCo3FwrK3iLTcviYwY.woff2') + format('woff2'); + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, + U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, + U+2215, U+FEFF, U+FFFD; +} diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css index c48bc4b1..f16f85fc 100644 --- a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css +++ b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css @@ -92,6 +92,8 @@ --c--theme--colors--rose-500: #e18b76; --c--theme--colors--primary-action: #1212ff; --c--theme--colors--primary-bg: #fafafa; + --c--theme--colors--primary-focus: #0a76f6; + --c--theme--colors--secondary-icon: var(--c--theme--colors--primary-text); --c--theme--colors--blue-400: #7ab1e8; --c--theme--colors--blue-600: #3558a2; --c--theme--colors--brown-400: #e6be92; @@ -190,10 +192,10 @@ --c--theme--breakpoints--xxs: 320px; --c--theme--breakpoints--mobile: 768px; --c--theme--breakpoints--tablet: 1024px; - --c--theme--logo--src: /assets/logo-gouv.svg; - --c--theme--logo--widthheader: 110px; - --c--theme--logo--widthfooter: 220px; - --c--theme--logo--alt: gouvernement logo; + --c--theme--logo--src: ; + --c--theme--logo--alt: ; + --c--theme--logo--widthheader: ; + --c--theme--logo--widthfooter: ; --c--components--modal--width-small: 342px; --c--components--tooltip--padding: 4px 8px; --c--components--tooltip--background-color: var( @@ -485,8 +487,9 @@ --c--theme--colors--info-100 ); --c--components--badge--info--color: var(--c--theme--colors--info-600); - --c--components--la-gauffre--activated: true; - --c--components--home-proconnect--activated: true; + --c--components--la-gaufre: false; + --c--components--home-proconnect: false; + --c--components--beta: false; } .cunningham-theme--dark { @@ -538,6 +541,154 @@ --c--theme--colors--danger-900: #9d6666; } +.cunningham-theme--dsfr { + --c--theme--colors--secondary-icon: #c9191e; + --c--theme--logo--src: /assets/logo-gouv.svg; + --c--theme--logo--widthHeader: 110px; + --c--theme--logo--widthFooter: 220px; + --c--theme--logo--alt: gouvernement logo; + --c--components--la-gaufre: true; + --c--components--home-proconnect: true; + --c--components--beta: true; +} + +.cunningham-theme--generic { + --c--theme--colors--primary-action: #206ebd; + --c--theme--colors--primary-focus: #1e64bf; + --c--theme--colors--primary-text: #2e2c28; + --c--theme--colors--primary-050: #f8f8f7; + --c--theme--colors--primary-100: #f0efec; + --c--theme--colors--primary-150: #f4f4fd; + --c--theme--colors--primary-200: #e8e7e4; + --c--theme--colors--primary-300: #cfcdc9; + --c--theme--colors--primary-400: #979592; + --c--theme--colors--primary-500: #82807d; + --c--theme--colors--primary-600: #3f3d39; + --c--theme--colors--primary-700: #2e2c28; + --c--theme--colors--primary-800: #302e29; + --c--theme--colors--primary-900: #282622; + --c--theme--colors--primary-950: #201f1c; + --c--theme--colors--secondary-text: #fff; + --c--theme--colors--secondary-50: #f4f7fa; + --c--theme--colors--secondary-100: #d7e3ee; + --c--theme--colors--secondary-200: #b8cce1; + --c--theme--colors--secondary-300: #99b4d3; + --c--theme--colors--secondary-400: #7595be; + --c--theme--colors--secondary-500: #5874a0; + --c--theme--colors--secondary-600: #3a5383; + --c--theme--colors--secondary-700: #1e3462; + --c--theme--colors--secondary-800: #091b41; + --c--theme--colors--secondary-900: #08183b; + --c--theme--colors--secondary-950: #071636; + --c--theme--colors--greyscale-text: #3c3b38; + --c--theme--colors--greyscale-000: #fff; + --c--theme--colors--greyscale-050: #f8f7f7; + --c--theme--colors--greyscale-100: #f3f3f2; + --c--theme--colors--greyscale-200: #ecebea; + --c--theme--colors--greyscale-250: #e4e3e2; + --c--theme--colors--greyscale-300: #d3d2cf; + --c--theme--colors--greyscale-350: #eee; + --c--theme--colors--greyscale-400: #96948e; + --c--theme--colors--greyscale-500: #817e77; + --c--theme--colors--greyscale-600: #6a6862; + --c--theme--colors--greyscale-700: #3c3b38; + --c--theme--colors--greyscale-750: #383632; + --c--theme--colors--greyscale-800: #2d2b27; + --c--theme--colors--greyscale-900: #262522; + --c--theme--colors--greyscale-950: #201f1c; + --c--theme--colors--greyscale-1000: #181714; + --c--theme--colors--success-text: #234935; + --c--theme--colors--success-50: #f3fbf5; + --c--theme--colors--success-100: #e4f7ea; + --c--theme--colors--success-200: #caeed4; + --c--theme--colors--success-300: #a0e0b5; + --c--theme--colors--success-400: #6cc88c; + --c--theme--colors--success-500: #6cc88c; + --c--theme--colors--success-600: #358d5c; + --c--theme--colors--success-700: #2d704b; + --c--theme--colors--success-800: #28583f; + --c--theme--colors--success-900: #234935; + --c--theme--colors--success-950: #0f281b; + --c--theme--colors--info-text: #212445; + --c--theme--colors--info-50: #f2f6fb; + --c--theme--colors--info-100: #e2e9f5; + --c--theme--colors--info-200: #ccd8ee; + --c--theme--colors--info-300: #a9c0e3; + --c--theme--colors--info-400: #809dd4; + --c--theme--colors--info-500: #617bc7; + --c--theme--colors--info-600: #4a5cbf; + --c--theme--colors--info-700: #3e49b2; + --c--theme--colors--info-800: #353c8f; + --c--theme--colors--info-900: #303771; + --c--theme--colors--info-950: #212445; + --c--theme--colors--warning-text: #d97c3a; + --c--theme--colors--warning-50: #fdf7f1; + --c--theme--colors--warning-100: #fbeddc; + --c--theme--colors--warning-200: #f5d9b9; + --c--theme--colors--warning-300: #edbe8c; + --c--theme--colors--warning-400: #e2985c; + --c--theme--colors--warning-500: #d97c3a; + --c--theme--colors--warning-600: #c96330; + --c--theme--colors--warning-700: #a34b32; + --c--theme--colors--warning-800: #813b2c; + --c--theme--colors--warning-900: #693327; + --c--theme--colors--warning-950: #381713; + --c--theme--colors--danger-action: #c0182a; + --c--theme--colors--danger-text: #fff; + --c--theme--colors--danger-050: #fdf5f4; + --c--theme--colors--danger-100: #fbebe8; + --c--theme--colors--danger-200: #f9e0dc; + --c--theme--colors--danger-300: #f3c3bd; + --c--theme--colors--danger-400: #e26552; + --c--theme--colors--danger-500: #c91f00; + --c--theme--colors--danger-600: #a71901; + --c--theme--colors--danger-700: #562c2b; + --c--theme--colors--danger-800: #392425; + --c--theme--colors--danger-900: #311f20; + --c--theme--colors--danger-950: #2a191a; + --c--theme--colors--blue-400: #8baecc; + --c--theme--colors--blue-500: #567aa2; + --c--theme--colors--blue-600: #455784; + --c--theme--colors--brown-400: #e4c090; + --c--theme--colors--brown-500: #ba9977; + --c--theme--colors--brown-600: #735c45; + --c--theme--colors--cyan-400: #5cbec9; + --c--theme--colors--cyan-500: #43a1b3; + --c--theme--colors--cyan-600: #39809b; + --c--theme--colors--gold-400: #ecbf50; + --c--theme--colors--gold-500: #dfa038; + --c--theme--colors--gold-600: #c17b31; + --c--theme--colors--green-400: #5dbd9a; + --c--theme--colors--green-500: #3aa183; + --c--theme--colors--green-600: #2a816d; + --c--theme--colors--olive-400: #afd662; + --c--theme--colors--olive-500: #90bb4b; + --c--theme--colors--olive-600: #6e9441; + --c--theme--colors--orange-400: #e2985c; + --c--theme--colors--orange-500: #d97c3a; + --c--theme--colors--orange-600: #c96330; + --c--theme--colors--pink-400: #be8fc8; + --c--theme--colors--pink-500: #a563b1; + --c--theme--colors--pink-600: #8b44a5; + --c--theme--colors--purple-400: #be8fc8; + --c--theme--colors--purple-500: #a563b1; + --c--theme--colors--purple-600: #8b44a5; + --c--theme--colors--yellow-400: #edc947; + --c--theme--colors--yellow-500: #dbb13a; + --c--theme--colors--yellow-600: #b88a34; + --c--theme--font--families--base: inter, roboto flex variable, sans-serif; + --c--theme--font--families--accent: inter, roboto flex variable, sans-serif; + --c--components--button--primary--background--color-hover: var( + --c--theme--colors--primary-focus + ); + --c--components--button--primary--background--color-active: var( + --c--theme--colors--primary-focus + ); + --c--components--button--primary--background--color-focus: var( + --c--theme--colors--primary-focus + ); +} + .clr-secondary-text { color: var(--c--theme--colors--secondary-text); } @@ -910,6 +1061,14 @@ color: var(--c--theme--colors--primary-bg); } +.clr-primary-focus { + color: var(--c--theme--colors--primary-focus); +} + +.clr-secondary-icon { + color: var(--c--theme--colors--secondary-icon); +} + .clr-blue-400 { color: var(--c--theme--colors--blue-400); } @@ -1366,6 +1525,14 @@ background-color: var(--c--theme--colors--primary-bg); } +.bg-primary-focus { + background-color: var(--c--theme--colors--primary-focus); +} + +.bg-secondary-icon { + background-color: var(--c--theme--colors--secondary-icon); +} + .bg-blue-400 { background-color: var(--c--theme--colors--blue-400); } diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts index 1687edf4..27d06644 100644 --- a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts +++ b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts @@ -96,6 +96,8 @@ export const tokens = { 'rose-500': '#E18B76', 'primary-action': '#1212FF', 'primary-bg': '#FAFAFA', + 'primary-focus': '#0A76F6', + 'secondary-icon': 'var(--c--theme--colors--primary-text)', 'blue-400': '#7AB1E8', 'blue-600': '#3558A2', 'brown-400': '#E6BE92', @@ -208,12 +210,7 @@ export const tokens = { mobile: '768px', tablet: '1024px', }, - logo: { - src: '/assets/logo-gouv.svg', - widthHeader: '110px', - widthFooter: '220px', - alt: 'Gouvernement Logo', - }, + logo: { src: '', alt: '', widthHeader: '', widthFooter: '' }, }, components: { modal: { 'width-small': '342px' }, @@ -366,8 +363,9 @@ export const tokens = { warning: { 'background-color': '#fff4f3', color: '#b34000' }, info: { 'background-color': '#E8EDFF', color: '#0063CB' }, }, - 'la-gauffre': { activated: true }, - 'home-proconnect': { activated: true }, + 'la-gaufre': false, + 'home-proconnect': false, + beta: false, }, }, dark: { @@ -422,5 +420,163 @@ export const tokens = { }, }, }, + dsfr: { + theme: { + colors: { 'secondary-icon': '#C9191E' }, + logo: { + src: '/assets/logo-gouv.svg', + widthHeader: '110px', + widthFooter: '220px', + alt: 'Gouvernement Logo', + }, + }, + components: { 'la-gaufre': true, 'home-proconnect': true, beta: true }, + }, + generic: { + theme: { + colors: { + 'primary-action': '#206EBD', + 'primary-focus': '#1E64BF', + 'primary-text': '#2E2C28', + 'primary-050': '#F8F8F7', + 'primary-100': '#F0EFEC', + 'primary-150': '#F4F4FD', + 'primary-200': '#E8E7E4', + 'primary-300': '#CFCDC9', + 'primary-400': '#979592', + 'primary-500': '#82807D', + 'primary-600': '#3F3D39', + 'primary-700': '#2E2C28', + 'primary-800': '#302E29', + 'primary-900': '#282622', + 'primary-950': '#201F1C', + 'secondary-text': '#fff', + 'secondary-50': '#F4F7FA', + 'secondary-100': '#D7E3EE', + 'secondary-200': '#B8CCE1', + 'secondary-300': '#99B4D3', + 'secondary-400': '#7595BE', + 'secondary-500': '#5874A0', + 'secondary-600': '#3A5383', + 'secondary-700': '#1E3462', + 'secondary-800': '#091B41', + 'secondary-900': '#08183B', + 'secondary-950': '#071636', + 'greyscale-text': '#3C3B38', + 'greyscale-000': '#fff', + 'greyscale-050': '#F8F7F7', + 'greyscale-100': '#F3F3F2', + 'greyscale-200': '#ECEBEA', + 'greyscale-250': '#E4E3E2', + 'greyscale-300': '#D3D2CF', + 'greyscale-350': '#eee', + 'greyscale-400': '#96948E', + 'greyscale-500': '#817E77', + 'greyscale-600': '#6A6862', + 'greyscale-700': '#3C3B38', + 'greyscale-750': '#383632', + 'greyscale-800': '#2D2B27', + 'greyscale-900': '#262522', + 'greyscale-950': '#201F1C', + 'greyscale-1000': '#181714', + 'success-text': '#234935', + 'success-50': '#F3FBF5', + 'success-100': '#E4F7EA', + 'success-200': '#CAEED4', + 'success-300': '#A0E0B5', + 'success-400': '#6CC88C', + 'success-500': '#6CC88C', + 'success-600': '#358D5C', + 'success-700': '#2D704B', + 'success-800': '#28583F', + 'success-900': '#234935', + 'success-950': '#0F281B', + 'info-text': '#212445', + 'info-50': '#F2F6FB', + 'info-100': '#E2E9F5', + 'info-200': '#CCD8EE', + 'info-300': '#A9C0E3', + 'info-400': '#809DD4', + 'info-500': '#617BC7', + 'info-600': '#4A5CBF', + 'info-700': '#3E49B2', + 'info-800': '#353C8F', + 'info-900': '#303771', + 'info-950': '#212445', + 'warning-text': '#D97C3A', + 'warning-50': '#FDF7F1', + 'warning-100': '#FBEDDC', + 'warning-200': '#F5D9B9', + 'warning-300': '#EDBE8C', + 'warning-400': '#E2985C', + 'warning-500': '#D97C3A', + 'warning-600': '#C96330', + 'warning-700': '#A34B32', + 'warning-800': '#813B2C', + 'warning-900': '#693327', + 'warning-950': '#381713', + 'danger-action': '#C0182A', + 'danger-text': '#FFF', + 'danger-050': '#FDF5F4', + 'danger-100': '#FBEBE8', + 'danger-200': '#F9E0DC', + 'danger-300': '#F3C3BD', + 'danger-400': '#E26552', + 'danger-500': '#C91F00', + 'danger-600': '#A71901', + 'danger-700': '#562C2B', + 'danger-800': '#392425', + 'danger-900': '#311F20', + 'danger-950': '#2A191A', + 'blue-400': '#8BAECC', + 'blue-500': '#567AA2', + 'blue-600': '#455784', + 'brown-400': '#E4C090', + 'brown-500': '#BA9977', + 'brown-600': '#735C45', + 'cyan-400': '#5CBEC9', + 'cyan-500': '#43A1B3', + 'cyan-600': '#39809B', + 'gold-400': '#ECBF50', + 'gold-500': '#DFA038', + 'gold-600': '#C17B31', + 'green-400': '#5DBD9A', + 'green-500': '#3AA183', + 'green-600': '#2A816D', + 'olive-400': '#AFD662', + 'olive-500': '#90BB4B', + 'olive-600': '#6E9441', + 'orange-400': '#E2985C', + 'orange-500': '#D97C3A', + 'orange-600': '#C96330', + 'pink-400': '#BE8FC8', + 'pink-500': '#A563B1', + 'pink-600': '#8B44A5', + 'purple-400': '#BE8FC8', + 'purple-500': '#A563B1', + 'purple-600': '#8B44A5', + 'yellow-400': '#EDC947', + 'yellow-500': '#DBB13A', + 'yellow-600': '#B88A34', + }, + font: { + families: { + base: 'Inter, Roboto Flex Variable, sans-serif', + accent: 'Inter, Roboto Flex Variable, sans-serif', + }, + }, + }, + components: { + button: { + primary: { + background: { + 'color-hover': 'var(--c--theme--colors--primary-focus)', + 'color-active': 'var(--c--theme--colors--primary-focus)', + 'color-focus': 'var(--c--theme--colors--primary-focus)', + }, + }, + }, + }, + }, }, }; diff --git a/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx b/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx index 7cc5e662..0e266199 100644 --- a/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx +++ b/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx @@ -12,30 +12,32 @@ type ComponentTokens = Tokens['components']; export type Theme = keyof typeof tokens.themes; interface ThemeStore { - theme: Theme; - setTheme: (theme: Theme) => void; - themeTokens: Partial; colorsTokens: Partial; - fontSizesTokens: Partial; - spacingsTokens: Partial; componentTokens: ComponentTokens; + currentTokens: Partial; + fontSizesTokens: Partial; + setTheme: (theme: Theme) => void; + spacingsTokens: Partial; + theme: Theme; + themeTokens: Partial; } const getMergedTokens = (theme: Theme) => { return merge({}, tokens.themes['default'], tokens.themes[theme]); }; -const DEFAULT_THEME: Theme = 'default'; +const DEFAULT_THEME: Theme = 'generic'; const defaultTokens = getMergedTokens(DEFAULT_THEME); const initialState: ThemeStore = { - theme: DEFAULT_THEME, - setTheme: () => {}, - themeTokens: defaultTokens.theme, colorsTokens: defaultTokens.theme.colors, componentTokens: defaultTokens.components, - spacingsTokens: defaultTokens.theme.spacings, + currentTokens: tokens.themes[DEFAULT_THEME] as Partial, fontSizesTokens: defaultTokens.theme.font.sizes, + setTheme: () => {}, + spacingsTokens: defaultTokens.theme.spacings, + theme: DEFAULT_THEME, + themeTokens: defaultTokens.theme, }; export const useCunninghamTheme = create((set) => ({ @@ -44,12 +46,13 @@ export const useCunninghamTheme = create((set) => ({ const newTokens = getMergedTokens(theme); set({ - theme, - themeTokens: newTokens.theme, colorsTokens: newTokens.theme.colors, componentTokens: newTokens.components, - spacingsTokens: newTokens.theme.spacings, + currentTokens: tokens.themes[theme] as Partial, fontSizesTokens: newTokens.theme.font.sizes, + spacingsTokens: newTokens.theme.spacings, + theme, + themeTokens: newTokens.theme, }); }, })); diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg index af34c0b0..027fb33b 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg @@ -1,51 +1,138 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg index 817cf203..ee656f0d 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg @@ -1,37 +1,117 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx index 1a02d87a..e4d13834 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx @@ -32,7 +32,7 @@ export const SimpleDocItem = ({ showAccesses = false, }: SimpleDocItemProps) => { const { t } = useTranslation(); - const { spacingsTokens } = useCunninghamTheme(); + const { spacingsTokens, colorsTokens } = useCunninghamTheme(); const { isDesktop } = useResponsiveStore(); const { untitledDocument } = useTrans(); @@ -52,9 +52,15 @@ export const SimpleDocItem = ({ `} > {isPinned ? ( - + ) : ( - + )} diff --git a/src/frontend/apps/impress/src/features/header/assets/icon-cells.svg b/src/frontend/apps/impress/src/features/header/assets/icon-cells.svg deleted file mode 100644 index 15329758..00000000 --- a/src/frontend/apps/impress/src/features/header/assets/icon-cells.svg +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - diff --git a/src/frontend/apps/impress/src/features/header/components/Header.tsx b/src/frontend/apps/impress/src/features/header/components/Header.tsx index 73b15d7e..39f3ce63 100644 --- a/src/frontend/apps/impress/src/features/header/components/Header.tsx +++ b/src/frontend/apps/impress/src/features/header/components/Header.tsx @@ -48,7 +48,11 @@ export const Header = () => { $height="fit-content" $margin={{ top: 'auto' }} > - + </Box> </StyledLink> diff --git a/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx b/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx index 8f99198d..39c4f1ea 100644 --- a/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx +++ b/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx @@ -15,7 +15,7 @@ const GaufreStyle = createGlobalStyle` export const LaGaufre = () => { const { componentTokens } = useCunninghamTheme(); - if (!componentTokens['la-gauffre'].activated) { + if (!componentTokens['la-gaufre']) { return null; } diff --git a/src/frontend/apps/impress/src/features/header/components/Title.tsx b/src/frontend/apps/impress/src/features/header/components/Title.tsx index be3b2706..9c328e4f 100644 --- a/src/frontend/apps/impress/src/features/header/components/Title.tsx +++ b/src/frontend/apps/impress/src/features/header/components/Title.tsx @@ -6,7 +6,9 @@ import { useCunninghamTheme } from '@/cunningham'; export const Title = () => { const { t } = useTranslation(); - const { spacingsTokens } = useCunninghamTheme(); + const { spacingsTokens, colorsTokens, componentTokens } = + useCunninghamTheme(); + const isBeta = componentTokens['beta']; return ( <Box @@ -18,32 +20,34 @@ export const Title = () => { <Text $margin="none" as="h2" - $color="#000091" + $color={colorsTokens['primary-text']} $zIndex={1} $size="1.375rem" > {t('Docs')} </Text> - <Text - $padding={{ - horizontal: '6px', - vertical: '4px', - }} - $size="11px" - $theme="primary" - $variation="500" - $weight="bold" - $radius="12px" - $css={css` - line-height: 9px; - `} - $width="40px" - $height="16px" - $background="#ECECFF" - $color="#5958D3" - > - BETA - </Text> + {isBeta && ( + <Text + $padding={{ + horizontal: '6px', + vertical: '4px', + }} + $size="11px" + $theme="primary" + $variation="500" + $weight="bold" + $radius="12px" + $css={css` + line-height: 9px; + `} + $width="40px" + $height="16px" + $background="#ECECFF" + $color="#5958D3" + > + BETA + </Text> + )} </Box> ); }; diff --git a/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx b/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx index e6c2d03c..03d92cb3 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx @@ -3,7 +3,7 @@ import Image from 'next/image'; import { useTranslation } from 'react-i18next'; import { css } from 'styled-components'; -import DocLogo from '@/assets/icons/icon-docs.svg?url'; +import IconDocs from '@/assets/icons/icon-docs.svg'; import { Box, Icon, Text } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; import { ProConnectButton, gotoLogin } from '@/features/auth'; @@ -15,9 +15,10 @@ import { getHeaderHeight } from './HomeHeader'; export default function HomeBanner() { const { t } = useTranslation(); - const { componentTokens, spacingsTokens } = useCunninghamTheme(); + const { componentTokens, spacingsTokens, colorsTokens } = + useCunninghamTheme(); const { isMobile, isSmallMobile } = useResponsiveStore(); - const withProConnect = componentTokens['home-proconnect'].activated; + const withProConnect = componentTokens['home-proconnect']; return ( <Box @@ -46,7 +47,11 @@ export default function HomeBanner() { $align="center" $gap={spacingsTokens['sm']} > - <Image src={DocLogo} alt="DocLogo" width={64} /> + <IconDocs + aria-label={t('Docs Logo')} + width={64} + color={colorsTokens['primary-text']} + /> <Text as="h2" $size={!isMobile ? 'xs-alt' : '2.3rem'} 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 fcf6f7b9..0c498347 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx @@ -1,7 +1,6 @@ -import Image from 'next/image'; import { useTranslation } from 'react-i18next'; -import DocLogo from '@/assets/icons/icon-docs.svg?url'; +import IconDocs from '@/assets/icons/icon-docs.svg'; import { Box, Text } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; import { ProConnectButton } from '@/features/auth'; @@ -10,7 +9,7 @@ import { useResponsiveStore } from '@/stores'; export function HomeBottom() { const { componentTokens } = useCunninghamTheme(); - const withProConnect = componentTokens['home-proconnect'].activated; + const withProConnect = componentTokens['home-proconnect']; if (!withProConnect) { return null; @@ -21,7 +20,7 @@ export function HomeBottom() { function HomeProConnect() { const { t } = useTranslation(); - const { spacingsTokens } = useCunninghamTheme(); + const { spacingsTokens, colorsTokens } = useCunninghamTheme(); const { isMobile } = useResponsiveStore(); const parentGap = '230px'; @@ -45,7 +44,11 @@ function HomeProConnect() { $height="fit-content" $css="zoom: 1.9;" > - <Image src={DocLogo} alt="DocLogo" /> + <IconDocs + aria-label={t('Docs Logo')} + width={34} + color={colorsTokens['primary-text']} + /> <Title /> </Box> <Text $size="md" $variation="1000" $textAlign="center"> 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 39390c25..ae4cdc9a 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx @@ -61,7 +61,7 @@ export function HomeContent() { $gap={isMobile ? '115px' : '230px'} $padding={{ bottom: '3rem' }} > - <Box $gap="30px"> + <Box $gap={isMobile ? '115px' : '30px'}> <HomeSection isColumn={false} isSmallDevice={isTablet} diff --git a/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx b/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx index 2c285d14..4837b7f9 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx @@ -17,7 +17,7 @@ export const getHeaderHeight = (isSmallMobile: boolean) => export const HomeHeader = () => { const { t } = useTranslation(); - const { themeTokens, spacingsTokens } = useCunninghamTheme(); + const { themeTokens, spacingsTokens, colorsTokens } = useCunninghamTheme(); const logo = themeTokens.logo; const { isSmallMobile } = useResponsiveStore(); @@ -44,7 +44,7 @@ export const HomeHeader = () => { <ButtonTogglePanel /> </Box> )} - {!isSmallMobile && logo && ( + {!isSmallMobile && logo?.src && ( <Image priority src={logo.src} @@ -61,7 +61,11 @@ export const HomeHeader = () => { $position="relative" $height="fit-content" > - <IconDocs aria-label={t('Docs Logo')} width={32} /> + <IconDocs + aria-label={t('Docs Logo')} + width={32} + color={colorsTokens['primary-text']} + /> <Title /> </Box> </Box> diff --git a/src/frontend/apps/impress/src/pages/404.tsx b/src/frontend/apps/impress/src/pages/404.tsx index 6bd66271..f4d008ed 100644 --- a/src/frontend/apps/impress/src/pages/404.tsx +++ b/src/frontend/apps/impress/src/pages/404.tsx @@ -1,37 +1,44 @@ import { Button } from '@openfun/cunningham-react'; +import Image from 'next/image'; import { ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import Icon404 from '@/assets/icons/icon-404.svg'; +import img403 from '@/assets/icons/icon-403.png'; import { Box, Icon, StyledLink, Text } from '@/components'; import { PageLayout } from '@/layouts'; import { NextPageWithLayout } from '@/types/next'; const StyledButton = styled(Button)` width: fit-content; - padding-left: 2rem; - padding-right: 2rem; `; const Page: NextPageWithLayout = () => { const { t } = useTranslation(); return ( - <Box $align="center" $margin="auto" $height="70vh" $gap="2rem"> - <Icon404 aria-label="Image 404" role="img" /> + <Box + $align="center" + $margin="auto" + $gap="1rem" + $padding={{ bottom: '2rem' }} + > + <Image + src={img403} + alt={t('Image 403')} + style={{ + maxWidth: '100%', + height: 'auto', + }} + /> - <Text $size="h2" $weight="700" $theme="greyscale" $variation="900"> - {t('Ouch !')} - </Text> + <Box $align="center" $gap="0.8rem"> + <Text as="p" $textAlign="center" $maxWidth="350px" $theme="primary"> + {t( + 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', + )} + </Text> - <Text as="p" $textAlign="center" $maxWidth="400px" $size="m"> - {t( - 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', - )} - </Text> - - <Box $margin={{ top: 'large' }}> <StyledLink href="/"> <StyledButton icon={<Icon iconName="house" $color="white" />}> {t('Home')}