feat(studio): draw icons that say what the feature does (#4262)

This commit is contained in:
Miguel Ángel
2026-09-21 21:05:20 -04:00
committed by GitHub
parent 3e63de4778
commit 2cc384f1fe
6 changed files with 68 additions and 23 deletions
@@ -5,6 +5,7 @@ import { usePanelLayoutContext } from "../contexts/PanelLayoutContext";
import { trackStudioEvent } from "../utils/studioTelemetry";
import { Button, buttonBase, buttonSizes, buttonVariants, cn, Tooltip } from "./ui";
import { Dock } from "./dock/Dock";
import { InspectorIcon } from "./icons/InspectorIcon";
export interface StudioHeaderProps {
captureFrameHref: string;
@@ -247,19 +248,7 @@ export function StudioHeader({
"h-full rounded-none",
inspectorButtonActive && "bg-hover text-accent enabled:hover:text-accent",
)}
icon={
<svg
width="12"
height="12"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
>
<circle cx="12" cy="12" r="10" />
<polygon points="10 8 16 12 10 16" fill="currentColor" stroke="none" />
</svg>
}
icon={<InspectorIcon size={16} />}
onClick={() => {
if (shouldOpenInspector(rightCollapsed, inspectorPanelActive)) {
trackStudioEvent("panel_toggle", { panel: "inspector", collapsed: false });
@@ -1,11 +1,5 @@
import { useEffect, useRef } from "react";
import {
Image,
Magnet,
MagnifyingGlassMinus,
MagnifyingGlassPlus,
Waves,
} from "@phosphor-icons/react";
import { Image, Magnet, MagnifyingGlassMinus, MagnifyingGlassPlus } from "@phosphor-icons/react";
import {
useEnableKeyframes,
isPlayheadWithinTween,
@@ -23,6 +17,7 @@ import { useTimelineZoom } from "../player/components/useTimelineZoom";
import { usePlayerStore, type TimelineElement } from "../player";
import { Tooltip } from "./ui";
import { AudioMetersIcon } from "./icons/AudioMetersIcon";
import { RippleEditIcon } from "./icons/RippleEditIcon";
import { flatActive, flatBtn, flatDisabled, flatIdle } from "./timelineToolbarStyles";
import { TimelineHistoryButtons } from "./TimelineHistoryButtons";
import { Scissors } from "../icons/SystemIcons";
@@ -252,7 +247,7 @@ export function TimelineToolbar({ domEditSession, onSplitElement }: TimelineTool
aria-pressed={rippleEditEnabled}
className={rippleEditEnabled ? flatActive : flatIdle}
>
<Waves size={16} weight="bold" aria-hidden="true" />
<RippleEditIcon size={16} />
</button>
</Tooltip>
{projectHasAudio && (
@@ -1,6 +1,6 @@
import { buildProjectApiPath } from "../../utils/projectRouting";
import { useMemo, useRef, useState } from "react";
import { Plus, RotateCcw, X } from "../../icons/SystemIcons";
import { Plus, X } from "../../icons/SystemIcons";
import {
buildDefaultGradientModel,
insertGradientStop,
@@ -8,6 +8,7 @@ import {
serializeGradient,
type GradientModel,
} from "./gradientValue";
import { ReverseGradientIcon } from "../icons/ReverseGradientIcon";
import { IMAGE_EXT } from "../../utils/mediaTypes";
import { FIELD, LABEL, RESPONSIVE_GRID } from "./propertyPanelHelpers";
import {
@@ -358,7 +359,7 @@ export function GradientField({
}}
className="inline-flex h-7 items-center gap-1.5 rounded-lg border border-neutral-700 bg-neutral-950 px-2.5 text-[11px] font-medium text-neutral-300 transition-colors hover:border-neutral-600 hover:text-white disabled:cursor-not-allowed disabled:text-neutral-600"
>
<RotateCcw size={12} />
<ReverseGradientIcon size={16} />
Reverse
</button>
</div>
@@ -0,0 +1,18 @@
export function InspectorIcon({ size = 16 }: { size?: number | string }) {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
>
<rect x="1.5" y="2" width="13" height="12" rx="1.5" />
<path d="M4 6h8M6 4.5v3M4 10h8m-2-1.5v3" />
</svg>
);
}
@@ -0,0 +1,23 @@
export function ReverseGradientIcon({ size = 16 }: { size?: number | string }) {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
>
<path d="M2 3h12m-2-2 2 2-2 2M14 8H2m2-2L2 8l2 2" />
<g fill="currentColor" stroke="none">
<path d="M2 12h3v2H2z" opacity="0.25" />
<path d="M5 12h3v2H5z" opacity="0.5" />
<path d="M8 12h3v2H8z" opacity="0.75" />
<path d="M11 12h3v2h-3z" />
</g>
</svg>
);
}
@@ -0,0 +1,19 @@
export function RippleEditIcon({ size = 16 }: { size?: number | string }) {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
>
<rect x="1.5" y="8" width="4" height="5" rx="0.5" />
<rect x="10.5" y="8" width="4" height="5" rx="0.5" />
<path d="M13 4H6m2-2L6 4l2 2" />
</svg>
);
}