Repository navigation
fix(components): dropdown-menu rows and tabs reach a 44 px touch target at phone width - #29348
Merged
Merged
Conversation
Below sm, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuSubTrigger and TabsTrigger get max-sm:min-h-11, and TabsList max-sm:h-auto so it grows with its triggers. From sm up every class list is upstream's. Declared as shadcn local patches with vendored registry fixtures. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jSMMkBJxrdeZwTifs8
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jSMMkBJxrdeZwTifs8
Contributor
Author
|
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m 席位核对 · ACCEPT · 2026-11-02T12:53ZHead-sha:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Steedos · project thread
Fixes #29215
Clause-②: no
Metadata-protocol: none
维护者速读
max-sm:前缀的样式类,桌面不受影响;手机上带固定高度的标签栏(如 AI 对话页的紧凑切换器)会变高。回滚即 revert 本 PR。ui/scripts/shadcn-local-patches.mjs(新增的两组补丁声明)、ui/packages/components/src/ui/tabs.tsx(TabsList 与 TabsTrigger 两行)、ui/packages/components/src/__tests__/menu-tabs-touch-target-29215.test.tsx。pnpm --dir ui exec vitest run packages/components/src/__tests__/menu-tabs-touch-target-29215.test.tsx scripts/__tests__/shadcn-local-patches.test.ts,预期全绿;或在 375 px 宽的 Console 打开任一记录页点「More actions」,每行高 44 px。What changes
sm, everyDropdownMenurow is at least 44 px tall:DropdownMenuItem,DropdownMenuCheckboxItem,DropdownMenuRadioItemandDropdownMenuSubTriggereach gainmax-sm:min-h-11right after theirpy-1.5.DropdownMenuSubTriggeris included because a phone user taps it to open the sub-menu;DropdownMenuLabelis not a control and is left alone.sm,TabsTriggergainsmax-sm:min-h-11, andTabsListgainsmax-sm:h-autoat the end of its class string, so the list drops its fixedh-10there and grows with its triggers.smup, every class list is upstream's, token for token. No export, prop orTabsContentchange.dropdown-menu.tsxandtabs.tsxare Shadcn-synced (ui/AGENTS.mdcommandment 7), so both edits are declared inui/scripts/shadcn-local-patches.mjsas two new families,dropdownMenuRowTouchTargetPatchesandtabsTouchTargetPatches, built by one smallphoneTouchTargetPatchhelper that inserts the phone class after a named token inside a registry anchor. The shipped files were written by applying those patches, andpnpm shadcn:updatere-applies them. The checkbox and radio items share one upstream class string, so their anchor declares two occurrences.LOCAL_PATCHES, so the registry provenance test requires vendored fixtures:ui/scripts/__tests__/fixtures/shadcn-registry/dropdown-menu.registry.txtandtabs.registry.txt, captured verbatim from shadcn-ui/ui8a7701ec27eb9cb8e0377db769fbe6d744113c52throughraw.githubusercontent.com. The same capture reproducesdialog's recorded sha256 byte for byte.tabsround-trips byte for byte (roundTrip: true).dropdown-menucannot, because it already ships the undeclared Tailwind v4origin-(--radix-…)spelling thatshadcn-components.jsondocuments, so its entry pins the inequality with that reason, ascalendardoes.ui/packages/components/shadcn-components.json: thedropdown-menulocalEditsnote names the new patch beside the Tailwind v4 note, andtabsgains alocalEditsnote..changeset/29215-menu-tabs-phone-touch-target.md:@object-ui/componentspatch.Tests
ui/packages/components/src/__tests__/menu-tabs-touch-target-29215.test.tsx(10 cases). For each ofDropdownMenuItem,DropdownMenuCheckboxItem,DropdownMenuRadioItem,DropdownMenuSubTrigger,TabsTriggerandTabsList, the rendered element carries exactly the one phone class, and every other token equals upstream's list in order. A label andTabsContentget no phone class. A caller's ownpy-2, orh-7andh-6, still merge throughcn, and the phone class survives them.ui/scripts/__tests__/shadcn-local-patches.test.ts: provenance entries for the two fixtures, plus a new describe block. It checks the declared ids. Applied to registry bytes, each family adds onlymax-sm:classes, leaves every class string's other tokens identical in order, and adds exactly 4max-sm:min-h-11for dropdown-menu and 1max-sm:min-h-11plus 1max-sm:h-autofor tabs. Only the four menu rows carry the floor, andTabsListstill opens withinline-flex h-10(the openinge2e/approvals-inbox-phone.spec.tsreads it by). The family refuses when upstream re-pads the item (found 0x), and when the checkbox and radio rows stop sharing a class string (found 1x).ui/packages/components/src/__tests__/__snapshots__/snapshot-critical.test.tsx.snap: the two "Tabs snapshots" regenerated withvitest --update. The diff is theTabsListandTabsTriggerclass attributes only, gainingmax-sm:h-autoandmax-sm:min-h-11. A sweep of every*.snap,*.test.*and*.spec.*file for the upstream item, trigger and list class strings finds no other pin.scripts/ablation-replace.mjs(anchor 1 to 0, restore verifiedgit diff HEADempty): withmax-sm:min-h-11dropped fromDropdownMenuItemin the shipped file, 3 cases go red. They are "DropdownMenuItem: at least 44 px below sm, upstream classes from sm up", "a caller's own padding still merges, and the phone floor survives it" and "dropdown-menu.tsx carries its declared patches".Acceptance notes
min-h-[44px] sm:min-h-0. This PR usesmax-sm:min-h-11andmax-sm:h-autoinstead, accepted by the seat before the build. It follows the shadcn-patch precedent on main (the Sheet close and Dialog close families aremax-sm:only). It leaves every desktop token byte-identical to upstream, which the tests assert token for token.sm:min-h-0would also change desktopmin-heightfromautoto0, which matters in aflex-coltab list (the verticaltabsrenderer,ViewSwitcher's vertical orientation). The helper Console at phone width: Forms flow audit and fixes at 375 and 390 px #29072 landed (touchTarget.ts) is internal to@object-ui/fields, so@object-ui/componentscannot import it either way.TabsListorTabsTriggergiven a fixed height by its caller still gets the phone floor, becausemax-sm:classes do not conflict with unprefixed ones intailwind-merge. The AI chat page's compact assistant switcher (h-7list,h-6triggers) is therefore 45 px tall belowsm. That is the card's intent: every tab strip.ApprovalsInboxPage(tabTouch),InboxPopover(TAB_TRIGGER_CLASS) andAppHeader(max-md:[&_[role=menuitem]]:min-h-11) already lift their own tabs or menu rows belowmd. They still own 640 to 767 px, so nothing is removed here.ContextMenu,Menubar,SelectandCommandrows have the samepy-1.5shape upstream. This card names only DropdownMenu and Tabs.Verification
objectstack dev --seed-admin --fresh) plus the Console Vite dev server on source, Playwright, CRM account record page (/apps/crm_app/crm_account/record/:id). Before means main'sdropdown-menu.tsxandtabs.tsx, with Vite restarted with--forcebefore the leg; the files were restored from HEAD afterwards andgit statuswas clean.TabsTriggerin real Chromium with real Tailwind (the installedtailwindcss, compiled for the class strings read out of eachtabs.tsx): 375 px, trigger 32 to 44 px and list 40 to 52 px. 1280 px, trigger 32 px and list 40 px in both legs.RecordTabRowin@object-ui/plugin-detail, anh-9button strip, so it measures 36 px in both legs and both widths. It is reported to the seat as a separate finding and is not changed here.dispatch-gates --commandsderives for this diff all exit 0, and the--ranreconciliation reads 36 derived, 36 run, 0 NOT-MEASURED. They includenode scripts/check-sdui-manifest.mjsandpnpm --dir ui exec vitest run scripts/(169 files, 4921 tests passed).@object-ui/componentstype-check (withtsconfig.test.json),pnpm --dir ui run type-check:scripts, eslint on the five touched source and test files andpnpm check:new-line-citations(0 new) all exit 0, measured at 43e61db.snapshot-critical, the patch registry test and main's newphoneCardRowActions-29150re-run green (6 files, 111 tests), andcheck-sdui-manifestexits 0. The whole components package is left to CI Test UI.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01QsR2jSMMkBJxrdeZwTifs8
Generated by Claude Code