diff --git a/frontend/editor/src/core/components/pageTracks/PageTracks.module.css b/frontend/editor/src/core/components/pageTracks/PageTracks.module.css index 0b3f8ea5c2..44b07525c4 100644 --- a/frontend/editor/src/core/components/pageTracks/PageTracks.module.css +++ b/frontend/editor/src/core/components/pageTracks/PageTracks.module.css @@ -233,6 +233,25 @@ pointer-events: auto; } +/* ── Unsaved-changes marker on the save button ───────────────────────────── */ + +.saveButton { + position: relative; +} + +.unsavedDot { + position: absolute; + top: 0.125rem; + right: 0.125rem; + width: 0.4375rem; + height: 0.4375rem; + border-radius: 999px; + background: var(--c-danger); + /* Ringed in the bar's own surface so it reads against the icon behind it. */ + box-shadow: 0 0 0 1.5px var(--c-bg-raised); + pointer-events: none; +} + /* ── Track reorder ───────────────────────────────────────────────────────── */ .trackDragging { diff --git a/frontend/editor/src/core/components/pageTracks/hooks/usePageTracksWorkbenchBarButtons.tsx b/frontend/editor/src/core/components/pageTracks/hooks/usePageTracksWorkbenchBarButtons.tsx index 5f2f2f8816..9eb074c38c 100644 --- a/frontend/editor/src/core/components/pageTracks/hooks/usePageTracksWorkbenchBarButtons.tsx +++ b/frontend/editor/src/core/components/pageTracks/hooks/usePageTracksWorkbenchBarButtons.tsx @@ -9,6 +9,9 @@ import { WorkbenchBarButtonWithAction, } from "@app/hooks/useWorkbenchBarButtons"; import LocalIcon from "@app/components/shared/LocalIcon"; +import { ActionIcon } from "@app/ui/ActionIcon"; +import { Tooltip } from "@app/components/shared/Tooltip"; +import styles from "@app/components/pageTracks/PageTracks.module.css"; export interface PageTracksBarParams { totalPages: number; @@ -151,15 +154,32 @@ export function usePageTracksWorkbenchBarButtons(params: PageTracksBarParams) { }, { id: "tracks-save", - icon: , tooltip: labels.save, ariaLabel: labels.save, section: "bottom" as const, order: 30, - active: isDirty, disabled: !isDirty || saving, visible: hasPages, onClick: onSave, + // Custom render for the unsaved-changes dot. A custom render also + // bypasses the bar's own tooltip wrapper, hence the Tooltip here. + render: ({ disabled, triggerAction }) => ( + + + + {isDirty && } + + + ), }, ], [