History

fix(web): align thread details panel controls and menus (#3606)

maria committed 4 months ago

Commit 7bf0a2c1 parent 2f774f811 files · +81 −19Browse files

Unified · Split

11 files
  1. apps/server/src/claudeModelOptions.test.ts +1 −1
  2. apps/server/src/orchestration-v2/ProviderSelectionTransition.test.ts +1 −1
  3. apps/web/src/components/BranchToolbarBranchSelector.tsx +5 −1
  4. apps/web/src/components/BranchToolbarEnvModeSelector.tsx +11 −3
  5. apps/web/src/components/BranchToolbarEnvironmentSelector.tsx +14 −3
  6. apps/web/src/components/GitActionsControl.tsx +8 −1
  7. apps/web/src/components/ProjectScriptsControl.tsx +10 −2
  8. apps/web/src/components/chat/OpenInPicker.tsx +11 −3
  9. apps/web/src/components/chat/ThreadRelationshipsControl.tsx +5 −3
  10. apps/web/src/components/chat/glassPopupStyles.ts +6 −0
  11. apps/web/src/components/chat/threadDetailsPanelStyles.ts +9 −1
apps/server/src/claudeModelOptions.test.ts+1−1
@@ -1,4 +1,4 @@
1import { describe, expect, it } from "vitest";1import { describe, expect, it } from "@effect/vitest";
2 2
3import { ProviderInstanceId, type ModelSelection } from "@t3tools/contracts";3import { ProviderInstanceId, type ModelSelection } from "@t3tools/contracts";
4 4
apps/server/src/orchestration-v2/ProviderSelectionTransition.test.ts+1−1
@@ -1,4 +1,4 @@
1import { describe, expect, it } from "vitest";1import { describe, expect, it } from "@effect/vitest";
2 2
3import {3import {
4 type ModelSelection,4 type ModelSelection,
apps/web/src/components/BranchToolbarBranchSelector.tsx+5−1
@@ -31,6 +31,7 @@ import { cn } from "../lib/utils"; · 30 unmodified lines
31import {31import {
32 THREAD_DETAILS_PANEL_CHEVRON_CLASS,32 THREAD_DETAILS_PANEL_CHEVRON_CLASS,
33 THREAD_DETAILS_PANEL_ICON_CLASS,33 THREAD_DETAILS_PANEL_ICON_CLASS,
34 THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
34 THREAD_DETAILS_PANEL_ROW_CLASS,35 THREAD_DETAILS_PANEL_ROW_CLASS,
35} from "./chat/threadDetailsPanelStyles";36} from "./chat/threadDetailsPanelStyles";
36import { parsePullRequestReference } from "../pullRequestReference";37import { parsePullRequestReference } from "../pullRequestReference";
@@ -730,7 +731,10 @@ export function BranchToolbarBranchSelector({ · 693 unmodified lines
730 <ComboboxPopup731 <ComboboxPopup
731 align={displayMode === "panel" ? "start" : "end"}732 align={displayMode === "panel" ? "start" : "end"}
732 side={displayMode === "panel" ? "bottom" : "top"}733 side={displayMode === "panel" ? "bottom" : "top"}
733 className="flex w-80 flex-col"734 className={cn(
735 "flex flex-col",
736 displayMode === "panel" ? THREAD_DETAILS_PANEL_ROW_POPUP_CLASS : "w-80",
737 )}
734 >738 >
735 <div className="shrink-0 px-3 pt-2.5">739 <div className="shrink-0 px-3 pt-2.5">
736 <div className="relative -translate-y-px border-b border-border/70 pb-1.5 transition-colors focus-within:border-ring">740 <div className="relative -translate-y-px border-b border-border/70 pb-1.5 transition-colors focus-within:border-ring">
apps/web/src/components/BranchToolbarEnvModeSelector.tsx+11−3
@@ -4,7 +4,8 @@ import { cn } from "../lib/utils"; · 3 unmodified lines
4import {4import {
5 THREAD_DETAILS_PANEL_ICON_CLASS,5 THREAD_DETAILS_PANEL_ICON_CLASS,
6 THREAD_DETAILS_PANEL_LOCKED_ROW_CLASS,6 THREAD_DETAILS_PANEL_LOCKED_ROW_CLASS,
7 THREAD_DETAILS_PANEL_ROW_CLASS,7 THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
8 THREAD_DETAILS_PANEL_SELECT_ROW_CLASS,
8} from "./chat/threadDetailsPanelStyles";9} from "./chat/threadDetailsPanelStyles";
9 10
10import {11import {
@@ -109,7 +110,7 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe · 98 unmodified lines
109 size={displayMode === "panel" ? "default" : "xs"}110 size={displayMode === "panel" ? "default" : "xs"}
110 className={cn(111 className={cn(
111 "font-medium",112 "font-medium",
112 displayMode === "panel" && THREAD_DETAILS_PANEL_ROW_CLASS,113 displayMode === "panel" && THREAD_DETAILS_PANEL_SELECT_ROW_CLASS,
113 )}114 )}
114 aria-label="Workspace"115 aria-label="Workspace"
115 />116 />
@@ -137,7 +138,14 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe · 21 unmodified lines
137 </TooltipTrigger>138 </TooltipTrigger>
138 {workspacePath ? <TooltipPopup side="left">{workspacePath}</TooltipPopup> : null}139 {workspacePath ? <TooltipPopup side="left">{workspacePath}</TooltipPopup> : null}
139 </Tooltip>140 </Tooltip>
140 <SelectPopup>141 <SelectPopup
142 {...(displayMode === "panel"
143 ? {
144 alignItemWithTrigger: false,
145 popupClassName: THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
146 }
147 : {})}
148 >
141 <SelectGroup>149 <SelectGroup>
142 <SelectGroupLabel>Workspace</SelectGroupLabel>150 <SelectGroupLabel>Workspace</SelectGroupLabel>
143 <SelectItem value="local">151 <SelectItem value="local">
apps/web/src/components/BranchToolbarEnvironmentSelector.tsx+14−3
@@ -7,7 +7,8 @@ import { cn } from "../lib/utils"; · 6 unmodified lines
7import {7import {
8 THREAD_DETAILS_PANEL_ICON_CLASS,8 THREAD_DETAILS_PANEL_ICON_CLASS,
9 THREAD_DETAILS_PANEL_LOCKED_ROW_CLASS,9 THREAD_DETAILS_PANEL_LOCKED_ROW_CLASS,
10 THREAD_DETAILS_PANEL_ROW_CLASS,10 THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
11 THREAD_DETAILS_PANEL_SELECT_ROW_CLASS,
11} from "./chat/threadDetailsPanelStyles";12} from "./chat/threadDetailsPanelStyles";
12import {13import {
13 Select,14 Select,
@@ -79,7 +80,10 @@ export const BranchToolbarEnvironmentSelector = memo(function BranchToolbarEnvir · 65 unmodified lines
79 <SelectTrigger80 <SelectTrigger
80 variant="ghost"81 variant="ghost"
81 size={displayMode === "panel" ? "default" : "xs"}82 size={displayMode === "panel" ? "default" : "xs"}
82 className={cn("font-medium", displayMode === "panel" && THREAD_DETAILS_PANEL_ROW_CLASS)}83 className={cn(
84 "font-medium",
85 displayMode === "panel" && THREAD_DETAILS_PANEL_SELECT_ROW_CLASS,
86 )}
83 aria-label="Run on"87 aria-label="Run on"
84 >88 >
85 {activeEnvironment?.isPrimary ? (89 {activeEnvironment?.isPrimary ? (
@@ -93,7 +97,14 @@ export const BranchToolbarEnvironmentSelector = memo(function BranchToolbarEnvir · 7 unmodified lines
93 )}97 )}
94 <SelectValue />98 <SelectValue />
95 </SelectTrigger>99 </SelectTrigger>
96 <SelectPopup>100 <SelectPopup
101 {...(displayMode === "panel"
102 ? {
103 alignItemWithTrigger: false,
104 popupClassName: THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
105 }
106 : {})}
107 >
97 <SelectGroup>108 <SelectGroup>
98 <SelectGroupLabel>Run on</SelectGroupLabel>109 <SelectGroupLabel>Run on</SelectGroupLabel>
99 {availableEnvironments.map((env) => (110 {availableEnvironments.map((env) => (
apps/web/src/components/GitActionsControl.tsx+8−1
@@ -91,6 +91,7 @@ import { readLocalApi } from "~/localApi"; · 90 unmodified lines
91import {91import {
92 THREAD_DETAILS_PANEL_CHEVRON_CLASS,92 THREAD_DETAILS_PANEL_CHEVRON_CLASS,
93 THREAD_DETAILS_PANEL_ICON_CLASS,93 THREAD_DETAILS_PANEL_ICON_CLASS,
94 THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
94 THREAD_DETAILS_PANEL_ROW_CLASS,95 THREAD_DETAILS_PANEL_ROW_CLASS,
95 THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS,96 THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS,
96 THREAD_DETAILS_PANEL_SPLIT_PRIMARY_CLASS,97 THREAD_DETAILS_PANEL_SPLIT_PRIMARY_CLASS,
@@ -989,6 +990,7 @@ export default function GitActionsControl({ · 892 unmodified lines
989}: GitActionsControlProps) {990}: GitActionsControlProps) {
990 const isPanel = displayMode === "panel";991 const isPanel = displayMode === "panel";
991 const ActionGroup = isPanel ? "div" : Group;992 const ActionGroup = isPanel ? "div" : Group;
993 const panelAnchorRef = useRef<HTMLDivElement | null>(null);
992 const updateThreadMetadata = useAtomCommand(994 const updateThreadMetadata = useAtomCommand(
993 threadEnvironment.updateMetadata,995 threadEnvironment.updateMetadata,
994 "thread branch metadata update",996 "thread branch metadata update",
@@ -1706,6 +1708,7 @@ export default function GitActionsControl({ · 711 unmodified lines
1706 <ActionGroup1708 <ActionGroup
1707 role="group"1709 role="group"
1708 aria-label="Git actions"1710 aria-label="Git actions"
1711 {...(isPanel ? { ref: panelAnchorRef } : {})}
1709 className={cn("shrink-0", isPanel && THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS)}1712 className={cn("shrink-0", isPanel && THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS)}
1710 >1713 >
1711 {quickActionDisabledReason ? (1714 {quickActionDisabledReason ? (
@@ -1793,7 +1796,11 @@ export default function GitActionsControl({ · 81 unmodified lines
1793 className={isPanel ? THREAD_DETAILS_PANEL_CHEVRON_CLASS : "size-4"}1796 className={isPanel ? THREAD_DETAILS_PANEL_CHEVRON_CLASS : "size-4"}
1794 />1797 />
1795 </MenuTrigger>1798 </MenuTrigger>
1796 <MenuPopup align="end" className="w-full">1799 <MenuPopup
1800 align="end"
1801 {...(isPanel ? { anchor: panelAnchorRef } : {})}
1802 className={isPanel ? THREAD_DETAILS_PANEL_ROW_POPUP_CLASS : "w-full"}
1803 >
1797 {gitActionMenuItems.map((item) => {1804 {gitActionMenuItems.map((item) => {
1798 const disabledReason = getMenuActionDisabledReason({1805 const disabledReason = getMenuActionDisabledReason({
1799 item,1806 item,
apps/web/src/components/ProjectScriptsControl.tsx+10−2
@@ -63,6 +63,7 @@ import { cn } from "~/lib/utils"; · 62 unmodified lines
63import {63import {
64 THREAD_DETAILS_PANEL_CHEVRON_CLASS,64 THREAD_DETAILS_PANEL_CHEVRON_CLASS,
65 THREAD_DETAILS_PANEL_ICON_CLASS,65 THREAD_DETAILS_PANEL_ICON_CLASS,
66 THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
66 THREAD_DETAILS_PANEL_ROW_CLASS,67 THREAD_DETAILS_PANEL_ROW_CLASS,
67 THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS,68 THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS,
68 THREAD_DETAILS_PANEL_SPLIT_PRIMARY_CLASS,69 THREAD_DETAILS_PANEL_SPLIT_PRIMARY_CLASS,
@@ -134,6 +135,7 @@ export default function ProjectScriptsControl({ · 65 unmodified lines
134}: ProjectScriptsControlProps) {135}: ProjectScriptsControlProps) {
135 const isPanel = displayMode === "panel";136 const isPanel = displayMode === "panel";
136 const ActionGroup = isPanel ? "div" : Group;137 const ActionGroup = isPanel ? "div" : Group;
138 const panelAnchorRef = React.useRef<HTMLDivElement | null>(null);
137 const addScriptFormId = React.useId();139 const addScriptFormId = React.useId();
138 const [editingScriptId, setEditingScriptId] = useState<string | null>(null);140 const [editingScriptId, setEditingScriptId] = useState<string | null>(null);
139 const [dialogOpen, setDialogOpen] = useState(false);141 const [dialogOpen, setDialogOpen] = useState(false);
@@ -267,7 +269,9 @@ export default function ProjectScriptsControl({ · 127 unmodified lines
267 <ActionGroup269 <ActionGroup
268 role="group"270 role="group"
269 aria-label="Project scripts"271 aria-label="Project scripts"
270 {...(isPanel ? { className: THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS } : {})}272 {...(isPanel
273 ? { className: THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS, ref: panelAnchorRef }
274 : {})}
271 >275 >
272 <Tooltip>276 <Tooltip>
273 <TooltipTrigger277 <TooltipTrigger
@@ -316,7 +320,11 @@ export default function ProjectScriptsControl({ · 42 unmodified lines
316 className={isPanel ? THREAD_DETAILS_PANEL_CHEVRON_CLASS : "size-4"}320 className={isPanel ? THREAD_DETAILS_PANEL_CHEVRON_CLASS : "size-4"}
317 />321 />
318 </MenuTrigger>322 </MenuTrigger>
319 <MenuPopup align="end">323 <MenuPopup
324 align="end"
325 {...(isPanel ? { anchor: panelAnchorRef } : {})}
326 className={isPanel ? THREAD_DETAILS_PANEL_ROW_POPUP_CLASS : undefined}
327 >
320 {scripts.map((script) => {328 {scripts.map((script) => {
321 const shortcutLabel = shortcutLabelForCommand(329 const shortcutLabel = shortcutLabelForCommand(
322 keybindings,330 keybindings,
apps/web/src/components/chat/OpenInPicker.tsx+11−3
@@ -1,5 +1,5 @@
1import { EditorId, type EnvironmentId, type ResolvedKeybindingsConfig } from "@t3tools/contracts";1import { EditorId, type EnvironmentId, type ResolvedKeybindingsConfig } from "@t3tools/contracts";
2import { memo, useCallback, useMemo } from "react";2import { memo, useCallback, useMemo, useRef } from "react";
3import { shortcutLabelForCommand } from "../../keybindings";3import { shortcutLabelForCommand } from "../../keybindings";
4import { usePreferredEditor } from "../../editorPreferences";4import { usePreferredEditor } from "../../editorPreferences";
5import { ChevronDownIcon, FolderClosedIcon } from "lucide-react";5import { ChevronDownIcon, FolderClosedIcon } from "lucide-react";
@@ -37,6 +37,7 @@ import { useAtomCommand } from "~/state/use-atom-command"; · 31 unmodified lines
37import {37import {
38 THREAD_DETAILS_PANEL_CHEVRON_CLASS,38 THREAD_DETAILS_PANEL_CHEVRON_CLASS,
39 THREAD_DETAILS_PANEL_ICON_CLASS,39 THREAD_DETAILS_PANEL_ICON_CLASS,
40 THREAD_DETAILS_PANEL_ROW_POPUP_CLASS,
40 THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS,41 THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS,
41 THREAD_DETAILS_PANEL_SPLIT_PRIMARY_CLASS,42 THREAD_DETAILS_PANEL_SPLIT_PRIMARY_CLASS,
42 THREAD_DETAILS_PANEL_SPLIT_SECONDARY_CLASS,43 THREAD_DETAILS_PANEL_SPLIT_SECONDARY_CLASS,
@@ -176,6 +177,7 @@ export const OpenInPicker = memo(function OpenInPicker({ · 133 unmodified lines
176}) {177}) {
177 const isPanel = displayMode === "panel";178 const isPanel = displayMode === "panel";
178 const ActionGroup = isPanel ? "div" : Group;179 const ActionGroup = isPanel ? "div" : Group;
180 const panelAnchorRef = useRef<HTMLDivElement | null>(null);
179 const openInEditorMutation = useAtomCommand(shellEnvironment.openInEditor, "open in editor");181 const openInEditorMutation = useAtomCommand(shellEnvironment.openInEditor, "open in editor");
180 const [preferredEditor, setPreferredEditor] = usePreferredEditor(availableEditors);182 const [preferredEditor, setPreferredEditor] = usePreferredEditor(availableEditors);
181 const options = useMemo(183 const options = useMemo(
@@ -212,7 +214,9 @@ export const OpenInPicker = memo(function OpenInPicker({ · 30 unmodified lines
212 <ActionGroup214 <ActionGroup
213 aria-label="Open in editor"215 aria-label="Open in editor"
214 role="group"216 role="group"
215 {...(isPanel ? { className: THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS } : {})}217 {...(isPanel
218 ? { className: THREAD_DETAILS_PANEL_SPLIT_GROUP_CLASS, ref: panelAnchorRef }
219 : {})}
216 >220 >
217 <Button221 <Button
218 aria-label={compact ? "Open file in preferred editor" : primaryLabel}222 aria-label={compact ? "Open file in preferred editor" : primaryLabel}
@@ -260,7 +264,11 @@ export const OpenInPicker = memo(function OpenInPicker({ · 41 unmodified lines
260 className={isPanel ? THREAD_DETAILS_PANEL_CHEVRON_CLASS : "size-4"}264 className={isPanel ? THREAD_DETAILS_PANEL_CHEVRON_CLASS : "size-4"}
261 />265 />
262 </MenuTrigger>266 </MenuTrigger>
263 <MenuPopup align="end">267 <MenuPopup
268 align="end"
269 {...(isPanel ? { anchor: panelAnchorRef } : {})}
270 className={isPanel ? THREAD_DETAILS_PANEL_ROW_POPUP_CLASS : undefined}
271 >
264 {options.length === 0 && <MenuItem disabled>No installed editors found</MenuItem>}272 {options.length === 0 && <MenuItem disabled>No installed editors found</MenuItem>}
265 {options.map(({ label, Icon, value }) => (273 {options.map(({ label, Icon, value }) => (
266 <MenuItem key={value} onClick={() => openInEditor(value)}>274 <MenuItem key={value} onClick={() => openInEditor(value)}>
apps/web/src/components/chat/ThreadRelationshipsControl.tsx+5−3
@@ -30,15 +30,17 @@ import { Button } from "../ui/button"; · 29 unmodified lines
30import { Menu, MenuItem, MenuPopup, MenuTrigger } from "../ui/menu";30import { Menu, MenuItem, MenuPopup, MenuTrigger } from "../ui/menu";
31import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";31import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
32import {32import {
33 THREAD_DETAILS_PANEL_ICON_CLASS,
34 THREAD_DETAILS_PANEL_ICON_ACTION_CLASS,33 THREAD_DETAILS_PANEL_ICON_ACTION_CLASS,
35 THREAD_DETAILS_PANEL_LINK_ROW_CLASS,34 THREAD_DETAILS_PANEL_LINK_ROW_CLASS,
36 THREAD_DETAILS_PANEL_LINK_SPLIT_GROUP_CLASS,35 THREAD_DETAILS_PANEL_LINK_SPLIT_GROUP_CLASS,
37 THREAD_DETAILS_PANEL_LINK_SPLIT_PRIMARY_CLASS,36 THREAD_DETAILS_PANEL_LINK_SPLIT_PRIMARY_CLASS,
38 THREAD_DETAILS_PANEL_LINK_SPLIT_SECONDARY_CLASS,37 THREAD_DETAILS_PANEL_LINK_SPLIT_SECONDARY_CLASS,
38 THREAD_DETAILS_PANEL_MENU_POPUP_CLASS,
39 THREAD_DETAILS_PANEL_SPLIT_SEPARATOR_CLASS,39 THREAD_DETAILS_PANEL_SPLIT_SEPARATOR_CLASS,
40} from "./threadDetailsPanelStyles";40} from "./threadDetailsPanelStyles";
41 41
42const THREAD_RELATIONSHIP_ICON_CLASS = "size-4 shrink-0 text-muted-foreground";
43
42function relationshipLabel(edge: ThreadRelationshipEdge, currentThreadId: ThreadId) {44function relationshipLabel(edge: ThreadRelationshipEdge, currentThreadId: ThreadId) {
43 if (edge.kind === "transfer") return "Context transfer";45 if (edge.kind === "transfer") return "Context transfer";
44 if (edge.kind === "subagent") {46 if (edge.kind === "subagent") {
@@ -190,7 +192,7 @@ export function ThreadRelationshipsPanel(props: { · 145 unmodified lines
190 >192 >
191 <MoreHorizontalIcon className="size-3.5" />193 <MoreHorizontalIcon className="size-3.5" />
192 </MenuTrigger>194 </MenuTrigger>
193 <MenuPopup align="end">195 <MenuPopup align="end" className={THREAD_DETAILS_PANEL_MENU_POPUP_CLASS}>
194 <MenuItem onClick={() => void detach()}>196 <MenuItem onClick={() => void detach()}>
195 <UnplugIcon className="size-3.5" />197 <UnplugIcon className="size-3.5" />
196 Disconnect agent session198 Disconnect agent session
@@ -221,7 +223,7 @@ export function ThreadRelationshipsPanel(props: { · 24 unmodified lines
221 const relationshipContent = (223 const relationshipContent = (
222 <>224 <>
223 <span className="relative -mx-0.5 grid size-4 shrink-0 place-items-center">225 <span className="relative -mx-0.5 grid size-4 shrink-0 place-items-center">
224 <RelationshipIcon className={THREAD_DETAILS_PANEL_ICON_CLASS} />226 <RelationshipIcon className={THREAD_RELATIONSHIP_ICON_CLASS} />
225 <span227 <span
226 className={cn(228 className={cn(
227 "absolute -bottom-1 -right-1 size-2 rounded-full border-2 border-card",229 "absolute -bottom-1 -right-1 size-2 rounded-full border-2 border-card",
apps/web/src/components/chat/glassPopupStyles.ts+6−0
@@ -0,0 +1,6 @@
1export const CHAT_GLASS_POPUP_SURFACE_CLASS =
2 "floating-glass-surface !bg-[color-mix(in_srgb,var(--card)_20%,transparent)] dark:!bg-[color-mix(in_srgb,var(--card)_45%,transparent)]";
3
4export const CHAT_GLASS_ROW_POPUP_CLASS = `${CHAT_GLASS_POPUP_SURFACE_CLASS} w-(--anchor-width)`;
5
6export const CHAT_GLASS_MENU_POPUP_CLASS = `${CHAT_GLASS_POPUP_SURFACE_CLASS} min-w-60 max-w-(--available-width)`;
apps/web/src/components/chat/threadDetailsPanelStyles.ts+9−1
@@ -1,3 +1,5 @@
1import { CHAT_GLASS_MENU_POPUP_CLASS, CHAT_GLASS_ROW_POPUP_CLASS } from "./glassPopupStyles";
2
1/**3/**
2 * Visual primitives shared by controls when they are rendered in the thread details panel.4 * Visual primitives shared by controls when they are rendered in the thread details panel.
3 *5 *
@@ -19,6 +21,8 @@ const THREAD_DETAILS_PANEL_SPLIT_BUTTON_SURFACE_CLASS = `${THREAD_DETAILS_PANEL_ · 15 unmodified lines
19 21
20export const THREAD_DETAILS_PANEL_ROW_CLASS = `h-9 w-full justify-start gap-2.5 rounded-lg border-transparent bg-transparent px-2.5 text-[13px] font-medium text-foreground/80 sm:h-9 sm:text-[13px] ${THREAD_DETAILS_PANEL_ROW_SURFACE_CLASS}`;22export const THREAD_DETAILS_PANEL_ROW_CLASS = `h-9 w-full justify-start gap-2.5 rounded-lg border-transparent bg-transparent px-2.5 text-[13px] font-medium text-foreground/80 sm:h-9 sm:text-[13px] ${THREAD_DETAILS_PANEL_ROW_SURFACE_CLASS}`;
21 23
24export const THREAD_DETAILS_PANEL_SELECT_ROW_CLASS = `${THREAD_DETAILS_PANEL_ROW_CLASS} pe-0 before:pointer-events-none before:absolute before:inset-0 [&_[data-slot=select-icon]]:-me-px [&_[data-slot=select-icon]]:relative [&_[data-slot=select-icon]]:flex [&_[data-slot=select-icon]]:h-full [&_[data-slot=select-icon]]:w-8 [&_[data-slot=select-icon]]:shrink-0 [&_[data-slot=select-icon]]:items-center [&_[data-slot=select-icon]]:justify-center [&_[data-slot=select-icon]]:before:absolute [&_[data-slot=select-icon]]:before:-left-px [&_[data-slot=select-icon]]:before:top-1/2 [&_[data-slot=select-icon]]:before:h-4 [&_[data-slot=select-icon]]:before:w-px [&_[data-slot=select-icon]]:before:-translate-y-1/2 [&_[data-slot=select-icon]]:before:bg-border/65 [&_[data-slot=select-icon]>svg]:me-0 [&_[data-slot=select-icon]>svg]:size-4 [&_[data-slot=select-icon]>svg]:text-muted-foreground [&_[data-slot=select-icon]>svg]:opacity-100`;
25
22export const THREAD_DETAILS_PANEL_LINK_ROW_CLASS = `flex h-9 min-w-0 flex-1 cursor-pointer items-center justify-start gap-2.5 rounded-lg border border-transparent bg-transparent px-2.5 text-left text-[13px] font-medium text-foreground/80 disabled:cursor-not-allowed disabled:opacity-55 sm:h-9 sm:text-[13px] ${THREAD_DETAILS_PANEL_ROW_SURFACE_CLASS}`;26export const THREAD_DETAILS_PANEL_LINK_ROW_CLASS = `flex h-9 min-w-0 flex-1 cursor-pointer items-center justify-start gap-2.5 rounded-lg border border-transparent bg-transparent px-2.5 text-left text-[13px] font-medium text-foreground/80 disabled:cursor-not-allowed disabled:opacity-55 sm:h-9 sm:text-[13px] ${THREAD_DETAILS_PANEL_ROW_SURFACE_CLASS}`;
23 27
24export const THREAD_DETAILS_PANEL_LINK_SPLIT_GROUP_CLASS = `group/thread-details-link flex w-full items-center rounded-lg transition-colors ${THREAD_DETAILS_PANEL_HOVER_SURFACE_CLASS}`;28export const THREAD_DETAILS_PANEL_LINK_SPLIT_GROUP_CLASS = `group/thread-details-link flex w-full items-center rounded-lg transition-colors ${THREAD_DETAILS_PANEL_HOVER_SURFACE_CLASS}`;
@@ -30,7 +34,7 @@ export const THREAD_DETAILS_PANEL_LINK_SPLIT_SECONDARY_CLASS = `h-9 w-8 shrink-0 · 5 unmodified lines
30export const THREAD_DETAILS_PANEL_LOCKED_ROW_CLASS =34export const THREAD_DETAILS_PANEL_LOCKED_ROW_CLASS =
31 "h-9 w-full justify-start gap-2.5 rounded-lg border border-transparent px-2.5 text-[13px] font-medium text-foreground/80 sm:h-9 sm:text-[13px]";35 "h-9 w-full justify-start gap-2.5 rounded-lg border border-transparent px-2.5 text-[13px] font-medium text-foreground/80 sm:h-9 sm:text-[13px]";
32 36
33export const THREAD_DETAILS_PANEL_ICON_CLASS = "size-4 shrink-0 text-muted-foreground";37export const THREAD_DETAILS_PANEL_ICON_CLASS = "-mx-0.5 size-4 shrink-0 text-muted-foreground";
34 38
35export const THREAD_DETAILS_PANEL_CHEVRON_CLASS = "size-4 shrink-0 text-muted-foreground";39export const THREAD_DETAILS_PANEL_CHEVRON_CLASS = "size-4 shrink-0 text-muted-foreground";
36 40
@@ -43,3 +47,7 @@ export const THREAD_DETAILS_PANEL_SPLIT_PRIMARY_CLASS = `h-9 min-w-0 flex-1 just · 6 unmodified lines
43export const THREAD_DETAILS_PANEL_SPLIT_SECONDARY_CLASS = `h-9 w-8 rounded-s-none border-transparent bg-transparent px-0 sm:h-9 sm:w-8 ${THREAD_DETAILS_PANEL_SPLIT_BUTTON_SURFACE_CLASS}`;47export const THREAD_DETAILS_PANEL_SPLIT_SECONDARY_CLASS = `h-9 w-8 rounded-s-none border-transparent bg-transparent px-0 sm:h-9 sm:w-8 ${THREAD_DETAILS_PANEL_SPLIT_BUTTON_SURFACE_CLASS}`;
44 48
45export const THREAD_DETAILS_PANEL_SPLIT_SEPARATOR_CLASS = "h-4 w-px shrink-0 bg-border/65";49export const THREAD_DETAILS_PANEL_SPLIT_SEPARATOR_CLASS = "h-4 w-px shrink-0 bg-border/65";
50
51export const THREAD_DETAILS_PANEL_ROW_POPUP_CLASS = CHAT_GLASS_ROW_POPUP_CLASS;
52
53export const THREAD_DETAILS_PANEL_MENU_POPUP_CLASS = CHAT_GLASS_MENU_POPUP_CLASS;