Unit System

Work with different measurement units like pixels, millimeters, centimeters, inches, and points.

This example demonstrates how to use the unit system to display and work with measurements in different units.

Overview

The Designer supports multiple unit systems, making it ideal for both screen and print design work.

  • Pixels (px) - For screen-based designs
  • Millimeters (mm) - Common for print design in metric countries
  • Centimeters (cm) - Larger metric measurements
  • Inches (in) - Standard for print design in the US
  • Points (pt) - Typography and print industry standard

Unit System Selector

Add a unit selector to your toolbar to allow users to switch between units:

components/unit-selector.tsx
import { useUnitSystem, useSetUnitSystem } from "@shadcn/designer"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@shadcn/designer/ui"
import type { Unit } from "@shadcn/designer/utils"
 
function UnitSystemSelector() {
  const unitSystem = useUnitSystem()
  const setUnitSystem = useSetUnitSystem()
 
  return (
    <Select value={unitSystem} onValueChange={(v) => setUnitSystem(v as Unit)}>
      <SelectTrigger className="w-36">
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="px">Pixels (px)</SelectItem>
        <SelectItem value="mm">Millimeters (mm)</SelectItem>
        <SelectItem value="cm">Centimeters (cm)</SelectItem>
        <SelectItem value="in">Inches (in)</SelectItem>
        <SelectItem value="pt">Points (pt)</SelectItem>
      </SelectContent>
    </Select>
  )
}

DPI Settings

DPI (dots per inch) determines how physical units are converted to pixels. This is crucial for print design:

components/dpi-selector.tsx
import { useDPI, useSetDPI } from "@shadcn/designer"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@shadcn/designer/ui"
 
function DPISelector() {
  const dpi = useDPI()
  const setDPI = useSetDPI()
 
  return (
    <Select value={String(dpi)} onValueChange={(v) => setDPI(Number(v))}>
      <SelectTrigger className="w-28">
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="72">72 DPI</SelectItem>
        <SelectItem value="96">96 DPI</SelectItem>
        <SelectItem value="150">150 DPI</SelectItem>
        <SelectItem value="300">300 DPI</SelectItem>
        <SelectItem value="600">600 DPI</SelectItem>
      </SelectContent>
    </Select>
  )
}

Converting Units

Use the fromPixels and toPixels utility functions to convert between units:

lib/unit-conversion.ts
import { fromPixels, toPixels } from "@shadcn/designer/utils"
 
// Convert pixels to another unit.
const mm = fromPixels(300, "mm", 300) // 25.4mm at 300 DPI
 
// Convert from another unit to pixels.
const pixels = toPixels(25.4, "mm", 300) // 300px at 300 DPI

Displaying Dimensions

Show frame or layer dimensions in the current unit system:

components/dimension-display.tsx
import { useUnitSystem, useDPI, useFrameSize } from "@shadcn/designer"
import { fromPixels } from "@shadcn/designer/utils"
 
function DimensionDisplay() {
  const unitSystem = useUnitSystem()
  const dpi = useDPI()
  const frameSize = useFrameSize()
 
  // Convert frame size to current unit.
  const width = fromPixels(frameSize.width, unitSystem, dpi)
  const height = fromPixels(frameSize.height, unitSystem, dpi)
 
  // Format with appropriate precision.
  const formatValue = (value: number) => {
    if (unitSystem === "px") {
      return Math.round(value)
    }
    return value.toFixed(2).replace(/\.?0+$/, "")
  }
 
  return (
    <div>
      Frame: {formatValue(width)} × {formatValue(height)} {unitSystem}
    </div>
  )
}

Setting the Default Unit System

Configure the default unit system when initializing the Designer:

components/designer-with-units.tsx
import { Designer, DesignerCanvas, DesignerFrame } from "@shadcn/designer"
 
function PrintDesigner() {
  return (
    <Designer
      unitSystem="mm"  // Start with millimeters
      dpi={300}        // Print quality DPI
    >
      <DesignerCanvas>
        <DesignerFrame />
      </DesignerCanvas>
    </Designer>
  )
}

Unit System Hooks

The Designer provides several hooks for working with units:

useUnitSystem

Get the current unit system:

const unitSystem = useUnitSystem() // "px" | "mm" | "cm" | "in" | "pt"

useSetUnitSystem

Change the unit system:

const setUnitSystem = useSetUnitSystem()
setUnitSystem("mm")

useDPI

Get the current DPI setting:

const dpi = useDPI() // number (e.g., 300)

useSetDPI

Change the DPI setting:

const setDPI = useSetDPI()
setDPI(300)

Common DPI Values

Different use cases require different DPI settings:

DPIUse Case
72Low-resolution screen design (legacy)
96Standard screen resolution
150Draft print quality
300Professional print quality (standard)
600High-quality print / fine details

Unit Conversion Reference

Understanding unit conversions:

  • 1 inch = 25.4 millimeters
  • 1 inch = 2.54 centimeters
  • 1 inch = 72 points (PostScript/CSS standard)
  • Pixels depend on DPI: At 300 DPI, 1 inch = 300 pixels

Example Conversions at 300 DPI

Physical UnitPixels
1 mm~11.81 px
1 cm~118.11 px
1 in300 px
1 pt~4.17 px

Use Cases

Screen Design

Use pixels (px) for web and app interfaces:

<Designer unitSystem="px" dpi={96}>
  {/* Your design */}
</Designer>

Use physical units (mm, cm, in) for print work:

<Designer unitSystem="mm" dpi={300}>
  {/* Your design */}
</Designer>

Typography

Use points (pt) for precise typography control:

<Designer unitSystem="pt" dpi={72}>
  {/* Your design */}
</Designer>

Notes

  • All measurements are stored internally as pixels for consistency.
  • Unit conversions happen on-the-fly when displaying or editing values.
  • Changing DPI only affects physical units (mm, cm, in, pt), not pixels.
  • The Action components (ActionSize, ActionPosition, etc.) automatically display values in the current unit system.