From 48f7d40e8752ed6663ff27f2798d33b49b1142f0 Mon Sep 17 00:00:00 2001 From: Shine1i Date: Thu, 26 Feb 2026 10:13:01 +0100 Subject: [PATCH] feat(ui): normalize recipe dialogs + chip/category UX polish --- .../recipe-studio/components/chip-input.tsx | 31 +++++++++++++++++-- .../recipe-studio/dialogs/import-dialog.tsx | 2 +- .../dialogs/models/model-provider-dialog.tsx | 21 +++---------- .../recipe-studio/dialogs/preview-dialog.tsx | 4 +-- .../dialogs/processors-dialog.tsx | 2 +- .../dialogs/samplers/category-dialog.tsx | 22 ++++++++----- 6 files changed, 52 insertions(+), 30 deletions(-) diff --git a/studio/frontend/src/features/recipe-studio/components/chip-input.tsx b/studio/frontend/src/features/recipe-studio/components/chip-input.tsx index 5162b73e03..a7dd5ccc16 100644 --- a/studio/frontend/src/features/recipe-studio/components/chip-input.tsx +++ b/studio/frontend/src/features/recipe-studio/components/chip-input.tsx @@ -1,7 +1,15 @@ import { Button } from "@/components/ui/button"; import { Cancel01Icon } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; -import { type KeyboardEvent, type ReactElement, useId, useMemo, useState } from "react"; +import { + type KeyboardEvent, + type ReactElement, + useEffect, + useId, + useMemo, + useRef, + useState, +} from "react"; type ChipInputProps = { values: string[]; @@ -19,12 +27,28 @@ export function ChipInput({ suggestions, }: ChipInputProps): ReactElement { const [draft, setDraft] = useState(""); + const [isWrapped, setIsWrapped] = useState(false); + const containerRef = useRef(null); const listId = useId(); const suggestionSet = useMemo( () => new Set((suggestions ?? []).map((value) => value.trim())), [suggestions], ); + useEffect(() => { + const element = containerRef.current; + if (!element) { + return; + } + const syncWrapped = () => { + setIsWrapped(element.clientHeight > 44); + }; + syncWrapped(); + const observer = new ResizeObserver(syncWrapped); + observer.observe(element); + return () => observer.disconnect(); + }, [values.length, draft]); + function addValue(rawValue: string, allowAny: boolean): void { const trimmed = rawValue.trim(); if (!trimmed) { @@ -55,7 +79,10 @@ export function ChipInput({ } return ( -
+
{values.map((value, index) => ( Import recipe diff --git a/studio/frontend/src/features/recipe-studio/dialogs/models/model-provider-dialog.tsx b/studio/frontend/src/features/recipe-studio/dialogs/models/model-provider-dialog.tsx index a4af84f356..589c33b6f1 100644 --- a/studio/frontend/src/features/recipe-studio/dialogs/models/model-provider-dialog.tsx +++ b/studio/frontend/src/features/recipe-studio/dialogs/models/model-provider-dialog.tsx @@ -1,4 +1,3 @@ -import { Button } from "@/components/ui/button"; import { Collapsible, CollapsibleContent, @@ -6,8 +5,6 @@ import { } from "@/components/ui/collapsible"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; -import { ArrowDown01Icon } from "@hugeicons/core-free-icons"; -import { HugeiconsIcon } from "@hugeicons/react"; import { type ReactElement, useState } from "react"; import type { ModelProviderConfig } from "../../types"; import { FieldLabel } from "../shared/field-label"; @@ -70,21 +67,13 @@ export function ModelProviderDialog({
- + Optional + {optionalOpen ? "Hide" : "Show"} +
diff --git a/studio/frontend/src/features/recipe-studio/dialogs/preview-dialog.tsx b/studio/frontend/src/features/recipe-studio/dialogs/preview-dialog.tsx index 296172777f..5ab40d80a5 100644 --- a/studio/frontend/src/features/recipe-studio/dialogs/preview-dialog.tsx +++ b/studio/frontend/src/features/recipe-studio/dialogs/preview-dialog.tsx @@ -285,7 +285,7 @@ export function RunDialog({ position="absolute" overlayPosition="absolute" overlayClassName="bg-transparent" - className="corner-squircle sm:max-w-2xl" + className="corner-squircle sm:max-w-2xl shadow-border" > {kindLabel} settings @@ -294,7 +294,7 @@ export function RunDialog({

-
+
Preview mode Processors diff --git a/studio/frontend/src/features/recipe-studio/dialogs/samplers/category-dialog.tsx b/studio/frontend/src/features/recipe-studio/dialogs/samplers/category-dialog.tsx index f209078799..49fb6c62a1 100644 --- a/studio/frontend/src/features/recipe-studio/dialogs/samplers/category-dialog.tsx +++ b/studio/frontend/src/features/recipe-studio/dialogs/samplers/category-dialog.tsx @@ -133,12 +133,15 @@ export function CategoryDialog({ Add values first, then set optional weights.

) : ( -
+
{(config.values ?? []).map((value, index) => ( -
- +
+

{value} - +

Rule weights (optional)

-
+
{(params.values ?? []).map((value, index) => (
- +

{value} - +