Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Editor Toolbar

A self-contained, floating on-page visual editor that lets you select, style, resize, reposition, and insert DOM elements on any web page — live, without touching code. Changes are tracked in a full undo/redo history and can be exported as copy-ready CSS and HTML for use in any builder or codebase.

Editor Toolbar Screenshot


Table of Contents


Demo

Open EditorToolbar.html directly in any modern browser — no build step, no server, no dependencies.


Features

Feature Description
Element Selection Click the cursor icon to enter pick mode; click any element to select it
Multi-Select Hold Shift and click to select multiple elements simultaneously
Bounding Box Live-tracking selection frame with 8 resize handles (corners + edges)
Free Reposition Drag the move handle to reposition elements; constrained within their parent
Snap to Siblings Pink alignment guides snap the dragged element to parent/sibling edges and centers
Typography Google Fonts search, font size, weight (100–900), color, style, alignment, line height
Layout Width/height with px/% toggle, aspect-ratio lock, min/max constraints, nudge, opacity, display
Style Background color, border radius, border/outline presets, cursor
Effects Box shadow, transforms, full CSS filter rack (blur/brightness/contrast/saturation/hue/grayscale), transitions
Spacing Padding and margin as T/R/B/L number inputs with linked-sides toggle, border radius per corner, gap
Insert Add paragraphs, headings, divs, cards, sections, buttons, images, spans with preset styles
Wrap Multi-select 2+ elements and wrap them in a new container (div/section/article/etc.)
Undo / Redo Full history for every style change, resize, reposition, and element insertion
Accept & Export Review all changes in a summary popup; copy CSS + HTML to clipboard
True Reset Restores every element to its exact page-load inline style, removes all inserted elements

Versions

File Use Case
EditorToolbar.html Drop into any plain HTML project; zero dependencies
EditorToolbar.tsx React component for Lovable, Bolt, or any React/Tailwind project

Both versions share identical behavior. The HTML file is the source of truth; the TSX file mirrors it.


Quick Start

Plain HTML

  1. Copy the three sections marked in EditorToolbar.html into your project:

    • The <style> block → into your CSS
    • The #et-bbox, #et-snap-v, #et-snap-h, #et-popup-overlay, #et-root markup → into your HTML body
    • The <script> block → before your closing </body> tag
  2. Add data-component="Your Name" to any element you want the toolbar to recognise:

<section data-component="Hero Section">
  <h1>Welcome</h1>
  <p>Subtitle text here.</p>
</section>

<div class="card-grid" data-component="Feature Cards">
  <!-- cards -->
</div>
  1. Open the page in a browser. The toolbar appears at the bottom center.

Elements without data-component can still be selected using the cursor pick mode — data-component just gives them a friendly display name in the toolbar.

React / Lovable

  1. Copy EditorToolbar.tsx into src/components/EditorToolbar.tsx

  2. Import and render it at the root level of any page:

import { EditorToolbar } from '@/components/EditorToolbar';

export default function MyPage() {
  return (
    <>
      <main>
        {/* your page content */}
      </main>
      <EditorToolbar />
    </>
  );
}
  1. Add data-component attributes to elements you want selectable:
<section data-component="Hero Section">
  <h1>Welcome</h1>
</section>

How It Works

The toolbar is a floating pill pinned to the bottom center of the viewport. All logic lives inside a single IIFE (const ET = (() => { ... })()) — no global pollution, no external dependencies, no build step required for the HTML version.

Selection

Clicking the cursor icon enters pick mode. Hovering any element outlines it; clicking selects it. Holding Shift while clicking adds or removes elements from a multi-selection pool. Selected elements are tracked by a requestAnimationFrame loop that keeps the bounding box accurate through scroll, resize, and layout changes.

Edits

Every UI control routes through a central apply(property, value) function. This writes the style directly to the element's inline style attribute and pushes an entry onto the history stack: { el, prop, old, val, elName }. Element insertions push a different entry type: { type: 'insert', el, parent, before, pos, elName }.

History

  • Undo reads from the top of the history stack and reverses the entry — setting the old CSS value or removing the inserted element from the DOM.
  • Redo re-applies entries forward through the stack.
  • Accept freezes the current pending batch, clears the working stack, and opens the export popup.

Export

The Accept popup shows every change grouped by element with deduplication (only the final value per property is shown). Copy CSS generates a clean, comment-annotated output:

/* ── Editor Toolbar — Accepted Changes ── */

/* ── Inserted Elements (HTML) ── */
/* Target: "Hero Section" | Position: inside */
<h2 data-component="New Heading" ...>My Heading</h2>

/* ── Style Changes (CSS) ── */

/* Hero Section <section> */
font-family: "Poppins", sans-serif;
font-size: 48px;
color: #111111;

Pane Reference

Typography

Control What It Does
Google Fonts search Type a font name, click a result — fetched from Google Fonts and applied instantly
Font size Slider, 10–96px
Font weight Buttons for every weight from 100 to 900
Text color 20-swatch palette + native OS color picker + hex/rgb input field
Style Italic, Normal, Underline, No decoration, UPPERCASE, None
Align Left, Center, Right, Justify
Line height Slider, 1.0–3.0

Layout

Control What It Does
W / H inputs Set exact width and height in px or %
Unit toggle Switch between px and % for W/H inputs
Aspect ratio lock Lock W:H ratio — changing one value adjusts the other; also active while Shift-dragging a resize handle
Auto / Full W Reset to auto or set width to 100%
Min/Max W and H Set min-width, max-width, min-height, max-height
Nudge Arrow buttons to move the element 1/2/4/8/16px at a time
Step size Choose the nudge amount
Position static, relative, absolute, fixed, sticky
Opacity Slider, 0–100%
Display block, flex, grid, inline-block, inline, none
Overflow visible, hidden, auto, scroll

Style

Control What It Does
Background color Same swatch + color picker + hex input as text color
Border radius Slider, 0–64px
Border Preset styles: None, Light, Dark, Blue, Lime, Dashed, Double
Outline Preset styles: None, Blue, Lime, Dashed
Cursor default, pointer, text, move, not-allowed, grab

Effects

Control What It Does
Box Shadow 9 presets: None, Soft, Medium, Deep, Deeper, Ring, Lime Ring, Brutal, Inset
Transform 10 presets: Reset, Scale+, Scale−, Scale++, Rot 2°, Rot −2°, Rot 45°, SkewX, SkewY, Float
CSS Filters Live sliders for: Blur (0–20px), Brightness (0–200%), Contrast (0–200%), Saturate (0–200%), Hue (0–360°), Grayscale (0–100%)
Transition None, Fast (0.2s), Medium (0.4s), Slow (0.6s), Bounce (cubic-bezier)

Spacing

Control What It Does
Padding T/R/B/L Four number inputs; linked toggle syncs all four sides
Margin T/R/B/L Four number inputs; linked toggle syncs all four sides
Border radius All corners + individual TL/TR/BL/BR inputs
Border width + style Width in px; style chips: Solid, Dashed, Dotted, None
Gap All, Column, Row
Width / Height Exact pixel size

Insert

Control What It Does
Target picker Click to activate; click any element on the page to set it as the insertion target
Position Inside (append child), Before (insert sibling), After (insert sibling)
Element types Paragraph, Heading (H2), H1, Div, Card, Section, Button, Image placeholder, Span
Content Text content for the new element
Component name The data-component label assigned to the inserted element
CSS classes Optional class names to add
Preset styles None, Card, Pill, Hero, Badge, Divider
Wrap (multi-select) Appears when 2+ elements are selected — choose a wrapper tag, name it, and click Wrap

Keyboard Shortcuts

