npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yourbestsoft/studio-screen-board

v0.1.13

Published

A React drawing board component with arrow tools, shape tools, and advanced styling features

Readme

Studio Screen Board

A powerful React drawing board component built with TypeScript and Fabric.js. Features comprehensive drawing tools, property editing, and a sleek Screen Studio-inspired design system with modern dark and light themes.

Features

Drawing Tools

  • Select Tool - Multi-element selection, manipulation, and layer management
  • 🏹 Arrow Tool - Dynamic arrow creation with proportional arrowheads that scale with line width
  • 📐 Line Tool - Straight lines with customizable stroke styles (solid, dashed, dotted)
  • Rectangle Tool - Rectangles with adjustable corner radius and styling
  • Circle Tool - Circles and ellipses with full styling support
  • 🎨 Paint Tool - Freehand drawing with customizable brush settings
  • 📝 Text Tool - Rich text with font family, size, color, and alignment options
  • 🌫️ Blur Tool - Privacy blur effects for sensitive content
  • 🎯 Highlight Tool - Attention-grabbing highlight annotations

Advanced Features

  • 🎨 Property Panel - Real-time style editing with color picker, sliders, and dropdowns
  • 🖼️ Background Images - Automatic canvas resizing to match image dimensions
  • 📱 Responsive Design - Smart canvas scaling and positioning for different screen sizes
  • 🔄 Undo/Redo - Complete command history with keyboard shortcuts
  • 👥 Group/Ungroup - Element grouping with hierarchical selection
  • 📚 Layer Management - Bring to front/back, forward/backward operations
  • ⌨️ Keyboard Shortcuts - Delete, Copy (Cmd+C), Paste (Cmd+V)
  • 💾 Document Serialization - Save and load drawing documents as JSON
  • 🎭 Draggable Panels - Moveable toolbar and property panels
  • 🌙 Modern Themes - Screen Studio-inspired dark and light themes
  • 🎨 Self-Contained Styles - All CSS automatically bundled, no separate imports needed

Styling System

  • Colors - Stroke and fill colors with advanced color picker
  • Line Styles - Solid, dashed, and dotted lines with configurable patterns
  • Line Width - Adjustable stroke width (1-20px)
  • Opacity - Element transparency control (0-100%)
  • Corner Radius - Rounded corners for rectangles (0-50px)
  • Text Styling - Font family, size (8-72px), color, weight, and style
  • Shadow Effects - Drop shadows with theme-aware styling

Installation

# Using pnpm (recommended)
pnpm add @yourbestsoft/studio-screen-board

# Using npm
npm install @yourbestsoft/studio-screen-board

# Using yarn
yarn add @yourbestsoft/studio-screen-board

Quick Start

import React from 'react';
import { DrawBoard } from '@yourbestsoft/studio-screen-board';

function App() {
  const handleSave = (imageDataURL: string, documentJSON: string) => {
    console.log('Image saved:', imageDataURL);
    console.log('Document saved:', documentJSON);
  };

  const handleClose = () => {
    console.log('Closing editor');
  };

  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <DrawBoard
        theme="dark"
        onSave={handleSave}
        onClose={handleClose}
        canvasWidth={1920}
        canvasHeight={1080}
      />
    </div>
  );
}

export default App;

API Reference

DrawBoard Props

Appearance

| Prop | Type | Default | Description | |------|------|---------|-------------| | theme | "light" \| "dark" | "light" | UI theme (dark theme features Screen Studio-inspired design) |

Canvas Configuration

| Prop | Type | Default | Description | |------|------|---------|-------------| | canvasWidth | number | 1920 | Canvas width in pixels | | canvasHeight | number | 1080 | Canvas height in pixels | | containerMaxWidth | string | "100vw" | Maximum width of the editor container (CSS value) | | containerMaxHeight | string | "100vh" | Maximum height of the editor container (CSS value) | | positionCanvas | CanvasPosition | {horizontal: "left", vertical: "top"} | Canvas position within container | | transparentBackground | boolean | false | Make the board background transparent |

Content

| Prop | Type | Default | Description | |------|------|---------|-------------| | image | string \| File | - | Background image (auto-resizes canvas) | | document | string | - | JSON document to load |

Event Handlers

| Prop | Type | Default | Description | |------|------|---------|-------------| | onSave | (image: string, doc: string) => void | - | Save callback when save button is clicked | | onClose | () => void | - | Close callback when close button is clicked | | onChange | (document: string) => void | - | Change callback triggered on every document modification | | onElementClick | (elementId: string) => void | - | Callback triggered when an element is clicked in view mode |

View Mode

| Prop | Type | Default | Description | |------|------|---------|-------------| | viewMode | boolean | false | Enable view-only mode (no editing, toolbar hidden, elements highlight on click) |

UI Customization

| Prop | Type | Default | Description | |------|------|---------|-------------| | customActionGroups | CustomActionGroup[] | - | Custom action groups to add to the toolbar | | toolbarPosition | {x: number, y: number} | {x: 16, y: 16} | Initial toolbar position | | propertiesPosition | {x: number, y: number} | Auto-calculated | Initial properties panel position |

Type Definitions

CanvasPosition

type CanvasPosition =
  | { horizontal?: "left" | "center" | "right", vertical?: "top" | "center" | "bottom" }
  | { x: number, y: number };

CustomAction

interface CustomAction {
  id: string;
  title: string;
  icon: React.ReactNode;
  onClick: () => void;
  disabled?: boolean;
  type: "icon" | "action";
  text?: string; // Only used when type is 'action'
}

CustomActionGroup

interface CustomActionGroup {
  id: string;
  actions: CustomAction[];
}

Advanced Usage

View Mode

Enable read-only mode where users can view the board and click on elements to highlight them, without editing capabilities:

import { DrawBoard } from '@yourbestsoft/studio-screen-board';

function ViewerApp() {
  const [selectedElementId, setSelectedElementId] = React.useState<string | null>(null);

  const handleElementClick = (elementId: string) => {
    console.log('Element clicked:', elementId);
    setSelectedElementId(elementId);
    // You can show element details, trigger actions, etc.
  };

  return (
    <DrawBoard
      viewMode={true}
      document={savedDocument}
      onElementClick={handleElementClick}
      theme="dark"
    />
  );
}

View Mode Features:

  • ✅ All elements are visible and rendered normally
  • ✅ Elements highlight with a glowing effect when clicked (color matches the element)
  • ✅ Toolbar and property panels are hidden
  • ✅ Elements cannot be dragged, edited, or deleted
  • ✅ Keyboard shortcuts are disabled
  • ✅ Background images are displayed
  • ✅ Perfect for presentations, previews, or read-only galleries

Highlight Effect:

  • Stroke width increases by 6px (minimum 8px total)
  • Element brightness increases by 30%
  • Glowing shadow effect in the element's color (opacity 80%, blur 25px)
  • Element opacity increases by 20%
  • Clicking elsewhere clears the highlight

Custom Action Groups

Add custom buttons to the toolbar using the customActionGroups prop. Each group is separated by dividers and can contain icon-only buttons or buttons with text and icons:

import { DrawBoard, CustomActionGroup } from '@yourbestsoft/studio-screen-board';

const customActions: CustomActionGroup[] = [
  {
    id: 'export-group',
    actions: [
      {
        id: 'export-pdf',
        title: 'Export to PDF',
        type: 'icon', // Icon-only button (compact)
        icon: (
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
            <polyline points="14,2 14,8 20,8" />
            <line x1="16" y1="13" x2="8" y2="13" />
            <line x1="16" y1="17" x2="8" y2="17" />
            <polyline points="10,9 9,9 8,9" />
          </svg>
        ),
        onClick: () => exportToPDF(),
      },
      {
        id: 'print',
        title: 'Print Document',
        type: 'action', // Button with icon and text
        text: 'Print',
        icon: (
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <polyline points="6,9 6,2 18,2 18,9" />
            <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" />
            <rect x="6" y="14" width="12" height="8" />
          </svg>
        ),
        onClick: () => window.print(),
        disabled: false
      }
    ]
  }
];

