export function FilePathConfigField()

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>
  );
}