Control rows while renaming

This commit is contained in:
Dustin Brett
2021-09-25 22:41:04 -07:00
parent a619919b7b
commit ffc12bf546
10 changed files with 84 additions and 7 deletions

View File

@@ -1,7 +1,9 @@
import { getLineCount } from "components/system/Files/FileEntry/functions";
import { haltEvent } from "components/system/Files/FileManager/functions";
import StyledRenameBox from "components/system/Files/Views/StyledRenameBox";
import { extname } from "path";
import { useEffect, useRef } from "react";
import { useCallback, useEffect, useRef } from "react";
import { useTheme } from "styled-components";
import { PREVENT_SCROLL } from "utils/constants";
type RenameBoxProps = {
@@ -13,11 +15,31 @@ type RenameBoxProps = {
const RenameBox = ({ name, path, renameFile }: RenameBoxProps): JSX.Element => {
const inputRef = useRef<HTMLTextAreaElement | null>(null);
const saveRename = (): void => renameFile(path, inputRef.current?.value);
const { formats, sizes } = useTheme();
const updateRows = useCallback(
(text: string): void => {
const lines = getLineCount(
text,
sizes.fileEntry.fontSize,
formats.systemFont,
sizes.fileEntry.renameWidth - sizes.fileEntry.renamePadding * 2
);
inputRef.current?.setAttribute("rows", lines.toString());
},
[
formats.systemFont,
sizes.fileEntry.fontSize,
sizes.fileEntry.renamePadding,
sizes.fileEntry.renameWidth,
]
);
useEffect(() => {
inputRef.current?.focus(PREVENT_SCROLL);
inputRef.current?.setSelectionRange(0, name.length - extname(name).length);
}, [name]);
updateRows(name);
}, [name, updateRows]);
return (
<StyledRenameBox
@@ -25,7 +47,13 @@ const RenameBox = ({ name, path, renameFile }: RenameBoxProps): JSX.Element => {
onBlurCapture={saveRename}
onClick={haltEvent}
onKeyDown={({ key }) => key === "Enter" && saveRename()}
onKeyUp={haltEvent}
onKeyUp={(event) => {
if (event.target instanceof HTMLTextAreaElement) {
updateRows(event.target.value);
}
haltEvent(event);
}}
ref={inputRef}
/>
);

View File

@@ -176,3 +176,37 @@ export const filterSystemFiles =
(directory: string) =>
(file: string): boolean =>
!SYSTEM_PATHS.has(join(directory, file)) && !SYSTEM_FILES.has(file);
export const getLineCount = (
text: string,
fontSize: string,
fontFamily: string,
maxWidth: number
): number => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d", {
alpha: false,
desynchronized: true,
}) as CanvasRenderingContext2D;
context.font = `${fontSize} ${fontFamily}`;
if (context.measureText(text).width > maxWidth) {
const lines = [""];
[...text].forEach((character) => {
const lineCount = lines.length - 1;
const lineText = `${lines[lineCount]}${character}`;
if (context.measureText(lineText).width > maxWidth) {
lines.push(character);
} else {
lines[lineCount] = lineText;
}
});
return lines.length;
}
return 1;
};

View File

@@ -17,6 +17,7 @@ import { MOUNTABLE_EXTENSIONS, SHORTCUT_EXTENSION } from "utils/constants";
type FileManagerProps = {
closing?: boolean;
hideLoading?: boolean;
hideScrolling?: boolean;
url: string;
view: FileManagerViewNames;
};
@@ -24,6 +25,7 @@ type FileManagerProps = {
const FileManager = ({
closing,
hideLoading,
hideScrolling,
url,
view,
}: FileManagerProps): JSX.Element => {
@@ -60,6 +62,7 @@ const FileManager = ({
) : (
<StyledFileManager
ref={fileManagerRef}
scrollable={!hideScrolling}
selecting={isSelecting}
{...selectionEvents}
{...fileDrop}

View File

@@ -14,6 +14,7 @@ const StyledFileManager = styled.ol<StyledFileManagerProps>`
grid-template-rows: ${({ theme }) =>
`repeat(auto-fill, ${theme.sizes.fileManager.gridEntryHeight})`};
height: ${({ theme }) => `calc(100% - ${theme.sizes.taskbar.height})`};
overflow: ${({ scrollable }) => (scrollable ? undefined : "hidden")};
padding: ${({ theme }) => theme.sizes.fileManager.padding};
pointer-events: ${({ selecting }) => (selecting ? "auto" : undefined)};
row-gap: ${({ theme }) => theme.sizes.fileManager.rowGap};

View File

@@ -9,12 +9,13 @@ const StyledRenameBox = styled.textarea.attrs({
font-family: inherit;
font-size: 11.5px;
margin-bottom: 2px;
padding: 1px 5px;
overflow: hidden;
padding: ${({ theme }) => `1px ${theme.sizes.fileEntry.renamePadding}px`};
position: relative;
resize: none;
text-align: center;
top: 2px;
width: 70px;
width: ${({ theme }) => `${theme.sizes.fileEntry.renameWidth}px`};
`;
export default StyledRenameBox;

View File

@@ -10,6 +10,7 @@ export type StyledFileEntryProps = {
};
export type StyledFileManagerProps = {
scrollable: boolean;
selecting: boolean;
};

View File

@@ -11,7 +11,12 @@ const Home = (): React.ReactElement => {
return (
<Desktop>
<FileManager url="/Users/Public/Desktop" view="icon" hideLoading />
<FileManager
url="/Users/Public/Desktop"
view="icon"
hideLoading
hideScrolling
/>
<Taskbar />
<AppsLoader />
</Desktop>

View File

@@ -13,7 +13,7 @@ const GlobalStyle = createGlobalStyle`
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-family: ${({ theme }) => theme.formats.systemFont};
overflow: hidden;
}

View File

@@ -15,6 +15,8 @@ const formats = {
minute: "2-digit",
hour12: true,
} as Intl.DateTimeFormatOptions,
systemFont:
"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif",
};
export default formats;

View File

@@ -9,6 +9,8 @@ const sizes = {
fileEntry: {
fontSize: "12px",
iconSize: "48px",
renamePadding: 5,
renameWidth: 75,
},
fileManager: {
columnGap: "1px",