Jon Taylor
ui complete
24d8b3c
raw
history blame
6.68 kB
"use client";
import {
Accordion,
ActionIcon,
SegmentedControl,
Textarea,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import {
IconArrowDownRight,
IconMinus,
IconPlus,
IconRotateClockwise,
} from "@tabler/icons-react";
import React, { useEffect } from "react";
import useDebounce from "../hooks/debounce";
import FieldSet from "./FieldSet";
import Label from "./Label";
import SelectInput from "./SelectInput";
import SlideInput from "./SliderInput";
import TextInput from "./TextInput";
export const Controls = React.memo(() => {
const form = useForm({
initialValues: {
positivePrompt: "some kind of prompt",
negativePrompt: "bad hands",
steps: 1,
guidance: 0.1,
seed: 45678,
resolution: "720",
},
});
const debounce = useDebounce();
const handleChange = (event) => {
console.log(event);
};
useEffect(() => {
if (!form) return;
form.isDirty() && debounce(() => handleChange(form.values), 500);
}, [form, debounce]);
return (
<div className="flex flex-col gap-4">
<Accordion
defaultValue="prompt"
classNames={{
chevron: "w-[20px] text-indigo-500",
label: "font-medium text-zinc-900",
control: "hover:bg-zinc-50",
item: "border-zinc-200",
}}
chevron={<IconArrowDownRight size={20} stroke={2} className="block" />}
>
<Accordion.Item value="prompt" key="prompt">
<Accordion.Control value="prompt">Prompt</Accordion.Control>
<Accordion.Panel>
<FieldSet>
<div className="flex flex-col">
<div className="flex flex-row items-center gap-2 mb-2">
<IconPlus size={20} stroke={1} className="text-emerald-500" />
<span className="font-mono uppercase text-xs tracking-wider text-emerald-600">
Positive Prompt
</span>
</div>
<Textarea
autosize
className="rounded-md"
minRows={3}
defaultValue={form.getInputProps("positivePrompt").value}
onChange={(e) =>
form.setFieldValue("positivePrompt", e.target.value)
}
classNames={{
input:
"p-3 font-mono text-emerald-800 bg-emerald-600/[0.07] border-emerald-500/30 focus:border-emerald-500 focus:ring-1 focus:ring-inset focus:ring-emerald-500",
}}
/>
</div>
<div className="flex flex-col">
<div className="flex flex-row items-center gap-2 mb-2">
<IconMinus size={20} stroke={1} className="text-rose-500" />
<span className="font-mono uppercase text-xs tracking-wider text-rose-600">
Negative Prompt
</span>
</div>
<Textarea
autosize
className="rounded-md"
minRows={3}
defaultValue={form.getInputProps("negativePrompt").value}
onChange={(e) =>
form.setFieldValue("negativePrompt", e.target.value)
}
classNames={{
input:
"p-3 font-mono text-rose-800 bg-rose-600/[0.07] border-rose-500/30 focus:border-rose-500 focus:ring-1 focus:ring-inset focus:ring-rose-500",
}}
/>
</div>
</FieldSet>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="camera" key="camera">
<Accordion.Control value="camera">Camera</Accordion.Control>
<Accordion.Panel>
<FieldSet>
<SelectInput label="Device" />
<div>
<Label>Resolution</Label>
<SegmentedControl
fullWidth
size="sm"
radius="xl"
defaultValue={"720"}
data={[
{ label: "480P", value: "480" },
{ label: "720P", value: "720" },
{ label: "1080P", value: "1080" },
]}
onChange={(v) => form.setFieldValue("resolution", v)}
/>
</div>
</FieldSet>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="diffusion" key="diffusion">
<Accordion.Control value="inference">Diffusion</Accordion.Control>
<Accordion.Panel>
<div className="flex flex-col gap-4">
<TextInput
label="Seed"
type="number"
fieldProps={form.getInputProps("seed")}
>
<ActionIcon
radius="sm"
variant="subtle"
onClick={() =>
form.setFieldValue(
"seed",
Math.floor(Math.random() * 100000001)
)
}
>
<IconRotateClockwise
style={{ width: "70%", height: "70%" }}
stroke={2}
/>
</ActionIcon>
</TextInput>
<SlideInput
label="Steps"
fieldProps={form.getInputProps("steps")}
step={1}
min={1}
max={15}
marks={[
{ value: 1, label: "Low" },
{ value: 15, label: "High" },
]}
/>
<SlideInput
label="Guidance"
fieldProps={form.getInputProps("guidance")}
step={0.001}
min={0}
max={30}
marks={[
{ value: 0, label: "None" },
{ value: 2.5, label: "Low" },
{ value: 7.5, label: "Normal" },
{ value: 12.5, label: "Strict" },
{ value: 17.5, label: "Very Strict" },
{ value: 30, label: "Max" },
]}
/>
</div>
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item value="cn" key="cn">
<Accordion.Control value="cn">Control Net</Accordion.Control>
<Accordion.Panel>Control net</Accordion.Panel>
</Accordion.Item>
</Accordion>
</div>
);
});
Controls.displayName = "Controls";
export default Controls;