function App() {
  return (
    <DrawBoard
      customActionGroups={customActions}
      onSave={handleSave}
      onClose={handleClose}
      theme="dark"
    />
  );
}

Background Images

The component automatically resizes the canvas to match image dimensions:

<DrawBoard
  image="/path/to/screenshot.png"  // Canvas auto-resizes to image size
  onSave={handleSave}
/>

// Or with File object
const handleFileUpload = (file: File) => {
  return (
    <DrawBoard
      image={file}
      onSave={handleSave}
    />
  );
};

Canvas Positioning

Control where the canvas is positioned within the container:

// Preset positioning
<DrawBoard
  containerMaxWidth="1200px"
  containerMaxHeight="800px"
  canvasWidth={800}
  canvasHeight={600}
  positionCanvas={{
    horizontal: "center",  // left | center | right
    vertical: "center"     // top | center | bottom
  }}
/>

// Coordinate positioning
<DrawBoard
  positionCanvas={{ x: 300, y: 200 }}
/>

Custom Container Size

// Fixed dimensions
<DrawBoard
  containerMaxWidth="800px"
  containerMaxHeight="600px"
  canvasWidth={1920}
  canvasHeight={1080}
/>

// Responsive dimensions
<DrawBoard
  containerMaxWidth="90vw"
  containerMaxHeight="80vh"
/>

Document Serialization

import { DrawBoard } from '@yourbestsoft/studio-screen-board';

// Save document
const handleSave = (imageDataURL: string, documentJSON: string) => {
  localStorage.setItem('drawing', documentJSON);
  // imageDataURL is a base64-encoded PNG of the canvas
};

// Auto-save on every change
const handleChange = (documentJSON: string) => {
  localStorage.setItem('drawing-autosave', documentJSON);
  console.log('Document auto-saved');
};

// Load document
const savedDocument = localStorage.getItem('drawing');

<DrawBoard
  document={savedDocument}
  onSave={handleSave}
  onChange={handleChange}  // Triggered on every modification
/>

Panel Positioning

<DrawBoard
  toolbarPosition={{ x: 20, y: 100 }}
  propertiesPosition={{ x: window.innerWidth - 300, y: 20 }}
/>

Design System

Themes

  • Light Theme - Clean, minimal design with subtle shadows
  • Dark Theme - Screen Studio-inspired with deep black backgrounds (#000000) and purple accents (#4d2ff5)

Color Palette

  • Primary Purple: #4d2ff5 (Screen Studio's signature color)
  • Dark Backgrounds: Pure black (#000000) with sophisticated secondary tones (#13151b)
  • Refined Typography: White text with carefully tuned opacity levels for hierarchy
  • Subtle Borders: White overlays with precise opacity for modern aesthetics

CSS Variables

The component uses CSS custom properties for theming:

  • --primary-color
  • --background-color
  • --text-color
  • --border-color
  • --shadow-color

Technical Details

Dependencies

Core Dependencies:

  • fabric (^6.5.1) - Canvas manipulation and object management
  • addict-ioc (^2.5.6) - Dependency injection container
  • uuid (^11.0.3) - Unique identifier generation

Peer Dependencies:

  • react (^19.0.0)
  • react-dom (^19.0.0)

Build System

  • Vite - Build tool and development server
  • TypeScript - Type safety and modern JavaScript features
  • SCSS - Advanced CSS preprocessing
  • CSS Injection - Automatic style bundling via vite-plugin-css-injected-by-js

Development

Building from Source

# Clone the repository
git clone https://github.com/YourBestSoft/studio-screen-board.git
cd studio-screen-board

# Install dependencies
pnpm install

# Build the library
pnpm run build:lib

# Run development server
pnpm run dev

# Lint code
pnpm run lint

Browser Support

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests if applicable
  5. Run linting (pnpm run lint)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Submit a pull request

License

MIT License - see LICENSE file for details.

Support


Built with ❤️ by YourBestSoft