Skip to content

Support grid layouts in the STACK flow element - #4365

Merged
DonOmalVindula merged 1 commit into
thunder-id:mainfrom
DonOmalVindula:fix/3703-stack-grid-layout
Jul 28, 2026
Merged

Support grid layouts in the STACK flow element#4365
DonOmalVindula merged 1 commit into
thunder-id:mainfrom
DonOmalVindula:fix/3703-stack-grid-layout

Conversation

@DonOmalVindula

@DonOmalVindula DonOmalVindula commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Purpose

Resolves the inability to arrange STACK children (e.g. action buttons) in a grid at runtime. A flow defining a STACK with four buttons could only render as a strict flex row or column, while the flow builder canvas already previewed grid layouts via the items property. This PR makes the runtime renderer honor items and gives the property one consistent meaning across the builder, the Gate, and the React SDK.

items is the number of slots across the main axis, and direction picks that axis:

direction items 4 children render as
row (default) 2 2 x 2 grid
row 3 3 columns, remainder on the next row
column 2 2 rows, children flow into further columns

Not a breaking change. Grid mode requires items >= 2. Stacks with items: 1 (which the builder seeds on every stack it creates) or no items at all keep their existing flex layout, so previously authored flows render exactly as before.

Approach

  • Added a shared getStackGridSx helper in @thunderid/design, used by both the runtime renderers and the console flow builder canvas, so the builder preview and the Gate can no longer drift apart.
  • Wired it into all three runtime STACK render sites (standalone StackAdapter, and the form and trigger block paths in BlockAdapter, which previously duplicated the layout mapping inline).
  • items is parsed defensively from the SDK's string | number type: malformed values ("2invalid"), zero, and negatives fall back to flex, and the slot count is clamped so a mistyped value cannot render thousands of cells.
  • Builder placeholders now fill the trailing cells of a partially filled last row, so every grid cell is a drop target.
  • Also fixes classes being dropped on STACKs nested inside BLOCKs.
  • Property panel: direction, align and justify gain searchable suggestions while staying free text. This is implemented as an optional suggestions prop on the existing TextPropertyField, so those fields keep the dynamic-value (fx) button, inline validation errors, label placement, and debounce handling that every other property field has.
  • No backend or SDK type changes needed: the backend passes element meta through verbatim, and EmbeddedFlowComponent.items already exists in the SDK.

A companion fix for the @thunderid/react SDK's own renderer (AuthOptionFactory) is submitted to thunder-id/javascript-sdks.

Related Issues

Related PRs

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (Add links if there are any)
    • Ran Vale and fixed all errors and warnings
  • Tests provided. (Add links if there are any)
    • Unit Tests
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.

Security checks

  • Followed secure coding standards in WSO2 Secure Coding Guidelines
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

Summary by CodeRabbit

  • New Features

    • Stack layout now supports CSS grid rendering when an item count is set, including row/column direction behavior and grid spacing/alignment.
    • Layout property autocomplete was added for stack direction/align/justify.
    • Added “Add Field”/“Add Component” controls for containers, including nested stack containers.
  • Bug Fixes

    • Improved grid/flex fallback when item counts are missing/invalid/1, including corrected placeholder behavior.
    • Actions inside grid stacks now trigger the correct identifiers.
  • Tests

    • Expanded coverage for grid/flex rendering, placeholder logic, autocomplete interactions, action wiring, and nested addition behavior.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

STACK rendering now uses shared grid utilities and StackContainer for grid-or-flex behavior. Console adapters support stack-specific insertion and placeholders, property panels provide layout suggestions, and recursive element insertion supports nested containers. Builder panel body spacing is also updated.

Changes

STACK layout rendering

Layer / File(s) Summary
Grid layout contract and container
frontend/packages/design/src/utils/getStackGridSx.ts, frontend/packages/design/src/components/flow/adapters/*, frontend/packages/design/src/index.ts, frontend/packages/design/src/utils/__tests__/*
Parses valid items values, generates direction-aware grid styles, and preserves flex rendering when grid configuration is unavailable.
Adapter integration
frontend/packages/design/src/components/flow/adapters/*, frontend/apps/console/src/features/flows/components/resources/elements/adapters/*
Uses shared stack rendering, updates grid placeholders, and adds container-scoped add-component and add-field menus.
Layout property autocomplete
frontend/apps/console/src/features/flows/components/resource-property-panel/*
Adds suggested free-text values for layout properties, dynamic-value gating, and tests for selection, custom input, and fallback behavior.
Nested container insertion
frontend/apps/console/src/features/flows/components/steps/view/*, frontend/apps/console/src/features/login-flow/hooks/useElementAddition.ts
Treats forms and stacks as containers and recursively appends selected elements to nested targets.
Renderer and layout validation
frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx
Tests grid dimensions, invalid-item fallback, action wiring, row flow, justification, standalone stacks, and custom classes.

Builder panel spacing

Layer / File(s) Summary
Panel body spacing
frontend/packages/components/src/lab/components/BuilderLayout/BuilderStaticPanel.tsx
Moves padding from the drawer paper to the body and makes top spacing conditional on header presence.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FlowComponentRenderer
  participant StackContainer
  participant getStackGridSx
  participant FlowChild
  FlowComponentRenderer->>StackContainer: render STACK component
  StackContainer->>getStackGridSx: parse items and derive styles
  getStackGridSx-->>StackContainer: grid styles or null
  StackContainer->>FlowChild: render nested children and actions
  FlowChild-->>FlowComponentRenderer: dispatch selected action or submit
Loading

Possibly related PRs

  • thunder-id/thunderid#3859: Updates stack rendering to apply component.classes, overlapping with class handling in StackContainer.

Suggested reviewers: brionmario, thamindudilshan

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the primary change: adding grid layout support for STACK flow elements.
Description check ✅ Passed The description matches the template well, with Purpose, Approach, Related Issues, Related PRs, Checklist, and Security sections filled in.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx`:
- Around line 324-325: Update the gridColumnCount helper in
FlowComponentRenderer tests to parse the repeat() count from gridTemplateColumns
rather than counting whitespace-separated tokens. Ensure repeat(3, 1fr) produces
a column count of 3 and preserve the helper’s numeric return behavior.

In `@frontend/packages/design/src/components/flow/adapters/StackContainer.tsx`:
- Around line 29-31: Update coerceItems so string inputs are accepted only when
the entire value represents a valid number, rather than relying on parseInt’s
partial parsing; malformed values such as “2invalid” must return the existing
flex fallback of 1, while valid numeric values continue through finite-number
validation and flooring.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e5aa8e0-ecc3-4768-8f0a-76c0a3499a5f

📥 Commits

Reviewing files that changed from the base of the PR and between ced4efc and 6f753e2.

📒 Files selected for processing (4)
  • frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx

Comment thread frontend/packages/design/src/components/flow/adapters/StackContainer.tsx Outdated
@DonOmalVindula
DonOmalVindula force-pushed the fix/3703-stack-grid-layout branch 2 times, most recently from 8cff9b3 to f73b3b0 Compare July 27, 2026 05:19
@DonOmalVindula DonOmalVindula added the trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes label Jul 27, 2026
@DonOmalVindula
DonOmalVindula force-pushed the fix/3703-stack-grid-layout branch from f73b3b0 to 9223917 Compare July 27, 2026 07:05
@DonOmalVindula DonOmalVindula changed the title Support grid layouts in the runtime STACK renderer Support grid layouts in the STACK flow element Jul 27, 2026
@DonOmalVindula DonOmalVindula added trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes and removed trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes labels Jul 27, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx (1)

183-193: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

emptySlotCount only accounts for the first row, undercounting empty cells in later rows.

let emptySlotCount: number; if (useGrid) { emptySlotCount = Math.max(0, (items ?? 0) - filteredComponents.length); } else { emptySlotCount = filteredComponents.length === 0 ? 1 : 0; }

With items=2 and 3 children (2 filled in row 1, 1 in row 2), this yields max(0, 2-3)=0, hiding the empty cell in row 2 that the comment above says should show a "Drop here" placeholder. The bug only surfaces when child count exceeds items and isn't an exact multiple — exactly the multi-row auto-flow scenario this PR introduces — and isn't covered by the current tests (items: 1, or items absent).

🐛 Proposed fix accounting for a partially-filled last row
   let emptySlotCount: number;
   if (useGrid) {
-    emptySlotCount = Math.max(0, (items ?? 0) - filteredComponents.length);
+    const columns = items ?? 1;
+    const totalCells = Math.ceil((filteredComponents.length || columns) / columns) * columns;
+    emptySlotCount = Math.max(0, totalCells - filteredComponents.length);
   } else {
     emptySlotCount = filteredComponents.length === 0 ? 1 : 0;
   }

Want me to add a regression test for items=2 with 3/5 children to lock this in?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx`
around lines 183 - 193, Update the useGrid branch calculating emptySlotCount in
StackAdapter so it accounts for every partially filled final row, not just total
capacity minus all children. Preserve zero placeholders for completely filled
rows, add the remaining cells needed to complete the last row when
filteredComponents.length is not divisible by items, and retain the existing
flex-mode behavior.
frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx (1)

179-180: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Em dash used in code comments across two files — violates the repo's punctuation guideline. As per coding guidelines, **/*: "Do not use em dashes (—) or double hyphens (--) in copy or UI strings, including i18n locale content; use a comma, period, or rephrasing instead." All three sites use "—" in an inline comment; replace with a period/comma or rephrase.

  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx#L179-L180: reword "STACK is a pure layout container — render it in place..." to drop the em dash.
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx#L398-L399: reword "Actions may sit inside STACK layout containers — look through them..." to drop the em dash.
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx#L183-L184: reword "always fill defined slots — show placeholders for every unoccupied slot" to drop the em dash.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx`
around lines 179 - 180, Remove the em dash from the inline comments at
frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx lines
179-180 and 398-399, and
frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx
lines 183-184. Rephrase each comment using a period, comma, or equivalent
wording while preserving its meaning.

Source: Coding guidelines

🧹 Nitpick comments (1)
frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/StackAdapter.test.tsx (1)

159-186: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add coverage for multi-row grids with a partial last row.

These tests only cover items: 1 and items absent. Neither exercises items >= 2 with a child count that isn't an exact multiple (e.g., items: 2 with 3 children), which is the scenario where the emptySlotCount calculation in StackAdapter.tsx undercounts empty placeholders (see comment on that file).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/StackAdapter.test.tsx`
around lines 159 - 186, The Grid mode tests in StackAdapter.test.tsx lack
coverage for a multi-row grid with a partially filled final row. Add a test
using items: 2 and three children, render StackAdapter, and assert the rendered
children plus the expected empty “Drop here” placeholder count based on the
remaining slot in the final row.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx`:
- Line 196: Update the flexDirection fallback in StackAdapter so an omitted
stackElement.direction defaults to 'column', matching StackContainer’s runtime
default while preserving explicitly provided directions.

In `@frontend/packages/design/src/components/flow/adapters/StackContainer.tsx`:
- Around line 34-58: Align the defaults used by getStackGridSx with
StackContainer’s flex branch: an unset direction must produce a column-oriented
layout, while unset align and justify must match center and flex-start. Update
the grid-style generation in getStackGridSx, preserving explicit direction,
align, and justify values so enabling items does not otherwise alter layout.

In `@frontend/packages/design/src/utils/getStackGridSx.ts`:
- Around line 44-50: Update parseStackItems so single-item values are rejected
by changing the minimum accepted slots threshold from 1 to 2, preserving flex
layout for values below 2 and returning undefined for them.

---

Outside diff comments:
In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx`:
- Around line 183-193: Update the useGrid branch calculating emptySlotCount in
StackAdapter so it accounts for every partially filled final row, not just total
capacity minus all children. Preserve zero placeholders for completely filled
rows, add the remaining cells needed to complete the last row when
filteredComponents.length is not divisible by items, and retain the existing
flex-mode behavior.

In `@frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx`:
- Around line 179-180: Remove the em dash from the inline comments at
frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx lines
179-180 and 398-399, and
frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx
lines 183-184. Rephrase each comment using a period, comma, or equivalent
wording while preserving its meaning.

---

Nitpick comments:
In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/StackAdapter.test.tsx`:
- Around line 159-186: The Grid mode tests in StackAdapter.test.tsx lack
coverage for a multi-row grid with a partially filled final row. Add a test
using items: 2 and three children, render StackAdapter, and assert the rendered
children plus the expected empty “Drop here” placeholder count based on the
remaining slot in the final row.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7045e0e4-e8a8-4a81-b152-4003c84bc2ca

📥 Commits

Reviewing files that changed from the base of the PR and between 6f753e2 and 9223917.

📒 Files selected for processing (11)
  • frontend/apps/console/src/features/flows/components/resource-property-panel/CommonElementPropertyFactory.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/__tests__/CommonElementPropertyFactory.test.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/StackAdapter.test.tsx
  • frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx
  • frontend/packages/design/src/index.ts
  • frontend/packages/design/src/utils/__tests__/getStackGridSx.test.ts
  • frontend/packages/design/src/utils/getStackGridSx.ts

Comment thread frontend/packages/design/src/utils/getStackGridSx.ts
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

@DonOmalVindula
DonOmalVindula force-pushed the fix/3703-stack-grid-layout branch from 9223917 to 549243f Compare July 27, 2026 08:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx`:
- Line 436: Update the existing track-count helper in FlowComponentRenderer
tests to accept a template string and correctly parse repeat expressions such as
repeat(2, 1fr). Replace the rows assertion’s whitespace-based split with this
helper, and reuse the same helper for both grid columns and rows.

In `@frontend/packages/design/src/utils/getStackGridSx.ts`:
- Around line 41-49: Update the JSDoc for parseStackItems to accurately state
that finite numeric inputs are floored before validating they produce at least
one slot, matching the current implementation and tests where 2.7 becomes 2. Do
not change the parser behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 60312460-e359-4cf5-a818-9dbb28e166c7

📥 Commits

Reviewing files that changed from the base of the PR and between 9223917 and 549243f.

📒 Files selected for processing (11)
  • frontend/apps/console/src/features/flows/components/resource-property-panel/CommonElementPropertyFactory.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/__tests__/CommonElementPropertyFactory.test.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/StackAdapter.test.tsx
  • frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx
  • frontend/packages/design/src/index.ts
  • frontend/packages/design/src/utils/__tests__/getStackGridSx.test.ts
  • frontend/packages/design/src/utils/getStackGridSx.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • frontend/packages/design/src/index.ts
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/CommonElementPropertyFactory.tsx
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx
  • frontend/packages/design/src/utils/tests/getStackGridSx.test.ts
  • frontend/apps/console/src/features/flows/components/resource-property-panel/tests/CommonElementPropertyFactory.test.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx

Comment thread frontend/packages/design/src/utils/getStackGridSx.ts Outdated
@DonOmalVindula
DonOmalVindula force-pushed the fix/3703-stack-grid-layout branch from 549243f to 0f55856 Compare July 27, 2026 08:57
Comment thread frontend/packages/design/src/utils/getStackGridSx.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (1)
frontend/apps/console/src/features/flows/components/resource-property-panel/TextPropertyField.tsx (1)

151-186: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add fallback default strings to the reworked t() calls.

The tooltip and placeholder lookups were rewritten in this hunk without a fallback default.

As per coding guidelines: "Every t('key') call must provide a fallback default string, either as the positional fallback argument or through defaultValue in the options object".

