feat(Footer): icon-only CV download below sm
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
export interface Props {
|
||||
/**
|
||||
* CSS classes on the svg element
|
||||
*/
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* File with downward arrow — download icon (Lucide file-down).
|
||||
*/
|
||||
export function FileDownIcon({ className }: Props) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-hidden={true}
|
||||
className={className}
|
||||
>
|
||||
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" />
|
||||
<path d="M14 2v5a1 1 0 0 0 1 1h5" />
|
||||
<path d="M12 18v-6" />
|
||||
<path d="m9 15 3 3 3-3" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export { CloseIcon } from './CloseIcon';
|
||||
export { FileDownIcon } from './FileDownIcon';
|
||||
export { MagnifyIcon } from './MagnifyIcon';
|
||||
|
||||
@@ -155,6 +155,12 @@ describe('Footer', () => {
|
||||
expect(link).toHaveClass('brutal-border', 'uppercase');
|
||||
});
|
||||
|
||||
it('CV link carries the download icon for the narrow-viewport fallback', async () => {
|
||||
render(await Footer());
|
||||
const link = screen.getByRole('link', { name: /download cv/i });
|
||||
expect(link.querySelector('svg')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render CV link when no cv field', async () => {
|
||||
vi.mocked(getFirstRecord).mockResolvedValue({ ...mockSettings, cv: '' });
|
||||
render(await Footer());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { SiteSettingsRecord } from '$shared/api';
|
||||
import { getFirstRecord } from '$shared/api';
|
||||
import { FileDownIcon } from '$shared/assets/icons';
|
||||
import { buildFileUrl } from '$shared/lib';
|
||||
import { Button, InlineSvg, Link } from '$shared/ui';
|
||||
|
||||
@@ -42,8 +43,16 @@ export async function Footer() {
|
||||
))}
|
||||
</div>
|
||||
{cvUrl && (
|
||||
<Button href={cvUrl} download size="sm" className="self-start sm:self-auto">
|
||||
Download CV
|
||||
<Button
|
||||
href={cvUrl}
|
||||
download
|
||||
size="sm"
|
||||
aria-label="Download CV"
|
||||
className="inline-flex items-center self-start sm:self-auto"
|
||||
>
|
||||
{/* Icon-only below sm, matching the contact row's icon/label switch */}
|
||||
<FileDownIcon className="w-5 h-5 sm:hidden" />
|
||||
<span className="hidden sm:inline">Download CV</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user