chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import { Switch } from "~/components/primitives/Switch";
|
||||
import { Select, SelectItem } from "~/components/primitives/Select";
|
||||
import { Input } from "~/components/primitives/Input";
|
||||
import { cn } from "~/utils/cn";
|
||||
|
||||
export const UNSET_VALUE = "__unset__";
|
||||
|
||||
export function BooleanControl({
|
||||
value,
|
||||
onChange,
|
||||
dimmed,
|
||||
}: {
|
||||
value: boolean | undefined;
|
||||
onChange: (val: boolean) => void;
|
||||
dimmed: boolean;
|
||||
}) {
|
||||
return (
|
||||
<Switch
|
||||
variant="small"
|
||||
checked={value ?? false}
|
||||
onCheckedChange={onChange}
|
||||
className={cn(dimmed && "opacity-50")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function EnumControl({
|
||||
value,
|
||||
options,
|
||||
onChange,
|
||||
dimmed,
|
||||
}: {
|
||||
value: string | undefined;
|
||||
options: string[];
|
||||
onChange: (val: string) => void;
|
||||
dimmed: boolean;
|
||||
}) {
|
||||
const items = [UNSET_VALUE, ...options];
|
||||
|
||||
return (
|
||||
<Select
|
||||
variant="tertiary/small"
|
||||
value={value ?? UNSET_VALUE}
|
||||
setValue={onChange}
|
||||
items={items}
|
||||
text={(val) => (val === UNSET_VALUE ? "unset" : val)}
|
||||
className={cn(dimmed && "opacity-50")}
|
||||
>
|
||||
{(items) =>
|
||||
items.map((item) => (
|
||||
<SelectItem key={item} value={item}>
|
||||
{item === UNSET_VALUE ? "unset" : item}
|
||||
</SelectItem>
|
||||
))
|
||||
}
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
|
||||
export type WorkerGroup = { id: string; name: string };
|
||||
|
||||
export function WorkerGroupControl({
|
||||
value,
|
||||
workerGroups,
|
||||
onChange,
|
||||
dimmed,
|
||||
}: {
|
||||
value: string | undefined;
|
||||
workerGroups: WorkerGroup[];
|
||||
onChange: (val: string) => void;
|
||||
dimmed: boolean;
|
||||
}) {
|
||||
const items = [UNSET_VALUE, ...workerGroups.map((wg) => wg.id)];
|
||||
|
||||
return (
|
||||
<Select
|
||||
variant="tertiary/small"
|
||||
value={value ?? UNSET_VALUE}
|
||||
setValue={onChange}
|
||||
items={items}
|
||||
text={(val) => {
|
||||
if (val === UNSET_VALUE) return "unset";
|
||||
const wg = workerGroups.find((w) => w.id === val);
|
||||
return wg ? wg.name : val;
|
||||
}}
|
||||
className={cn(dimmed && "opacity-50")}
|
||||
>
|
||||
{(items) =>
|
||||
items.map((item) => {
|
||||
const wg = workerGroups.find((w) => w.id === item);
|
||||
return (
|
||||
<SelectItem key={item} value={item}>
|
||||
{item === UNSET_VALUE ? "unset" : wg ? wg.name : item}
|
||||
</SelectItem>
|
||||
);
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
|
||||
export function NumberControl({
|
||||
value,
|
||||
onChange,
|
||||
min,
|
||||
max,
|
||||
dimmed,
|
||||
}: {
|
||||
value: number | undefined;
|
||||
onChange: (val: number | undefined) => void;
|
||||
min?: number;
|
||||
max?: number;
|
||||
dimmed: boolean;
|
||||
}) {
|
||||
// Number and string fields share the same input shape; surface the range
|
||||
// (or "number") as the placeholder so an unset field still signals its type.
|
||||
const placeholder = min !== undefined && max !== undefined ? `${min}-${max}` : "number";
|
||||
return (
|
||||
<Input
|
||||
type="number"
|
||||
variant="small"
|
||||
// Empty string when unset so the placeholder shows instead of "0".
|
||||
value={value ?? ""}
|
||||
min={min}
|
||||
max={max}
|
||||
step={1}
|
||||
onChange={(e) => {
|
||||
const next = e.target.valueAsNumber;
|
||||
onChange(Number.isNaN(next) ? undefined : next);
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
className={cn("w-40", dimmed && "opacity-50")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function StringControl({
|
||||
value,
|
||||
onChange,
|
||||
dimmed,
|
||||
}: {
|
||||
value: string;
|
||||
onChange: (val: string) => void;
|
||||
dimmed: boolean;
|
||||
}) {
|
||||
return (
|
||||
<Input
|
||||
variant="small"
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
placeholder="unset"
|
||||
className={cn("w-40", dimmed && "opacity-50")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user