The menu surface that opens when a Select is tapped — a rounded card wrapping a Figma Slot of Select Items. 9 variants across Border Type (Middle Inset / Full Width / None) × Density (Compact / Default / Comfortable).
SLOT, the detached last row is now a real instance, dividers are separate nodes (so no stray bottom border), and it's consumed by Select. The Consolidate verdict is withdrawn — it earns its place as a component. Remaining work is cleanup: a MIddle Inset typo, a vestigial Dropdown Item - Last name, hidden 366px leftovers, and a Scrollbar frame native renders itself.The group appears immediately below a Dropdown trigger in the expanded state. On native platforms it is rendered by the OS menu primitive, not drawn manually.
SLOT now wraps the content, so consumers can drop in any number of Select Items rather than rebuilding the composition. Fill behaviour works — nested in Select the instance resizes to the 366px trigger and the Slot, items, and dividers all fill with it.Select Group, matching Avatar Group / Button Group — the irregular " - " separator is gone. Border Type values are spelled correctly (Middle Inset / Full Width / None), and the terminal row reads Select Item - Last, where the - Last suffix is a deliberate semantic marker rather than a leftover.SLOT, and Select nests it as an instance alongside Select Field rather than drawing its own list. Maps to a @ViewBuilder / @Composable content slot.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default (open) | Yes | Yes | — | White bg, 6px radius, drop shadow. Rendered by Menu (iOS) / DropdownMenu (Android) automatically. |
| Item hover/press | Yes | Yes | — | Handled by the per-item Dropdown Item component, not the group. Touch feedback is platform-native. |
| Scroll | Yes | Yes | — | Native menus clip and scroll automatically when item count exceeds available height. |
- Code Connect mappings not registered. Unblocked by the Slot rebuild — the container now has a real native counterpart rather than being a preview artifact. Not yet wired, and still waiting on the native library to exist. C7 · Code Connect Linkability
- v2.0: Rebuilt as a real Slot-based container — every variant now wraps a Figma
SLOT, so consumers can compose any number of Select Items instead of rebuilding the stack. The Consolidate verdict is withdrawn: it is a genuine component, not a preview artifact. (C1) - v2.0: Detached last row replaced with a real instance — the hand-built
Dropdown - Itemframe (node6383:3442) is gone. Every row is now a Select Item instance, so item changes propagate. (C1) - v2.0: Redundant bottom border removed — dividers are now separate
Horizontal / Dividernodes placed between rows, so the last row carries none.Border Type=Nonedrops them entirely. (C1) - v2.0: Renamed
Dropdown Item - Group→Select Group, matching Avatar Group / Button Group. The irregular" - "separator is gone. (C2) - v2.0: Now genuinely composed — Select nests this as an instance alongside Select Field rather than drawing its own list. The popover surface is a real container mapping to a native content slot, which answers the earlier C4 concern that it was a phantom. (C4)
- v2.0: Divider treatment promoted to a property —
Border Type(Middle Inset / Full Width / None) ×Density(Compact / Default / Comfortable) gives 9 variants where the old component had one hardcoded layout. (C2) - v2.0: The stacked 366px
Select Item/Horizontal / Dividerinstances and theLabelinside the Slot are intentional, not leftovers — reviewed and confirmed. They sit inside the Slot as scroll-overflow content and are not dead layers. (C1) - v2.0: The
Scrollbarframe is intentional — reviewed and confirmed. It documents the menu's scroll affordance in the design. Handoff note: SwiftUI and Compose render scroll indicators inside their own scroll containers, so developers should rely on the native indicator rather than rebuilding this layer. (C4) - v2.0: Fill-container width verified working — the standalone component sits at 320px, but nested in Select the instance resizes to 366px and the Slot, every Select Item, and every divider fill with it. The Scrollbar stays right-aligned to the card edge. No fixed-width bug; the 320px is just the component's canvas size. (C1)
- v2.0:
Border Type=MIddle Insettypo fixed — the value now readsMiddle Insetacross all 9 variants, so the generated type no longer carries the capital-I misspelling. (C2) - v2.0: Last row renamed
Dropdown Item - Last→Select Item - Last— the vestigialDropdownprefix from the old architecture is gone. The- Lastsuffix is intentional, marking the terminal row. (C1)
- Register Code Connect mapping to
EBSelectGroup. With the Slot rebuild the container now has a genuine native counterpart — a menu surface wrapping a content slot. WireBorder TypeandDensityto the SwiftUI / Compose API once the native component exists. Docs
- Convert to a Slot-based container. v2.0: Applied — every variant now wraps a real Figma
SLOT, so consumers compose any number of Select Items instead of rebuilding the stack. This is what withdrew the Consolidate verdict. Slot - Replace the detached last row with a real instance. v2.0: Applied — the hand-built
Dropdown - Itemframe is gone; every row is a live Select Item instance, so item changes propagate. Composition - Remove the bottom border on the last item. v2.0: Applied — dividers are now separate
Horizontal / Dividernodes placed between rows, so the last row carries none.Border Type=Nonedrops them entirely. Property - Rename to match DS group naming. v2.0: Applied —
Dropdown Item - Group→Select Group, matching Avatar Group / Button Group. The irregular" - "separator is gone. Rename - Fix the
MIddle Insettypo. v2.0: Applied — the value now readsMiddle Insetacross all 9 variants, so the generated type no longer carries the capital-I misspelling. Rename - Rename the last row off the old
Dropdownprefix. v2.0: Applied — the terminal row is nowSelect Item - Last. The vestigialDropdownprefix is gone; the- Lastsuffix is retained deliberately as a semantic marker for the last row. Rename
Rounded card surface containing a vertical stack of Dropdown Items. 6px corner radius, white background, 12px-blur drop shadow at 6px offset.
Display-only surface. The group itself only contributes bg, shadow, and row dividers — all per-item colors come from Dropdown Item.
| Role | Token | VALUE |
|---|---|---|
| Surface bg | bg/color-bg-main | #FFFFFF |
| Row divider | main/dropdown-item/color/default/border | #E5EBF4 |
| Shadow color | elevation/app/shadow/color-shadow | #020E2229 |
| Shadow border | elevation/app/shadow/color-border | #FFFFFF00 |
| Item label | main/dropdown-item/color/default/label | #0A2757 |
| Figma Property | SwiftUI | Compose |
|---|---|---|
| (no properties) | Menu / View ZStack | DropdownMenu |
| Width 366px | — | — |
| Item count 8 | ForEach(items) | items.forEach |
| Requirement | iOS | Android |
|---|---|---|
| Menu role | Automatic via Menu | Automatic via DropdownMenu (Role.DropdownList) |
| Focus trap | VoiceOver moves focus into the menu on open | TalkBack moves focus into the menu on open |
| Dismiss on outside tap | Automatic | onDismissRequest |
| Max visible items | Native scroll when exceeded | Native scroll when exceeded |
Do
Render the menu surface through SwiftUI's Menu or Compose's DropdownMenu. Let the platform handle shadow, clipping, positioning, and keyboard dismissal.
Don't
Don't hand-draw a shadowed card and place items inside it. You'll reimplement focus management, scroll clipping, and accessibility semantics that the platform gives you for free.
Do
Keep Dropdown Item as the per-row component. Use it inside the native menu's builder closure (SwiftUI) or inside DropdownMenuItem's text slot (Compose).
Don't
Don't use this Figma component as a layout reference for production — the fixed 8-row, 366px-wide, detached-last-row structure won't match real menu content.
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Requires Rework | Fixed 8-item layout with no slot. Last row is a detached frame (6383:3442), not a DropdownItem instance. Component name uses irregular " - " separator. |
| C2 | Variant & Property Naming | Needs Refinement | No variant properties exist. Component name Dropdown Item - Group is irregular; prefer Dropdown Menu. |
| C3 | Token Coverage | Ready | All colors, radius, spacing, and shadow values bound to tokens (bg/color-bg-main, elevation/app/shadow/*, space/space-*). |
| C4 | Native Mappability | Requires Rework | Popover surface is rendered by Menu / DropdownMenu natively. No 1:1 component to map to. |
| C5 | Interaction State Coverage | Ready | Surface has no interactive states of its own. Per-item states live on Dropdown Item. |
| C6 | Asset & Icon Quality | Ready | No icons or raster assets. Pure layout + shadow. |
| C7 | Code Connect Linkability | Not Applicable | No native component to map to. Consolidate into Dropdown instead. |
| Aspect | Status | Notes |
|---|---|---|
| Property naming | Not Applicable | No properties exist on the component. |
| Slot coverage | Requires Rework | No items slot — blocks any meaningful mapping. |
| Native component file | Not Applicable | Handled by Menu/DropdownMenu. No dedicated EB component required. |
| Recommendation | Consolidate | Fold into Dropdown's Expanded variant or convert to a slot-based Dropdown Menu before mapping. |
Single variant, no property axes.
| Variant | Width | Item Count | Node ID |
|---|---|---|---|
| Default | 366px | 8 (7 instances + 1 detached frame) | 6383:3446 |
6383:3442 is a hand-built Dropdown - Item frame instead of a DropdownItem component instance. Breaks consistency.
OpenMenu (iOS) and DropdownMenu (Compose) draw the shadowed card automatically. This component has no 1:1 native mapping.
Open