Skip to content

Feat/yfm html block experiment#1161

Draft
makhnatkin wants to merge 74 commits into
mainfrom
feat/yfm-html-block-experiment
Draft

Feat/yfm html block experiment#1161
makhnatkin wants to merge 74 commits into
mainfrom
feat/yfm-html-block-experiment

Conversation

@makhnatkin

Copy link
Copy Markdown
Collaborator

No description provided.

makhnatkin and others added 30 commits June 14, 2026 19:35
Add a templates button inside the YfmHtmlBlock node that opens a popup
with a searchable list of templates and an "add" action.

- templates are merged from plugin options and localStorage (localStorage
  overrides by id); adding writes only to localStorage, never to markup
- the add form accepts several <template id title> blocks at once
- selecting a template overwrites the block srcdoc
- new `templates` plugin option: { items, showButton, allowAdd }

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…locks

Replace native HTML5 drag with a pointer-based drag handle so reordering
works reliably over preview HTML; make the handle visible above block
content (z-index, float background, touch-action: none).

Keep user-entered raw HTML verbatim inside the block instead of unwrapping
its root element, so a pasted <div>text</div> stays as
<div class="block-N"><div>text</div></div> on serialization.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a second textarea in the container gear popup for free-form CSS rules
with selectors (.grid {}, .block-1 {}). Rules are scoped to the grid
instance so they never leak to other grids, applied live in the preview
and serialized into a <style> tag inside the html block.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap the menu in both the container-templates and block-insert popups in
a scrollable container (max-height) so a long list of templates no longer
overflows the viewport; the search field stays pinned above it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tyles

Replace inline CSS everywhere with a single selector-based model. The
container gear has one CSS field (.grid {}, .block-1 {}); the block gear
keeps HTML + a CSS field where & targets the block root and other
selectors are scoped under it. All rules are scoped to the instance and
emitted into a <style> tag instead of style="" attributes; templates
convert their inline style to rules on insert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
makhnatkin and others added 27 commits June 21, 2026 21:23
Layer the stacked card so the closer sheet sits above the farther one and
both stay behind the preview, keeping a stable order on hover. Highlight the
whole stack's border (preview + sheets) on hover.

Co-authored-by: Cursor <cursoragent@cursor.com>
… a marketplace cover

A structure is now strictly a layout container: any non-block markup inside a
structure template is discarded during parsing, and the structure starts empty
with its blocks providing all content. The Gravity UI landing intro is moved
from structure content into a dedicated block.

Family templates now capture their inner HTML/CSS, used as the family cover in
the external templates marketplace (never rendered by the editor).

Co-authored-by: Cursor <cursoragent@cursor.com>
…de editor

The block HTML editor now renders the spec wrapper div
(`<div class="g-md-hc-block g-md-hc-block-N">` and `</div>`) as greyed-out,
non-editable first and last lines, with the editable markup in between. The CSS
editor stays fully editable. The framed HTML pane shares one scroll area with an
auto-growing textarea so the wrapper lines and line numbers stay aligned.

Co-authored-by: Cursor <cursoragent@cursor.com>
…he popup

The structure panel's theme picker renders in a portal outside the toolbar, so
the panel's outside-pointerdown handler closed the panel before the theme
button's click fired, dropping the insertion. Treat any element carrying the
constructor stop class (portaled popups included) as inside.

Co-authored-by: Cursor <cursoragent@cursor.com>
The Import button showed the export glyph (ArrowUpFromSquare); switch it to the
matching import glyph (ArrowDownToSquare).

Co-authored-by: Cursor <cursoragent@cursor.com>
…ure panel

Replace the old menu-style block insert popup with a panel that mirrors the
structure picker: searchable, family groups, live scaled previews, a Custom HTML
entry, and a hover popup with the block's state/theme variants. Extract the
shared shadow-DOM LivePreview so both pickers reuse it.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ditor

The structure code editor now renders the complete document — its own content
plus every block's markup — inside a locked g-md-hc-structure frame, with all CSS
combined. Everything inside the frame is editable; on commit the inner markup is
split back into structure content + blocks (preserving block identity by position),
and CSS is consolidated into the structure stylesheet. Structure edits commit on
blur to avoid fighting the cursor with re-assembled values.

Co-authored-by: Cursor <cursoragent@cursor.com>
…h icon

Co-authored-by: Cursor <cursoragent@cursor.com>
… picker

A "Custom structure" button opens an inline HTML + CSS editor; on insert it
applies a fresh structure built from the entered markup and styles (clearing any
existing blocks), mirroring the block picker's custom HTML flow.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the block picker's "Custom HTML" single-field entry with a "Custom block"
editor that has separate HTML and CSS inputs, matching the custom structure flow.

Co-authored-by: Cursor <cursoragent@cursor.com>
…one component

Extract the shared picker UI (header, search, custom HTML/CSS editor, collapsible
family groups, preview cards with a stacked variants popup) into a single
configurable TemplatePickerPanel driven by a normalized card model. The structure
and block panels are now thin wrappers that map their templates to cards and pass
picker-specific labels, extra editors (template import) and actions.

Co-authored-by: Cursor <cursoragent@cursor.com>
…heme

Replace the legacy dropdown menus on an existing block (and the structure
theme switch) with the unified card picker. The state button now uses a
sliders icon and is disabled when the block has no related states; the
theme switch stays disabled when no themes are available. The picker gained
optional search/custom slots, flat (header-less) groups and active-card
highlighting; preview building moved to shared blockUtils helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
… animation

Raise the drag handle above the toolbar and content so it is never covered,
give it more corner padding and a hover elevation, and animate the dragged
block with a subtle scale, lift shadow and fade.

Co-authored-by: Cursor <cursoragent@cursor.com>
…amed HTML scroll

Introduce a localStorage-backed preferences store shared across every HTML
constructor instance on the page, and bind the code editor's "compact view"
toggle to it so the choice is remembered instead of resetting each time.

Fix the framed (structure) HTML pane not scrolling: lay its gutter and stack
out at natural height so the body becomes the scroll container.

Co-authored-by: Cursor <cursoragent@cursor.com>
…are clearable

The bundled "Gravity UI" family was passed as static `templates.items`, while
the picker's "Clear all templates" button only looks at localStorage — so it
was always disabled and could never remove them. Seed the defaults into storage
once (guarded by a flag) and drop the static items, so the whole list is read
from localStorage and the clear button can delete it.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ng contract

Quick-style controls (background, text color, rounding, border) now serialize
as CSS custom properties instead of concrete properties, so user-authored
themes can react to them. Each aspect has light/dark companions
(--g-md-hc-<name>-light/-dark) resolved for the active Gravity UI theme, with a
fallback chain: toolbar override -> theme companion -> neutral default.

The contract stylesheet is injected in output markup and template previews; the
editor consumes the same variables via SCSS (keeping chrome fallbacks). Adds a
theming doc describing the contract for theme authors.

Co-authored-by: Cursor <cursoragent@cursor.com>
Adds a `scopeStyles` option that isolates each constructor's generated CSS by
wrapping it in a unique class derived from the node's (persisted) entity id and
prefixing the per-instance rules with it. This prevents styles from one
constructor leaking into another on the same page. The generic contract
stylesheet stays unscoped (it is identical per instance).

Off by default; enabled in the demo for evaluation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the bulky 40px edit button that overlapped the text with a compact
28px circular brand badge pinned to the highlight's top-right corner, refine
the highlight outline (softer ring, rounded), add subtle pop-in animations,
and give the inline textarea a matching focus ring.

Co-authored-by: Cursor <cursoragent@cursor.com>
Move the drag ghost's dim and scale onto the block body instead of the
whole item, so the floating toolbar (a sibling) no longer inherits the
reduced opacity and scale during drag.

Co-authored-by: Cursor <cursoragent@cursor.com>
Measure the code body and keep numbering the gutter for the rows that
fit below the last line, and stretch the framed gutter to the body
height, so short snippets no longer leave a blank, numberless gap.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a reusable confirmation dialog and guard overwriting/removing
actions with it: applying a structure over existing content, switching a
block's state (which overwrites its content), deleting a block or the
whole constructor, and clearing all stored templates. Applying a
structure into an empty constructor still inserts without a prompt.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ructor

Cloning a block now also rewrites element ids inside its HTML (and their
href/for/aria references), and duplicating a constructor refreshes the
structure content ids alongside the already-fresh entity id and block
ids, so a copy never collides with the original's ids/scope hash on the
same page.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the in-place textarea/input editors (which resized the content
and made it jump) with a popup anchored to the hovered element. The
underlying text/link/image node is mutated in place on save, so editing
no longer shifts the layout and keeps the element's other attributes.

Co-authored-by: Cursor <cursoragent@cursor.com>
During a drag the hover state is lost, leaving the floating toolbar
stuck half-faded and shifted. Hide it outright while the block is the
moving ghost (it returns on hover after drop).

Co-authored-by: Cursor <cursoragent@cursor.com>
…+Enter

Enter now commits the inline text edit; Shift+Enter inserts a line break
in the multiline editor.

Co-authored-by: Cursor <cursoragent@cursor.com>
… styles, container defaults

Universal inline editing: any element is editable through one popup that shows
its text (when present) plus all attributes under a collapsible section.
Images, video and large SVG become attributes-only; SVG icons (<=50px) keep the
glyph picker. The hook and icon set are extracted into useInlineHtmlEditing and
iconLibrary, shrinking HtmlBlockItem.

Theme-aware quick-style palette: background and text color are now per light/dark
theme, serialized as the --g-md-hc-<name>-light/-dark companions. The floating
toolbar adds a Light/Dark toggle, defaults to the active editor theme and
previews the selected theme's color.

Container-provided defaults: the constructor contract resolves each -current
variable as override -> theme companion -> a theme-aware Gravity UI default, so
templates read var(--g-md-hc-<name>, var(--g-md-hc-<name>-current)) without
carrying any fallback of their own.

Co-authored-by: Cursor <cursoragent@cursor.com>
…inside the block

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @makhnatkin, your pull request is larger than the review limit of 150000 diff characters

@gravity-ui

gravity-ui Bot commented Jun 24, 2026

Copy link
Copy Markdown

🎭 Playwright Report

@gravity-ui

gravity-ui Bot commented Jun 24, 2026

Copy link
Copy Markdown

Storybook Deployed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant