Skip to content

Commit 5cf5def

Browse files
zhujeCopilot
andcommitted
[IGNORE] document state and portal conventions; use accessible focus ring color
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8bd2af1 commit 5cf5def

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

‎components/src/next/README.md‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,32 @@ Keep selectors for focus, disabled, multiline, and status overrides outside `:wh
113113

114114
Apply `--perses-opacity-disabled` (default `0.5`) once at the disabled group's root, preserving status and custom colors without dimming labels or helpers again. Checkbox and Switch dim their label wrapper based on the control's effective Base UI disabled state, including inheritance; unlabeled controls dim themselves.
115115

116+
If a nested part also fades (for example a decorative checkbox inside a disabled menu item), mark it `data-decorative` and skip the fade on it so the row is not dimmed twice.
117+
118+
Selected, hovered, and focused must look different from each other:
119+
120+
- **Selected:** show a check mark or other shape, never color alone. A `color` prop tints this indicator, not the whole
121+
row. In `forced-colors`, use `CanvasText`.
122+
- **Hovered:** use a faint `--perses-status-bg-default` background, and skip it when disabled.
123+
- **Focused (`:focus-visible`):** use `--perses-focus-ring-width` and `--perses-focus-ring-offset` with
124+
`--perses-focus-ring-color`. In `forced-colors`, use `Highlight`.
125+
126+
```css
127+
:where(.ps-Example:focus-visible) {
128+
outline: var(--perses-focus-ring-width) solid var(--perses-focus-ring-color);
129+
outline-offset: var(--perses-focus-ring-offset);
130+
}
131+
```
132+
133+
When the element sits in a scrolling or clipping container, such as a menu popup, use a negative outline offset so the
134+
ring stays inside the element and is not clipped.
135+
116136
When zero-specificity defaults set the same property on the same element in the same layer, later rules win. Put base defaults before size defaults, and keep state overrides easy to identify. Avoid `!important` or increasingly specific selectors as a substitute for the layer and default/override structure.
117137

138+
### Portaled components
139+
140+
Popups rendered in a portal (Menu, Tooltip) live outside the `ThemeModeProvider` wrapper and lose its tokens. Read `ThemeModeContext` and set `data-perses-mode` on the portaled element, as [Menu](./primitives/Menu/Menu.tsx) does. Use `data-perses-mode` only for colors and tokens, never for layout: it can land on any portaled element, so a layout rule keyed on it (such as `min-height: 100vh`) will resize popups.
141+
118142
## Content elements
119143

120144
When a component offers optional content before or after its main content, name the `ReactNode` props `startElement` and
@@ -192,4 +216,14 @@ uses the component's own custom properties, type it as `SlotStyleProps<Component
192216
- Preserve visible focus indicators and accessible disabled/error behavior.
193217
- Keep stories and focused tests aligned with public behavior. CSS-source contract tests, such as
194218
[`controlSize.test.ts`](./primitives/controlSize.test.ts), may need selector updates when adding `:where()`.
219+
- Re-read story prose and JSDoc after behavior changes so defaults and descriptions stay accurate.
195220
- Run the affected workspace's checks and the repository validation required by the contributor guide.
221+
222+
### Visual pass in Ladle before requesting review
223+
224+
- Portaled popups open beside their trigger, in both dark and light mode.
225+
- Popup and page backgrounds are distinguishable in light mode. If you change a shared overlay token, check every component that uses it (Menu, Tooltip).
226+
- Selected, hovered, and focused states are distinct, including in `forced-colors` mode.
227+
- Density: padding applies on all four sides, and `sm` is the default size.
228+
- Disabled content fades once, not twice.
229+
- Compare before and after: run Ladle on the parent commit and on your branch (a `git worktree` on a second port works), and attach both screenshots to the PR.

‎design-tokens/src/css/semantic.css‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
--perses-border-control: var(--perses-color-gray-400);
4949

5050
/* Focus ring */
51-
--perses-focus-ring-color: var(--perses-status-border-primary);
51+
--perses-focus-ring-color: var(--perses-color-blue-700);
5252

5353
/* Text */
5454
--perses-text-primary: var(--perses-color-gray-800);
@@ -136,7 +136,7 @@
136136
--perses-border-control: var(--perses-color-gray-700);
137137

138138
/* Focus ring */
139-
--perses-focus-ring-color: var(--perses-status-border-primary);
139+
--perses-focus-ring-color: var(--perses-color-blue-200);
140140

141141
/* Text */
142142
--perses-text-primary: var(--perses-color-white);

0 commit comments

Comments
 (0)