♻️ Proposed change
-      <Tooltip title={t('flows:core.elements.textPropertyField.tooltip.configureDynamicValue')}>
+      <Tooltip
+        title={t('flows:core.elements.textPropertyField.tooltip.configureDynamicValue', 'Configure dynamic value')}
+      >
@@
   const placeholder: string = t('flows:core.elements.textPropertyField.placeholder', {
+    defaultValue: 'Enter {{propertyName}}',
     propertyName: startCase(propertyKey),
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/apps/console/src/features/flows/components/resource-property-panel/TextPropertyField.tsx`
around lines 151 - 186, Update the translation calls for the dynamic-value
tooltip and text placeholder in the TextPropertyField component to include
explicit fallback default strings, using either the positional fallback argument
or the defaultValue option while preserving the existing interpolation for
propertyName.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@frontend/apps/console/src/features/flows/components/resource-property-panel/TextPropertyField.tsx`:
- Around line 222-268: Update the Autocomplete branch in the TextPropertyField
render to assign its underlying input the same `${resource.id}-${propertyKey}`
id targeted by FormLabel, preserving the label association and accessible name.
Also forward the existing rest props to the Autocomplete-rendered TextField,
matching the plain textField path instead of dropping caller-supplied
properties.

In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx`:
- Around line 36-43: Update the StackElement documentation for the items
property to state that CSS Grid activates only when items is a valid value of at
least two; clarify that 1, malformed, and non-positive values preserve the flex
layout.
- Around line 142-144: Update the direction handling in StackAdapter’s grid-mode
controls to use the same condition as getStackGridSx: treat every direction
other than “column” as row-oriented. Add the custom-direction case so reorder
controls match the rendered grid axis, while preserving existing behavior for
explicit “row” and “column” values.

---

Nitpick comments:
In
`@frontend/apps/console/src/features/flows/components/resource-property-panel/TextPropertyField.tsx`:
- Around line 151-186: Update the translation calls for the dynamic-value
tooltip and text placeholder in the TextPropertyField component to include
explicit fallback default strings, using either the positional fallback argument
or the defaultValue option while preserving the existing interpolation for
propertyName.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 09a2736b-72a9-4573-9baf-982741f8924b

📥 Commits

Reviewing files that changed from the base of the PR and between 549243f and 0f55856.

📒 Files selected for processing (13)
  • frontend/apps/console/src/features/flows/components/resource-property-panel/CommonElementPropertyFactory.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/TextPropertyField.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/__tests__/CommonElementPropertyFactory.test.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/__tests__/TextPropertyField.test.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/StackAdapter.test.tsx
  • frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx
  • frontend/packages/design/src/index.ts
  • frontend/packages/design/src/utils/__tests__/getStackGridSx.test.ts
  • frontend/packages/design/src/utils/getStackGridSx.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • frontend/packages/design/src/index.ts
  • frontend/packages/design/src/utils/getStackGridSx.ts
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/tests/CommonElementPropertyFactory.test.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx

@DonOmalVindula
DonOmalVindula force-pushed the fix/3703-stack-grid-layout branch 2 times, most recently from bbc3498 to c5466cd Compare July 27, 2026 10:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx (2)

162-170: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

isRow still diverges from getStackGridSx's axis logic for custom directions.

getStackGridSx treats every direction other than 'column' as row-oriented, but isRow here only treats exactly 'row' as row-oriented. For a custom/non-standard direction value, the grid renders row-oriented while reorder controls (Move Up/Down vs Left/Right) show the column-oriented set. A prior review flagged this same code and marked it "Addressed in commit c5466cd," yet the code is unchanged.

🐛 Proposed fix
-  const isRow = (stackElement?.direction ?? 'row') === 'row';
+  const isRow = useGrid
+    ? stackElement?.direction !== 'column'
+    : (stackElement?.direction ?? 'row') === 'row';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx`
around lines 162 - 170, Update the isRow calculation in the StackAdapter
component to match getStackGridSx axis logic: treat only direction === 'column'
as column-oriented and all other directions, including custom values and the
default, as row-oriented. Keep reorder controls aligned with the grid’s
orientation.

38-45: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

JSDoc still describes the wrong grid-activation threshold.

Line 38 says grid activates whenever items is set, but parseStackItems (and getStackGridSx) treat 1, 0, negative, and malformed values as flex mode — grid only kicks in for a valid value of at least two. A prior review on this exact file/line range flagged this and it was marked "Addressed in commit c5466cd," but the current code still has the pre-fix text.

🐛 Proposed fix
- * When `items` is set, the stack uses CSS Grid instead of flexbox.
+ * When `items` is a valid value of at least two, the stack uses CSS Grid instead of flexbox.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx`
around lines 38 - 45, Update the StackElement JSDoc to state that CSS Grid
activates only when items is a valid value of at least two; zero, one, negative,
missing, or malformed values retain the flex layout. Keep the change limited to
the documentation above StackElement.
🧹 Nitpick comments (3)
frontend/apps/console/src/features/login-flow/hooks/useElementAddition.ts (1)

198-247: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename formId to containerId for consistency.

The public type (line 47) already renamed this parameter to containerId to reflect that it now targets any container (form or stack), but the implementation still uses formId internally.

♻️ Proposed rename
-    (element: Element, formId: string): void => {
+    (element: Element, containerId: string): void => {
       // Use generateStepElement to properly apply variants and generate unique IDs
       const generatedElement: Element = generateStepElement(element);
       let viewStepId: string | null = null;

       setNodes((prevNodes: Node[]) => {
         const existingViewStep = prevNodes.find((node) => {
           if (node.type !== StepTypes.View) return false;
           const nodeData = node.data as {components?: Element[]} | undefined;
-          return containsComponent(nodeData?.components ?? [], formId);
+          return containsComponent(nodeData?.components ?? [], containerId);
         });

(and similarly for the appendToComponent(existingComponents, formId, generatedElement) call.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/apps/console/src/features/login-flow/hooks/useElementAddition.ts`
around lines 198 - 247, Rename the handleAddElementToForm parameter and all
internal references from formId to containerId, including containsComponent and
appendToComponent calls, so the implementation matches the public type and
supports any container.
frontend/apps/console/src/features/flows/components/resources/steps/view/__tests__/ReorderableElement.test.tsx (1)

332-372: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider a regression test for late-loading availableElements.

None of the new stack tests re-render with an updated availableElements prop after mount, so they wouldn't catch the formCompatibleElements staleness issue flagged in ReorderableElement.tsx (lines 320-332). A rerender-based test (render with an empty list, then rerender with mockStackElements, then assert the menu now shows the newly available item) would pin down the fix.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/apps/console/src/features/flows/components/resources/steps/view/__tests__/ReorderableElement.test.tsx`
around lines 332 - 372, Update the Stack-element test coverage around
ReorderableElement to verify late-loading availableElements: initially render
with an empty list, rerender with mockStackElements, open the add-component
handle, and assert the newly available stack-compatible item appears. Use the
existing ReorderableElement test setup and preserve the current compatibility
assertions.
frontend/apps/console/src/features/flows/components/resources/steps/view/ReorderableElement.tsx (1)

322-332: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Same "addable elements" filter copy-pasted in three places. Each site independently re-implements allowedTypes.includes(element.type) && element.display?.showOnResourcePanel !== false, only varying the allowedTypes constant; a future change to the visibility rule (e.g. adding a deprecated check) would need to be applied in all three, and one is easy to miss.

  • frontend/apps/console/src/features/flows/components/resources/steps/view/ReorderableElement.tsx#L322-L332: extract a shared getAddableElements(elements, allowedTypes) helper and call it here with the already-computed allowedTypes.
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx#L222-L226: replace the inline filter with the same shared helper, passing VisualFlowConstants.FLOW_BUILDER_STACK_ALLOWED_RESOURCE_TYPES.
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/FormAdapter.tsx#L79-L83: replace the inline filter with the same shared helper, passing VisualFlowConstants.FLOW_BUILDER_FORM_ALLOWED_RESOURCE_TYPES.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@frontend/apps/console/src/features/flows/components/resources/steps/view/ReorderableElement.tsx`
around lines 322 - 332, Extract a shared getAddableElements(elements,
allowedTypes) helper that centralizes the allowed-type and showOnResourcePanel
visibility checks. Update ReorderableElement.tsx (lines 322-332) to call it with
the computed allowedTypes, StackAdapter.tsx (lines 222-226) with
FLOW_BUILDER_STACK_ALLOWED_RESOURCE_TYPES, and FormAdapter.tsx (lines 79-83)
with FLOW_BUILDER_FORM_ALLOWED_RESOURCE_TYPES.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@frontend/apps/console/src/features/flows/components/resources/steps/view/ReorderableElement.tsx`:
- Around line 320-332: Update the formCompatibleElements useMemo in
ReorderableElement so it recomputes when availableElements changes, rather than
relying only on isContainer and isStack while reading
depsRef.current.availableElements. Preserve the existing filtering and
allowed-type selection, and use the component’s availableElements value as a
dependency/source so late-loaded updates refresh the add-menu.

---

Duplicate comments:
In
`@frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx`:
- Around line 162-170: Update the isRow calculation in the StackAdapter
component to match getStackGridSx axis logic: treat only direction === 'column'
as column-oriented and all other directions, including custom values and the
default, as row-oriented. Keep reorder controls aligned with the grid’s
orientation.
- Around line 38-45: Update the StackElement JSDoc to state that CSS Grid
activates only when items is a valid value of at least two; zero, one, negative,
missing, or malformed values retain the flex layout. Keep the change limited to
the documentation above StackElement.

---

Nitpick comments:
In
`@frontend/apps/console/src/features/flows/components/resources/steps/view/__tests__/ReorderableElement.test.tsx`:
- Around line 332-372: Update the Stack-element test coverage around
ReorderableElement to verify late-loading availableElements: initially render
with an empty list, rerender with mockStackElements, open the add-component
handle, and assert the newly available stack-compatible item appears. Use the
existing ReorderableElement test setup and preserve the current compatibility
assertions.

In
`@frontend/apps/console/src/features/flows/components/resources/steps/view/ReorderableElement.tsx`:
- Around line 322-332: Extract a shared getAddableElements(elements,
allowedTypes) helper that centralizes the allowed-type and showOnResourcePanel
visibility checks. Update ReorderableElement.tsx (lines 322-332) to call it with
the computed allowedTypes, StackAdapter.tsx (lines 222-226) with
FLOW_BUILDER_STACK_ALLOWED_RESOURCE_TYPES, and FormAdapter.tsx (lines 79-83)
with FLOW_BUILDER_FORM_ALLOWED_RESOURCE_TYPES.

In `@frontend/apps/console/src/features/login-flow/hooks/useElementAddition.ts`:
- Around line 198-247: Rename the handleAddElementToForm parameter and all
internal references from formId to containerId, including containsComponent and
appendToComponent calls, so the implementation matches the public type and
supports any container.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1760ef7b-a74d-4cd4-9318-75a747673fdc

📥 Commits

Reviewing files that changed from the base of the PR and between 0f55856 and c5466cd.

📒 Files selected for processing (19)
  • frontend/apps/console/src/features/flows/components/resource-property-panel/CommonElementPropertyFactory.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/TextPropertyField.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/__tests__/CommonElementPropertyFactory.test.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/__tests__/TextPropertyField.test.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/FormAdapter.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/StackAdapter.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/FormAdapter.test.tsx
  • frontend/apps/console/src/features/flows/components/resources/elements/adapters/__tests__/StackAdapter.test.tsx
  • frontend/apps/console/src/features/flows/components/resources/steps/view/ReorderableElement.tsx
  • frontend/apps/console/src/features/flows/components/resources/steps/view/__tests__/ReorderableElement.test.tsx
  • frontend/apps/console/src/features/login-flow/hooks/useElementAddition.ts
  • frontend/packages/components/src/lab/components/BuilderLayout/BuilderStaticPanel.tsx
  • frontend/packages/design/src/components/flow/__tests__/FlowComponentRenderer.test.tsx
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx
  • frontend/packages/design/src/index.ts
  • frontend/packages/design/src/utils/__tests__/getStackGridSx.test.ts
  • frontend/packages/design/src/utils/getStackGridSx.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • frontend/packages/design/src/components/flow/adapters/BlockAdapter.tsx
  • frontend/packages/design/src/utils/tests/getStackGridSx.test.ts
  • frontend/packages/design/src/index.ts
  • frontend/packages/design/src/utils/getStackGridSx.ts
  • frontend/packages/design/src/components/flow/adapters/StackContainer.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/tests/TextPropertyField.test.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/tests/CommonElementPropertyFactory.test.tsx
  • frontend/packages/design/src/components/flow/adapters/StackAdapter.tsx
  • frontend/apps/console/src/features/flows/components/resource-property-panel/TextPropertyField.tsx

@DonOmalVindula
DonOmalVindula force-pushed the fix/3703-stack-grid-layout branch 5 times, most recently from 6479809 to cb31e9b Compare July 28, 2026 03:15
@DonOmalVindula
DonOmalVindula enabled auto-merge July 28, 2026 05:02
@DonOmalVindula
DonOmalVindula added this pull request to the merge queue Jul 28, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a manual request Jul 28, 2026
@DonOmalVindula
DonOmalVindula enabled auto-merge July 28, 2026 05:33
Honor the items property on STACK flow elements so children can be laid
out in a grid. items is the number of slots across the main axis and
direction picks that axis: row makes it the column count (items: 2 with
four buttons renders a 2 x 2 grid, items: 1 renders one per row), and
column makes it the row count. Stacks without items keep the flex layout.

The flow builder canvas and the runtime renderer now share a single
layout helper so the builder preview matches what the Gate renders, and
the direction, align and justify property fields become searchable
autocompletes that still accept custom values.

Fixes thunder-id#3703
@DonOmalVindula
DonOmalVindula force-pushed the fix/3703-stack-grid-layout branch from cb31e9b to 54a4882 Compare July 28, 2026 06:17
@DonOmalVindula
DonOmalVindula added this pull request to the merge queue Jul 28, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 28, 2026
@DonOmalVindula
DonOmalVindula added this pull request to the merge queue Jul 28, 2026
Merged via the queue into thunder-id:main with commit 2a158a2 Jul 28, 2026
26 checks passed
@DonOmalVindula
DonOmalVindula deleted the fix/3703-stack-grid-layout branch July 28, 2026 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes Type/Improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to create a 2 x 2 button grid layout using Stack component

2 participants