Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions openspec/changes/fix-combobox-flex-collapse/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-05-13
38 changes: 38 additions & 0 deletions openspec/changes/fix-combobox-flex-collapse/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Why

Combobox shrinks to 1px when placed in a flex container with `align-items: center` (row). The widget becomes unusable — invisible to the user — without any CSS override from the app developer.

## Root cause

The actual DOM chain in the bug scenario:

```
.row-center (user's CSS: display:flex, flex-flow:row, align-items:center)
└─ .form-group.no-columns (Atlas: flex-direction:column, no explicit width)
└─ .widget-combobox (flex-grow:1 — grows height in column container, not width)
└─ .widget-combobox-input-container.form-control (Atlas: min-width:50px — too narrow)
└─ .widget-combobox-selected-items (min-width:0 — intentional for tag wrapping)
└─ .widget-combobox-input (max-width:0 unfocused, width:1px multiselect inactive)
```

The user created `.row-center`. Atlas injected `.form-group.no-columns` (column flex, no explicit width). Inside it, `flex-grow:1` on `.widget-combobox` distributes height, not width. Width is sized by content.

Atlas has `min-width: 0` on `.widget-combobox` and `min-width: 50px` on `.form-control` (`.widget-combobox-input-container`). The `50px` floor propagates up — but it is too narrow: the down-arrow icon alone consumes ~53px, leaving zero space for text input.

**Why native textbox is not affected:**

Textbox renders `.form-control` directly inside `.form-group` — Atlas's `min-width: 50px` is wide enough for a plain input. Combobox `.form-control` must also contain the down-arrow icon, making `50px` insufficient.

## What changes

`packages/pluggableWidgets/combobox-web/src/ui/Combobox.scss` — `.widget-combobox-input-container` rule.

Add `min-width: 15ch` — overrides Atlas's `50px` floor on `.form-control` with a value wide enough to be usable. Scoped to the combobox, not a global Atlas change. `ch` scales with font-size.

## Impact

Must not break:

- Single-select combobox layout in all container types
- Multiselect combobox layout (active and inactive states)
- Atlas UI demo site rendering (already unaffected per ticket)
29 changes: 29 additions & 0 deletions openspec/changes/fix-combobox-flex-collapse/tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Tests

- [ ] **Combobox root element has min-width: 15ch in stylesheet**
- **Type:** unit
- **Given:** Combobox.scss source
- **When:** `.widget-combobox` rule is inspected
- **Then:** `min-width` is `15ch`
- **Status:** needs update — `src/__tests__/ComboboxStyles.spec.ts` currently asserts `min-content`

- [ ] **Single-select combobox renders with visible width in flex container with align-items center**
- **Type:** e2e
- **Given:** Single-select Combobox on page `/p/combobox-flex-layout` (`.mx-name-comboBoxFlexSingle`)
- **When:** Page loads with no interaction
- **Then:** Combobox bounding rect width is greater than 10px
- **Status:** pending — needs test page in Studio Pro

- [ ] **Multiselect combobox renders with visible width in flex container with align-items center**
- **Type:** e2e
- **Given:** Multiselect Combobox on page `/p/combobox-flex-layout` (`.mx-name-comboBoxFlexMulti`)
- **When:** Page loads with no interaction
- **Then:** Combobox bounding rect width is greater than 10px
- **Status:** pending — needs test page in Studio Pro

- [x] **Multiselect inactive input still collapses to 1px (intentional behavior preserved)**
- **Type:** unit
- **Given:** Combobox.scss source
- **When:** multiselect inactive rule inspected
- **Then:** `.widget-combobox-input` has `width: 1px`
- **Status:** done — `src/__tests__/ComboboxStyles.spec.ts`
22 changes: 22 additions & 0 deletions packages/pluggableWidgets/combobox-web/e2e/Combobox.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,28 @@ test.describe("combobox-web", () => {
});
});

// WC-3409: flex align-items center collapse fix
test.describe("flex container layout (WC-3409)", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/p/combobox-flex-layout");
await waitForMendixApp(page);
});

test("single-select combobox has visible width in flex align-items:center container", async ({ page }) => {
const comboBox = page.locator(".mx-name-comboBoxFlexSingle");
await expect(comboBox).toBeVisible({ timeout: 10000 });
const box = await comboBox.boundingBox();
expect(box.width).toBeGreaterThan(10);
});

test("multiselect combobox has visible width in flex align-items:center container", async ({ page }) => {
const comboBox = page.locator(".mx-name-comboBoxFlexMulti");
await expect(comboBox).toBeVisible({ timeout: 10000 });
const box = await comboBox.boundingBox();
expect(box.width).toBeGreaterThan(10);
});
});

function getOptions(combobox) {
return combobox.locator(`[role=listbox] [role=option]`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ $cb-skeleton-light: rgba(194, 194, 194, 0.2);
$cb-skeleton-dark: #d2d2d2;

.widget-combobox {
min-width: 0;
flex-grow: 1;
position: relative;
transition: color 150ms ease 0s;
Expand Down Expand Up @@ -141,6 +140,7 @@ $cb-skeleton-dark: #d2d2d2;

.widget-combobox-input-container {
flex-grow: 1;
min-width: 15ch; // overrides Atlas .form-control 50px floor; prevents collapse in column flex containers
transition: box-shadow 150ms ease 0s;

&-disabled {
Expand Down
Loading