Skip to content

feat: CSS Grid UI#5614

Open
kof wants to merge 82 commits intomainfrom
grid
Open

feat: CSS Grid UI#5614
kof wants to merge 82 commits intomainfrom
grid

Conversation

@kof
Copy link
Member

@kof kof commented Feb 12, 2026

Description

  1. What is this PR about (link the issue and add a short description)

Steps for reproduction

  1. click button
  2. expect xyz

Code Review

  • hi @kof, I need you to do
    • conceptual review (architecture, feature-correctness)
    • detailed review (read every line)
    • test it on preview

Before requesting a review

  • made a self-review
  • added inline comments where things may be not obvious (the "why", not "what")

Before merging

  • tested locally and on preview environment (preview dev login: 0000)
  • updated test cases document
  • added tests
  • if any new env variables are added, added them to .env file

@vercel
Copy link

vercel bot commented Feb 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
webstudio-builder Error Error Feb 15, 2026 11:49am

Request Review

kof added 23 commits March 1, 2026 10:22
- Add GridAxisMode type and getGridAxisMode() to analyze grid values
- Add isImplicitGridMode() to detect modes needing DOM probing
- Add isEditableGridMode() to detect modes editable in visual UI
- Add getGridAxisLabel() for consistent label generation
- Refactor grid-generator.tsx to use new pure functions
- Refactor grid-settings.tsx to use new pure functions
- Fix grid-areas.tsx to use parseGridTemplateTrackList
- Update tests to match correct parser behavior
Show '?' for unknown track counts instead of blocking the UI.
Users can still override with explicit grid values.
- Add hover highlighting for column/row tracks and grid areas in canvas
- Move $gridEditingTrack and $gridEditingArea to builder nano-states
- Add TrackHighlight and AreaHighlight components to GridOutlines
- Highlight tracks/areas on hover in addition to when editing
- Add maxHeight constraint to FloatingPanel for bottom-within placement
- Remove auto-open of edit popover when adding new tracks/areas
- Inflate grid containers proportionally to track count (INFLATE_PADDING per cell)
  using --ws-inflate-w/h custom properties with CSS fallback for non-grids
- Detect all-zero tracks in grids with gaps to ensure inflation triggers
- Rewrite grid outline probing: probe per-axis edges, compute line positions
  as midpoints between adjacent track boundaries (centre of gaps)
- On inflated axes always use even-distribution fallback since probed
  positions sit in a tiny content area
- Remove debounceEffect dependency from grid overlay subscriptions;
  use self-contained rAF→rAF scheduling for reliable updates
- Re-evaluate findGridContainer on every style change so display:block→grid
  shows outlines immediately without re-selection
- Apply default 2×2 grid with 16px gap when first switching to grid display
- Extract DEFAULT_GRID_TRACK_COUNT and DEFAULT_GRID_GAP constants
- Prevent removing last grid track in settings (canRemove guard)
…cale\n\n- Replace DOM probe approach with getComputedStyle resolved CSS strings\n- GridCellData now carries resolved template/gap/padding/border/direction strings\n- Builder overlay mirrors grid with CSS transform: scale() instead of manual per-value scaling\n- Grid inflation uses track-level minmax(75px, 1fr) instead of padding\n- CSS rules skip padding for grid containers with inline grid-template overrides\n- Remove ~300 lines of probe/clamp/line calculation code from grid-outlines.tsx
…rchitecture

- Split overlay into positioning parent + canvas mirror child
- Sync user transforms (transform, transformOrigin, scale) to mirror div
- Recover untransformed rect via DOMMatrix inversion of getBoundingClientRect
- Sync display, width, height, boxSizing, borderStyle from canvas
- Add gridTemplateAreas and justifyItems support
- Move contain: strict to outermost container (avoids transform clipping)
- Only remove grid-template overrides from actually-inflated elements
…\nReplace manual matrix math on canvas with a hidden probe element on\nthe builder side. The probe applies the same resolvedCssText at\nposition fixed (0,0) and reads its BCR — the browser handles all\nCSS parsing (variables, units, 3D axes) with zero manual parsing.\n\n- Remove getUntransformedRect (~80 lines) from canvas\n- Canvas now sends raw BCR + offsetWidth/offsetHeight\n- Builder computes transform offset via getTransformOffset probe\n- Works with individual translate/scale/rotate CSS properties\n- GridCellData type: rect → bcr + untransformedWidth/Height
…or of SelectedInstanceOutline: return null when\n$ephemeralStyles is non-empty so grid outlines don't show stale\npositions while the style panel is previewing changes.\n\nAlso fix skewX value not showing in transform editor (\"skewx\" typo\nreplaced with shared extractSkewPropertiesFromTransform extractor).
- Move parseGridAreas to @webstudio-is/css-data with css-tree parser
- Area name conversion: spaces→dashes via toAreaName helper
- Enter key commits value in position inputs (onKeyDown prop)
- Inclusive end mode for area position inputs (display 1,1 not 1,2)
- Fix span=1 producing auto: always emit span N tuple
- Auto mode sets span 1 on all axes instead of auto keyword
- Merged area outlines: single solid border per area, not per cell
- Area labels with textVariants.regular typography
- Highlight uses oklch color with alpha instead of opacity property
Previously grid containers were only inflated when they had zero
children. Adding a single child caused all other empty tracks to
collapse because the grid was no longer a "leaf" element.

Now every grid container on the canvas gets per-track minmax wrapping:
each resolved track value is wrapped with minmax(75px, <resolved>),
guaranteeing every cell at least 75px. This is a builder-only
affordance — preview and published sites use authored values.

- Collect grid containers during element scan regardless of childCount
- New step 5: per-track minmax(75px, <resolved>) wrapping for all grids
- Separate gridInflatedAttribute marker for cleanup
- Simplified clearInflation to handle both marker attributes
…s, gap simulates borders, blue hover on free cells
…\n\nAdd grid-template-rows/columns: 1fr to the html preset so the root\nelement always has defined templates. Move grid default application\nfrom LayoutSectionGrid mount to a display-transition effect that only\nfires when display changes from non-grid to grid on the same instance.\n\nAlso fix grid outlines not restoring after scrubbing position/span\ninputs by calling resetEphemeralStyles() in the appropriate handlers.
kof added 6 commits March 1, 2026 10:40
Grid inflation sets inline grid-template-* on the parent element,
which triggers the MutationObserver watching for style changes.
The observer calls update() → updateInflation() → style change → loop.

Skip mutation batches where every record is a style attribute change
on an element with data-ws-grid-inflated, as these are caused by
the inflator, not by user or React changes.
…ltering

Simpler and agnostic approach — no dependency on inflator internals.
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