src: use prop unpacking pattern

This makes the code a bit shorter by not having to use `props.` all of
the time. Also make everything VoidFunctionComponent while we are
touching this.
This commit is contained in:
David Lechner
2022-03-12 16:07:31 -06:00
parent 228ba4ebb8
commit 8e4045449c
18 changed files with 193 additions and 131 deletions
+20 -14
View File
@@ -46,16 +46,22 @@ type ActionButtonProps = {
onClick: () => void;
};
const ActionButton: React.VoidFunctionComponent<ActionButtonProps> = (props) => {
const ActionButton: React.VoidFunctionComponent<ActionButtonProps> = ({
icon,
toolTipId,
toolTipReplacements,
disabled,
onClick,
}) => {
const [i18n] = useI18n({ id: 'explorer', translations: { en }, fallback: en });
return (
<Button
icon={props.icon}
title={i18n.translate(props.toolTipId, props.toolTipReplacements)}
disabled={props.disabled}
icon={icon}
title={i18n.translate(toolTipId, toolTipReplacements)}
disabled={disabled}
onMouseDown={preventFocusOnClick}
onClick={props.onClick}
onClick={onClick}
/>
);
};
@@ -73,7 +79,7 @@ type ActionButtonGroupProps = {
const FileActionButtonGroup = forwardRef<
FileActionButtonGroupRef,
ActionButtonGroupProps
>((props, ref) => {
>(({ fileName }, ref) => {
const dispatch = useDispatch();
const [visible, setVisible] = useState(false);
const [isRenameDialogOpen, setIsRenameDialogOpen] = useState(false);
@@ -85,10 +91,10 @@ const FileActionButtonGroup = forwardRef<
// received.
const fileNames = useSelector((s) => s.fileStorage.fileNames);
useEffect(() => {
if (!fileNames.includes(props.fileName)) {
if (!fileNames.includes(fileName)) {
setVisible(false);
}
}, [fileNames, props.fileName, setVisible]);
}, [fileNames, fileName, setVisible]);
useImperativeHandle(ref, () => ({ setVisible }), [setVisible]);
@@ -97,11 +103,11 @@ const FileActionButtonGroup = forwardRef<
<ActionButton
icon="edit"
toolTipId={ExplorerStringId.TreeItemRenameTooltip}
toolTipReplacements={{ fileName: props.fileName }}
toolTipReplacements={{ fileName: fileName }}
onClick={() => setIsRenameDialogOpen(true)}
/>
<RenameFileDialog
oldName={props.fileName}
oldName={fileName}
isOpen={isRenameDialogOpen}
onClose={() => setIsRenameDialogOpen(false)}
/>
@@ -113,14 +119,14 @@ const FileActionButtonGroup = forwardRef<
// download operation
icon="import"
toolTipId={ExplorerStringId.TreeItemExportTooltip}
toolTipReplacements={{ fileName: props.fileName }}
onClick={() => dispatch(fileStorageExportFile(props.fileName))}
toolTipReplacements={{ fileName: fileName }}
onClick={() => dispatch(fileStorageExportFile(fileName))}
/>
<ActionButton
icon="trash"
toolTipId={ExplorerStringId.TreeItemDeleteTooltip}
toolTipReplacements={{ fileName: props.fileName }}
onClick={() => dispatch(explorerDeleteFile(props.fileName))}
toolTipReplacements={{ fileName: fileName }}
onClick={() => dispatch(explorerDeleteFile(fileName))}
/>
</ButtonGroup>
);
+18 -14
View File
@@ -17,12 +17,12 @@ type FileNameHelpTextProps = {
/**
* Component that maps FileNameValidationResult to help message to display to user.
*/
const FileNameHelpText: React.VoidFunctionComponent<FileNameHelpTextProps> = (
props,
) => {
const FileNameHelpText: React.VoidFunctionComponent<FileNameHelpTextProps> = ({
validation,
}) => {
const [i18n] = useI18n({ id: 'explorer', translations: { en }, fallback: en });
switch (props.validation) {
switch (validation) {
case FileNameValidationResult.IsOk:
return <>{i18n.translate(NewFileWizardStringId.FileNameHelpTextIsOk)}</>;
case FileNameValidationResult.IsEmpty:
@@ -92,23 +92,27 @@ type FileNameFormGroupProps = {
/**
* Component used to get a valid new file name.
*/
const FileNameFormGroup: React.VoidFunctionComponent<FileNameFormGroupProps> = (
props,
) => {
const FileNameFormGroup: React.VoidFunctionComponent<FileNameFormGroupProps> = ({
fileName,
fileExtension,
inputRef,
onChange,
onValidation,
}) => {
const [i18n] = useI18n({ id: 'explorer', translations: { en }, fallback: en });
const fileNames = useSelector((s) => s.fileStorage.fileNames);
const [fileNameValidation, fileNameIntent] = useMemo(() => {
const result = validateFileName(props.fileName, props.fileExtension, fileNames);
const result = validateFileName(fileName, fileExtension, fileNames);
// can't call callback now because it would break react, so defer it
setTimeout(() => props.onValidation(result), 0);
setTimeout(() => onValidation(result), 0);
return [
result,
result === FileNameValidationResult.IsOk ? Intent.NONE : Intent.DANGER,
];
}, [props.fileName, props.fileExtension, fileNames]);
}, [fileName, fileExtension, fileNames]);
return (
<FormGroup
@@ -118,11 +122,11 @@ const FileNameFormGroup: React.VoidFunctionComponent<FileNameFormGroupProps> = (
>
<InputGroup
aria-label="File name"
value={props.fileName}
inputRef={props.inputRef}
value={fileName}
inputRef={inputRef}
intent={fileNameIntent}
rightElement={<Tag>{props.fileExtension}</Tag>}
onChange={(e) => props.onChange(e.target.value)}
rightElement={<Tag>{fileExtension}</Tag>}
onChange={(e) => onChange(e.target.value)}
/>
</FormGroup>
);
+7 -4
View File
@@ -32,7 +32,10 @@ type NewFileWizardProps = {
readonly onClose: () => void;
};
const NewFileWizard: React.VoidFunctionComponent<NewFileWizardProps> = (props) => {
const NewFileWizard: React.VoidFunctionComponent<NewFileWizardProps> = ({
isOpen,
onClose,
}) => {
const [i18n] = useI18n({ id: 'explorer', translations: { en }, fallback: en });
const dispatch = useDispatch();
@@ -48,10 +51,10 @@ const NewFileWizard: React.VoidFunctionComponent<NewFileWizardProps> = (props) =
<Dialog
icon="plus"
title={i18n.translate(NewFileWizardStringId.Title)}
isOpen={props.isOpen}
isOpen={isOpen}
onOpening={() => setFileName('')}
onOpened={() => fileNameInputRef.current?.focus()}
onClose={props.onClose}
onClose={onClose}
>
<div className={Classes.DIALOG_BODY}>
<FileNameFormGroup
@@ -83,7 +86,7 @@ const NewFileWizard: React.VoidFunctionComponent<NewFileWizardProps> = (props) =
disabled={fileNameValidation !== FileNameValidationResult.IsOk}
onMouseDown={preventFocusOnClick}
onClick={() => {
props.onClose();
onClose();
dispatch(
explorerCreateNewFile(
fileName,
+11 -9
View File
@@ -21,13 +21,15 @@ type RenameFileDialogProps = {
onClose: () => void;
};
const RenameFileDialog: React.VoidFunctionComponent<RenameFileDialogProps> = (
props,
) => {
const RenameFileDialog: React.VoidFunctionComponent<RenameFileDialogProps> = ({
oldName,
isOpen,
onClose,
}) => {
const [i18n] = useI18n({ id: 'explorer', translations: { en }, fallback: en });
const dispatch = useDispatch();
const [baseName, extension] = props.oldName.split(/(\.\w+)$/);
const [baseName, extension] = oldName.split(/(\.\w+)$/);
const [newName, setNewName] = useState(baseName);
const [result, setResult] = useState(FileNameValidationResult.Unknown);
@@ -37,15 +39,15 @@ const RenameFileDialog: React.VoidFunctionComponent<RenameFileDialogProps> = (
return (
<Dialog
title={i18n.translate(RenameFileStringId.Title, {
fileName: props.oldName,
fileName: oldName,
})}
isOpen={props.isOpen}
isOpen={isOpen}
onOpening={() => setNewName(baseName)}
onOpened={() => {
inputRef.current?.select();
inputRef.current?.focus();
}}
onClose={() => props.onClose()}
onClose={() => onClose()}
>
<div className={Classes.DIALOG_BODY}>
<FileNameFormGroup
@@ -64,10 +66,10 @@ const RenameFileDialog: React.VoidFunctionComponent<RenameFileDialogProps> = (
disabled={result !== FileNameValidationResult.IsOk}
onMouseDown={preventFocusOnClick}
onClick={() => {
props.onClose();
onClose();
dispatch(
fileStorageRenameFile(
props.oldName,
oldName,
`${newName}${extension}`,
),
);