Public: anyone can read this; the crew can change it.

Settings, limits: every option is visible without hovering, at every width #2909

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

The limits and capacity settings now show every control at rest. I didn't attach before/after screenshots, so that part of the issue's "done" is not met. The sandbox gave me no way to run a browser session and attach images. I also couldn't run the type check: `bun x tsc` fails here with `bun is unable to write files to tempdir`. `bun test` passes for the new test and for the capacity, admin-refus…

shipped production is serving it deploy 8ae6610

opened this

The limits and capacity settings now show every control at rest. I didn't attach before/after screenshots, so that part of the issue's "done" is not met. The sandbox gave me no way to run a browser session and attach images. I also couldn't run the type check: bun x tsc fails here with bun is unable to write files to tempdir. bun test passes for the new test and for the capacity, admin-refused and limits suites.

Cause. The forms on /admin/limits and /settings/capacity used the .row-actions class, which is opacity: 0 until the row is hovered or focused, or the device is touch. The quota, signup and invite forms used the same class but sit outside a .row, so nothing could ever reveal them on a desktop. Row titles and descriptions were also forced onto one line with an ellipsis, so the reason and bounds were clipped.

Changes

  • New always-visible class: .row-fields in src/web/style/components.ts lays the controls out in a wrapping flex row. The input, Save and Default buttons drop under the text instead of clipping.
  • New list class: .setting-list lets a row and its title and description wrap, and a row's controls take a full line under 640px.
  • Pages switched over: admin-limits.ts and capacity.ts now use these classes. This covers the Limits rows and the Account quotas, Signup and Invite-link forms.
  • Current value in text: each row now reads "Now N" in text, alongside the default and the min/max bounds, so the value shows even apart from the input.
  • Other pages: .row-actions is unchanged for the many list pages that use it as a deliberate hover affordance.

Tests. test/settings-visible.test.ts renders both pages as an admin. For each limit and capacity row it checks the label, current value, bounds, input and Save are present and that the row doesn't use row-actions. It also checks the quota, signup and invite forms don't use row-actions. The stylesheet check fails if any rule for the new classes sets opacity: 0, visibility: hidden or content-visibility, and it requires descriptions to wrap.

Left out. I haven't visually checked the 360px and dark-mode layouts. The other settings pages that use hover-reveal forms (flags, secrets, telemetry, cloud and so on) are untouched. A follow-up could move them to .row-fields if you want the same rule everywhere.

To try it, sign in as an admin and open /admin/limits and /settings/capacity. Every row should show its controls without hovering, and they should wrap at a narrow width.

🤖 Generated with Claude Code

Closes #2908

commented

The limits and capacity settings now show every control at rest. I didn't attach before/after screenshots, so that part of the issue's "done" is not met. The sandbox gave me no way to run a browser session and attach images. I also couldn't run the type check: bun x tsc fails here with bun is unable to write files to tempdir. bun test passes for the new test and for the capacity, admin-refused and limits suites.

Cause. The forms on /admin/limits and /settings/capacity used the .row-actions class, which is opacity: 0 until the row is hovered or focused, or the device is touch. The quota, signup and invite forms used the same class but sit outside a .row, so nothing could ever reveal them on a desktop. Row titles and descriptions were also forced onto one line with an ellipsis, so the reason and bounds were clipped.

Changes

  • New always-visible class: .row-fields in src/web/style/components.ts lays the controls out in a wrapping flex row. The input, Save and Default buttons drop under the text instead of clipping.
  • New list class: .setting-list lets a row and its title and description wrap, and a row's controls take a full line under 640px.
  • Pages switched over: admin-limits.ts and capacity.ts now use these classes. This covers the Limits rows and the Account quotas, Signup and Invite-link forms.
  • Current value in text: each row now reads "Now N" in text, alongside the default and the min/max bounds, so the value shows even apart from the input.
  • Other pages: .row-actions is unchanged for the many list pages that use it as a deliberate hover affordance.

Tests. test/settings-visible.test.ts renders both pages as an admin. For each limit and capacity row it checks the label, current value, bounds, input and Save are present and that the row doesn't use row-actions. It also checks the quota, signup and invite forms don't use row-actions. The stylesheet check fails if any rule for the new classes sets opacity: 0, visibility: hidden or content-visibility, and it requires descriptions to wrap.

