in desktop/flipper-ui-core/src/chrome/settings/configFields.tsx [60:147]
export function FilePathConfigField(props: {
label: string;
resetValue?: string;
defaultValue: string;
onChange: (path: string) => void;
frozen?: boolean;
// Defaults to allowing directories only, this changes to expect regular files.
isRegularFile?: boolean;
}) {
const renderHost = getRenderHostInstance();
const [value, setValue] = useState(props.defaultValue);
const [isValid, setIsValid] = useState(true);
useEffect(() => {
(async function () {
try {
const stat = await getFlipperLib().remoteServerContext.fs.stat(value);
setIsValid(props.isRegularFile !== stat.isDirectory);
} catch (_) {
setIsValid(false);
}
})();
}, [props.isRegularFile, value]);
return (
<ConfigFieldContainer>
<InfoText>{props.label}</InfoText>
<FileInputBox
placeholder={props.label}
value={value}
isValid={isValid}
onChange={(e) => {
setValue(e.target.value);
props.onChange(e.target.value);
getFlipperLib()
.remoteServerContext.fs.stat(e.target.value)
.then((stat) => stat.isDirectory)
.then((valid) => {
if (valid !== isValid) {
setIsValid(valid);
}
})
.catch((_) => setIsValid(false));
}}
/>
{renderHost.showSelectDirectoryDialog && (
<FlexColumn
onClick={() => {
renderHost
.showSelectDirectoryDialog?.()
.then((path) => {
if (path) {
setValue(path);
props.onChange(path);
}
})
.catch((e) => {
console.warn('Failed to select dir', e);
});
}}>
<CenteredGlyph
color={theme.primaryColor}
name="dots-3-circle"
variant="outline"
/>
</FlexColumn>
)}
{props.resetValue && (
<FlexColumn
title={`Reset to default path ${props.resetValue}`}
onClick={() => {
setValue(props.resetValue!);
props.onChange(props.resetValue!);
}}>
<CenteredGlyph
color={theme.primaryColor}
name="undo"
variant="outline"
/>
</FlexColumn>
)}
{isValid ? null : (
<CenteredGlyph name="caution-triangle" color={colors.yellow} />
)}
{props.frozen && <GrayedOutOverlay />}
</ConfigFieldContainer>
);
}