Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
08ec8eb
docs(openspec): propose popover compound component export
misama-ct Aug 19, 2026
ec4a8cb
feat(popover): export Popover as a public compound component
misama-ct Aug 19, 2026
d25ec33
docs(popover): add documentation set and narrow the popover spec
misama-ct Aug 19, 2026
afa1716
fix(popover): forward Trigger props supplied via asChild
misama-ct Aug 20, 2026
a4a733f
test(popover): add Chromatic snapshots and tighten assertions
misama-ct Aug 20, 2026
6e300b9
docs(popover): render the consumer tests and correct focus claims
misama-ct Aug 20, 2026
0ea8823
refactor(combobox): tidy leftovers from the popover migration
misama-ct Aug 20, 2026
dd9f67d
chore(openspec): archive the popover compound export change
misama-ct Aug 20, 2026
46e63a4
chore(openspec): correct the Popover Optimized Rendering requirement
misama-ct Aug 20, 2026
85973f9
fix(popover): reject Trigger button props under asChild
misama-ct Aug 20, 2026
b09815a
docs(popover): trim the changeset to release-note scope
misama-ct Aug 20, 2026
20e688f
fix(popover): ring the dialog when it holds focus
misama-ct Aug 20, 2026
e786b7c
refactor(localized-field): adopt the public Popover component
misama-ct Aug 20, 2026
ebe20a1
refactor(localized-field): let the popover surface style the hint box
misama-ct Aug 20, 2026
50855ab
docs(localized-field): note the hint popover's new appearance
misama-ct Aug 20, 2026
e3ed9b0
revert(popover): drop the dialog focus ring
misama-ct Aug 20, 2026
66bed6a
fix(popover): stop the a11y doc crashing on an undefined Kbd
misama-ct Aug 20, 2026
389b7ec
fix(popover): gate the trigger ring on :focus-visible
misama-ct Aug 21, 2026
f4f6f97
fix(popover): stop the uncontrolled example blocking the docs page
misama-ct Aug 21, 2026
58f9d71
docs(popover): trim the designer doc to overview and variables
misama-ct Aug 21, 2026
19463c5
test(popover): cover focus containment and placement, de-flake focus …
misama-ct Aug 21, 2026
237a6e8
chore(changeset): release the LocalizedField popover change as minor
misama-ct Aug 21, 2026
a4d81d3
chore(serena): apply the project config schema migration
misama-ct Aug 21, 2026
3e20169
revert(serena): drop the project config schema migration
misama-ct Aug 21, 2026
dc236eb
fix(popover): narrow PopoverRootProps to the props Root honours
misama-ct Aug 21, 2026
391aebe
fix(popover): forward Content's DOM props to the dialog element
misama-ct Aug 21, 2026
7269d3c
test(popover): cover Escape not reaching a parent overlay
misama-ct Aug 21, 2026
4f4b08c
feat(popover): make Root the compound's configuration surface
misama-ct Aug 21, 2026
50372a1
docs(popover): align the specs and archived proposals with Root's sur…
misama-ct Aug 21, 2026
9b81418
docs(popover): trim the changeset to consumer-visible changes
misama-ct Aug 21, 2026
9bfecd3
docs(popover): correct where isNonModal and placement are set
misama-ct Aug 21, 2026
b23889a
docs(popover): drop comments duplicated by the types and recipe
misama-ct Aug 21, 2026
ea81b72
fix(popover): reject role, offset and maxHeight on Content
misama-ct Aug 21, 2026
9ac25c9
fix(popover): correct the non-modal and labelling claims in the docs
misama-ct Aug 21, 2026
4948673
docs(popover): resync the specs, proposals and guidelines with the code
misama-ct Aug 21, 2026
8010c40
docs(popover): simplify Popover.Content usage instructions and clarif…
misama-ct Aug 21, 2026
449cfe5
docs(popover): revert the compound-components guideline edits
misama-ct Aug 21, 2026
f889de7
docs(popover): condense the types file comments
misama-ct Aug 21, 2026
beee352
docs(popover): document slot="close" for dismissing from content
misama-ct Aug 21, 2026
9a1ac30
docs(popover): drop the non-conforming dev.mdx sections
misama-ct Aug 21, 2026
2a3ab0a
docs(popover): move the isNonModal mechanics to the Implementation tab
misama-ct Aug 25, 2026
b18c451
Merge branch 'main' into FEC-1167-popover-compound-export
misama-ct Aug 25, 2026
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
15 changes: 15 additions & 0 deletions .changeset/lucky-pandas-explore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@commercetools/nimbus": minor
---

