pascal-maker's picture
Upload folder using huggingface_hub
92189dd verified
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Tooltip from '@/common/components/Tooltip';
import {ArrowPathIcon, CheckIcon, XMarkIcon} from '@heroicons/react/24/solid';
import {ChangeEvent, KeyboardEvent, useEffect, useMemo, useState} from 'react';
import {Button, Form, Input, Join} from 'react-daisyui';
type Props<T extends string | number> = Omit<
React.InputHTMLAttributes<HTMLInputElement>,
'size' | 'color' | 'onChange'
> & {
label: string;
defaultValue: T;
initialValue: T;
onChange: (value: string) => void;
};
function getStep(value: number) {
const stringValue = String(value);
const decimals = stringValue.split('.')[1];
if (decimals != null) {
// Not using 0.1 ** decimals.length because this will result in rounding
// errors, e.g., 0.1 ** 2 => 0.010000000000000002.
return 1 / 10 ** decimals.length;
}
return 1;
}
export default function ApprovableInput<T extends string | number>({
label,
defaultValue,
initialValue,
onChange,
...otherProps
}: Props<T>) {
const [value, setValue] = useState<string>(`${initialValue}`);
useEffect(() => {
setValue(`${initialValue}`);
}, [initialValue]);
const step = useMemo(() => {
return typeof defaultValue === 'number' && isFinite(defaultValue)
? getStep(defaultValue)
: undefined;
}, [defaultValue]);
return (
<div>
<Form.Label className="flex-col items-start gap-2" title={label}>
<Join className="w-full">
<Input
{...otherProps}
className="w-full join-item"
value={value}
step={step}
placeholder={`${defaultValue}`}
onChange={(event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
}}
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
event.preventDefault();
onChange(value);
}
}}
/>
<Tooltip message="Reset to default">
<Button
className="join-item"
onClick={event => {
event.preventDefault();
setValue(`${defaultValue}`);
}}>
<ArrowPathIcon className="h-4 w-4" />
</Button>
</Tooltip>
<Tooltip message="Revert change">
<Button
className="join-item"
color="neutral"
disabled={initialValue == value}
onClick={event => {
event.preventDefault();
setValue(`${initialValue}`);
}}>
<XMarkIcon className="h-4 w-4" />
</Button>
</Tooltip>
<Tooltip message="Apply change">
<Button
className="join-item"
color="primary"
disabled={initialValue == value}
onClick={event => {
event.preventDefault();
onChange(value);
}}>
<CheckIcon className="h-4 w-4" />
</Button>
</Tooltip>
</Join>
</Form.Label>
</div>
);
}