style(chat): restore composer active control states
This commit is contained in:
parent
5d2b189068
commit
b24a450f26
3 changed files with 75 additions and 134 deletions
|
|
@ -699,8 +699,12 @@ const Composer: FC<{
|
|||
{...inputProps}
|
||||
/>
|
||||
<ComposerRightControls
|
||||
disabled={disabled || isComposing || hasPendingAttachments}
|
||||
showSend={hasSendableContent}
|
||||
disabled={
|
||||
disabled ||
|
||||
!hasSendableContent ||
|
||||
isComposing ||
|
||||
hasPendingAttachments
|
||||
}
|
||||
shouldBlockSend={shouldBlockSend}
|
||||
menuSide={effectiveMenuSide}
|
||||
/>
|
||||
|
|
@ -1053,18 +1057,6 @@ const ReasoningToggle: FC<{ side?: "top" | "bottom" }> = ({
|
|||
const activeLook = isEffort
|
||||
? reasoningLockedOn || (effectiveReasoningVisualEnabled && !disabled)
|
||||
: reasoningLockedOn || (effectiveReasoningEnabled && !disabled);
|
||||
const canDismissReasoning =
|
||||
activeLook &&
|
||||
!disabled &&
|
||||
!reasoningLockedOn &&
|
||||
effectiveSupportsReasoningOff;
|
||||
const dismissReasoning = () => {
|
||||
if (!canDismissReasoning) return;
|
||||
setReasoningEnabled(false);
|
||||
applyQwenThinkingParams(false);
|
||||
setPreserveThinking(false);
|
||||
};
|
||||
|
||||
if (useDropdown) {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
|
|
@ -1074,7 +1066,6 @@ const ReasoningToggle: FC<{ side?: "top" | "bottom" }> = ({
|
|||
disabled={disabled}
|
||||
className="unsloth-thinking-pill"
|
||||
data-active={activeLook ? "true" : "false"}
|
||||
data-dismissible={canDismissReasoning ? "true" : undefined}
|
||||
aria-label={thinkEffortAriaLabel({
|
||||
modelLoaded,
|
||||
reasoningDisabled: disabled,
|
||||
|
|
@ -1086,21 +1077,6 @@ const ReasoningToggle: FC<{ side?: "top" | "bottom" }> = ({
|
|||
<span>{isEffort ? `Thinking · ${effortLabel}` : "Thinking"}</span>
|
||||
) : null}
|
||||
<ArrowDownStandardIcon className="unsloth-thinking-chevron size-[15px]" />
|
||||
{canDismissReasoning ? (
|
||||
<XIcon
|
||||
className="composer-pill-close unsloth-thinking-close"
|
||||
aria-hidden={true}
|
||||
onPointerDown={(event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
dismissReasoning();
|
||||
}}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
|
|
@ -1233,7 +1209,6 @@ const ReasoningToggle: FC<{ side?: "top" | "bottom" }> = ({
|
|||
}}
|
||||
className="unsloth-thinking-pill"
|
||||
data-active={activeLook ? "true" : "false"}
|
||||
data-dismissible={canDismissReasoning ? "true" : undefined}
|
||||
aria-label={thinkToggleAriaLabel({
|
||||
reasoningLockedOn,
|
||||
modelLoaded,
|
||||
|
|
@ -1243,9 +1218,6 @@ const ReasoningToggle: FC<{ side?: "top" | "bottom" }> = ({
|
|||
>
|
||||
<ThinkIcon />
|
||||
{activeLook ? <span>Thinking</span> : null}
|
||||
{canDismissReasoning ? (
|
||||
<XIcon className="composer-pill-close" aria-hidden={true} />
|
||||
) : null}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
|
@ -1727,10 +1699,9 @@ const ComposerToolsMenu: FC<{
|
|||
|
||||
const ComposerRightControls: FC<{
|
||||
disabled?: boolean;
|
||||
showSend?: boolean;
|
||||
shouldBlockSend?: () => boolean;
|
||||
menuSide?: "top" | "bottom";
|
||||
}> = ({ disabled, showSend, shouldBlockSend, menuSide }) => {
|
||||
}> = ({ disabled, shouldBlockSend, menuSide }) => {
|
||||
return (
|
||||
<div className="aui-composer-action-wrapper flex shrink-0 items-center gap-0.5">
|
||||
<ReasoningToggle side={menuSide} />
|
||||
|
|
@ -1758,29 +1729,27 @@ const ComposerRightControls: FC<{
|
|||
</TooltipIconButton>
|
||||
</ComposerPrimitive.StopDictation>
|
||||
</ComposerPrimitive.If>
|
||||
{showSend ? (
|
||||
<AuiIf condition={({ thread }) => !thread.isRunning}>
|
||||
<ComposerPrimitive.Send asChild={true}>
|
||||
<TooltipIconButton
|
||||
tooltip="Send message"
|
||||
side="bottom"
|
||||
type="submit"
|
||||
variant="default"
|
||||
size="icon"
|
||||
disabled={disabled}
|
||||
onClick={(event) => {
|
||||
if (shouldBlockSend?.()) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}}
|
||||
className="aui-composer-send composer-send-enter size-8 rounded-full disabled:bg-transparent disabled:text-foreground/40 disabled:opacity-100 disabled:pointer-events-none"
|
||||
aria-label="Send message"
|
||||
>
|
||||
<ArrowUpIcon className="aui-composer-send-icon size-[22px] stroke-2" />
|
||||
</TooltipIconButton>
|
||||
</ComposerPrimitive.Send>
|
||||
</AuiIf>
|
||||
) : null}
|
||||
<AuiIf condition={({ thread }) => !thread.isRunning}>
|
||||
<ComposerPrimitive.Send asChild={true}>
|
||||
<TooltipIconButton
|
||||
tooltip="Send message"
|
||||
side="bottom"
|
||||
type="submit"
|
||||
variant="default"
|
||||
size="icon"
|
||||
disabled={disabled}
|
||||
onClick={(event) => {
|
||||
if (shouldBlockSend?.()) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}}
|
||||
className="aui-composer-send composer-send-enter size-8 rounded-full disabled:bg-primary/35 disabled:text-primary-foreground/80 disabled:opacity-100 disabled:pointer-events-none"
|
||||
aria-label="Send message"
|
||||
>
|
||||
<ArrowUpIcon className="aui-composer-send-icon size-[22px] stroke-2" />
|
||||
</TooltipIconButton>
|
||||
</ComposerPrimitive.Send>
|
||||
</AuiIf>
|
||||
<AuiIf condition={({ thread }) => thread.isRunning}>
|
||||
<ComposerPrimitive.Cancel asChild={true}>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -555,17 +555,6 @@ export function SharedComposer({
|
|||
? reasoningLockedOn ||
|
||||
(effectiveReasoningVisualEnabled && !reasoningDisabled)
|
||||
: reasoningLockedOn || (effectiveReasoningEnabled && !reasoningDisabled);
|
||||
const canDismissReasoning =
|
||||
thinkingActiveLook &&
|
||||
!reasoningDisabled &&
|
||||
!reasoningLockedOn &&
|
||||
effectiveSupportsReasoningOff;
|
||||
const dismissReasoning = () => {
|
||||
if (!canDismissReasoning) return;
|
||||
setReasoningEnabled(false);
|
||||
applyQwenThinkingParams(false);
|
||||
setPreserveThinking(false);
|
||||
};
|
||||
// Two-pill gating: Search pill lights up when the runtime has either
|
||||
// a local tool runtime (supportsTools, gives us our Code/python + local
|
||||
// web_search) OR a server-side web_search the provider runs for us
|
||||
|
|
@ -1405,7 +1394,6 @@ export function SharedComposer({
|
|||
disabled={reasoningDisabled}
|
||||
className="unsloth-thinking-pill"
|
||||
data-active={thinkingActiveLook ? "true" : "false"}
|
||||
data-dismissible={canDismissReasoning ? "true" : undefined}
|
||||
aria-label={thinkEffortAriaLabel({
|
||||
modelLoaded,
|
||||
reasoningDisabled,
|
||||
|
|
@ -1424,21 +1412,6 @@ export function SharedComposer({
|
|||
</span>
|
||||
) : null}
|
||||
<ArrowDownStandardIcon className="unsloth-thinking-chevron size-[15px]" />
|
||||
{canDismissReasoning ? (
|
||||
<XIcon
|
||||
className="composer-pill-close unsloth-thinking-close"
|
||||
aria-hidden={true}
|
||||
onPointerDown={(event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
dismissReasoning();
|
||||
}}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
|
|
@ -1576,7 +1549,6 @@ export function SharedComposer({
|
|||
}}
|
||||
className="unsloth-thinking-pill"
|
||||
data-active={thinkingActiveLook ? "true" : "false"}
|
||||
data-dismissible={canDismissReasoning ? "true" : undefined}
|
||||
aria-label={thinkToggleAriaLabel({
|
||||
reasoningLockedOn,
|
||||
modelLoaded,
|
||||
|
|
@ -1586,9 +1558,6 @@ export function SharedComposer({
|
|||
>
|
||||
<BulbIcon className="size-[15px]" />
|
||||
{thinkingActiveLook ? <span>Thinking</span> : null}
|
||||
{canDismissReasoning ? (
|
||||
<XIcon className="composer-pill-close" aria-hidden={true} />
|
||||
) : null}
|
||||
</button>
|
||||
)
|
||||
) : null}
|
||||
|
|
@ -1631,20 +1600,20 @@ export function SharedComposer({
|
|||
>
|
||||
<SquareIcon className="size-3 fill-current" />
|
||||
</Button>
|
||||
) : hasComposerContent ? (
|
||||
) : (
|
||||
<TooltipIconButton
|
||||
tooltip="Send message"
|
||||
side="bottom"
|
||||
variant="default"
|
||||
size="icon"
|
||||
className="composer-send-enter size-8 rounded-full disabled:bg-transparent disabled:text-foreground/40 disabled:opacity-100 disabled:pointer-events-none"
|
||||
className="composer-send-enter size-8 rounded-full disabled:bg-primary/35 disabled:text-primary-foreground/80 disabled:opacity-100 disabled:pointer-events-none"
|
||||
onClick={send}
|
||||
disabled={!canSend}
|
||||
aria-label="Send message"
|
||||
>
|
||||
<ArrowUpIcon className="size-[22px] stroke-2" />
|
||||
</TooltipIconButton>
|
||||
) : null}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -900,19 +900,21 @@
|
|||
}
|
||||
|
||||
.composer-pill-btn {
|
||||
@apply flex h-6 cursor-pointer items-center gap-1 rounded-full pl-1 pr-2 py-0 text-[14px] font-medium leading-6 text-muted-foreground/75 transition-colors hover:bg-black/[0.06] dark:hover:bg-white/[0.08] disabled:cursor-not-allowed disabled:opacity-40;
|
||||
@apply flex h-6 cursor-pointer items-center gap-1 rounded-full pl-1 pr-2 py-0 text-[14px] font-medium leading-6 text-muted-foreground/75 transition-colors hover:bg-primary/10 dark:hover:bg-primary/15 disabled:cursor-not-allowed disabled:opacity-40;
|
||||
}
|
||||
|
||||
.composer-pill-btn:is(:hover, :focus-visible) {
|
||||
background-color: color-mix(in oklch, var(--primary) 10%, transparent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.dark .composer-pill-btn:is(:hover, :focus-visible) {
|
||||
background-color: color-mix(in oklch, var(--primary) 15%, transparent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.composer-pill-btn:is(:hover, :focus-visible),
|
||||
.composer-pill-btn[data-active="true"] {
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.dark .composer-pill-btn:is(:hover, :focus-visible),
|
||||
.dark .composer-pill-btn[data-active="true"] {
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
color: var(--foreground);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.composer-pill-btn > span {
|
||||
|
|
@ -929,14 +931,15 @@
|
|||
|
||||
.composer-pill-close {
|
||||
display: none;
|
||||
order: -1;
|
||||
}
|
||||
|
||||
.composer-pill-btn[data-active="true"]:not(:disabled):is(
|
||||
:hover,
|
||||
:focus-visible
|
||||
) {
|
||||
background-color: rgba(0, 0, 0, 0.14);
|
||||
padding-right: 0.25rem;
|
||||
background-color: color-mix(in oklch, var(--primary) 10%, transparent);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.dark
|
||||
|
|
@ -944,7 +947,16 @@
|
|||
:hover,
|
||||
:focus-visible
|
||||
) {
|
||||
background-color: rgba(255, 255, 255, 0.14);
|
||||
background-color: color-mix(in oklch, var(--primary) 15%, transparent);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.composer-pill-btn[data-active="true"]:not(:disabled):is(
|
||||
:hover,
|
||||
:focus-visible
|
||||
)
|
||||
> svg:not(.composer-pill-close) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.composer-pill-btn[data-active="true"]:not(:disabled):is(
|
||||
|
|
@ -1106,7 +1118,7 @@
|
|||
|
||||
/* Right-side Thinking pill (toggle or dropdown). */
|
||||
.unsloth-thinking-pill {
|
||||
@apply inline-flex h-6 shrink-0 cursor-pointer items-center gap-1 rounded-full pl-1 pr-2 py-0 text-[14px] font-medium leading-6 text-muted-foreground/75 transition-colors hover:bg-black/[0.06] dark:hover:bg-white/[0.08] disabled:cursor-not-allowed disabled:opacity-40;
|
||||
@apply inline-flex h-6 shrink-0 cursor-pointer items-center gap-1 rounded-full pl-1 pr-2 py-0 text-[14px] font-medium leading-6 text-muted-foreground/75 transition-colors hover:bg-primary/10 dark:hover:bg-primary/15 disabled:cursor-not-allowed disabled:opacity-40;
|
||||
}
|
||||
|
||||
.unsloth-thinking-pill > span {
|
||||
|
|
@ -1121,54 +1133,45 @@
|
|||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.unsloth-thinking-pill[data-active="true"],
|
||||
.unsloth-thinking-pill[data-state="open"] {
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
color: var(--foreground);
|
||||
.unsloth-thinking-pill[data-active="true"] {
|
||||
color: var(--primary);
|
||||
/* See .unsloth-composer-plus: re-enable pointer-events on the open trigger. */
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dark .unsloth-thinking-pill[data-active="true"],
|
||||
.unsloth-thinking-pill[data-state="open"] {
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
color: var(--foreground);
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.unsloth-thinking-pill[data-active="true"][data-state="open"] {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.dark .unsloth-thinking-pill[data-state="open"] {
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.unsloth-thinking-pill .composer-pill-close {
|
||||
display: none;
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
flex-shrink: 0;
|
||||
.dark .unsloth-thinking-pill[data-active="true"][data-state="open"] {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.unsloth-thinking-pill[data-dismissible="true"][data-active="true"]:not(
|
||||
:disabled
|
||||
):is(:hover, :focus-visible) {
|
||||
background-color: rgba(0, 0, 0, 0.14);
|
||||
padding-right: 0.25rem;
|
||||
.unsloth-thinking-pill:is(:hover, :focus-visible) {
|
||||
background-color: color-mix(in oklch, var(--primary) 10%, transparent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.dark
|
||||
.unsloth-thinking-pill[data-dismissible="true"][data-active="true"]:not(
|
||||
:disabled
|
||||
):is(:hover, :focus-visible) {
|
||||
background-color: rgba(255, 255, 255, 0.14);
|
||||
.dark .unsloth-thinking-pill:is(:hover, :focus-visible) {
|
||||
background-color: color-mix(in oklch, var(--primary) 15%, transparent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.unsloth-thinking-pill[data-dismissible="true"][data-active="true"]:not(
|
||||
:disabled
|
||||
):is(:hover, :focus-visible)
|
||||
.composer-pill-close {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.unsloth-thinking-pill[data-dismissible="true"][data-active="true"]:not(
|
||||
:disabled
|
||||
):is(:hover, :focus-visible)
|
||||
.unsloth-thinking-chevron {
|
||||
display: none;
|
||||
.unsloth-thinking-pill[data-active="true"]:is(:hover, :focus-visible) {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* Smaller tick for selected Thinking options. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue