Catalog npm
PACKAGE EXPLORERView in registry

@01.works/layout-overlay

npm

React and framework-independent live layout guide overlays, plus captured layout-map SVG rendering

design-systemdeveloper-toolsgridlayoutlayout-mapoverlayreactsvg
Versions collected5
Direct dependencies7From release 0.3.2
Last observed20 Oct, 21:55 UTC

README

Current package documentation

@01.works/layout-overlay

A development overlay that draws live layout regions and guides over a browser application. The root entry is an SSR-safe React component; the dom subpath is a React-free imperative API for any modern ESM browser application. Neither requires Next.js, Tailwind CSS, or a specific design-token system.

Installation

pnpm add @01.works/layout-overlay

React 18 or newer is required only when importing the root React component. Both @01.works/layout-overlay/dom and ./layout-map are framework-independent and do not import React. The package is ESM-only and does not provide a CommonJS require() entry.

Version 0.3.0 adds the ./dom public subpath. It is a backward-compatible minor release: existing root React and ./layout-map imports retain their public API. Install @01.works/layout-overlay@^0.3.0 (or a later compatible minor) when using ./dom.

Quick start

import {
  LayoutOverlay,
  type LayoutOverlayRegion,
} from "@01.works/layout-overlay";

const regions = [
  { key: "logo", start: 0, end: "var(--logo-end)" },
  {
    key: "navigation",
    start: "var(--nav-start)",
    end: "var(--nav-end)",
    minWidth: "48rem",
  },
] satisfies readonly LayoutOverlayRegion[];

export function DevelopmentTools() {
  return (
    <LayoutOverlay
      enabled={process.env.NODE_ENV === "development"}
      defaultVisible={process.env.NODE_ENV === "development"}
      insetInline="var(--page-margin)"
      regions={regions}
      horizontalGuides={[
        { key: "header", at: "var(--header-height)" },
      ]}
    />
  );
}

Framework-neutral browser usage

Import the dom subpath in vanilla JS, Web Components, Svelte, Vue, or any other modern ESM browser application. It does not pull React into the runtime.

import {
  mountLayoutOverlay,
  type LayoutOverlayRegion,
} from "@01.works/layout-overlay/dom";

const regions = [
  { key: "content", start: "var(--page-margin)", end: "calc(100% - var(--page-margin))" },
  { key: "navigation", start: 320, end: 640, minWidth: "48rem" },
] satisfies readonly LayoutOverlayRegion[];

const overlay = mountLayoutOverlay({
  // Use the build tool's development flag. The overlay is inert in production.
  enabled: import.meta.env.DEV,
  insetInline: "var(--page-margin)",
  regions,
  horizontalGuides: [{ key: "header", at: "var(--header-height)" }],
});

// For a settings panel, live preview, or application teardown:
overlay.setVisible(true);
overlay.update({ verticalGuides: [{ key: "center", at: "50%" }] });
overlay.unmount();

mountLayoutOverlay() is browser-only and performs no import-time DOM work. It returns an idempotent handle. update() shallow-merges options (provided arrays replace prior arrays), setVisible() sets current visibility, and toggle() flips it. element is the current root or null while hidden, disabled, or after unmount(). In this imperative API, visible sets current visibility on mount or update(); it is not a React-style controlled prop.

Keep enabled false in production as a runtime exclusion mechanism. An enabled: false mount creates no overlay DOM, generated style element, or keyboard listener. Bundlers may still retain the imported module; this package does not promise a zero-byte production bundle. For complete bundle exclusion, conditionally import @01.works/layout-overlay/dom from your own development-only integration point.

The package does nothing unless enabled is explicitly set to true. Press the physical G key to toggle the overlay. The shortcut works across keyboard layouts and is ignored while typing, during IME composition, on repeated key events, or when Meta, Control, or Alt is held.

The component ships with a "use client" directive, so it can be imported from Next.js App Router Server Components without an extra client wrapper. It has no import-time side effects and does not read from window during server rendering.

Captured layout maps

Use the framework-independent subpath to turn a captured layout analysis map into a transparent SVG. The output uses document CSS-pixel coordinates, so it can be placed directly over a matching full-page screenshot without rasterizing the guides or labels.

import {
  renderLayoutMapSvg,
  type LayoutAnalysisMap,
} from "@01.works/layout-overlay/layout-map";

const map: LayoutAnalysisMap = await fetch("/layout-map.json").then(response =>
  response.json(),
);

const svg = renderLayoutMapSvg(map, {
  labels: "all",
  layers: { columns: true, rows: true, regions: true },
  maxDepth: 3,
});

labels accepts "all", "guides", or "none". Layers can independently enable columns, rows, regions, layout containers, and floating regions. Invalid document dimensions throw; individual geometry is clamped to the document and identity-bearing text is XML-escaped before rendering. maxGuides, maxRegions, and maxDepth bound work when rendering maps from an external archive. All guide lines remain visible; labels that would collide are suppressed while the first and last boundary labels are retained.

LAYOUT_MAP_RENDERER_VERSION changes when serialized output changes. Include it in cache keys or asset URLs when SVG responses are cached by a browser or CDN. Only layout-map schema version 1 is rendered. The public version field stays numeric for 0.3.x source compatibility, while unsupported values fail closed at runtime instead of being interpreted as version 1.

Responsive guides

Every region and guide accepts minWidth and maxWidth:

<LayoutOverlay
  enabled
  defaultVisible
  verticalGuides={[
    { key: "mobile-center", at: "50%", maxWidth: 767 },
    { key: "desktop-left", at: 320, minWidth: 768 },
    { key: "wide-center", at: "50%", minWidth: "64rem" },
  ]}
/>

Numeric coordinates and widths are converted to pixels. Strings are emitted as CSS values, so rem, %, calc(), and custom properties all work. CSS control tokens are rejected; arbitrary raw media queries are not part of the API.

Region and vertical-guide coordinates follow the logical inline axis; horizontal guides follow the logical block axis. In the usual horizontal writing mode these render as vertical and horizontal guides respectively. Logical coordinates also keep the overlay meaningful in RTL and vertical writing modes.

Controlled React visibility

Use visible and onVisibleChange when another UI owns the state:

const [visible, setVisible] = useState(false);

<LayoutOverlay
  enabled
  visible={visible}
  onVisibleChange={(next) => setVisible(next)}
/>

When visible is omitted, defaultVisible initializes internal state and the keyboard shortcut updates it automatically.

CSS tokens

No stylesheet import is required because every visual value has an inline fallback. Import the optional token entry when the same values should be shared with application CSS:

@import "@01.works/layout-overlay/tokens.css";

:root {
  --layout-overlay-line-color: rgb(0 140 255 / 55%);
  --layout-overlay-band-color: rgb(0 140 255 / 8%);
  --layout-overlay-line-width: 1px;
}

For Tailwind CSS v4, import the Tailwind entry instead. Do not import both:

@import "tailwindcss";
@import "@01.works/layout-overlay/tailwind.css";

This registers bg-layout-overlay-line, bg-layout-overlay-band, w-layout-overlay-line, and h-layout-overlay-line utilities.

API

LayoutOverlay

type CssLength = number | string;

type LayoutOverlayResponsiveRule = {
  minWidth?: CssLength;
  maxWidth?: CssLength;
};

type LayoutOverlayRegion = LayoutOverlayResponsiveRule & {
  key: string;
  start: CssLength;
  end: CssLength;
};

