From f490c01f8af02e4aa01bdc5c410e650145d9cc14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Wed, 15 Oct 2025 14:20:30 +0200 Subject: [PATCH 1/2] Add button to download file --- .../src/components/DocumentView/File.tsx | 105 +++++++++--------- .../src/components/DocumentView/FileIcon.tsx | 2 +- .../components/primitives/DownloadButton.tsx | 39 +++++++ packages/gitbook/src/intl/translations/de.ts | 2 + packages/gitbook/src/intl/translations/en.ts | 2 + packages/gitbook/src/intl/translations/es.ts | 2 + packages/gitbook/src/intl/translations/fr.ts | 2 + packages/gitbook/src/intl/translations/it.ts | 2 + packages/gitbook/src/intl/translations/ja.ts | 2 + packages/gitbook/src/intl/translations/nl.ts | 2 + packages/gitbook/src/intl/translations/no.ts | 2 + .../gitbook/src/intl/translations/pt-br.ts | 2 + packages/gitbook/src/intl/translations/ru.ts | 2 + packages/gitbook/src/intl/translations/zh.ts | 2 + packages/gitbook/src/lib/files.ts | 4 +- 15 files changed, 119 insertions(+), 53 deletions(-) create mode 100644 packages/gitbook/src/components/primitives/DownloadButton.tsx diff --git a/packages/gitbook/src/components/DocumentView/File.tsx b/packages/gitbook/src/components/DocumentView/File.tsx index fe72164fc6..71e03d810b 100644 --- a/packages/gitbook/src/components/DocumentView/File.tsx +++ b/packages/gitbook/src/components/DocumentView/File.tsx @@ -1,10 +1,12 @@ import { type DocumentBlockFile, SiteInsightsLinkPosition } from '@gitbook/api'; +import { t } from '@/intl/translate'; import { getSimplifiedContentType } from '@/lib/files'; import { resolveContentRef } from '@/lib/references'; -import { tcls } from '@/lib/tailwind'; -import { Link } from '../primitives'; +import { getSpaceLanguage } from '@/intl/server'; +import { Button, Link } from '../primitives'; +import { DownloadButton } from '../primitives/DownloadButton'; import type { BlockProps } from './Block'; import { Caption } from './Caption'; import { FileIcon } from './FileIcon'; @@ -12,67 +14,70 @@ import { FileIcon } from './FileIcon'; export async function File(props: BlockProps) { const { block, context } = props; - const contentRef = context.contentContext - ? await resolveContentRef(block.data.ref, context.contentContext) - : null; + if (!context.contentContext) { + return null; + } + + const contentRef = await resolveContentRef(block.data.ref, context.contentContext); const file = contentRef?.file; if (!file) { return null; } + const language = getSpaceLanguage(context.contentContext); const contentType = getSimplifiedContentType(file.contentType); + const insights = { + type: 'link_click' as const, + link: { + target: block.data.ref, + position: SiteInsightsLinkPosition.Content, + }, + }; return ( - -
-
- -
-
- {getHumanFileSize(file.size)} -
+
+
+ +
{getHumanFileSize(file.size)}
-
-
{file.name}
-
- {contentType} +
+
+ + {file.name} +
+
{contentType}
+
+
+ + {t(language, 'download')} + +
- +
); } diff --git a/packages/gitbook/src/components/DocumentView/FileIcon.tsx b/packages/gitbook/src/components/DocumentView/FileIcon.tsx index 45ec588845..61d38700e5 100644 --- a/packages/gitbook/src/components/DocumentView/FileIcon.tsx +++ b/packages/gitbook/src/components/DocumentView/FileIcon.tsx @@ -9,7 +9,7 @@ export function FileIcon(props: { contentType: SimplifiedFileType | null; classN const { contentType, className } = props; switch (contentType) { - case 'pdf': + case 'PDF': return ; case 'image': return ; diff --git a/packages/gitbook/src/components/primitives/DownloadButton.tsx b/packages/gitbook/src/components/primitives/DownloadButton.tsx new file mode 100644 index 0000000000..205d0bcf6f --- /dev/null +++ b/packages/gitbook/src/components/primitives/DownloadButton.tsx @@ -0,0 +1,39 @@ +'use client'; +import { Button, type ButtonProps } from './Button'; + +/** + * Button that triggers a file download when clicked. + */ +export function DownloadButton( + props: Omit & { downloadUrl: string; filename: string } +) { + const { downloadUrl, filename, ...buttonProps } = props; + + return ( +
-
-
+
+
) { {file.name}
-
{contentType}
+
{contentType}