LibreChat/client/src/components/Artifacts/DownloadArtifact.tsx
Daniel Lew 1143f73f59
Some checks failed
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Has been cancelled
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Has been cancelled
🔇 fix: Hide Button Icons from Screen Readers (#10776)
If you've got a screen reader that is reading out the whole page,
each icon button (i.e., `<button><SVG></button>`) will have both
the button's aria-label read out as well as the title from the
SVG (which is usually just "image").

Since we are pretty good about setting aria-labels, we should instead
use `aria-hidden="true"` on these images, since they are not useful
to be read out.

I don't consider this a comprehensive review of all icons in the app,
but I knocked out all the low hanging fruit in this commit.
2025-12-11 16:35:17 -05:00

53 lines
1.6 KiB
TypeScript

import React, { useState } from 'react';
import { Download, CircleCheckBig } from 'lucide-react';
import type { Artifact } from '~/common';
import { Button } from '@librechat/client';
import useArtifactProps from '~/hooks/Artifacts/useArtifactProps';
import { useCodeState } from '~/Providers/EditorContext';
import { useLocalize } from '~/hooks';
const DownloadArtifact = ({ artifact }: { artifact: Artifact }) => {
const localize = useLocalize();
const { currentCode } = useCodeState();
const [isDownloaded, setIsDownloaded] = useState(false);
const { fileKey: fileName } = useArtifactProps({ artifact });
const handleDownload = () => {
try {
const content = currentCode ?? artifact.content ?? '';
if (!content) {
return;
}
const blob = new Blob([content], { type: 'text/plain' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
setIsDownloaded(true);
setTimeout(() => setIsDownloaded(false), 3000);
} catch (error) {
console.error('Download failed:', error);
}
};
return (
<Button
size="icon"
variant="ghost"
onClick={handleDownload}
aria-label={localize('com_ui_download_artifact')}
>
{isDownloaded ? (
<CircleCheckBig size={16} aria-hidden="true" />
) : (
<Download size={16} aria-hidden="true" />
)}
</Button>
);
};
export default DownloadArtifact;