type LayoutOverlayGuide = LayoutOverlayResponsiveRule & {
  key: string;
  at: CssLength;
};
PropTypeDefaultPurpose
enabledbooleanfalseOpt in to rendering and keyboard handling.
defaultVisiblebooleanfalseInitial visibility for uncontrolled usage.
visibleboolean—Controlled visibility.
onVisibleChange(visible, detail) => void—Receives shortcut visibility requests. detail.reason is "shortcut".
regionsreadonly LayoutOverlayRegion[][]Filled inline-axis regions with automatic start/end guides.
verticalGuidesreadonly LayoutOverlayGuide[][]Extra inline-axis guide coordinates.
horizontalGuidesreadonly LayoutOverlayGuide[][]Extra block-axis guide coordinates.
insetInlineCssLength0Insets the logical inline coordinate space.
insetBlockCssLength0Insets the logical block coordinate space.
drawEdgesbooleantrueDraws inline-start and inline-end boundary guides.
lineColorstringCSS tokenOverrides guide colors.
bandColorstringCSS tokenOverrides region fill colors.
lineWidthCssLengthCSS tokenOverrides guide thickness.
zIndexnumber100Sets the root stacking order; must be a safe integer whose +1 is representable for View Transitions.
toggleCodestring | null"KeyG"Matches a physical KeyboardEvent.code.
toggleKeysreadonly string[]['g', 'G', 'ㅎ']Additional KeyboardEvent.key matches.
position"fixed" | "absolute""fixed"Binds the overlay to the viewport or a positioned ancestor.
classNamestring—Customizes the root class.
styleCSSProperties—Adds or overrides root inline styles.
viewTransitionNamestring | nullnullEnables View Transition persistence; use a stable, unique name.
noncestring—Applies a CSP nonce to the generated <style> element.

Set toggleCode={null} and toggleKeys={[]} to disable keyboard toggling.

mountLayoutOverlay

The @01.works/layout-overlay/dom entry exports the same CssLength, LayoutOverlayResponsiveRule, LayoutOverlayRegion, and LayoutOverlayGuide geometry types as independent DOM types. Its options share the visual and keyboard options above, except that target?: HTMLElement replaces React placement and style?: LayoutOverlayDomStyle is a plain record of CSS property names to string values. Use explicit units such as "12px"; numeric custom style values are rejected rather than assigned guessed units.

const handle = mountLayoutOverlay(options);

handle.update({ enabled: true, visible: true });
handle.setVisible(false);
handle.toggle();
handle.unmount();

enabled defaults to false, and defaultVisible defaults to false. target defaults to document.body; use position: "absolute" with a positioned target when the overlay should follow an ancestor rather than the viewport. The default shortcut and editable-target guard are identical to the React component. onVisibleChange is called only for keyboard shortcut changes, with detail.reason === "shortcut".

The rendered DOM is decorative (aria-hidden) and does not receive pointer events. The following attribute names and documented values are public for debugging and consumer styling:

  • data-layout-overlay identifies the root and data-layout-overlay-canvas identifies its coordinate space.
  • data-layout-overlay-key contains the corresponding region or guide key.
  • data-layout-overlay-kind is one of region, region-start, region-end, vertical-guide, horizontal-guide, inline-start-edge, or inline-end-edge.
  • data-layout-overlay-query is an opaque implementation token. Its presence is stable for responsive items, but consumers must not depend on its value.

Content Security Policy

The component renders geometry with inline styles. A nonce can authorize the generated responsive and View Transition rules, but it does not make the package compatible with style-src-attr 'none'. Use the overlay in development or preview environments, or allow inline style attributes in the relevant policy.

Development

pnpm install
pnpm test
pnpm run test:package
pnpm run test:all
pnpm run typecheck
pnpm run lint:package
pnpm pack --dry-run

pnpm test runs the fast, local server and DOM suite without downloading packages. pnpm run test:package installs the generated tarball and React 18 into an isolated consumer project, so it requires package-registry access. pnpm run test:all runs both suites and is used before publishing. The package smoke test verifies JavaScript, declarations, source maps, the "use client" directive, and CSS subpath exports. pnpm run lint:package checks the packed metadata and exports with Publint.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 5

Collected releases
VersionPublishedDirect dependenciesOpen version
0.3.2Registry latest1 Sept 20267
0.3.128 Aug 20267
0.3.027 Aug 20267
0.2.021 Aug 20267
0.1.020 Aug 20267

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
01-office/layout-overlay

Shared repository data · GitHub

License detected in repository
Not collected

Repository

NOT_FOUND
01-office/design-context

Shared repository data · GitHub

License detected in repository
Not collected

Repository

PENDING
01-office/layout

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:55 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:117db4a7a2d2a118d6c0a9505862acdd898716e07a4c4bdd60b4a764b1772fea