From d7a5e3ab51c980e95580a027dd7156ec75a2a3fa Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 10:04:11 +0000 Subject: [PATCH 01/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20truncate=20?= =?UTF-8?q?middle=20shorten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/truncate.test.ts | 31 ++++++++++++++++++++++++++++++- src/utils/truncate.ts | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/utils/truncate.test.ts b/src/utils/truncate.test.ts index e9f5f0bcb..6d72ea004 100644 --- a/src/utils/truncate.test.ts +++ b/src/utils/truncate.test.ts @@ -1,5 +1,5 @@ import { expect } from "vitest"; -import { truncateFilename } from "@/utils/truncate"; +import { truncateFilename, shortenMiddle } from "@/utils/truncate"; describe("truncateFilename", () => { it("dotfile (short)", () => { @@ -32,3 +32,32 @@ describe("truncateFilename", () => { expect(truncated).toBe(filename); }); }); + +describe("shortenMiddle", () => { + it("should return unchanged when filename is within maxLen", () => { + const filename = "console.clickhouse.cloud_Archive.01.csv"; + expect(shortenMiddle(filename)).toBe(filename); + }); + + it("should shorten filename with default delimiter in the middle", () => { + const filename = + "console.clickhouse.cloud_Archive.01-01-1975.lorem-ipsum-a-very-long-filename-001.csv"; + const result = shortenMiddle(filename); + expect(result).toBe("console.clickhous...ong-filename-001.csv"); + }); + + it("should shorten filename without extension", () => { + const filename = + "admin_postgresql_heroku_Backup_03-22-2023_transaction-logs-monthly-summary"; + const result = shortenMiddle(filename); + expect(result).toBe("admin_postgresql_he...gs-monthly-summary"); + }); + + it("shgould shorten with custom maxLen", () => { + const filename = + "dashboard.mongodb.atlas_Export.12-15-2024.customer-data-analysis-report-final-v2.json"; + const result = shortenMiddle(filename, 50); + expect(result).toBe("dashboard.mongodb.atl...lysis-report-final-v2.json"); + expect(result.length).toBe(50); + }); +}); diff --git a/src/utils/truncate.ts b/src/utils/truncate.ts index 46ffebe3c..e3c9d8070 100644 --- a/src/utils/truncate.ts +++ b/src/utils/truncate.ts @@ -1,3 +1,6 @@ +const DEFAULT_MAX_LEN = 40; +const DEFAULT_DELIMITER = "..."; + /** * truncateFilename * @@ -12,7 +15,7 @@ */ export const truncateFilename = ( filename: string, - maxLength: number = 40, + maxLength: number = DEFAULT_MAX_LEN, delimiter: string = "~" ): string => { if (filename.length <= maxLength) { @@ -33,3 +36,33 @@ export const truncateFilename = ( const truncatedName = nameWithoutExtension.slice(0, maxLength) + delimiter; return truncatedName + extension; }; + +export const shortenMiddle = (filename: string, maxLen: number = DEFAULT_MAX_LEN) => { + if (filename.length <= maxLen) { + return filename; + } + + const lastDotIndex = filename.lastIndexOf("."); + const hasExtension = lastDotIndex > 0 && lastDotIndex < filename.length - 1; + + if (!hasExtension) { + const charsToShow = maxLen - DEFAULT_DELIMITER.length; + const frontChars = Math.ceil(charsToShow / 2); + const backChars = Math.floor(charsToShow / 2); + return `${filename.slice(0, frontChars)}${DEFAULT_DELIMITER}${filename.slice(-backChars)}`; + } + + const name = filename.slice(0, lastDotIndex); + const extension = filename.slice(lastDotIndex); + + const availableLength = maxLen - extension.length - DEFAULT_DELIMITER.length; + + if (availableLength <= 0) { + return `${filename.slice(0, maxLen - DEFAULT_DELIMITER.length)}${DEFAULT_DELIMITER}`; + } + + const frontChars = Math.ceil(availableLength / 2); + const backChars = Math.floor(availableLength / 2); + + return `${name.slice(0, frontChars)}${DEFAULT_DELIMITER}${name.slice(-backChars)}${extension}`; +}; From b7745490ac841e11e17bdf384d51c2ab7d6f0ada Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 10:07:28 +0000 Subject: [PATCH 02/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20remove=20deprecat?= =?UTF-8?q?ed=20truncate=20util?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileMultiUpload.tsx | 4 +-- src/components/FileUpload/FileUpload.tsx | 4 +-- src/utils/truncate.test.ts | 34 +----------------- src/utils/truncate.ts | 36 ------------------- 4 files changed, 5 insertions(+), 73 deletions(-) diff --git a/src/components/FileUpload/FileMultiUpload.tsx b/src/components/FileUpload/FileMultiUpload.tsx index 43d464263..afd3d59ba 100644 --- a/src/components/FileUpload/FileMultiUpload.tsx +++ b/src/components/FileUpload/FileMultiUpload.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { styled, css } from "styled-components"; import { useState, useRef, useCallback } from "react"; -import { truncateFilename } from "@/utils/truncate"; +import { shortenMiddle } from "@/utils/truncate"; import { Text } from "@/components/Typography/Text/Text"; import { Title } from "@/components/Typography/Title/Title"; import { Button, Icon, IconButton, ProgressBar } from "@/components"; @@ -381,7 +381,7 @@ export const FileMultiUpload = ({ - {truncateFilename(file.name)} + {shortenMiddle(file.name)} {file.status === "uploading" && ( {file.progress}% )} diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index 6c670d048..7b6060fe5 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { styled, css } from "styled-components"; import { useState, useRef, useCallback } from "react"; -import { truncateFilename } from "@/utils/truncate"; +import { shortenMiddle } from "@/utils/truncate"; import { Text } from "@/components/Typography/Text/Text"; import { Title } from "@/components/Typography/Title/Title"; import { Button, Icon, IconButton, ProgressBar } from "@/components"; @@ -407,7 +407,7 @@ export const FileUpload = ({ - {truncateFilename(file.name)} + {shortenMiddle(file.name)} {showProgress && !showSuccess && ( {progress}% )} diff --git a/src/utils/truncate.test.ts b/src/utils/truncate.test.ts index 6d72ea004..9366eb64e 100644 --- a/src/utils/truncate.test.ts +++ b/src/utils/truncate.test.ts @@ -1,37 +1,5 @@ import { expect } from "vitest"; -import { truncateFilename, shortenMiddle } from "@/utils/truncate"; - -describe("truncateFilename", () => { - it("dotfile (short)", () => { - const filename = ".github"; - const truncated = truncateFilename(filename); - expect(truncated).toBe(".github"); - }); - - it("dotfile (long)", () => { - const filename = ".gitignoreverylongfilename"; - const truncated = truncateFilename(filename, 10, "..."); - expect(truncated).toBe(".gitignore..."); - }); - - it("file name with extension", () => { - const filename = "testalargefilename.png"; - const truncated = truncateFilename(filename, 10); - expect(truncated).toBe("testalarge~.png"); - }); - - it("file name with extension lower than threshold", () => { - const filename = "test.png"; - const truncated = truncateFilename(filename); - expect(truncated).toBe(filename); - }); - - it("file name with same length as the threshold", () => { - const filename = "test.png"; - const truncated = truncateFilename(filename, filename.length); - expect(truncated).toBe(filename); - }); -}); +import { shortenMiddle } from "@/utils/truncate"; describe("shortenMiddle", () => { it("should return unchanged when filename is within maxLen", () => { diff --git a/src/utils/truncate.ts b/src/utils/truncate.ts index e3c9d8070..366aef762 100644 --- a/src/utils/truncate.ts +++ b/src/utils/truncate.ts @@ -1,42 +1,6 @@ const DEFAULT_MAX_LEN = 40; const DEFAULT_DELIMITER = "..."; -/** - * truncateFilename - * - * On occasion, we may be dealing with filenames - which could be very large - * and not practical to display in the user interface. This utility func - * ensures that we return a name that looks recognisable and fits the - * component using the data. - * - * @param filename - * @param maxLength - * @param delimiter - */ -export const truncateFilename = ( - filename: string, - maxLength: number = DEFAULT_MAX_LEN, - delimiter: string = "~" -): string => { - if (filename.length <= maxLength) { - return filename; - } - - if (filename.startsWith(".")) { - return `${filename.slice(0, maxLength)}${delimiter}`; - } - - const extension = - filename.lastIndexOf(".") !== -1 ? filename.slice(filename.lastIndexOf(".")) : ""; - - const nameWithoutExtension = extension - ? filename.slice(0, filename.lastIndexOf(".")) - : filename; - - const truncatedName = nameWithoutExtension.slice(0, maxLength) + delimiter; - return truncatedName + extension; -}; - export const shortenMiddle = (filename: string, maxLen: number = DEFAULT_MAX_LEN) => { if (filename.length <= maxLen) { return filename; From 99370459ebc90b3194b828691702394e23d73b54 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 10:47:59 +0000 Subject: [PATCH 03/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/breezy-nails-remain.md | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .changeset/breezy-nails-remain.md diff --git a/.changeset/breezy-nails-remain.md b/.changeset/breezy-nails-remain.md new file mode 100644 index 000000000..8d9b78805 --- /dev/null +++ b/.changeset/breezy-nails-remain.md @@ -0,0 +1,36 @@ +--- +"@clickhouse/click-ui": minor +--- + +Truncate filenames by shortening the middle revealing critical parts. + +Assume you have: + +``` +console.clickhouse.cloud_Archive.01-01-1975.lorem-ipsum-a-very-long-filename-001.csv +console.clickhouse.cloud_Archive.01-01-1975.lorem-ipsum-a-very-long-filename-005.csv +dashboard.mongodb.atlas_Export.12-15-2024.customer-data-analysis-report-final-v2.json +admin.postgresql.heroku_Backup.03-22-2023.transaction-logs-monthly-summary-march.sql +``` + +In the current faulty version you'd get something like: + +``` +console.clickhouse.cloud_Archive.01-~.csv +console.clickhouse.cloud_Archive.01-~.csv +dashboard.mongodb.atlas_Export.12-1~.csv +admin.postgresql.heroku_Backup.03-2~.csv +``` + +Notice that the first two filenames, when presented truncated, have the same shortened name, making it hard to differentiate. + +In the PR proposed version you'd find easier to identify files if these are named in a maintainable way: + +``` +console.clickh...filename-001.csv +console.clickh...filename-005.csv +dashboard.mong...ort-final-v2.json +admin.postgres...ummary-march.sql +``` + +Notice that the first and last digits help identify the file more concisely, allowing for a shorter length. From 4563cf487633f724593c4bdd9702d598e8a122d7 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 14:05:31 +0000 Subject: [PATCH 04/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20filename=20?= =?UTF-8?q?reveal=20component=20to=20control=20responsiveness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.tsx | 42 ++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index 7b6060fe5..c1b0ba422 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useMemo } from "react"; import { styled, css } from "styled-components"; import { useState, useRef, useCallback } from "react"; @@ -37,12 +37,33 @@ interface FileUploadProps { onFileClose?: () => void; } +const FilenameReveal = styled.span` + span { + display: none; + } + + span[data-truncated] { + display: inline-block; + } + + @container uploadArea (width > ${({ theme }) => theme.breakpoint.sizes.md}) { + span { + display: inline-block; + } + span[data-truncated] { + display: none; + } + } +`; + const UploadArea = styled.div<{ $isDragging: boolean; $size: "sm" | "md"; $hasFile: boolean; $isError?: boolean; }>` + container-type: inline-size; + container-name: uploadArea; background-color: ${({ theme }) => theme.click.fileUpload.color.background.default}; border: ${({ theme }) => `1px solid ${theme.click.fileUpload.color.stroke.default}`}; border-radius: ${({ theme, $hasFile }) => @@ -352,6 +373,10 @@ export const FileUpload = ({ }, [onRetry]); const acceptedFileTypes = supportedFileTypes.join(","); + const shortenFilename = useMemo( + () => (file ? shortenMiddle(file.name) : ""), + [file?.name] + ); return ( <> @@ -407,7 +432,20 @@ export const FileUpload = ({ - {shortenMiddle(file.name)} + + + + {file.name} + + {showProgress && !showSuccess && ( {progress}% )} From 5eb893071a7510a744d8a2c4f7dd489fa6c0cafc Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 14:07:51 +0000 Subject: [PATCH 05/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/tame-rivers-write.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tame-rivers-write.md diff --git a/.changeset/tame-rivers-write.md b/.changeset/tame-rivers-write.md new file mode 100644 index 000000000..d01c85e86 --- /dev/null +++ b/.changeset/tame-rivers-write.md @@ -0,0 +1,5 @@ +--- +"@clickhouse/click-ui": minor +--- + +Adapts file upload filename truncation responsiveness, e.g. shows truncated file name on smaller container sizes, showing the original otherwise. It shows the complete filename on element hover. From c3772fc034d90aab7b69788d8350f90890ccfd58 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 14:15:34 +0000 Subject: [PATCH 06/14] =?UTF-8?q?fix:=20=F0=9F=90=9B=20lint=20amend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index c1b0ba422..d3adad0df 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -375,7 +375,7 @@ export const FileUpload = ({ const acceptedFileTypes = supportedFileTypes.join(","); const shortenFilename = useMemo( () => (file ? shortenMiddle(file.name) : ""), - [file?.name] + [file] ); return ( From 3a0947ed5cc7622530e85f7f101e97f0bf0e13d2 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 17:35:16 +0000 Subject: [PATCH 07/14] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20add=20shorter?= =?UTF-8?q?=20filename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.tsx | 25 ++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index 22b5a1f05..cb5552036 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -42,10 +42,20 @@ const FilenameReveal = styled.span` display: none; } - span[data-truncated] { + span[data-truncated="s"] { display: inline-block; } + @container uploadArea (width > ${({ theme }) => parseInt(theme.breakpoint.sizes.sm) / 1.5}px) { + span[data-truncated="s"] { + display: none; + } + + span[data-truncated="m"] { + display: inline-block; + } + } + @container uploadArea (width > ${({ theme }) => theme.breakpoint.sizes.md}) { span { display: inline-block; @@ -361,7 +371,8 @@ export const FileUpload = ({ }, [onRetry]); const acceptedFileTypes = supportedFileTypes.join(","); - const shortenFilename = useMemo(() => (file ? shortenMiddle(file.name) : ""), [file]); + const shortenMFilename = useMemo(() => (file ? shortenMiddle(file.name) : ""), [file]); + const shortenSFilename = useMemo(() => (file ? shortenMiddle(file.name, 20) : ""), [file]); return ( <> @@ -423,10 +434,16 @@ export const FileUpload = ({ aria-label={file.name} > + {file.name} From 76f2e834f2f3defe47e401ffff4b0bc88d9c2bdd Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 17:37:25 +0000 Subject: [PATCH 08/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20make=20story=20co?= =?UTF-8?q?ntainer=20max=20width=20wider=20for=20testing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/FileUpload/FileUpload.stories.tsx b/src/components/FileUpload/FileUpload.stories.tsx index 295b7152d..eb6d6c6e6 100644 --- a/src/components/FileUpload/FileUpload.stories.tsx +++ b/src/components/FileUpload/FileUpload.stories.tsx @@ -8,7 +8,7 @@ import { useState } from "react"; const Wrapper = styled.div` width: 100%; @media (min-width: ${({ theme }) => theme.breakpoint.sizes.md}) { - max-width: 800px; + max-width: 1024px; width: 100%; margin: 0 auto; } From 4003332a678a65c86b0166584ff4d7b7083affdf Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 27 Jan 2026 17:40:05 +0000 Subject: [PATCH 09/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index cb5552036..e52b66b12 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -46,7 +46,8 @@ const FilenameReveal = styled.span` display: inline-block; } - @container uploadArea (width > ${({ theme }) => parseInt(theme.breakpoint.sizes.sm) / 1.5}px) { + @container uploadArea (width > ${({ theme }) => + parseInt(theme.breakpoint.sizes.sm) / 1.5}px) { span[data-truncated="s"] { display: none; } @@ -372,7 +373,10 @@ export const FileUpload = ({ const acceptedFileTypes = supportedFileTypes.join(","); const shortenMFilename = useMemo(() => (file ? shortenMiddle(file.name) : ""), [file]); - const shortenSFilename = useMemo(() => (file ? shortenMiddle(file.name, 20) : ""), [file]); + const shortenSFilename = useMemo( + () => (file ? shortenMiddle(file.name, 20) : ""), + [file] + ); return ( <> From bb5968fb7456388a9d55b06847c892452989d206 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Wed, 28 Jan 2026 09:35:07 +0000 Subject: [PATCH 10/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20make=20a=20trunca?= =?UTF-8?q?tor=20container=20faking=20shorten=20middle-like=20truncation?= =?UTF-8?q?=20technique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.tsx | 97 ++++++++++-------------- 1 file changed, 41 insertions(+), 56 deletions(-) diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index e52b66b12..c7b34262b 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -1,8 +1,7 @@ -import React, { useEffect, useMemo } from "react"; +import React, { useEffect } from "react"; import { styled, css } from "styled-components"; import { useState, useRef, useCallback } from "react"; -import { shortenMiddle } from "@/utils/truncate"; import { Text } from "@/components/Typography/Text/Text"; import { Title } from "@/components/Typography/Title/Title"; import { Button, Icon, IconButton, ProgressBar, Container } from "@/components"; @@ -37,35 +36,43 @@ interface FileUploadProps { onFileClose?: () => void; } -const FilenameReveal = styled.span` - span { - display: none; - } +// TODO: Make it a component + story +const TruncatorContainer = styled.div` + display: flex; + width: 100%; + min-width: 0; + overflow: hidden; + white-space: nowrap; + font: ${({ theme }) => theme.click.fileUpload.typography.description.default}; + color: ${({ theme }) => theme.click.fileUpload.color.title.default}; +`; - span[data-truncated="s"] { - display: inline-block; - } +const TruncatorStart = styled.span` + flex-shrink: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +`; - @container uploadArea (width > ${({ theme }) => - parseInt(theme.breakpoint.sizes.sm) / 1.5}px) { - span[data-truncated="s"] { - display: none; - } +const TruncatorEnd = styled.span` + flex-shrink: 0; + white-space: nowrap; +`; - span[data-truncated="m"] { - display: inline-block; - } - } +const MiddleTruncator = ({ text, trailingChars = 10 }: { text: string; trailingChars?: number; }) => { + const startText = text.slice(0, -trailingChars); + const endText = text.slice(-trailingChars); - @container uploadArea (width > ${({ theme }) => theme.breakpoint.sizes.md}) { - span { - display: inline-block; - } - span[data-truncated] { - display: none; - } - } -`; + return ( + + {startText} + {endText} + + ); +}; const UploadArea = styled.div<{ $isDragging: boolean; @@ -132,10 +139,10 @@ const FileUploadTitle = styled(Title)<{ $isNotSupported: boolean }>` : theme.click.fileUpload.color.title.default}; `; -const FileName = styled(Text)` - font: ${({ theme }) => theme.click.fileUpload.typography.description.default}; - color: ${({ theme }) => theme.click.fileUpload.color.title.default}; -`; +// const FileName = styled(Text)` +// font: ${({ theme }) => theme.click.fileUpload.typography.description.default}; +// color: ${({ theme }) => theme.click.fileUpload.color.title.default}; +// `; const FileUploadDescription = styled(Text)<{ $isError?: boolean }>` font: ${({ theme }) => theme.click.fileUpload.typography.description.default}; @@ -190,6 +197,7 @@ const FileDetails = styled.div` display: flex; gap: ${({ theme }) => theme.click.fileUpload.md.space.gap}; border: none; + min-width: 0; `; const FileActions = styled.div` @@ -205,6 +213,7 @@ const FileContentContainer = styled.div<{ $size: "sm" | "md" }>` flex-direction: column; justify-content: center; min-height: ${({ $size }) => ($size === "sm" ? "24px" : "auto")}; + min-width: 0; `; const ProgressBarWrapper = styled.div` @@ -372,11 +381,6 @@ export const FileUpload = ({ }, [onRetry]); const acceptedFileTypes = supportedFileTypes.join(","); - const shortenMFilename = useMemo(() => (file ? shortenMiddle(file.name) : ""), [file]); - const shortenSFilename = useMemo( - () => (file ? shortenMiddle(file.name, 20) : ""), - [file] - ); return ( <> @@ -432,26 +436,7 @@ export const FileUpload = ({ - - - - - {file.name} - - + {showProgress && !showSuccess && ( {progress}% )} From 83e7548ebc51b827f232f6b235df0e3e0f8e9a96 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Wed, 28 Jan 2026 10:10:13 +0000 Subject: [PATCH 11/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index c7b34262b..0bea97b19 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -59,7 +59,13 @@ const TruncatorEnd = styled.span` white-space: nowrap; `; -const MiddleTruncator = ({ text, trailingChars = 10 }: { text: string; trailingChars?: number; }) => { +const MiddleTruncator = ({ + text, + trailingChars = 10, +}: { + text: string; + trailingChars?: number; +}) => { const startText = text.slice(0, -trailingChars); const endText = text.slice(-trailingChars); From c94d8d9499fdcaec398c27b3b2d5f13c2ef8bb45 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Wed, 28 Jan 2026 10:12:33 +0000 Subject: [PATCH 12/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20changset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/large-hats-type.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/large-hats-type.md diff --git a/.changeset/large-hats-type.md b/.changeset/large-hats-type.md new file mode 100644 index 000000000..8f75aa685 --- /dev/null +++ b/.changeset/large-hats-type.md @@ -0,0 +1,9 @@ +--- +"@clickhouse/click-ui": minor +--- + +Adapts file upload filename truncation responsiveness, e.g. shows truncated file name on smaller container sizes, showing the original otherwise. It shows the complete filename on element hover. + +This is a variation of [779](https://github.com/ClickHouse/click-ui/pull/781), which shortens the middle of the text responsively but over breakpoints. Ideally, it should be fluid, but that'd require computation/listener/observables, through container size, it might be hard to justify the time. + +As an alternative, we introduce text number of characters responsive fluidity by faking it, e.g. does not introduce listeners/observables, uses native css resulting in a fluid, well-performing responsive truncation. From 7035975977a7df7620bba31e5be581bac98b938b Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Wed, 28 Jan 2026 10:13:00 +0000 Subject: [PATCH 13/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20delete=20concurre?= =?UTF-8?q?nt=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/tame-rivers-write.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/tame-rivers-write.md diff --git a/.changeset/tame-rivers-write.md b/.changeset/tame-rivers-write.md deleted file mode 100644 index d01c85e86..000000000 --- a/.changeset/tame-rivers-write.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@clickhouse/click-ui": minor ---- - -Adapts file upload filename truncation responsiveness, e.g. shows truncated file name on smaller container sizes, showing the original otherwise. It shows the complete filename on element hover. From 01e79470c3f0699337868e4224d6397180cf796f Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Wed, 28 Jan 2026 10:13:51 +0000 Subject: [PATCH 14/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20remove=20commente?= =?UTF-8?q?d=20out=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FileUpload/FileUpload.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index 0bea97b19..8be2d1384 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -145,11 +145,6 @@ const FileUploadTitle = styled(Title)<{ $isNotSupported: boolean }>` : theme.click.fileUpload.color.title.default}; `; -// const FileName = styled(Text)` -// font: ${({ theme }) => theme.click.fileUpload.typography.description.default}; -// color: ${({ theme }) => theme.click.fileUpload.color.title.default}; -// `; - const FileUploadDescription = styled(Text)<{ $isError?: boolean }>` font: ${({ theme }) => theme.click.fileUpload.typography.description.default}; color: ${({ theme, $isError }) =>