feat(rundown): clarify offset toggle with labels and info tip

The Absolute/Relative offset toggle in the rundown header gave users no
hint it was even about offsets, and its explanation only lived on
per-button hover (low discoverability, splits a comparative concept).

- Add a small group label to each toolbar toggle (Mode / View / Offset)
  so each control's purpose is self-evident at a glance.
- Add an info icon on the Offset group with a single tooltip explaining
  both modes together, reusing the existing Tooltip + IoInformationCircle
  pattern. Removes the now-redundant per-button offset tooltips.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hj5P4eDgf97zSCzViGHNDy
This commit is contained in:
Claude
2026-07-19 08:51:48 +00:00
parent 5f040092cb
commit a93f2a765e
2 changed files with 71 additions and 38 deletions
@@ -58,8 +58,31 @@
}
}
.toggleTooltipTrigger {
.controlGroup {
display: flex;
align-items: center;
gap: 0.375rem;
}
.groupLabel {
color: $gray-400;
font-size: calc(1rem - 3px);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.02em;
white-space: nowrap;
}
.infoIcon {
display: flex;
align-items: center;
color: $gray-400;
font-size: calc(1rem + 1px);
cursor: help;
&:hover {
color: $gray-200;
}
}
.apart {
@@ -3,6 +3,7 @@ import { ToggleGroup } from '@base-ui/react/toggle-group';
import { Toolbar } from '@base-ui/react/toolbar';
import { OffsetMode } from 'ontime-types';
import { memo } from 'react';
import { IoInformationCircle } from 'react-icons/io5';
import Tooltip from '../../../common/components/tooltip/Tooltip';
import { setOffsetMode, useOffsetMode } from '../../../common/hooks/useSocket';
@@ -74,52 +75,61 @@ function RundownHeader({ isExtracted, viewMode, setViewMode }: RundownHeaderProp
return (
<Toolbar.Root className={style.header}>
{showRunEditToggle && (
<ToggleGroup value={[editorMode]} onValueChange={toggleAppMode} className={style.group}>
<Tooltip
text='Live playback view with auto-follow'
render={<Toolbar.Button render={<Toggle />} value={AppMode.Run} className={style.radioButton} />}
>
Run
</Tooltip>
<Tooltip
text='Manual editing without playback automation'
render={<Toolbar.Button render={<Toggle />} value={AppMode.Edit} className={style.radioButton} />}
>
Edit
</Tooltip>
</ToggleGroup>
<div className={style.controlGroup}>
<span className={style.groupLabel}>Mode</span>
<ToggleGroup value={[editorMode]} onValueChange={toggleAppMode} className={style.group}>
<Tooltip
text='Live playback view with auto-follow'
render={<Toolbar.Button render={<Toggle />} value={AppMode.Run} className={style.radioButton} />}
>
Run
</Tooltip>
<Tooltip
text='Manual editing without playback automation'
render={<Toolbar.Button render={<Toggle />} value={AppMode.Edit} className={style.radioButton} />}
>
Edit
</Tooltip>
</ToggleGroup>
</div>
)}
<ToggleGroup value={[viewMode]} onValueChange={toggleViewMode} className={style.group}>
<Tooltip
text='View rundown in list mode'
render={<Toolbar.Button render={<Toggle />} value={RundownViewMode.List} className={style.radioButton} />}
>
List
</Tooltip>
<Tooltip
text='View rundown in table mode'
render={<Toolbar.Button render={<Toggle />} value={RundownViewMode.Table} className={style.radioButton} />}
>
Table
</Tooltip>
</ToggleGroup>
{showOffsetToggle && (
<ToggleGroup value={[offsetMode]} onValueChange={toggleOffsetMode} className={style.group}>
<div className={style.controlGroup}>
<span className={style.groupLabel}>View</span>
<ToggleGroup value={[viewMode]} onValueChange={toggleViewMode} className={style.group}>
<Tooltip
text='Offsets use fixed clock time'
render={<Toolbar.Button render={<Toggle />} value={OffsetMode.Absolute} className={style.radioButton} />}
text='View rundown in list mode'
render={<Toolbar.Button render={<Toggle />} value={RundownViewMode.List} className={style.radioButton} />}
>
Absolute
List
</Tooltip>
<Tooltip
text='Offsets follow the rundown relative start'
render={<Toolbar.Button render={<Toggle />} value={OffsetMode.Relative} className={style.radioButton} />}
text='View rundown in table mode'
render={<Toolbar.Button render={<Toggle />} value={RundownViewMode.Table} className={style.radioButton} />}
>
Relative
Table
</Tooltip>
</ToggleGroup>
</div>
{showOffsetToggle && (
<div className={style.controlGroup}>
<span className={style.groupLabel}>Offset</span>
<ToggleGroup value={[offsetMode]} onValueChange={toggleOffsetMode} className={style.group}>
<Toolbar.Button render={<Toggle />} value={OffsetMode.Absolute} className={style.radioButton}>
Absolute
</Toolbar.Button>
<Toolbar.Button render={<Toggle />} value={OffsetMode.Relative} className={style.radioButton}>
Relative
</Toolbar.Button>
</ToggleGroup>
<Tooltip
text='Absolute measures offset against the scheduled clock time. Relative measures it from when the rundown actually started.'
render={<span className={style.infoIcon} />}
>
<IoInformationCircle />
</Tooltip>
</div>
)}
{showOverflowMenu && <RundownMenu allowNavigation={!isExtracted} />}