refine assistant window controls

This commit is contained in:
ajnart committed 2026-08-10 14:09:44 +02:00
1 parent 6baac9298f
commit f7eed7ce8a
4 files changed
+14 -77

No files matched your search

+2 -2
View File
@@ -22,8 +22,8 @@ While a response is running, a compact activity bar appears at the bottom of the
avatar shows a thinking indicator. The activity bar can be opened to follow the response. Completed
responses add an unread count to the user menu until they are opened or dismissed. The expanded
conversation has a minimize action that returns it to the activity bar without interrupting a response.
Its desktop-style window controls can also maximize the conversation to the available viewport or close it
without leaving an activity bar behind. Each control includes an icon, tooltip, and accessible label.
Its adjacent close action hides the panel without leaving an activity bar behind. Both window actions use
subtle buttons with an icon, tooltip, and accessible label.
The transcript follows streamed output while it is already at the bottom, including fast responses. Scrolling
up releases that follow state until **Scroll to latest** is selected or the user returns to the bottom.
@@ -117,15 +117,6 @@
animation: assistant-panel-in 180ms cubic-bezier(0.22, 1, 0.36, 1);
}
.floatingPanel[data-maximized] {
inset: 1rem;
width: auto;
height: auto;
min-height: 0;
transform: none;
animation: none;
}
.widgetPanel {
container-name: assistant-widget;
container-type: size;
@@ -188,21 +179,8 @@
}
.windowControl {
width: 1.75rem;
height: 1.75rem;
border: 0;
color: rgba(0, 0, 0, 0.72);
transition:
filter 160ms cubic-bezier(0.22, 1, 0.36, 1),
transform 160ms cubic-bezier(0.22, 1, 0.36, 1);
}
.windowControl:hover {
filter: brightness(0.94) saturate(1.08);
}
.windowControl:active {
transform: scale(0.92);
width: 2.25rem;
height: 2.25rem;
}
.windowControl:focus-visible {
@@ -210,18 +188,6 @@
outline-offset: 2px;
}
.windowControlClose {
background: var(--mantine-color-red-6);
}
.windowControlMinimize {
background: var(--mantine-color-yellow-5);
}
.windowControlMaximize {
background: var(--mantine-color-green-6);
}
.panelAction {
width: 2.625rem;
height: 2.625rem;
@@ -1666,14 +1632,6 @@
min-height: min(20rem, calc(100dvh - 1rem - env(safe-area-inset-bottom, 0px)));
}
.floatingPanel[data-maximized] {
inset: 0;
width: 100vw;
height: 100dvh;
min-height: 0;
border-radius: 0;
}
.panelHeader {
min-height: 3.5rem;
padding: 0.5rem;
@@ -1809,7 +1767,6 @@
@media (prefers-reduced-motion: reduce) {
.activityBar,
.floatingPanel,
.windowControl,
.disclosureIcon,
.reasoningChevron {
animation: none;
@@ -78,7 +78,6 @@ import {
IconApps,
IconArrowUp,
IconArrowsMaximize,
IconArrowsMinimize,
IconAt,
IconCheck,
IconChevronDown,
@@ -2733,8 +2732,6 @@ interface AssistantConversationSurfaceProps extends AssistantConversationControl
onExpand?: () => void;
onMinimize?: () => void;
onWindowClose?: () => void;
onToggleMaximize?: () => void;
maximized?: boolean;
}
export const AssistantConversationSurface = ({
@@ -2752,8 +2749,6 @@ export const AssistantConversationSurface = ({
onExpand,
onMinimize,
onWindowClose,
onToggleMaximize,
maximized = false,
}: AssistantConversationSurfaceProps) => {
const t = useScopedI18n("common.assistant");
const reducedMotion = useReducedMotion();
@@ -2768,7 +2763,7 @@ export const AssistantConversationSurface = ({
return (
<>
<Group className={classes.panelHeader} justify="space-between" wrap="nowrap" gap="xs">
{onWindowClose && onMinimize && onToggleMaximize && (
{onWindowClose && onMinimize && (
<Group
component="fieldset"
className={classes.windowControls}
@@ -2778,34 +2773,24 @@ export const AssistantConversationSurface = ({
>
<Tooltip label={t("close")}>
<ActionIcon
className={`${classes.windowControl} ${classes.windowControlClose}`}
className={classes.windowControl}
variant="subtle"
color="gray"
onClick={onWindowClose}
aria-label={t("close")}
>
<IconX size={12} stroke={2.4} />
<IconX size={16} />
</ActionIcon>
</Tooltip>
<Tooltip label={t("minimize")}>
<ActionIcon
className={`${classes.windowControl} ${classes.windowControlMinimize}`}
className={classes.windowControl}
variant="subtle"
color="gray"
onClick={onMinimize}
aria-label={t("minimize")}
>
<IconMinus size={12} stroke={2.4} />
</ActionIcon>
</Tooltip>
<Tooltip label={maximized ? t("restore") : t("maximize")}>
<ActionIcon
className={`${classes.windowControl} ${classes.windowControlMaximize}`}
onClick={onToggleMaximize}
aria-label={maximized ? t("restore") : t("maximize")}
aria-pressed={maximized}
>
{maximized ? (
<IconArrowsMinimize size={11} stroke={2.4} />
) : (
<IconArrowsMaximize size={11} stroke={2.4} />
)}
<IconMinus size={17} />
</ActionIcon>
</Tooltip>
</Group>
@@ -2925,7 +2910,6 @@ export const AssistantPanel = ({
}: AssistantPanelProps) => {
const t = useScopedI18n("common.assistant");
const previousFocusRef = useRef<HTMLElement | null>(null);
const [maximized, setMaximized] = useState(false);
useWindowEvent("keydown", (event) => {
if (opened && event.key === "Escape") onClose();
@@ -2965,7 +2949,7 @@ export const AssistantPanel = ({
/>
)}
{opened && (
<dialog className={classes.floatingPanel} data-maximized={maximized || undefined} aria-label={t("title")} open>
<dialog className={classes.floatingPanel} aria-label={t("title")} open>
<AssistantConversationSurface
isRunning={isRunning}
pendingAction={pendingAction}
@@ -2983,8 +2967,6 @@ export const AssistantPanel = ({
onDismissActivity();
onClose();
}}
onToggleMaximize={() => setMaximized((current) => !current)}
maximized={maximized}
/>
</dialog>
)}
-2
View File
@@ -2018,8 +2018,6 @@
"open": "Open Homarr Assistant",
"close": "Close assistant",
"minimize": "Minimize assistant",
"maximize": "Maximize assistant",
"restore": "Restore assistant size",
"windowControls": "Conversation window controls",
"spotlight": "Ask Homarr Assistant",
"spotlightDescription": "Type and send a prompt without leaving the command menu.",