v2.0.0-beta.2 — React-parity custom UI + demo polish - #19
Merged
Conversation
Add nine <gjs-*-provider> components mirroring @grapesjs/react's render-props surface (blocks, layers, selectors, styles, traits, pages, devices, assets, modal), a <gjs-canvas> custom-UI mount point, and the *gjsContainer directive for projecting GrapesJS-owned elements. Editor component gains async CDN plugin loading, editorCreated/projectUpdated outputs, grapesjsCss/waitReady inputs, SSR safety, and a height/width:100% host-fill default. Service adds isInitialized; editorReady now fires on onReady() (breaking vs beta.1). Selectors and Styles providers self-trigger their initial custom event on wire() so their panels render in custom-UI mode, where GrapesJS skips the default panel render that would otherwise fire it.
Rework the demo to showcase every provider with a full custom editor shell (pages, blocks with drag ghost, layers tree, selectors, styles, traits, assets/modal overlays) alongside the default-UI mode. Layers rows now select via editor.select(component) — a GrapesJS Component has no .select() method, so the previous call threw at runtime. Raise anyComponentStyle budget to fit the demo stylesheet; rename the private workspace package to grapesjs-angular-workspace.
Tokenized design-system spec (light/dark) and the interactive editor-chrome mockup it derives from, as the visual source of truth for the demo redesign.
…les.css One :root token set (surfaces, text, lines, accent, selection, status, shadow, type, radii) plus a [data-theme=dark] override, defined after the grapes.min.css import so overrides win. Sets global body background/color/font. Nothing consumes the accent/panel tokens yet — wired in following commits.
UI in Inter, mono surfaces (IDs, selectors, style values, HTML export) in JetBrains Mono, per the redesign spec. preconnect + display=swap.
Toolbar icon button (inline sun/moon) flips data-theme on documentElement so both custom rails and the GrapesJS panels inherit it. Initial theme = saved choice, else OS prefers-color-scheme; persisted to localStorage. Editor logic untouched.
Toolbar gains a clear action hierarchy (Get HTML primary / Save secondary / Reset quiet-destructive) and a token-styled device select. Every custom-rail surface (panels, page list with accent active-bar, block tiles, layer tree, selector chips, state/trait controls, read-only style list, drag ghost, drop indicator, asset/modal overlays, HTML export) now maps to tokens — zero hardcoded hex, #0f0 and #276ef1 gone, and the .property-list !important pile-up is removed via scoping. Adds focus-visible rings and a prefers-reduced-motion guard.
Map the engine's --gjs-* variables (verified against the installed build) onto our design tokens so they re-resolve on theme flip, plus minimal scoped .gjs-* overrides for the colours GrapesJS hardcodes (panel/title/field borders, canvas selection badge -> --select). Flipping Custom <-> Default in either light or dark now reads as one product — no stock-grey panels.
Replace the single Custom/Default button with a real 2-segment control, and the bare <pre> export with a slide-up dock (header + HTML pill + Copy + close) on a panel surface. Reuses existing editor logic via a thin setCustomUi(boolean) and a copyHtml() clipboard helper. Slide animation respects prefers-reduced-motion.
… drops Each Custom<->Default toggle recreates the gjs-editor, and onEditorReady was unconditionally re-seeding the sample, wiping edits. Now snapshot the project on switch (setCustomUi) and restore it in the new instance; seed the sample only on first load and on Reset. Also select the dropped component on block:drag:stop so its styles/traits populate without a second click. Verified: a component added in one mode survives the switch (and back) into the recreated editor.
The custom-UI right rail was read-only, so the State dropdown had nothing to affect. Each style property now renders an editable control (select for select/radio types via getOptions, text input otherwise, read-only value for composite/stack shorthands), bound to property.upValue(). Editing drives the canvas; switching State now writes state-specific rules (e.g. :hover). Selectors panel gets a mono targets readout, styled chips, a labeled State field, and a proper empty state. Both panels gate on the current selection. Verified live: editing font-size/text-align updates the canvas; selecting hover state + editing creates a :hover rule.
Render each block's own GrapesJS media SVG as the tile icon (fill=currentColor, so it themes), memoized per block id through DomSanitizer. Block tiles become icon-over-label, matching the reference mockup.
…ock icon In custom-UI mode the block drag ends via sorter:drag:end, NOT block:drag:stop (which the cleanup was listening for). So dragging never reset: the source button stayed dimmed/'active', the floating ghost stuck at a stale position (looking like 'no ghost' on later drags), and the drop never auto-selected. Clean up on sorter:drag:end instead, and auto-select the dropped element via component:add while the drag is active. The ghost now carries the block's icon so it's clearly visible as you drag. Verified via the editor event lifecycle: block:drag:start sets dragging; a component added mid-drag auto-selects; sorter:drag:end resets dragging/label/icon.
Layers: filter out non-layerable nodes (textnodes that surfaced as meaningless 'Box' rows), mirroring GrapesJS's own layer manager. Verified: 0 'Box' rows remain. Drag: drop the demo's full-canvas 'DROP HERE' overlay (it covered the real indicator and the badge sat centered, not at the cursor). Rely on GrapesJS's own .gjs-placeholder — a precise insertion line at the drop point — themed to --accent in global styles.css. The floating ghost (icon + label) still follows the cursor.
…, selects) The right rail was a wall of identical text/select boxes. Drive it from a curated styleManager (Typography / Background / Spacing) so each property is the right control: range sliders with value readout (font-size, line-height, padding, margin), colour swatches (color, background-color), a segmented control (text-align), and selects for true enums (font-weight). Small typed helpers wrap GrapesJS's dynamic Property API (slider unit handling, colour->hex, options). Applies to both custom and default UI. Verified live: the font-size slider updates the canvas (with unit), and the segmented text-align sets alignment.
The .gjs-pn-devices-c panel is 44px but the canvas starts at 40px (--gjs-canvas-top), so its bottom edge bled into the canvas. Pin the panel to the bar height and center the dropdown within it (bottom now 5px clear of the canvas).
The REDESIGN-SPEC and mockup were process artifacts for the demo re-skin, not part of the demo app or the published library.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v2.0.0-beta.2
Second beta. Headline is the React-parity custom-UI provider system — the library now mirrors the
@grapesjs/reactcomponent model so consumers can build a fully bespoke editor shell in Angular templates.Library (ships to npm)
<gjs-*-provider>components for pages, blocks, layers, selectors, styles, traits, devices, assets, modal; plus<gjs-canvas>and thegjsContainerdirective.Selectors/Stylespanels now render in custom mode (__trgCustom()on wire — custom mode skips the default panel render where the engine's initial event fires).vitest run),build:libclean.Demo (does not ship to npm)
.gjs-placeholdershows the real insertion point.Release mechanics
pages.ymldeploys the demo.v2.0.0-beta.2→publish.ymlpublishes to npm under thebetadist-tag (Trusted Publishing).