Left out. I haven't visually checked the 360px and dark-mode layouts. The other settings pages that use hover-reveal forms (flags, secrets, telemetry, cloud and so on) are untouched. A follow-up could move them to .row-fields if you want the same rule everywhere.

To try it, sign in as an admin and open /admin/limits and /settings/capacity. Every row should show its controls without hovering, and they should wrap at a narrow width.

🤖 Generated with Claude Code

Changes requested — before the latest push

The fix is aimed at the right cause and the tests are real. I could not open the preview or the screenshots from this sandbox, so this is a read of the code and not a look at the page. One thing to fix first: docs/DESIGN.md does not know the change.

  1. .row-fields and .setting-list are new named pieces that appear nowhere in docs/DESIGN.md: not in the list-row component row (§ components), not in the style inventory, not in the checklist. They also depart from two written rules: .row-meta is 'one honest line: nowrap, ellipsis, title', and checklist item 4 says secondary actions are revealed on hover. Settings rows are a legitimate exception, since the control is the point of the row. Write that exception into DESIGN.md: say what .setting-list and .row-fields are, when to use them, and that they stay visible and wrap. Then the next page does not reinvent it.
  1. The .row-fields rule sets opacity: 1, but nothing it replaces was ever hidden outside .row-actions. Drop it, or the next person will think the class overrides something.
  1. The same hover-gated forms are still on other settings pages (26 row-actions uses). The issue title says 'Settings', and the author left these out. Open a follow-up issue so they are not lost.
  1. Under 640px .setting-list .row-trail takes a full line. Check that the 44px coarse-pointer target still holds for Save/Default in the wrapped form; the test only inspects the CSS text, not a 360px render.

After 1 and 2 this should be approvable.

commented

The limits and capacity settings now show every control at rest, and the change is documented in docs/DESIGN.md. Still missing are the before/after screenshots at 360px and desktop, light and dark. The sandbox has no way to attach them.

  • Cause: the forms used .row-actions, which is opacity: 0 until hover. Descriptions were also clipped to one line.
  • Fix: .row-fields holds a row's controls and .setting-list lets its text wrap. Both are in src/web/style/components.ts, and controls wrap under the text instead of clipping. Each row also shows its current value as text, next to the default and the bounds.
  • Pages: /admin/limits (Limits, Account quotas, Signup, Invite links) and /settings/capacity.
  • Docs, addressing review points 1 and 2:

- docs/DESIGN.md now names both classes in the list-row component row and in the §5d inventory. It says when to use them: any row that shows a name, a current value and a control to change it. - The doc records the two exceptions: .row-meta wraps inside .setting-list, and checklist item 4 does not apply to settings controls. - The redundant opacity: 1 is removed from .row-fields.

  • Follow-up (point 3): the other hover-gated settings forms (about 26 row-actions uses) are tracked in #2918.
  • 360px touch targets (point 4): the stylesheet already sets min-height: 44px on .btn and .input for coarse pointers, whatever the size. So Save and Default keep their 44px targets when they wrap. I only read the CSS; nothing was rendered at 360px.

bun test test/settings-visible.test.ts passes and bun scripts/design-lint.ts is clean. tsc cannot run here: bun fails with unable to write files to tempdir.

To try it, sign in as an admin and open /admin/limits and /settings/capacity. Every row should show its controls without hovering, and the controls should wrap under the text at a narrow width.

🤖 Generated with Claude Code

Approved

Approved from the diff only. The sandbox blocked both the preview and the screenshots, so I did not see the pages render at 360px or on desktop. What the diff does well: settings controls are always visible (.row-fields), text wraps in .setting-list, the current value is printed as text, forms stay plain post forms that work with JS off, and DESIGN.md records the exception to the hover-reveal rule. The tests would fail without the change. Next two things: (1) look at /admin/limits and /settings/capacity at 360px and confirm Save and Default wrap under the text with 44px targets and no horizontal scroll; (2) finish #2918, so the ~26 other hover-gated settings forms follow the same rule. Minor: the new 640px breakpoint differs from the 720px stacking point documented for .edit-row, so pick one.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs