diff --git a/src/frontend/apps/impress/src/features/docs/doc-presenter/__tests__/PresenterPrintDocument.spec.tsx b/src/frontend/apps/impress/src/features/docs/doc-presenter/__tests__/PresenterPrintDocument.spec.tsx new file mode 100644 index 000000000..cd9499cba --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-presenter/__tests__/PresenterPrintDocument.spec.tsx @@ -0,0 +1,80 @@ +import { render } from '@testing-library/react'; +import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; + +import { + PRESENTER_PRINT_CONTENT_CLASS, + PRESENTER_PRINT_CSS, + PRESENTER_PRINT_LOGO_CLASS, + PRESENTER_PRINT_PAGE_CLASS, + PRESENTER_PRINT_PAGE_SELECTOR, + PRESENTER_PRINT_TITLE_CLASS, + PresenterPrintDocument, +} from '../components/PresenterPrintDocument'; +import type { PresenterBlock } from '../types'; + +const para = (text: string): PresenterBlock => ({ + children: [], + content: [{ type: 'text', text, styles: {} }], + id: 'paragraph', + props: { + backgroundColor: 'default', + textAlignment: 'left', + textColor: 'default', + }, + type: 'paragraph', +}); + +describe('PresenterPrintDocument', () => { + beforeEach(() => { + Object.defineProperty(window, 'matchMedia', { + configurable: true, + writable: true, + value: vi.fn().mockImplementation((query: string) => ({ + addEventListener: vi.fn(), + addListener: vi.fn(), + dispatchEvent: vi.fn(), + matches: false, + media: query, + onchange: null, + removeEventListener: vi.fn(), + removeListener: vi.fn(), + })), + }); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + test('renders one print page per slide', () => { + const { container } = render( + , + ); + + expect( + container.querySelectorAll(PRESENTER_PRINT_PAGE_SELECTOR), + ).toHaveLength(4); + expect( + container.querySelector(`.${PRESENTER_PRINT_TITLE_CLASS}`), + ).toHaveTextContent('Deck title'); + expect( + container.querySelectorAll(`.${PRESENTER_PRINT_LOGO_CLASS}`), + ).toHaveLength(4); + }); + + test('centers short slide content vertically in print pages', () => { + expect(PRESENTER_PRINT_CSS).toContain(`.${PRESENTER_PRINT_PAGE_CLASS} {`); + expect(PRESENTER_PRINT_CSS).toContain('justify-content: safe center;'); + expect(PRESENTER_PRINT_CSS).toContain( + `.${PRESENTER_PRINT_CONTENT_CLASS} {`, + ); + expect(PRESENTER_PRINT_CSS).toContain('max-height: 100%;'); + }); +}); diff --git a/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresenterFloatingBar.tsx b/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresenterFloatingBar.tsx index b4421eff9..e8f73f076 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresenterFloatingBar.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-presenter/components/PresenterFloatingBar.tsx @@ -3,6 +3,7 @@ import { DropdownMenu, DropdownMenuItem } from '@gouvfr-lasuite/ui-kit'; import { ChevronLeft, ChevronRight, + Download, Link, Maximize, Minimize, @@ -22,8 +23,10 @@ interface PresenterFloatingBarProps { onPrev: () => void; onNext: () => void; onCopyLink: () => void; + onExportPdf: () => void; onToggleFullscreen: () => void; onClose: () => void; + isExportingPdf: boolean; } const barCss = css` @@ -80,8 +83,10 @@ export const PresenterFloatingBar = ({ onPrev, onNext, onCopyLink, + onExportPdf, onToggleFullscreen, onClose, + isExportingPdf, }: PresenterFloatingBarProps) => { const { t } = useTranslation(); const isFirst = index <= 0; @@ -118,8 +123,14 @@ export const PresenterFloatingBar = ({ icon: , callback: onCopyLink, }, + { + label: t('Download PDF'), + icon: