/* * Shared menu-item indicator recipe. * * Mirrors the visual treatment of `` and `` so a * menu CheckboxItem / RadioItem reads identically to its standalone * sibling: * * - off → outlined box / circle (transparent fill, neutral border) * - on → filled solid box / circle with a white SVG ✓ / dot inside * * Targets the four pseudo-element indicators that signal `data-state` * on menu items inside a `role="menu"` container: * * [data-context-menu-checkbox-item] * [data-context-menu-radio-item] * [data-dropdown-menu-checkbox-item] * [data-dropdown-menu-radio-item] * * Layout: the indicator slot is reserved on every checkbox / radio * menu item so the row text doesn't shift when state flips. `::before` * paints the box / circle (always present); `::after` paints the glyph * inside (only when checked). * * Tokens (consumer-overridable): * --_menu-indicator-size @default 0.875rem * --_menu-indicator-radius @default 0.2rem (rounded square) * --_menu-indicator-color @default var(--color-primary-solid) (filled accent) * --_menu-indicator-glyph @default white (color of the check / dot) * --_menu-indicator-border @default var(--color-border-default) (off-state border) * --_menu-indicator-inset @default var(--space-2) * * NOT INCLUDED: standalone `` / `` / Select. * ItemIndicator. Those use real DOM parts with size scales and their * own SVG markers; this partial is the simplified version for items * rendered inside a menu chrome. */ /* Reserve the indicator slot. Selectors are DOUBLED (`[x][x]` → specificity 0,2,0) so this longhand `padding-inline-start` beats the menu recipe's `padding-inline` shorthand (0,1,0) REGARDLESS of load order. Required now that menu recipes are code-split: this partial loads with its own chunk and may resolve before or after the menu recipe; the specificity bump removes the order dependency. */ [data-context-menu-checkbox-item][data-context-menu-checkbox-item], [data-context-menu-radio-item][data-context-menu-radio-item], [data-dropdown-menu-checkbox-item][data-dropdown-menu-checkbox-item], [data-dropdown-menu-radio-item][data-dropdown-menu-radio-item] { --_menu-indicator-size: 0.875rem; --_menu-indicator-radius: 0.2rem; --_menu-indicator-color: var(--color-primary-solid); --_menu-indicator-glyph: var(--color-content-on-solid, #fff); --_menu-indicator-border: var(--color-border-default); --_menu-indicator-inset: var(--space-2); position: relative; padding-inline-start: calc( var(--_menu-indicator-inset) + var(--_menu-indicator-size) + var(--space-1) ); } /* ── Box / circle (::before) — always painted, regardless of state ───── */ [data-context-menu-checkbox-item]::before, [data-context-menu-radio-item]::before, [data-dropdown-menu-checkbox-item]::before, [data-dropdown-menu-radio-item]::before { content: ''; position: absolute; inset-inline-start: var(--_menu-indicator-inset); inline-size: var(--_menu-indicator-size); block-size: var(--_menu-indicator-size); border: 1px solid var(--_menu-indicator-border); border-radius: var(--_menu-indicator-radius); background: transparent; transition: background var(--duration-fast) var(--ease-default), border-color var(--duration-fast) var(--ease-default); } /* Checked state: box fills with accent colour, border tracks it. */ [data-context-menu-checkbox-item][data-state='checked']::before, [data-context-menu-radio-item][data-state='checked']::before, [data-dropdown-menu-checkbox-item][data-state='checked']::before, [data-dropdown-menu-radio-item][data-state='checked']::before { border-color: var(--_menu-indicator-color); background: var(--_menu-indicator-color); } /* Radio variant: circular box (both off and on). */ [data-context-menu-radio-item]::before, [data-dropdown-menu-radio-item]::before { border-radius: 50%; } /* ── Glyph (::after) — only painted when state='checked' ─────────────── */ /* Checkbox: SVG ✓ centred inside the box. We use mask-image so the glyph colour follows --_menu-indicator-glyph (white over the solid accent fill). The SVG is the same shape `` paints in the standalone Checkbox component. */ [data-context-menu-checkbox-item][data-state='checked']::after, [data-dropdown-menu-checkbox-item][data-state='checked']::after { content: ''; position: absolute; inset-inline-start: var(--_menu-indicator-inset); inset-block-start: 50%; transform: translateY(-50%); inline-size: var(--_menu-indicator-size); block-size: var(--_menu-indicator-size); background-color: var(--_menu-indicator-glyph); mask-image: url("data:image/svg+xml;utf8,"); -webkit-mask-image: url("data:image/svg+xml;utf8,"); mask-repeat: no-repeat; mask-position: center; mask-size: contain; -webkit-mask-repeat: no-repeat; -webkit-mask-position: center; -webkit-mask-size: contain; } /* Radio: smaller solid inner dot centred inside the circle, sized to ~40% of the indicator (matches RadioGroup's dot ratio). */ [data-context-menu-radio-item][data-state='checked']::after, [data-dropdown-menu-radio-item][data-state='checked']::after { content: ''; position: absolute; inset-inline-start: calc(var(--_menu-indicator-inset) + var(--_menu-indicator-size) * 0.3); inset-block-start: 50%; transform: translateY(-50%); inline-size: calc(var(--_menu-indicator-size) * 0.4); block-size: calc(var(--_menu-indicator-size) * 0.4); border-radius: 50%; background: var(--_menu-indicator-glyph); }