From 66f83db0e50101f3a4a148240569381ff532e2cc Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Wed, 5 Nov 2025 10:14:10 +0100 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8(frontend)=20add=20"Add=20Emoji"?= =?UTF-8?q?=20button=20to=20doc=20options=20menu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add "Add Emoji" button to doc options menu - Remove default emoji when none selected - Improve doc options styling --- .../__tests__/app-impress/doc-header.spec.ts | 27 ++++- .../__tests__/app-impress/doc-tree.spec.ts | 2 +- .../docs/doc-header/components/DocTitle.tsx | 31 ++--- .../docs/doc-header/components/DocToolBox.tsx | 112 +++++++++--------- 4 files changed, 102 insertions(+), 70 deletions(-) diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts index 89f052864..99635176f 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts @@ -68,9 +68,18 @@ test.describe('Doc Header', () => { await createDoc(page, 'doc-update-emoji', browserName, 1); const emojiPicker = page.locator('.--docs--doc-title').getByRole('button'); + const optionMenu = page.getByLabel('Open the document options'); + const addEmojiMenuItem = page.getByRole('menuitem', { name: 'Add emoji' }); + const removeEmojiMenuItem = page.getByRole('menuitem', { + name: 'Remove emoji', + }); // Top parent should not have emoji picker await expect(emojiPicker).toBeHidden(); + await optionMenu.click(); + await expect(addEmojiMenuItem).toBeHidden(); + await expect(removeEmojiMenuItem).toBeHidden(); + await page.keyboard.press('Escape'); const { name: docChild } = await createRootSubPage( page, @@ -80,13 +89,23 @@ test.describe('Doc Header', () => { await verifyDocName(page, docChild); - await expect(emojiPicker).toBeVisible(); + // Emoji picker should be hidden initially + await expect(emojiPicker).toBeHidden(); + + // Add emoji + await optionMenu.click(); + await expect(removeEmojiMenuItem).toBeHidden(); + await addEmojiMenuItem.click(); + await expect(emojiPicker).toHaveText('πŸ“„'); + + // Change emoji await emojiPicker.click({ delay: 100, }); await page.getByRole('button', { name: 'πŸ˜€' }).first().click(); await expect(emojiPicker).toHaveText('πŸ˜€'); + // Update title const docTitle = page.getByRole('textbox', { name: 'Document title' }); await docTitle.fill('Hello Emoji World'); await docTitle.blur(); @@ -95,6 +114,12 @@ test.describe('Doc Header', () => { // Check the tree const row = await getTreeRow(page, 'Hello Emoji World'); await expect(row.getByText('πŸ˜€')).toBeVisible(); + + // Remove emoji + await optionMenu.click(); + await expect(addEmojiMenuItem).toBeHidden(); + await removeEmojiMenuItem.click(); + await expect(emojiPicker).toBeHidden(); }); test('it deletes the doc', async ({ page, browserName }) => { diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts index 422231f71..0e3bf49cc 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts @@ -352,7 +352,7 @@ test.describe('Doc Tree', () => { await page.getByRole('menuitem', { name: 'Remove emoji' }).click(); await expect(row.getByText('πŸ˜€')).toBeHidden(); - await expect(titleEmojiPicker).not.toHaveText('πŸ˜€'); + await expect(titleEmojiPicker).toBeHidden(); }); }); diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx index c3d669181..33905caa7 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx @@ -55,8 +55,16 @@ const DocTitleEmojiPicker = ({ doc }: DocTitleProps) => { const { colorsTokens } = useCunninghamTheme(); const { emoji } = getEmojiAndTitle(doc.title ?? ''); + if (!emoji) { + return null; + } + return ( - + { `} > { const { isDesktop } = useResponsiveStore(); const { t } = useTranslation(); const { colorsTokens } = useCunninghamTheme(); - const { spacingsTokens } = useCunninghamTheme(); const { isTopRoot } = useDocUtils(doc); const { untitledDocument } = useTrans(); const { emoji, titleWithoutEmoji } = getEmojiAndTitle(doc.title ?? ''); @@ -139,19 +152,9 @@ const DocTitleInput = ({ doc }: DocTitleProps) => { className="--docs--doc-title" $direction="row" $align="center" - $gap={spacingsTokens['xs']} + $gap="4px" $minHeight="40px" > - {isTopRoot && ( - From a9b77fb9a7af6e37edcae88968de26aa16d7baee Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Wed, 5 Nov 2025 15:53:12 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=92=84(frontend)=20visual=20improveme?= =?UTF-8?q?nts=20around=20the=20Icon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With time some visual inconsistencies have crept into the DropButton and Icon component. This commit aims to harmonize the appearance with the design system. --- CHANGELOG.md | 2 ++ .../__tests__/app-impress/doc-grid.spec.ts | 2 ++ .../impress/src/components/DropButton.tsx | 3 ++- .../apps/impress/src/components/Icon.tsx | 12 ++++++++---- .../src/cunningham/cunningham-style.css | 5 +++++ .../InterlinkingLinkInlineContent.tsx | 2 +- .../doc-header/components/BoutonShare.tsx | 2 +- .../doc-management/components/DocIcon.tsx | 10 ++++++---- .../doc-share/components/DocVisibility.tsx | 12 +++++++++++- .../doc-tree/components/DocSubPageItem.tsx | 19 ++++++++----------- .../apps/impress/src/i18n/translations.json | 8 ++++---- 11 files changed, 50 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efc2c7328..0d931c0d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ and this project adheres to - πŸ›(backend) fix s3 version_id validation - πŸ›(frontend) retry check media status after page reload #1555 - πŸ›(frontend) fix Interlinking memory leak #1560 +- πŸ›(frontend) button new doc UI fix #1557 +- πŸ›(frontend) interlinking UI fix #1557 ## [3.8.2] - 2025-10-17 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 61535fffe..2bdb9d8e6 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 @@ -134,6 +134,8 @@ test.describe('Document grid item options', () => { test('it deletes the document', async ({ page, browserName }) => { const [docTitle] = await createDoc(page, `delete doc`, browserName); + await verifyDocName(page, docTitle); + await page.goto('/'); await expect(page.getByText(docTitle)).toBeVisible(); diff --git a/src/frontend/apps/impress/src/components/DropButton.tsx b/src/frontend/apps/impress/src/components/DropButton.tsx index 30172b426..09772b4b4 100644 --- a/src/frontend/apps/impress/src/components/DropButton.tsx +++ b/src/frontend/apps/impress/src/components/DropButton.tsx @@ -31,7 +31,7 @@ const StyledButton = styled(Button)` font-weight: 500; font-size: 0.938rem; padding: 0; - ${({ $css }) => $css}; + border-radius: 4px; &:hover { background-color: var( --c--components--button--primary-text--background--color-hover @@ -41,6 +41,7 @@ const StyledButton = styled(Button)` box-shadow: 0 0 0 2px var(--c--theme--colors--primary-400); border-radius: 4px; } + ${({ $css }) => $css}; `; export interface DropButtonProps { diff --git a/src/frontend/apps/impress/src/components/Icon.tsx b/src/frontend/apps/impress/src/components/Icon.tsx index fd1458a82..f5c0baa1a 100644 --- a/src/frontend/apps/impress/src/components/Icon.tsx +++ b/src/frontend/apps/impress/src/components/Icon.tsx @@ -13,7 +13,7 @@ export const Icon = ({ iconName, disabled, variant = 'outlined', - $variation, + $variation = 'text', ...textProps }: IconProps) => { const hasLabel = 'aria-label' in textProps || 'aria-labelledby' in textProps; @@ -41,15 +41,19 @@ type IconOptionsProps = TextType & { isHorizontal?: boolean; }; -export const IconOptions = ({ isHorizontal, ...props }: IconOptionsProps) => { +export const IconOptions = ({ + isHorizontal, + $css, + ...props +}: IconOptionsProps) => { return ( ); }; diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-style.css b/src/frontend/apps/impress/src/cunningham/cunningham-style.css index bc4e5e248..54d0c67d0 100644 --- a/src/frontend/apps/impress/src/cunningham/cunningham-style.css +++ b/src/frontend/apps/impress/src/cunningham/cunningham-style.css @@ -44,6 +44,11 @@ contain: content; } +.c__button--medium { + min-height: var(--c--components--button--medium-height); + height: auto; +} + /** * Modal */ diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx index 769d6c15e..747e6e7cf 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx @@ -77,7 +77,7 @@ const LinkSelected = ({ url, title }: LinkSelectedProps) => { onClick={handleClick} draggable="false" $css={css` - display: inline; + display: contents; padding: 0.1rem 0.4rem; border-radius: 4px; & svg { diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx index c0e31db59..c821e5ac3 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/BoutonShare.tsx @@ -76,7 +76,7 @@ export const BoutonShare = ({ return (