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. 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; } diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index 4607e2fe2..8be2d1384 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -2,7 +2,6 @@ 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,12 +36,58 @@ interface FileUploadProps { onFileClose?: () => void; } +// 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}; +`; + +const TruncatorStart = styled.span` + flex-shrink: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +`; + +const TruncatorEnd = styled.span` + flex-shrink: 0; + white-space: nowrap; +`; + +const MiddleTruncator = ({ + text, + trailingChars = 10, +}: { + text: string; + trailingChars?: number; +}) => { + const startText = text.slice(0, -trailingChars); + const endText = text.slice(-trailingChars); + + return ( + + {startText} + {endText} + + ); +}; + 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 }) => @@ -100,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 }) => @@ -158,6 +198,7 @@ const FileDetails = styled.div` display: flex; gap: ${({ theme }) => theme.click.fileUpload.md.space.gap}; border: none; + min-width: 0; `; const FileActions = styled.div` @@ -173,6 +214,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` @@ -395,7 +437,7 @@ export const FileUpload = ({ - {shortenMiddle(file.name)} + {showProgress && !showSuccess && ( {progress}% )}