# FooBox Gutenberg Modernization

This document captures the implementation decisions for making FooBox usable from the block editor without hand-written Custom HTML blocks.

## Goals

- Let users configure FooBox from native block inspector controls.
- Prefer extending familiar core blocks over requiring new custom blocks for every use case.
- Save normal WordPress block markup with FooBox attributes, so content remains readable and portable.
- Avoid requiring users to add selectors such as `.foobox.wp-block-button a` to the "Specific CSS classes" setting.
- Let FooBox take over core Image/Gallery blocks when users choose WordPress's "Open in lightbox" option.
- Keep runtime JavaScript changes in the client source and copy built assets into the plugin.

## Core Block Strategy

### Button

The Button block is the primary visual trigger for non-image content. The FooBox panel can turn the button into a lightbox trigger and set:

- content type: image, HTML, iframe, video, or auto
- width and height
- poster image for self-hosted videos
- style, theme, and opening effect
- caption title and description
- gallery group

The saved output keeps the normal `core/button` wrapper, adds `foobox` and `data-foobox-trigger="button"` to the wrapper, and writes runtime attributes such as `target="foobox"` and `data-width` to the inner link.

FooBox already initializes anchors inside a `.foobox` wrapper, so this removes the need for a custom selector like `.foobox.wp-block-button a`.

### Image

The Image block remains the main single-image workflow. Users still choose or upload an image visually. The FooBox panel adds style, theme, effect, captions, group, and panning controls. The saved figure receives FooBox wrapper attributes, while link-specific attributes are added to the inner anchor when present.

When the "WordPress Lightbox" compatibility setting is enabled, Image blocks with `lightbox.enabled` are converted to FooBox. The editor sets `fooboxEnabled`, switches the image to `linkDestination: "media"`, and disables the core block lightbox to avoid duplicate overlays. The frontend render filter repeats this conversion as a fallback for existing content.

### Gallery

The Gallery block remains the multiple-image workflow. Users build the gallery visually using core media tools. FooBox controls live on the Gallery block, but the editor mirrors those settings onto the nested Image blocks before save. This preserves WordPress's native nested Gallery markup and avoids breaking inner image serialization.

The client runtime is updated to support `data-foobox-group`. This gives block-editor gallery images an explicit grouping mechanism without relying on the legacy global REL Grouping setting.

When the "WordPress Lightbox" compatibility setting is enabled, Gallery blocks with `linkTo: "lightbox"` are converted to FooBox by switching the Gallery to `linkTo: "media"`, assigning a FooBox group, and mirroring FooBox attributes to each child Image block.

### Group

The Group block becomes the visual hidden HTML-content container. Users can place normal blocks inside it, including Shortcode blocks for forms and FooGallery shortcodes. The FooBox panel can:

- assign an HTML id
- hide the group on the front end
- mark it as FooBox inline content

A Button block can then point to `#that-id` and use the HTML content type.

## Content Types Covered

- Single image: Image block with FooBox enabled.
- Multiple images: Gallery block with FooBox enabled.
- HTML content: hidden Group block plus Button trigger.
- YouTube video: Button trigger linking to a YouTube URL.
- Self-hosted video: Button trigger linking to an uploaded video URL.
- HTML content with a form: hidden Group block containing a Shortcode block.
- Iframe: Button trigger with iframe content type and external URL.
- FooGallery shortcode: hidden Group block containing a Shortcode block.
- Large image with panning: Image block with panning enabled.

## Editor UX Rules

- Controls live in a "FooBox" inspector panel.
- A single "Enable FooBox" toggle reveals advanced controls.
- Fields use `@wordpress/components` primitives and native Gutenberg controls.
- The saved markup is deterministic and does not require Custom HTML blocks.
- Empty optional settings are not serialized into markup.
