diff --git a/apps/web/package.json b/apps/web/package.json index 12bd0c28929f..ffccf206f910 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -48,8 +48,10 @@ "jose": "catalog:", "jsonc-parser": "3.3.1", "jszip": "3.10.1", + "lucide": "^0.564.0", "lucide-react": "^0.564.0", "mermaid": "^11.17.2", + "morphicons": "^1.7.1", "react": "19.2.6", "react-dom": "19.2.6", "react-markdown": "^10.1.0", diff --git a/apps/web/src/components/ChatMarkdown.tsx b/apps/web/src/components/ChatMarkdown.tsx index d31b189a9c53..5358e253af4f 100644 --- a/apps/web/src/components/ChatMarkdown.tsx +++ b/apps/web/src/components/ChatMarkdown.tsx @@ -5,10 +5,8 @@ import { encodeComposerContextClipboardHtml, } from "@t3tools/shared/composerContextClipboard"; import { - CheckIcon, ChevronRightIcon, CodeIcon, - CopyIcon, FileSpreadsheetIcon, FileTextIcon, GlobeIcon, @@ -16,10 +14,8 @@ import { InfoIcon, LightbulbIcon, MailIcon, - Maximize2Icon, MessageSquareIcon, MessageSquareWarningIcon, - Minimize2Icon, OctagonAlertIcon, PlayIcon, PresentationIcon, @@ -29,6 +25,7 @@ import { WrapTextIcon, type LucideIcon, } from "lucide-react"; +import { Check, Copy, Maximize2, Minimize2 } from "lucide"; import type { AssetResource, EnvironmentId, @@ -123,6 +120,7 @@ import { import { hasSpecificPierreIconForFileName, syntheticFileNameForLanguageId } from "../pierre-icons"; import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip"; import { Button } from "./ui/button"; +import { MorphIcon } from "~/components/MorphIcon"; import { ContextChip } from "./ContextChip"; import { Collapsible, CollapsiblePanel, CollapsibleTrigger } from "./ui/collapsible"; import { ScrollArea } from "./ui/scroll-area"; @@ -849,7 +847,7 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) { /> } > - {expanded ? : } + {expandLabel} @@ -869,7 +867,7 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) { /> } > - {copied ? : } + {copyLabel} @@ -1063,7 +1061,7 @@ function MarkdownCodeBlock({ /> } > - {copied ? : } + {copyLabel} diff --git a/apps/web/src/components/DiffFilePathCopyButton.tsx b/apps/web/src/components/DiffFilePathCopyButton.tsx index 5e78949336cf..ab42f126189e 100644 --- a/apps/web/src/components/DiffFilePathCopyButton.tsx +++ b/apps/web/src/components/DiffFilePathCopyButton.tsx @@ -1,12 +1,14 @@ -import { CheckIcon, CopyIcon } from "lucide-react"; +import { Check, Copy } from "lucide"; import { useRef } from "react"; import { useCopyToClipboard } from "../hooks/useCopyToClipboard"; +import { cn } from "../lib/utils"; import { ANCHORED_COPY_TOAST_TIMEOUT_MS, showAnchoredCopyErrorToast, showAnchoredCopySuccessToast, } from "./ui/anchoredCopyToast"; import { Button } from "./ui/button"; +import { MorphIcon } from "~/components/MorphIcon"; import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip"; export function DiffFilePathCopyButton({ filePath }: { filePath: string }) { @@ -30,7 +32,10 @@ export function DiffFilePathCopyButton({ filePath }: { filePath: string }) { /> } > - {isCopied ? : } +

{isCopied ? "Copied" : "Copy path"}

diff --git a/apps/web/src/components/DiffPanel.tsx b/apps/web/src/components/DiffPanel.tsx index 32f5bfabcbaf..50df89109e05 100644 --- a/apps/web/src/components/DiffPanel.tsx +++ b/apps/web/src/components/DiffPanel.tsx @@ -12,15 +12,13 @@ import { ArrowRightIcon, CheckIcon, ChevronDownIcon, - ChevronRightIcon, - ChevronsDownUpIcon, - ChevronsUpDownIcon, Columns2Icon, FolderTreeIcon, PilcrowIcon, Rows3Icon, TextWrapIcon, } from "lucide-react"; +import { ChevronDown, ChevronRight, ChevronsDownUp, ChevronsUpDown } from "lucide"; import * as Schema from "effect/Schema"; import * as DateTime from "effect/DateTime"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; @@ -58,6 +56,7 @@ import { AnnotatableCodeView, type AnnotatableCodeViewHandle } from "./diffs/Ann import { DiffFileTree } from "./diffs/DiffFileTree"; import { diffFileTreeEntries } from "./diffs/diffFileTree.logic"; import { Button } from "./ui/button"; +import { MorphIcon } from "~/components/MorphIcon"; import { ToggleGroup, Toggle } from "./ui/toggle-group"; import { Switch } from "./ui/switch"; import { @@ -873,11 +872,10 @@ export default function DiffPanel({ /> } > - {allDiffFilesCollapsed ? ( - - ) : ( - - )} + {allDiffFilesCollapsed ? "Expand all files" : "Collapse all files"} @@ -1133,15 +1131,10 @@ export default function DiffPanel({ /> } > - {collapsed ? ( - - ) : ( - - )} + {collapsed ? "Expand diff" : "Collapse diff"} diff --git a/apps/web/src/components/MorphIcon.tsx b/apps/web/src/components/MorphIcon.tsx new file mode 100644 index 000000000000..053921dde42f --- /dev/null +++ b/apps/web/src/components/MorphIcon.tsx @@ -0,0 +1,6 @@ +import { MorphIcon as BaseMorphIcon, type MorphIconProps } from "morphicons/react"; + +/** Renders `lucide` icon data and morphs between shapes when `icon` changes. */ +export function MorphIcon({ reducedMotion = "user", ...props }: MorphIconProps) { + return ; +} diff --git a/apps/web/src/components/RightPanelTabs.tsx b/apps/web/src/components/RightPanelTabs.tsx index d3c3d5c31ded..914028f7c8cd 100644 --- a/apps/web/src/components/RightPanelTabs.tsx +++ b/apps/web/src/components/RightPanelTabs.tsx @@ -23,9 +23,8 @@ import { Globe2, Plus, TerminalSquare, - Volume2, - VolumeOff, } from "lucide-react"; +import { Volume2, VolumeOff } from "lucide"; import { type KeyboardEvent as ReactKeyboardEvent, type MouseEvent as ReactMouseEvent, @@ -44,6 +43,7 @@ import type { RightPanelSurface } from "~/rightPanelStore"; import { cn } from "~/lib/utils"; import { readLocalApi } from "~/localApi"; import { Button } from "~/components/ui/button"; +import { MorphIcon } from "~/components/MorphIcon"; import { AndroidIcon, AppleIcon } from "~/components/Icons"; import { Tooltip, TooltipPopup, TooltipTrigger } from "~/components/ui/tooltip"; import { Kbd } from "~/components/ui/kbd"; @@ -1149,11 +1149,10 @@ export function RightPanelTabs(props: RightPanelTabsProps) { .catch(() => undefined); }} > - {audio === "muted" ? ( - - ) : ( - - )} + } /> diff --git a/apps/web/src/components/chat/ChangedFilesTree.tsx b/apps/web/src/components/chat/ChangedFilesTree.tsx index 39d17cd3de9b..a1cb0dac252a 100644 --- a/apps/web/src/components/chat/ChangedFilesTree.tsx +++ b/apps/web/src/components/chat/ChangedFilesTree.tsx @@ -6,20 +6,15 @@ import { summarizeTurnDiffStats, type TurnDiffTreeNode, } from "../../lib/turnDiffTree"; -import { - ChevronsDownUpIcon, - ChevronsUpDownIcon, - ChevronRightIcon, - FileDiffIcon, - FolderIcon, - FolderClosedIcon, -} from "lucide-react"; +import { ChevronRightIcon, FileDiffIcon } from "lucide-react"; +import { ChevronsDownUp, ChevronsUpDown, Folder, FolderClosed } from "lucide"; import { cn } from "~/lib/utils"; import { DiffStatLabel, hasNonZeroStat } from "./DiffStatLabel"; import { PierreEntryIcon } from "./PierreEntryIcon"; import { Button } from "../ui/button"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; import { MiddleTruncate } from "../ui/middle-truncate"; +import { MorphIcon } from "~/components/MorphIcon"; const EMPTY_DIRECTORY_OVERRIDES: Record = {}; @@ -86,11 +81,10 @@ export const ChangedFilesCard = memo(function ChangedFilesCard(props: { /> } > - {allDirectoriesExpanded ? ( - - ) : ( - - )} + {allDirectoriesExpanded ? "Collapse all folders" : "Expand all folders"} @@ -195,11 +189,10 @@ export const ChangedFilesTree = memo(function ChangedFilesTree(props: { isExpanded && "rotate-90", )} /> - {isExpanded ? ( - - ) : ( - - )} + {node.name} diff --git a/apps/web/src/components/chat/ComposerPrimaryActions.tsx b/apps/web/src/components/chat/ComposerPrimaryActions.tsx index 76156ffda49c..81bce817fe4a 100644 --- a/apps/web/src/components/chat/ComposerPrimaryActions.tsx +++ b/apps/web/src/components/chat/ComposerPrimaryActions.tsx @@ -1,12 +1,7 @@ import { memo, type MouseEventHandler, type PointerEventHandler } from "react"; -import { - CheckIcon, - ChevronDownIcon, - ChevronLeftIcon, - CornerUpRightIcon, - ListPlusIcon, - PlayIcon, -} from "lucide-react"; +import { CheckIcon, ChevronDownIcon, ChevronLeftIcon, PlayIcon } from "lucide-react"; +import { CornerUpRight, ListPlus } from "lucide"; +import { MorphIcon } from "~/components/MorphIcon"; import { useEnvironmentIdentificationMode } from "~/hooks/useSettings"; import { cn } from "~/lib/utils"; import { useShortcutModifierState } from "../../shortcutModifierState"; @@ -315,10 +310,8 @@ export const ComposerPrimaryActions = memo(function ComposerPrimaryActions({