Shortcut Action
P Toggle pick mode
Shift + Click Add / remove element from multi-selection
Arrow keys Nudge selected element (uses the active step size)
Ctrl / Cmd + Z Undo
Ctrl / Cmd + Y or Ctrl / Cmd + Shift + Z Redo
Escape Close active pane or exit pick mode
Shift (hold while resizing) Lock aspect ratio during corner/edge drag

API Reference

All toolbar logic is exposed on the global ET object. These are the methods you can call from outside the toolbar if you need to integrate it programmatically.

Core Controls

ET.togglePick()         // Enter / exit element pick mode
ET.togglePane('text')   // Open or close a pane: 'text'|'layout'|'style'|'effects'|'spacing'|'insert'
ET.undo()               // Undo the last change
ET.redo()               // Redo the last undone change
ET.accept()             // Freeze pending changes and open the export popup
ET.erase()              // Clear all inline styles on the selected element
ET.resetAll()           // Restore every element to its page-load state
ET.closePopup()         // Close the export popup
ET.copyChanges()        // Copy the CSS/HTML summary to clipboard

Style Application

ET._a('fontSize', '24px')       // Apply any CSS property to the selected element
ET._gb(btnEl, 'textAlign', 'center')  // Apply + mark button active in its group

Resize

ET._rdStart(mouseEvent, 'br')   // Begin a resize drag from a handle: 'tl'|'tr'|'bl'|'br'|'tm'|'bm'|'ml'|'mr'
ET._szApply()                   // Apply W/H from the layout pane inputs
ET._szApply('100%', null)       // Apply explicit values
ET._setResizeUnit('px')         // Switch resize unit: 'px' or '%'
ET._toggleLock()                // Toggle aspect-ratio lock

Spacing

ET._pi('top', '16')     // Set padding for one side (or all sides if linked)
ET._mi('left', '8')     // Set margin for one side (or all sides if linked)
ET._tl('pad')           // Toggle padding link: 'pad' or 'mar'
ET._bs('dashed')        // Set border style chip active: 'solid'|'dashed'|'dotted'|'none'

Insert / Wrap

ET._itp()               // Activate insert target pick mode
ET._ipos('inside')      // Set insert position: 'inside'|'before'|'after'
ET._ityp('card')        // Set element type to insert
ET._ips(el, 'card')     // Set a preset style chip active
ET._ins()               // Execute the insertion
ET._wrap()              // Wrap all currently multi-selected elements
ET._swt('section')      // Set the wrap tag

Color Pickers

ET._sw(swatchEl, 'bg')  // Click a swatch: 'bg' (background) or 'fg' (text color)
ET._np(inputEl, 'fg')   // Native color picker input changed
ET._ah('bg')            // Apply the hex/rgb value typed into the input

Nudge

ET._nu('up')            // Nudge selected element: 'up'|'down'|'left'|'right'
ET._sn(4)               // Set nudge step size in px

Effects / Filters

ET._sf('blur', '4px')   // Apply a CSS filter function (composes with existing filters)

Configuration

All of the following are single-line changes at the top of the IIFE inside the <script> block.

Accent color

const ACCENT = '#0099fe';

Change this one value to retheme every highlight, slider thumb, focus ring, active button, and bounding box in the toolbar.

Snap threshold

const SNAP_THRESH = 6;

The pixel distance within which a dragged element snaps to a sibling or parent edge. Increase for easier snapping, decrease for more precision.

Selectable elements

Add data-component="Name" to any HTML element. Elements without this attribute are still selectable via pick mode, but won't have a friendly name in the toolbar.

Marking inserted elements

All elements inserted via the Insert pane receive data-et-inserted="1" automatically. The Reset All function uses this attribute to find and remove them.


Contributing

Contributions welcome. Before submitting a PR, please run the validation check described in CONTRIBUTING.md — specifically the syntax and public API coverage tests — since this project has had real regressions caused by missing closing braces and nested template literals that are easy to introduce accidentally.

See CONTRIBUTING.md for the full development guide.


License

MIT — see LICENSE for details.

About

A self-contained floating visual editor toolbar for any web page

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages