Skip to content

Conversation

kaeizen
Copy link
Contributor

@kaeizen kaeizen commented Sep 18, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Stabilized design previews by rendering only when ready and avoiding height jumps during load.
  • New Features

    • Lazy-rendering of library items using intersection-based visibility for smoother scrolling and faster initial load.
  • Style

    • Modal/grid tweaks and container classes to support large/small preview sizes; design items now span full width.
  • Refactor

    • Improved preview scaling and animation scheduling for more responsive, efficient rendering.

Copy link

coderabbitai bot commented Sep 18, 2025

Warning

Rate limit exceeded

@kaeizen has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 24 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between ef9b9a0 and e355456.

📒 Files selected for processing (1)
  • src/components/design-library-list/index.js (2 hunks)

Walkthrough

usePreviewRenderer now requires a hostRef and no longer exposes adjustScale; scaling uses host width and RAF scheduling. DesignLibraryListItem delays rendering until shadowRoot exists and loading is false and stops passing adjustScale. DesignPreview drops the adjustScale prop. IntersectionObserver replaces scroll-based lazy rendering. Two SCSS tweaks added.

Changes

Cohort / File(s) Summary of changes
Hook: scaling & scheduling
src/components/design-library-list/use-preview-renderer.js
Added hostRef param; use hostRect/hostWidth in scaling; adjustScale made internal (signature (force = true)), scheduling moved from timers to requestAnimationFrame with cancellation and cleanup; prevEnableBackgroundRef init changed to null; returned object no longer includes adjustScale.
List item: render gating & hook usage
src/components/design-library-list/design-library-list-item.js
Passes hostRef into usePreviewRenderer; removed exposure/use of adjustScale; getDesignPreviewSize returns 0 when no shadowRoot or loading; rendering gated on shadowRoot && !isLoading; added wrapper .stk-block-design__design-container and conditional stk--design-preview-large / stk--design-preview-small classes.
Preview component: prop cleanup
src/components/design-library-list/design-preview.js
Removed adjustScale prop and mount-side timeout call; component no longer calls adjustScale on mount; other behavior unchanged.
List container: lazy rendering change
src/components/design-library-list/index.js
Replaced scrollTop state/onScroll with IntersectionObserver-based lazy rendering; items use wrapperRef observed against .ugb-modal-design-library__designs with rootMargin: 250px; toggles shouldRender to render placeholder vs real item.
Modal layout: full-pages grid tweak
src/components/modal-design-library/editor.scss
When .ugb-modal-design-library__full-pages is present, .ugb-modal-design-library__designs set to grid-row: 1 / -1 (span full grid rows).
Item layout: width fix
src/components/design-library-list/editor.scss
Added width: 100% to .ugb-design-library-item.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant List as DesignLibraryList
  participant Item as DesignLibraryListItem
  participant Hook as usePreviewRenderer
  participant Host as hostRef
  participant Card as ref
  participant Shadow as shadowRoot
  participant Preview as DesignPreview

  User->>List: opens modal / scrolls
  List->>Item: mount (attach wrapperRef)
  Item->>List: IntersectionObserver reports visibility
  alt not visible and not selected
    Item-->>User: render placeholder
  else visible or selected
    Item->>Hook: init(..., ref, hostRef, shadowRoot, setIsLoading)
    Hook->>Host: read hostRect (hostRef.current)
    Hook->>Card: read cardRect (ref.current)
    Hook->>Hook: schedule adjustScale(force=true) via RAF
    Hook-->>Item: update isLoading / size states
    alt no shadowRoot or isLoading
      Item-->>User: height = 0 (no Preview)
    else ready
      Item->>Preview: render with blocks, shadowRoot, selectedTab, onMouseDown
    end
  end
  Note over Hook: on blocks/content/tab changes -> cancel prior RAF and schedule adjustScale(false)\nCleanup: cancel RAF on unmount
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

I nibble wires, ears held tall,
Frames now hum and timeouts fall.
I measure host and card with glee,
Shadows wait—then set previews free.
Grids align; small hops, big see—🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix (design library): design preview scale adjustment" succinctly and accurately captures the primary change in the diff — fixes to the design preview scaling logic (usePreviewRenderer, adjustScale, and DesignPreview) — and is appropriately scoped to the design library so a reviewer scanning history will understand the main intent.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

github-actions bot commented Sep 18, 2025

🤖 Pull request artifacts

file commit
pr3598-stackable-3598-merge.zip e355456

github-actions bot added a commit that referenced this pull request Sep 18, 2025
github-actions bot added a commit that referenced this pull request Sep 18, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (4)
src/components/design-library-list/use-preview-renderer.js (2)

73-91: Scale guard and width equality check are brittle.

  • Using cardWidth === hostWidth is fragile due to sub‑pixel rounding; minor resizes may never trigger or may thrash.
  • Consider a tolerance or a more direct signal (ResizeObserver on host).

Minimal change:

- if ( ! force && cardWidth === hostWidth ) {
+ if ( ! force && Math.abs(cardWidth - hostWidth) < 0.5 ) {
    return
}

Or switch to ResizeObserver on hostRef.current to drive adjustScale.


321-326: Unmount cleanup — add null check and clear handle.

Minor safety nit: guard cancelAnimationFrame and null the ref (you already do the latter in your proposed fix above).

- cancelAnimationFrame( adjustAnimateFrameRef.current )
- adjustAnimateFrameRef.current = null
+ if (adjustAnimateFrameRef.current != null) {
+   cancelAnimationFrame( adjustAnimateFrameRef.current )
+   adjustAnimateFrameRef.current = null
+ }
src/components/design-library-list/design-library-list-item.js (2)

61-64: Zero height during load — OK; prevents layout flicker.

Ensure the spinner container provides sufficient min-height so the card doesn’t collapse visually.


106-110: Default scale to 1 to avoid invalid CSS during init.

previewSize?.scale can be undefined before the first adjust; scale(undefined) is invalid. Fallback to 1.

- transform: `scale(${ selectedNum && selectedData ? selectedData.selectedPreviewSize.scale : previewSize?.scale })`,
+ transform: `scale(${ selectedNum && selectedData ? selectedData.selectedPreviewSize.scale : (previewSize?.scale ?? 1) })`,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6aad06 and efeef6b.

📒 Files selected for processing (4)
  • src/components/design-library-list/design-library-list-item.js (2 hunks)
  • src/components/design-library-list/design-preview.js (0 hunks)
  • src/components/design-library-list/use-preview-renderer.js (7 hunks)
  • src/components/modal-design-library/editor.scss (1 hunks)
💤 Files with no reviewable changes (1)
  • src/components/design-library-list/design-preview.js
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/design-library-list/design-library-list-item.js (5)
src/components/design-library-list/use-preview-renderer.js (3)
  • usePreviewRenderer (37-349)
  • usePreviewRenderer (37-349)
  • shadowBodySizeRef (63-63)
src/components/design-library-list/index.js (2)
  • previewProps (109-114)
  • previewSize (106-106)
src/components/design-library-list/design-preview.js (3)
  • ref (18-18)
  • DesignPreview (12-91)
  • DesignPreview (12-91)
src/components/design-library-list/use-shadow-root.js (2)
  • hostRef (9-9)
  • shadowRoot (10-10)
src/components/design-library-list/use-auto-scroll.js (2)
  • useAutoScroll (8-147)
  • useAutoScroll (8-147)
src/components/design-library-list/use-preview-renderer.js (2)
src/components/design-library-list/use-shadow-root.js (3)
  • hostRef (9-9)
  • shadowRoot (10-10)
  • useSelect (12-12)
src/components/design-library-list/index.js (2)
  • previewSize (106-106)
  • cardHeight (105-105)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: PHP 8.2 and WP 6.5.5
  • GitHub Check: PHP 8.2 and WP latest
  • GitHub Check: PHP 8.2 and WP 6.7.2
  • GitHub Check: PHP 7.3 and WP 6.5.5
  • GitHub Check: PHP 7.3 and WP latest
  • GitHub Check: PHP 8.2 and WP 6.6.2
🔇 Additional comments (5)
src/components/design-library-list/use-preview-renderer.js (3)

40-41: Signature change to include hostRef and setIsLoading — OK.

Call sites appear updated; no further concerns.


65-65: Initialize prevEnableBackgroundRef to null — OK.

This ensures the first post‑parse adjustment triggers.


344-348: Return shape update — OK.

Removing adjustScale from the public API is consistent with the new scheduling.

src/components/design-library-list/design-library-list-item.js (2)

49-54: Hook result/use invocation updates — OK.

Dropping adjustScale and passing hostRef match the hook changes.


113-118: Gate preview rendering on readiness — OK.

Rendering only when shadowRoot && !isLoading is correct and avoids unnecessary work.

github-actions bot added a commit that referenced this pull request Sep 18, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/components/design-library-list/use-preview-renderer.js (2)

138-140: Stop the infinite rAF loop; only schedule a follow‑up when explicitly forced.

Unconditionally scheduling requestAnimationFrame(() => adjustScale(false)) creates a perpetual loop (even when shouldAdjust is false). Make scheduling conditional on force, guard cancellations, and clear the handle.

Apply:

- cancelAnimationFrame( adjustAnimateFrameRef.current )
- adjustAnimateFrameRef.current = requestAnimationFrame( () => adjustScale( false ) )
+ if ( force ) {
+   if ( adjustAnimateFrameRef.current != null ) {
+     cancelAnimationFrame( adjustAnimateFrameRef.current )
+   }
+   adjustAnimateFrameRef.current = requestAnimationFrame( () => {
+     adjustAnimateFrameRef.current = null
+     adjustScale( false )
+   } )
+ }

295-297: Normalize rAF handling: guard cancels, store handles, and clear on run/cleanup.

  • Guard cancelAnimationFrame calls to avoid passing null.
  • In the [content] effect you don’t store the returned handle, so you can’t cancel it later.
  • Clear handles to null after use and during unmount.

Apply:

- cancelAnimationFrame( adjustAnimateFrameRef.current )
- adjustAnimateFrameRef.current = requestAnimationFrame( adjustScale )
+ if ( adjustAnimateFrameRef.current != null ) cancelAnimationFrame( adjustAnimateFrameRef.current )
+ adjustAnimateFrameRef.current = requestAnimationFrame( adjustScale )
- cancelAnimationFrame( adjustAnimateFrameRef.current )
- adjustAnimateFrameRef.current = requestAnimationFrame( adjustScale )
+ if ( adjustAnimateFrameRef.current != null ) cancelAnimationFrame( adjustAnimateFrameRef.current )
+ adjustAnimateFrameRef.current = requestAnimationFrame( adjustScale )
- cancelAnimationFrame( adjustAnimateFrameRef.current )
- requestAnimationFrame( () => {
-   adjustScale()
-   prevSelectedTabRef.current = selectedTab
- } )
+ if ( adjustAnimateFrameRef.current != null ) cancelAnimationFrame( adjustAnimateFrameRef.current )
+ adjustAnimateFrameRef.current = requestAnimationFrame( () => {
+   adjustAnimateFrameRef.current = null
+   adjustScale()
+   prevSelectedTabRef.current = selectedTab
+ } )
- cancelAnimationFrame( adjustAnimateFrameRef.current )
- adjustAnimateFrameRef.current = null
+ if ( adjustAnimateFrameRef.current != null ) {
+   cancelAnimationFrame( adjustAnimateFrameRef.current )
+   adjustAnimateFrameRef.current = null
+ }

Also applies to: 307-309, 318-323, 325-332

🧹 Nitpick comments (5)
src/components/design-library-list/use-preview-renderer.js (2)

135-135: Replace 500ms timeout with rAF (and clear on cleanup).

The fixed 500ms delay is brittle and can update after unmount. Use rAF and keep a dedicated ref for it.

Apply:

- setTimeout( () => setCardHeight( newCardHeight ), 500 )
+ if ( cardHeightRafRef.current != null ) cancelAnimationFrame( cardHeightRafRef.current )
+ cardHeightRafRef.current = requestAnimationFrame( () => {
+   setCardHeight( newCardHeight )
+   cardHeightRafRef.current = null
+ } )

Also add the ref and cleanup:

- const adjustAnimateFrameRef = useRef( null )
+ const adjustAnimateFrameRef = useRef( null )
+ const cardHeightRafRef = useRef( null )
   return () => {
-    cancelAnimationFrame( adjustAnimateFrameRef.current )
-    adjustAnimateFrameRef.current = null
+    if ( adjustAnimateFrameRef.current != null ) {
+      cancelAnimationFrame( adjustAnimateFrameRef.current )
+      adjustAnimateFrameRef.current = null
+    }
+    if ( cardHeightRafRef.current != null ) {
+      cancelAnimationFrame( cardHeightRafRef.current )
+      cardHeightRafRef.current = null
+    }
   }

61-62: Remove unused state.

hasBackgroundTargetRef is written but never read in this file. Drop it to reduce noise.

src/components/design-library-list/index.js (1)

112-127: Stabilize lazy rendering and avoid global query.

  • Prefer scoping the observer root via closest() to the container instead of document.querySelector.
  • Don’t unrender once rendered to prevent thrash and state loss; flip shouldRender to sticky true.
- const rootEl = document.querySelector( '.ugb-modal-design-library__designs' )
+ const rootEl = wrapperRef.current?.closest?.( '.ugb-modal-design-library__designs' )

- const observer = new IntersectionObserver( ( [ entry ] ) => {
-   setShouldRender( entry.isIntersecting )
- }, {
+ const observer = new IntersectionObserver( ( [ entry ] ) => {
+   setShouldRender( prev => prev || entry.isIntersecting )
+ }, {
src/components/design-library-list/design-library-list-item.js (2)

61-67: Avoid layout jank while loading; keep a stable height.

Returning 0 collapses the container during load. Fall back to the last measured card height (or a sane default).

- if ( ! shadowRoot || isLoading ) {
-   return 0
- }
+ if ( ! shadowRoot || isLoading ) {
+   const key = enableBackground ? 'background' : 'noBackground'
+   return cardHeight?.[ key ] ?? 250
+ }

107-107: Default scale to 1 to avoid invalid CSS.

When previewSize.scale is undefined, scale(undefined) is invalid. Use a neutral fallback.

- transform: `scale(${ selectedNum && selectedData ? selectedData.selectedPreviewSize.scale : previewSize?.scale })`,
+ transform: `scale(${ ( selectedNum && selectedData ? selectedData.selectedPreviewSize.scale : previewSize?.scale ) ?? 1 })`,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between efeef6b and 4dda0a5.

📒 Files selected for processing (4)
  • src/components/design-library-list/design-library-list-item.js (3 hunks)
  • src/components/design-library-list/editor.scss (1 hunks)
  • src/components/design-library-list/index.js (2 hunks)
  • src/components/design-library-list/use-preview-renderer.js (7 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/components/design-library-list/index.js (2)
src/components/design-library-list/design-library-list-item.js (2)
  • props (27-36)
  • DesignLibraryListItem (26-158)
src/components/design-library-list/use-preview-renderer.js (1)
  • props (42-53)
src/components/design-library-list/use-preview-renderer.js (3)
src/components/design-library-list/design-preview.js (1)
  • ref (18-18)
src/components/design-library-list/use-shadow-root.js (3)
  • hostRef (9-9)
  • shadowRoot (10-10)
  • useSelect (12-12)
src/components/design-library-list/index.js (2)
  • previewSize (101-101)
  • cardHeight (100-100)
src/components/design-library-list/design-library-list-item.js (5)
src/components/design-library-list/use-preview-renderer.js (3)
  • usePreviewRenderer (37-354)
  • usePreviewRenderer (37-354)
  • shadowBodySizeRef (63-63)
src/components/design-library-list/index.js (2)
  • previewProps (104-109)
  • previewSize (101-101)
src/components/design-library-list/design-preview.js (3)
  • ref (18-18)
  • DesignPreview (12-91)
  • DesignPreview (12-91)
src/components/design-library-list/use-shadow-root.js (2)
  • hostRef (9-9)
  • shadowRoot (10-10)
src/components/design-library-list/use-auto-scroll.js (2)
  • useAutoScroll (8-147)
  • useAutoScroll (8-147)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: PHP 8.2 and WP latest
  • GitHub Check: PHP 8.2 and WP 6.6.2
  • GitHub Check: PHP 7.3 and WP latest
  • GitHub Check: PHP 8.2 and WP 6.5.5
  • GitHub Check: PHP 7.3 and WP 6.5.5
  • GitHub Check: PHP 8.2 and WP 6.7.2
🔇 Additional comments (4)
src/components/design-library-list/use-preview-renderer.js (1)

73-96: Early‑exit check looks good; confirm host/card pairing.

The height/width equality gate should cut redundant work. Please confirm hostRef always points to the transformed element whose rect reflects the applied scale; otherwise the equality test may misfire.

src/components/design-library-list/editor.scss (1)

30-30: LGTM: make item span full grid width.

width: 100% on the grid item is appropriate and shouldn’t disrupt the existing 1fr columns.

Please sanity‑check on narrow breakpoints to ensure no unintended horizontal scroll appears.

src/components/design-library-list/index.js (1)

37-39: Guard scroll reset.

Avoid potential null deref when containerRef.current isn’t set yet.
[raise_nitpick_refactor]

- containerRef.current.scrollTop = 0
+ if ( containerRef.current ) containerRef.current.scrollTop = 0
src/components/design-library-list/design-library-list-item.js (1)

113-118: Conditional render looks good.

Rendering DesignPreview only when shadowRoot exists and loading is done avoids work and errors.

github-actions bot added a commit that referenced this pull request Sep 18, 2025
github-actions bot added a commit that referenced this pull request Sep 18, 2025
github-actions bot added a commit that referenced this pull request Sep 18, 2025
github-actions bot added a commit that referenced this pull request Sep 18, 2025
@bfintal bfintal merged commit 51e501e into develop Sep 19, 2025
8 of 9 checks passed
@bfintal bfintal deleted the fix/design-library-full-pages-preview branch September 19, 2025 03:36
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.

2 participants