Repository navigation
fix(fields, plugin-form): form controls reach a 44 px touch target at phone width - #29209
Merged
Merged
Conversation
…low sm At phone width the create / edit form's registered field widgets kept the primitives' 40 px (inputs, select trigger, lookup trigger), 32 px (select options, calendar days, line-item cells, lookup search) and 28 px (date picker buttons) heights. They now carry the same `min-h-[44px] sm:min-h-0` token the form renderer's built-in controls already do, and the form footers' buttons do too. From `sm` up nothing changes. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jUqXiWNJKjMJYThRr1
…low sm Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jUqXiWNJKjMJYThRr1
…d and by class Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jUqXiWNJKjMJYThRr1
This was referenced Nov 2, 2026
… touch floor below sm The take-photo button (Button size sm, 36 px) gets PHONE_TOUCH_HEIGHT and the per-file remove button (24 px) gets PHONE_TOUCH_SQUARE, from #29071's run. Pinned in the touchTarget test. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jUqXiWNJKjMJYThRr1
Contributor
Author
|
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y 席位核对 · ACCEPT · 2026-11-02T10:11ZHead-sha:
Generated by Claude Code |
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.
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y
Requested by Steedos · project thread
Fixes #29072
Clause-②: no
Metadata-protocol: none
维护者速读
sm,640 px)下,新建 / 编辑表单里的输入框、下拉、查找字段、日期选择器、明细行表格和表单底部按钮,触控区域统一达到 44 px;桌面宽度外观不变。min-h-[44px] sm:min-h-0,与表单内置控件已用的同一个记号),不改逻辑、不改导出、不改元数据;回滚即 revert 本 PR。ui/packages/fields/src/widgets/date-picker/DatePickerField.tsx(右侧按钮变大后输入框右内边距改为pr-24 sm:pr-16、日历格子 44 px);ui/packages/fields/src/widgets/LookupField.tsx;ui/packages/fields/src/widgets/touchTarget.ts。What changes
At phone width (below
sm), the create / edit form's registered field widgets now carry the same touch floor the form renderer's built-in controls already use,min-h-[44px] sm:min-h-0, through a package-internal token moduleui/packages/fields/src/widgets/touchTarget.ts(not re-exported, so no published surface moves). Fromsmup every control keeps its previous height.sm([--cell-size:2.75rem] sm:[--cell-size:2rem]passed to theCalendarprimitive, whichcnmerges over its default). Seven 44 px days plus the calendar padding measure 332 px, inside a 343 px form column at 375 px. The input's right padding grows topr-24belowsmso its text stops short of the two 44 px buttons.PHONE_TOUCH_HEIGHTand the per-file remove buttonPHONE_TOUCH_SQUAREinFileField.tsx. Their before sizes, 36 px (Buttonsize="sm",h-9) and 24×24 (h-6 w-6), were read from theButtontoken and the class, not measured on a page; no create form in either example drew a file field on this flow.Fence check:
FormPage.tsxis not touched (its refusal path stays with #29019), norsectionFields.ts(#29021),sheet.tsx(#29078),dialog.tsx(#29107),navigation-overlay.tsx,record-list-face.tsx,ObjectView.tsx,recordOpenPreference.ts,ui/packages/mobile/**, the console'smain/App/AppContent, or any shared chrome. Noui/packages/components/src/ui/**primitive is edited: every change is a className handed to it.Run record
Driven in Chromium (Playwright,
isMobile,hasTouch, DPR 2) at 375×812 and 390×844, against the Console served from source (Vite) overexamples/app-crmandexamples/app-showcasestarted withobjectstack dev --seed-admin --fresh. Flow per object: list → phone create button → create form → select listbox → date picker (where the object has one) → lookup dropdown → browse-all record picker → keyboard check on the last and a middle text control → clear the required field and submit (validation) → open a seeded record → Edit form. Before = merge basea4015ab4(the widget sources restored from it), after = this branch head.How each check was measured
document.documentElement.scrollWidthagainstinnerWidth, and every element in the open dialog whose box crosses the viewport edge without anoverflow-xancestor clipping it (the line-item table and the picker table scroll inside their own containers, which is by design).button,input,select,textarea,[role=combobox],[role=option],[role=checkbox],[role=switch],a[href]and the percent slider root inside the open dialog, listbox or popover, by bounding box, against 44 px on both axes.adjustResizemodel: focus the control, shrink the layout viewport by 336 px (a Gboard-height keyboard on an 812 px screen), let the browser scroll the focused editable into view, then assert its box is inside the shortened viewport andelementFromPointat its centre hits it (no sticky footer or header over it). A real device IME was not exercised.Emulation.setCPUThrottlingRate4 on the production Console bundle (pnpm console:build, served at/_consolebyobjectstack dev), with 300 extra accounts seeded through the data API. Pass = every Event Timing entry (click, key) at most 200 ms (the "good" INP line), and no long task over 200 ms while scrolling. The dev-server (unbundled React) numbers the harness also prints are 2–3× slower and are not the reading.Tests
ui/packages/fields/src/widgets/touchTarget.formControls-29072.test.tsx(14 cases): the token shape, each input widget, a host className still reaching the input beside the token, the slider root, the select trigger and options, the lookup trigger / clear / browse-all, the date picker's input, buttons and calendar cell size, and the file field's camera and remove buttons. Reverse-verified: with the widget sources restored from the merge base, 12 of 13 go red (the token-shape case reads only the new module).ui/e2e/form-controls-phone-touch.spec.ts(3 cases, shape ofrecord-path-phone-row.spec.ts): reads the tokens, theInput/ icon-Buttonbase heights and the calendar's cell-size classes out of the sources, compiles real Tailwind for them, and measures a fixture: at 375 and 390 px the input, the date-picker button, the browse-all button and all seven calendar days are at least 44 px and the calendar ends inside the form column with no page scroll; at 1024 px the primitives keep 40 / 28 / 40 / 32 px. Red on the merge base (the date picker carries no cell-size override there).Acceptance notes
DialogContent, whose Close button measures 16×16 px at both widths (CRM lead and opportunity Account picker, showcase task Project picker).dialog.tsxis Dialog close button at phone width: the X in the shared Dialog is a 16x16 px target, below the 44 px minimum, in every modal the mobile app shows #29107's file, so it is left as is here.RecordFormPagewas not reached. The drawer form's footer gets the same token for parity.Verification
At head
99a5359b(main merged atdedc3505; main touched none of these files). The file-field commit was re-verified on its own: the touchTarget test 14 / 14 (its new file case red withFileField.tsxfrom the previous head), the touched test files pluscomplex-widgets.test.tsx110 files / 851 tests, the@object-ui/fieldstype-check 47 tasks exit 0, ESLint on the file 0 errors,check-sdui-manifest0. The readings below were taken at6034e7ec:node scripts/pm/dispatch-gates.mjs --ran: 34 derived, 34 run, all exit 0.pnpm --dir ui exec vitest run scripts/was killed once by memory pressure while the run-record servers were up; rerun alone it passes (169 files, 4900 tests).node scripts/check-sdui-manifest.mjs: exit 0, after the merge.@object-ui/fieldsand@object-ui/plugin-form(turbo, 49 tasks): exit 0. ESLint on the changed files: 0 errors.6034e7ec, 14 now) and the touched widgets' and form footers' existing test files: 106 files, 768 tests, pass after the merge. The e2e spec: 3 pass.99a5359b: 20 files, +405 / −38, well under 3000 lines. No exported type of a published package moves.The os-dev report on #29072 carries the same readings.
Generated by Claude Code