Files
Stirling-PDF/frontend/src/components/shared/rightRail/RightRail.README.md
T
EthanHealy01andGitHub 5354f08766 Chore/v2/right rail cleanup (#4689)
# Description of Changes

- Migrated all dynamic right-rail controls into their owning views (file
editor, page editor, viewer) using dedicated helper hooks, so the rail
is
    purely a renderer now.
- Tightened layout/animation: dynamic buttons grow in with a top-down
reveal
    and center correctly.

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [x] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 15:58:20 +01:00

3.4 KiB

RightRail Component

A dynamic vertical toolbar on the right side of the application that supports both static buttons (Undo/Redo, Save, Print, Share) and dynamic buttons registered by tools.

Structure

  • Top Section: Dynamic buttons from tools (empty when none)
  • Middle Section: Grid, Cut, Undo, Redo
  • Bottom Section: Save, Print, Share

Usage

import { useRightRailButtons } from '../hooks/useRightRailButtons';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';

function MyTool() {
  const handleAction = useCallback(() => {
    // Your action here
  }, []);

  useRightRailButtons([
    {
      id: 'my-action',
      icon: <PlayArrowIcon />,
      tooltip: 'Execute Action',
      onClick: handleAction,
    },
  ]);

  return <div>My Tool</div>;
}

Multiple Buttons

useRightRailButtons([
  {
    id: 'primary',
    icon: <StarIcon />,
    tooltip: 'Primary Action',
    order: 1,
    onClick: handlePrimary,
  },
  {
    id: 'secondary',
    icon: <SettingsIcon />,
    tooltip: 'Secondary Action',
    order: 2,
    onClick: handleSecondary,
  },
]);

Conditional Buttons

useRightRailButtons([
  // Always show
  {
    id: 'process',
    icon: <PlayArrowIcon />,
    tooltip: 'Process',
    disabled: isProcessing,
    onClick: handleProcess,
  },
  // Only show when condition met
  ...(hasResults ? [{
    id: 'export',
    icon: <DownloadIcon />,
    tooltip: 'Export',
    onClick: handleExport,
  }] : []),
]);

API

Button Config

interface RightRailButtonWithAction {
  id: string;                    // Unique identifier
  icon?: React.ReactNode;        // Icon component (omit when using render)
  tooltip?: React.ReactNode;     // Hover tooltip / description
  section?: 'top' | 'middle' | 'bottom'; // Section (default: 'top')
  order?: number;                // Sort order (default: 0)
  disabled?: boolean;            // Disabled state (default: false)
  visible?: boolean;             // Visibility (default: true)
  render?: (ctx: RightRailRenderContext) => React.ReactNode; // Custom renderer
  onClick?: () => void;          // Click handler (optional if using render)
}

interface RightRailRenderContext {
  id: string;
  disabled: boolean;
  allButtonsDisabled: boolean;
  action?: () => void;
  triggerAction: () => void;
}

Custom Rendering (Popovers, Multi-button Blocks)

useRightRailButtons([
  {
    id: 'viewer-search',
    tooltip: t('rightRail.search', 'Search PDF'),
    render: ({ disabled }) => (
      <Tooltip content={t('rightRail.search', 'Search PDF')}>
        <Popover position="left">
          <Popover.Target>
            <ActionIcon disabled={disabled}>
              <SearchIcon />
            </ActionIcon>
          </Popover.Target>
          <Popover.Dropdown>
            <SearchInterface />
          </Popover.Dropdown>
        </Popover>
      </Tooltip>
    ),
  },
]);

Built-in Features

  • Undo/Redo: Automatically integrates with Page Editor
  • Theme Support: Light/dark mode with CSS variables
  • Auto Cleanup: Buttons unregister when tool unmounts

Best Practices

  • Use descriptive IDs: 'compress-optimize', 'ocr-process'
  • Choose appropriate Material-UI icons
  • Keep tooltips concise: 'Compress PDF', 'Process with OCR'
  • Use useCallback for click handlers to prevent re-registration
  • Reach for render when you need popovers or multi-control groups inside the rail