`Popover`: new compound component for interactive content anchored to a trigger
— `Popover.Root`, `Popover.Trigger` and `Popover.Content`. Reach for it for
filter panels, short edit forms and context-sensitive actions; `Tooltip` still
covers plain hints, and `Dialog` covers flows that should block the page.

Name `Popover.Content` with `aria-label` or `aria-labelledby` — a visible
heading inside the popover does not name it.

Beta. See the
[Popover docs](https://nimbus-documentation.vercel.app/components/feedback/popover)
for the full prop reference.
10 changes: 10 additions & 0 deletions .changeset/wise-moons-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@commercetools/nimbus": minor
---

`LocalizedField`: the info popover opened by the hint button now has an
accessible name, so screen readers announce it instead of an unnamed dialog. It
also matches the appearance of other popovers — one shadow rather than two
stacked, no border or background tint of its own — and fades in and out like
them. It no longer draws an outline around itself when opened, matching `Dialog`
and `Drawer`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-08-20
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Proposal: Correct the Popover Optimized Rendering requirement

## Why

Rewrite the `Optimized Rendering` requirement in the `nimbus-popover` capability
so it describes observable Popover behavior instead of React Aria internals and
a configuration option that does not exist.

### Background

`popover-compound-export` narrowed this capability from an eight-part
aspirational surface to the three parts actually built, and corrected the
requirements it touched. `Optimized Rendering` was not among them, so its
`Scroll optimization` scenario still specifies two things the component cannot
be held to:

- **`SHALL use requestAnimationFrame for positioning updates`** — an assertion
about React Aria's internals. Nimbus neither implements nor tests it, and it
would silently become false if React Aria changed its scheduling.
- **`MAY close popover on scroll if configured`** — there is no such option.
`Popover.Root` accepts `placement`, `offset`, `crossOffset`, `shouldFlip`,
`containerPadding`, `boundaryElement`, `isNonModal`,
`isKeyboardDismissDisabled`, `shouldCloseOnInteractOutside` and `triggerRef`,
and none of them dismisses on scroll. (At the time of this change those props
were accepted on `Popover.Content`; they moved to `Popover.Root` when it
became the compound's single configuration surface. The conclusion is
unaffected.)

Both are the same class of inaccuracy as the `portalContainer` and
`trigger="hover"` scenarios corrected in the previous change, and they were left
behind only because that change's scope did not reach this requirement.

## What Changes

Keep both scenario names and restate their bodies against what the component
actually does:

- `Lazy mounting` is accurate and stays, worded against the overlay content
rather than "content in DOM".
- `Scroll optimization` becomes a statement about the observable outcome — the
popover stays anchored to its trigger and within the viewport while the page
moves — and records that no scroll-dismissal option is exposed.

## Scope

- **In scope**: the `Optimized Rendering` requirement of `nimbus-popover`.
- **Out of scope**: any implementation change. This corrects the specification
to match shipped behavior; no source file changes.

## Impact

- **Breaking changes**: None
- **Migration required**: None
- **Dependencies**: None
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## MODIFIED Requirements

### Requirement: Optimized Rendering

The component SHALL keep overlay content out of the DOM while closed, and SHALL
stay anchored to its trigger while the page moves.

#### Scenario: Lazy mounting

- **WHEN** the popover is closed
- **THEN** the overlay content SHALL NOT be mounted in the DOM
- **AND** it SHALL mount when the popover opens
- **AND** it SHALL unmount once the exit animation has finished

#### Scenario: Scroll optimization

- **WHEN** the page scrolls or the viewport resizes while the popover is open
- **THEN** the popover SHALL remain anchored to its trigger
- **AND** it SHALL stay within the viewport, flipping or shifting as needed
- **AND** no scroll-dismissal option SHALL be exposed
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Tasks: Correct the Popover Optimized Rendering requirement

- [x] Task 1: Rewrite the `Optimized Rendering` requirement as a delta
- [x] Task 2: Validate and archive

---

## Task 1: Rewrite the `Optimized Rendering` requirement as a delta

**File:**
`openspec/changes/correct-popover-rendering-spec/specs/nimbus-popover/spec.md`

- Restate `Lazy mounting` against the overlay content.
- Replace the `Scroll optimization` body: drop the `requestAnimationFrame`
claim and the non-existent scroll-dismissal option, and state the observable
anchoring behavior instead.
- Keep both scenario names, since a MODIFIED requirement may not drop scenarios
the current spec still has.

**Validation:**

- `pnpm exec openspec validate correct-popover-rendering-spec --strict` clean

## Task 2: Validate and archive

- Archive so the delta applies to `openspec/specs/nimbus-popover/spec.md`.

**Validation:**

- `openspec/specs/nimbus-popover/spec.md` no longer mentions
`requestAnimationFrame` or closing on scroll
- No source or test files change
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-08-19
Loading
Loading