Files
Stirling-PDF/frontend/src/components/shared/fitText/FitText.README.md
T
EthanHealy01andGitHub 8f32082145 Feature/v2/all tools sidebar (#4151)
# Description of Changes

- Added the all tools sidebar
- Added a TextFit component that shrinks text to fit containers
- Added a TopToolIcon on the nav, that animates down to give users
feedback on what tool is selected
- Added the baseToolRegistry, to replace the old pattern of listing
tools, allowing us to clean up the ToolRegistry code
- Fixed Mantine light/dark theme race condition 
- General styling tweaks

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] 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)
- [ ] I have performed a self-review of my own code
- [ ] 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-08-19 13:31:09 +01:00

3.4 KiB

FitText Component

Adaptive text component that automatically scales font size down so the content fits within its container, with optional multi-line clamping. Built with a small hook wrapper around ResizeObserver and MutationObserver for reliable, responsive fitting.

Features

  • 📏 Auto-fit text to available width (and optional line count)
  • 🧵 Single-line and multi-line support with clamping and ellipsis
  • 🔁 React hook + component interface
  • ⚡ Efficient: observers and rAF, minimal layout thrash
  • 🎛️ Configurable min scale, max font size, and step size

Behavior

  • On mount and whenever size/text changes, the font is reduced (never increased) until the text fits the given constraints.
  • If lines is provided, height is constrained to an estimated maximum based on computed line-height.

Basic Usage

import FitText from '@/components/shared/FitText';

export function CardTitle({ title }: { title: string }) {
  return (
    <FitText text={title} />
  );
}

API Reference

Props

Prop Type Default Description
text string — The string to render and fit
fontSize number computed Maximum starting font size in rem (e.g., 1.2, 0.9)
minimumFontScale number 0.8 Smallest scale relative to the max (0..1)
lines number 1 Maximum number of lines to display and fit
className string — Optional class on the rendered element
style CSSProperties — Inline styles (merged with internal clamp styles)
as `'span' 'div'` 'span'

Notes:

  • For multi-line, the component applies WebKit line clamping (with reasonable fallbacks) and fits within that height.
  • The component only scales down; if the content already fits, it keeps the starting size.

Examples

Single-line title (default)

<FitText text="Very long single-line title that should shrink" />

Multi-line label (up to 3 lines)

<FitText
  text="This label can wrap up to three lines and will shrink so it fits nicely"
  lines={3}
  minimumFontScale={0.6}
  className="my-multiline-label"
/>

Explicit starting size

<FitText text="Starts at 1.2rem, scales down if needed" fontSize={1.2} />

Render as a div

<FitText as="div" text="Block-level content" lines={2} />

Hook Usage (Advanced)

If you need to control your own element, you can use the underlying hook directly.

import React, { useRef } from 'react';
import { useAdjustFontSizeToFit } from '@/components/shared/fitText/textFit';

export function CustomFit() {
  const ref = useRef<HTMLSpanElement | null>(null);

  useAdjustFontSizeToFit(ref as any, {
    maxFontSizePx: 20,
    minFontScale: 0.6,
    maxLines: 2,
    singleLine: false,
  });

  return (
    <span ref={ref} style={{ display: 'inline-block', maxWidth: 240 }}>
      Arbitrary text that will scale to fit two lines.
    </span>
  );
}

Tips

  • For predictable measurements, ensure the container has a fixed width (or stable layout) when fitting occurs.
  • Avoid animating width while fitting; update after animation completes for best results.
  • When you need more control of typography, pass fontSize to define the starting ceiling.
  • Important: The fontSize prop expects rem values (e.g., 1.2, 0.9) to ensure text scales with global font size changes.