The settings sidebar ships two dropdown primitives plus the standalone VarPicker for design-token selection. This doc explains which is which, what triggers them, and lists every registered property by primitive.
UnifiedDropdown — the multi-column popover (Auto / Full / Screen / Min / Max / Fit | S / M / L / XL | 2ths / 3ths / …). Lives inside UniversalInput. Used only for property defs whose input.type === "universal" (plus a few hand-rolled inputs that wrap UniversalInput directly: WidthInput, HeightInput, GapInput, ShadowInput, EffectsClassInput, ShorthandInput).ToolbarDropdown — the single-column Headless UI Listbox (None / Extra Small / Small / Base / …). Used for every other selectable property: tailwind-select, plain select, plus a bunch of bespoke editors (actions, conditions, modifiers, text-style editor, media toolbar sort, icon set picker, design-system styles tab).VarPicker — the FloatingPanel that opens from the {} braces type-chip. Lists every design token (palette + typography + styleGuide + custom) and lets the user pick / create / edit. NOT a dropdown — a separate full-CRUD surface. See var-picker.md.ToolbarItem with type="select" always renders ToolbarDropdown. There is no hybrid.
| Primitive | File | Trigger |
|---|---|---|
UnifiedDropdown | packages/sdk/src/chrome/toolbar/inputs/universal-input/UnifiedDropdown.tsx | Layout config keyed by propTag / tailwindKey in layouts.ts (COMMON_SIZING_LAYOUT, COMMON_SPACING_LAYOUT, COMMON_NAMED_ONLY_LAYOUT, …) |
ToolbarDropdown | packages/sdk/src/chrome/toolbar/ToolbarDropdown.tsx | Headless UI <Listbox>. Children are <option> (or <optgroup>) elements; the component flattens them. |
Dispatch happens in PropertyRenderer.tsx:64:
case "universal" → UniversalInput → UnifiedDropdown
case "tailwind-select" → TailwindInput / ToolbarItem(type="select") → ToolbarDropdown
case "select" → ToolbarItem(type="select") → ToolbarDropdown
case "tailwind-radio" → ToolbarItem(type="radio") → segmented chips (neither)
case "checkbox" / "text" → ToolbarItem → not a dropdown
case "shorthand" → ShorthandInput → UniversalInput → UnifiedDropdown
case "custom" → component-specific (often ToolbarDropdown)
UnifiedDropdown (multi-column)Source: every registered property def with input.type: "universal" in packages/sdk/src/chrome/toolbar/inspector/registry/properties/.
| Section | Property ids |
|---|---|
Layout (layout.ts) | width, height, maxWidth, maxHeight, minWidth, minHeight |
Display (display.ts) | display, position, cursor, overflow, zIndex |
Appearance (appearance.ts) | shadowSize, opacity, ringWidth, ringOffsetWidth, outlineWidth, outlineOffset |
Interactions (interactions.ts) | hover.borderWidth, hover.scale, hover.shadowSize, hover.opacity, hover.translateY, hover.ringWidth, hover.ringOffsetWidth |
Also reaches UnifiedDropdown indirectly via wrapper inputs:
WidthInput, HeightInput — main-tab width/height pickers (Layout panel)GapInput — gap / gap-x / gap-y (Alignment panel)ShadowInput — shadow class pickerEffectsClassInput — generic class picker for the effects builderShorthandInput — wraps UniversalInput per side for margin, padding, etc.Layout configs that drive the column structure (in layouts.ts):
COMMON_SIZING_LAYOUT (3-col: named + numeric + fractions) → width, height, maxWidth, minHeight. This is what screenshot 1 shows.
COMMON_SPACING_LAYOUT (2-col: tokens+named | numeric) → margin, padding, gap, gapX, gapY.
COMMON_NAMED_ONLY_LAYOUT (single named col, stacked) → display, position, flexDirection, alignItems, justifyContent, fontSize (note: fontSize is tailwind-select in the registry, so this layout entry is unused — see "Surprises" below), fontWeight, textAlign, borderStyle, twTransform.
COMMON_NUMERIC_LAYOUT / COMMON_NUMERIC_SUBGROUPED_LAYOUT / COMMON_TIME_LAYOUT / RING_LIKE_WIDTH_LAYOUT / COMMON_NAMED_OTHER_COLUMN / COMMON_NAMED_OTHER_SPLIT_LAYOUT — see layouts.ts for the full keyset.
ToolbarDropdown (single-column Listbox)input.type: "tailwind-select":
| Section | Property ids |
|---|---|
| Appearance | borderStyle, divideX, divideY, divideStyle, outlineStyle |
| Display | order, visibility, pointerEvents, userSelect, float, verticalAlign, fontSmoothing, resize, touchAction, cssAppearance, boxSizing, isolation, columns, breakBefore, breakInside, breakAfter, listStyleType, listStylePosition, tableLayout, captionSide, fill, stroke, strokeWidth, cssContent, srOnly |
| Interactions | hover.borderStyle |
| Layout | aspectRatio |
| Background | bgClip, bgBlend, mixBlend |
| Alignment | gridColSpan, gridRowSpan |
| Typography | fontSize, fontWeight, lineHeight, tracking, indent, transform, textDecoration, decorationStyle, decorationThickness, textWrap, textOverflow, hyphens |
input.type: "select":
| Section | Property ids |
|---|---|
| Typography | whiteSpace, wordBreak |
| Aria | ariaExpanded, ariaSelected, role, tabIndex, ariaHidden, ariaLive |
Each of these imports ToolbarDropdown directly:
| File | What it picks |
|---|---|
| inspector/mainTabs/ConditionalContainerMainTab.tsx | conditional-container mode |
| inputs/modifiers/ModifiersPickerBody.tsx, ExclusiveDropdown.tsx | breakpoint / pseudo modifier |
| inputs/action/ActionEditorPanel.tsx, ActionInput.tsx, HandlerEditorPanel.tsx | action type, handler event, target page |
| inputs/advanced/ConditionsInput.tsx | condition type / operator / source |
| inputs/typography/TextStyleEditorPanel.tsx | preset font-size / weight / line-height / letter-spacing / transform / decoration — this is screenshot 2 |
| inputs/media/components/MediaToolbar.tsx | media library sort, kind filter |
| dialogs/IconDialog/components/IconsTab.tsx | icon set (tb / fa / si / …) |
| viewport/design-system/components/StylesTab.tsx | design-system style tokens |
ToolbarItem itself (ToolbarItem.tsx:187) is the entry point that routes type="select" into ToolbarDropdown, so any bespoke main-tab passing <ToolbarItem type="select"> also lands here.
fontSize, fontWeight, textAlign have entries in DROPDOWN_LAYOUTS (COMMON_NAMED_ONLY_LAYOUT) but the registry registers them as tailwind-select — so they render through ToolbarDropdown, never through UnifiedDropdown. The layout entries are dead config. Either flip the registry to universal or delete the layout entries.borderStyle is registered as tailwind-select (Appearance) → ToolbarDropdown, while display, position, flexDirection, alignItems, justifyContent are universal → UnifiedDropdown. All five are pure named-only enums, so the split is historical, not principled.UnifiedDropdown has a sticky Reset to Default footer; ToolbarDropdown represents empty as a __ph_empty__ sentinel labeled None. Be aware when porting between them.universal + add a DROPDOWN_LAYOUTS entry → UnifiedDropdown.tailwind-select → ToolbarDropdown. Don't add a layout entry.select with explicit options[] → ToolbarDropdown.ToolbarItem plumbingFloatingPanel pattern used by TextStyleEditorPanel (which itself uses ToolbarDropdown){} type-chip on every UniversalInput