From 6ac96a7dd3ac00bbc204dbd8f97af3764729556b Mon Sep 17 00:00:00 2001 From: ss Date: Sat, 20 Jun 2026 09:37:25 +0200 Subject: [PATCH 1/3] fix(ui): move menu checks to the right --- apps/web/src/components/chat/ChatComposer.tsx | 23 +++-- apps/web/src/components/chat/TraitsPicker.tsx | 93 ++++++++++++------- apps/web/src/components/ui/menu.tsx | 46 +++++---- 3 files changed, 102 insertions(+), 60 deletions(-) diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index db26fa55a73..147da5cf25f 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -95,6 +95,7 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; import { toastManager } from "../ui/toast"; import { BotIcon, + CheckIcon, CircleAlertIcon, ListTodoIcon, PencilRulerIcon, @@ -273,16 +274,20 @@ const ComposerFooterModeControls = memo(function ComposerFooterModeControls(prop {runtimeModeOptions.map((mode) => { const option = runtimeModeConfig[mode]; const OptionIcon = option.icon; + const isSelected = props.runtimeMode === mode; return ( - -
- - - {option.label} - - - {option.description} - + +
+
+ + + {option.label} + + + {option.description} + +
+
); diff --git a/apps/web/src/components/chat/TraitsPicker.tsx b/apps/web/src/components/chat/TraitsPicker.tsx index 91e14f20a91..c157d2e135a 100644 --- a/apps/web/src/components/chat/TraitsPicker.tsx +++ b/apps/web/src/components/chat/TraitsPicker.tsx @@ -16,7 +16,7 @@ import { } from "@t3tools/shared/model"; import { memo, useCallback, useState } from "react"; import type { VariantProps } from "class-variance-authority"; -import { ChevronDownIcon } from "lucide-react"; +import { CheckIcon, ChevronDownIcon } from "lucide-react"; import { Button, buttonVariants } from "../ui/button"; import { Menu, @@ -310,30 +310,44 @@ export const TraitsMenuContent = memo(function TraitsMenuContentImpl({ option.
) : null} - { + const selectedValue = ultrathinkPromptControlled && descriptor.id === primarySelectDescriptor?.id ? "ultrathink" - : (getDescriptorStringValue(descriptor) ?? "") - } - onValueChange={(value) => handleSelectChange(descriptor, value)} - > - {descriptor.options.map((option) => ( - handleSelectChange(descriptor, value)} > - {option.label} - {option.isDefault ? ( - <> - {" "} - - - ) : null} - - ))} - + {descriptor.options.map((option) => ( + + + + {option.label} + {option.isDefault ? ( + <> + {" "} + + + ) : null} + + {option.id === selectedValue ? ( + + ) : null} + + + ))} + + ); + })()} ))} @@ -344,17 +358,30 @@ export const TraitsMenuContent = memo(function TraitsMenuContentImpl({
{descriptor.label}
- { - updateDescriptors( - replaceDescriptorCurrentValue(descriptors, descriptor.id, value === "on"), - ); - }} - > - On - Off - + {(() => { + const selectedValue = descriptor.currentValue === true ? "on" : "off"; + return ( + { + updateDescriptors( + replaceDescriptorCurrentValue(descriptors, descriptor.id, value === "on"), + ); + }} + > + {(["on", "off"] as const).map((value) => ( + + + {value === "on" ? "On" : "Off"} + {value === selectedValue ? ( + + ) : null} + + + ))} + + ); + })()} ))} diff --git a/apps/web/src/components/ui/menu.tsx b/apps/web/src/components/ui/menu.tsx index 07e27d23f46..e9ee42c8f65 100644 --- a/apps/web/src/components/ui/menu.tsx +++ b/apps/web/src/components/ui/menu.tsx @@ -147,32 +147,42 @@ function MenuRadioGroup(props: MenuPrimitive.RadioGroup.Props) { return ; } -function MenuRadioItem({ className, children, ...props }: MenuPrimitive.RadioItem.Props) { +function MenuRadioItem({ + className, + children, + hideIndicator = false, + ...props +}: MenuPrimitive.RadioItem.Props & { + hideIndicator?: boolean; +}) { return ( - - - - - - {children} + {hideIndicator ? null : ( + + + + + + )} + {children} ); } From 412fcdd3cc2c87f0dfc454bae3607c5d3f9a1a55 Mon Sep 17 00:00:00 2001 From: ss Date: Sat, 20 Jun 2026 09:37:53 +0200 Subject: [PATCH 2/3] fix(ui): make selected menu checks blue --- apps/web/src/components/chat/ChatComposer.tsx | 7 ++++++- apps/web/src/components/chat/TraitsPicker.tsx | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index 147da5cf25f..6ec2e631d19 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -287,7 +287,12 @@ const ComposerFooterModeControls = memo(function ComposerFooterModeControls(prop {option.description} - +
); diff --git a/apps/web/src/components/chat/TraitsPicker.tsx b/apps/web/src/components/chat/TraitsPicker.tsx index c157d2e135a..8816d45d85e 100644 --- a/apps/web/src/components/chat/TraitsPicker.tsx +++ b/apps/web/src/components/chat/TraitsPicker.tsx @@ -340,7 +340,7 @@ export const TraitsMenuContent = memo(function TraitsMenuContentImpl({ ) : null} {option.id === selectedValue ? ( - + ) : null} @@ -374,7 +374,7 @@ export const TraitsMenuContent = memo(function TraitsMenuContentImpl({ {value === "on" ? "On" : "Off"} {value === selectedValue ? ( - + ) : null} From 5141f95df0c98b7297b2e0baaa8c5f25ae03dfe9 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Sat, 18 Jul 2026 13:26:46 +0200 Subject: [PATCH 3/3] Refactor trait option rendering Co-authored-by: codex --- apps/web/src/components/chat/TraitsPicker.tsx | 166 +++++++++--------- 1 file changed, 81 insertions(+), 85 deletions(-) diff --git a/apps/web/src/components/chat/TraitsPicker.tsx b/apps/web/src/components/chat/TraitsPicker.tsx index 8816d45d85e..714ee4239f3 100644 --- a/apps/web/src/components/chat/TraitsPicker.tsx +++ b/apps/web/src/components/chat/TraitsPicker.tsx @@ -297,94 +297,90 @@ export const TraitsMenuContent = memo(function TraitsMenuContentImpl({ return ( <> - {selectDescriptors.map((descriptor, index) => ( -
- {index > 0 ? : null} - -
- {descriptor.label} -
- {ultrathinkInBodyText && descriptor.id === primarySelectDescriptor?.id ? ( -
- Your prompt contains "ultrathink" in the text. Remove it to change this - option. + {selectDescriptors.map((descriptor, index) => { + const selectedValue = + ultrathinkPromptControlled && descriptor.id === primarySelectDescriptor?.id + ? "ultrathink" + : (getDescriptorStringValue(descriptor) ?? ""); + + return ( +
+ {index > 0 ? : null} + +
+ {descriptor.label}
- ) : null} - {(() => { - const selectedValue = - ultrathinkPromptControlled && descriptor.id === primarySelectDescriptor?.id - ? "ultrathink" - : (getDescriptorStringValue(descriptor) ?? ""); - return ( - handleSelectChange(descriptor, value)} - > - {descriptor.options.map((option) => ( - - - - {option.label} - {option.isDefault ? ( - <> - {" "} - - - ) : null} - - {option.id === selectedValue ? ( - - ) : null} - - - ))} - - ); - })()} -
-
- ))} - {booleanDescriptors.map((descriptor, index) => ( -
- {index > 0 || selectDescriptors.length > 0 ? : null} - -
- {descriptor.label} -
- {(() => { - const selectedValue = descriptor.currentValue === true ? "on" : "off"; - return ( - { - updateDescriptors( - replaceDescriptorCurrentValue(descriptors, descriptor.id, value === "on"), - ); - }} - > - {(["on", "off"] as const).map((value) => ( - - - {value === "on" ? "On" : "Off"} - {value === selectedValue ? ( - + {ultrathinkInBodyText && descriptor.id === primarySelectDescriptor?.id ? ( +
+ Your prompt contains "ultrathink" in the text. Remove it to change this + option. +
+ ) : null} + handleSelectChange(descriptor, value)} + > + {descriptor.options.map((option) => ( + + + + {option.label} + {option.isDefault ? ( + <> + {" "} + + ) : null} - - ))} - - ); - })()} -
-
- ))} + {option.id === selectedValue ? ( + + ) : null} + + + ))} + + +
+ ); + })} + {booleanDescriptors.map((descriptor, index) => { + const selectedValue = descriptor.currentValue === true ? "on" : "off"; + + return ( +
+ {index > 0 || selectDescriptors.length > 0 ? : null} + +
+ {descriptor.label} +
+ { + updateDescriptors( + replaceDescriptorCurrentValue(descriptors, descriptor.id, value === "on"), + ); + }} + > + {(["on", "off"] as const).map((value) => ( + + + {value === "on" ? "On" : "Off"} + {value === selectedValue ? ( + + ) : null} + + + ))} + +
+
+ ); + })} ); });