From 2221ecad4cdf225fcdb027c20027edff304da478 Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Wed, 22 Apr 2026 13:01:16 +0300 Subject: [PATCH] feat(Footer): create Footer widget with project name and portfolio link --- src/widgets/Footer/index.ts | 1 + src/widgets/Footer/ui/Footer.stories.svelte | 47 ++++++++++++++++++ src/widgets/Footer/ui/Footer.svelte | 36 ++++++++++++++ src/widgets/Footer/ui/Footer.svelte.test.ts | 54 +++++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 src/widgets/Footer/index.ts create mode 100644 src/widgets/Footer/ui/Footer.stories.svelte create mode 100644 src/widgets/Footer/ui/Footer.svelte create mode 100644 src/widgets/Footer/ui/Footer.svelte.test.ts diff --git a/src/widgets/Footer/index.ts b/src/widgets/Footer/index.ts new file mode 100644 index 0000000..c50a1d1 --- /dev/null +++ b/src/widgets/Footer/index.ts @@ -0,0 +1 @@ +export { default as Footer } from './ui/Footer.svelte'; diff --git a/src/widgets/Footer/ui/Footer.stories.svelte b/src/widgets/Footer/ui/Footer.stories.svelte new file mode 100644 index 0000000..4c16162 --- /dev/null +++ b/src/widgets/Footer/ui/Footer.stories.svelte @@ -0,0 +1,47 @@ + + + + {#snippet template()} +
+
+
+ {/snippet} +
+ + + {#snippet template()} +
+

Footer should be hidden on mobile.

+
+
+ {/snippet} +
diff --git a/src/widgets/Footer/ui/Footer.svelte b/src/widgets/Footer/ui/Footer.svelte new file mode 100644 index 0000000..a8b1f6f --- /dev/null +++ b/src/widgets/Footer/ui/Footer.svelte @@ -0,0 +1,36 @@ + + + +{#if responsive?.isDesktop || responsive?.isDesktopLarge} + +{/if} diff --git a/src/widgets/Footer/ui/Footer.svelte.test.ts b/src/widgets/Footer/ui/Footer.svelte.test.ts new file mode 100644 index 0000000..420c95b --- /dev/null +++ b/src/widgets/Footer/ui/Footer.svelte.test.ts @@ -0,0 +1,54 @@ +import { + render, + screen, +} from '@testing-library/svelte'; +import { setContext } from 'svelte'; +import Footer from './Footer.svelte'; + +// Mock component to provide context +import ContextWrapper from '$shared/lib/providers/ResponsiveProvider/ResponsiveProvider.svelte'; + +describe('Footer', () => { + const currentYear = new Date().getFullYear(); + + it('renders on desktop', () => { + // Mock responsive context + const mockResponsive = { + isDesktop: true, + isDesktopLarge: false, + }; + + const { container } = render(Footer, { + context: new Map([['responsive', mockResponsive]]), + }); + + expect(screen.getByText(`GlyphDiff © 2025 — ${currentYear}`)).toBeInTheDocument(); + expect(screen.getByText('allmy.work')).toBeInTheDocument(); + }); + + it('renders on large desktop', () => { + const mockResponsive = { + isDesktop: false, + isDesktopLarge: true, + }; + + render(Footer, { + context: new Map([['responsive', mockResponsive]]), + }); + + expect(screen.getByText(`GlyphDiff © 2025 — ${currentYear}`)).toBeInTheDocument(); + }); + + it('does not render on mobile or tablet', () => { + const mockResponsive = { + isDesktop: false, + isDesktopLarge: false, + }; + + render(Footer, { + context: new Map([['responsive', mockResponsive]]), + }); + + expect(screen.queryByText(/GlyphDiff/)).not.toBeInTheDocument(); + }); +});