Zoom HUD

Zoom controls with current percentage, increment buttons, and reset action for canvas views.

Report a bug

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Installation

pnpm dlx shadcn@latest add https://ui.vllnt.ai/r/zoom-hud.json
bash

Storybook

Explore all variants, controls, and accessibility checks in the interactive Storybook playground.

View in Storybook

Code

import { forwardRef } from "react";

import { Minus, Plus, RotateCcw } from "lucide-react";

import { cn } from "../../lib/utils";
import { Button } from "../button";

export type ZoomHUDProps = React.ComponentPropsWithoutRef<"div"> & {
  onReset?: () => void;
  onZoomIn?: () => void;
  onZoomOut?: () => void;
  zoom: number;
};

const ZoomHUD = forwardRef<HTMLDivElement, ZoomHUDProps>(
  ({ className, onReset, onZoomIn, onZoomOut, zoom, ...props }, ref) => (
    <div
      className={cn(
        "inline-flex items-center gap-1 rounded-sm border border-border bg-background p-1 font-mono",
        className,
      )}
      ref={ref}
      {...props}
    >
      <Button
        aria-label="Zoom out"
        onClick={onZoomOut}
        size="icon"
        type="button"
        variant="ghost"
      >
        <Minus className="size-4" />
      </Button>
      <div className="min-w-16 px-2 text-center text-xs font-medium tabular-nums text-foreground">
        {Math.round(zoom * 100)}%
      </div>
      <Button
        aria-label="Zoom in"
        onClick={onZoomIn}
        size="icon"
        type="button"
        variant="ghost"
      >
        <Plus className="size-4" />
      </Button>
      <Button
        aria-label="Reset zoom"
        onClick={onReset}
        size="icon"
        type="button"
        variant="ghost"
      >
        <RotateCcw className="size-4" />
      </Button>
    </div>
  ),
);

ZoomHUD.displayName = "ZoomHUD";

export { ZoomHUD };
typescript

Dependencies

  • @vllnt/ui@^0.2.1
  • lucide-react