Skip to content

feat(PowerSearchMobile): the touch form of PowerSearch - #5314

Draft
imdreamrunner wants to merge 1 commit into
mainfrom
feat/powersearch-mobile
Draft

feat(PowerSearchMobile): the touch form of PowerSearch#5314
imdreamrunner wants to merge 1 commit into
mainfrom
feat/powersearch-mobile

Conversation

@imdreamrunner

@imdreamrunner imdreamrunner commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

What

PowerSearchMobile — the touch form of PowerSearch, in core.

Following the mobile exploration: Mobile Prototypes → PowerSearch ("bottom sheet, pinned tall").

Why

PowerSearch's desktop shape doesn't survive a phone. The typeahead drops a popover that fights the on-screen keyboard, and the edit popover lays field / operator / value out in a row that has nowhere to go at 390px.

How

Same props, same PowerSearchFilter model, same tokens. The typeahead dropdown and the row-shaped popover are replaced by a pinned-tall bottom sheet that drills down field → operator → value. Pick between the two variants on viewport and the call site does not change:

const isTouch = useMediaQuery('(max-width: 768px)');
const Search = isTouch ? PowerSearchMobile : PowerSearch;
<Search config={config} filters={filters} onChange={setFilters} />
Tap target The same input shell, showing the filters as tokens. Tapping a token reopens its editor, where Delete removes it; the token's own × removes it in place.
Field list Grouped by field.group, each row captioned with the operator it will produce. Past seven fields it gains a search box pinned under the sheet title.
Operator A drill-down row, shown only when the field defines more than one. With one, the sheet header carries it — so the happy path stays two taps, as in the prototype.
Value enum commits on a single tap (Selector's mobile pattern); enum_list applies from a pinned footer (MultiSelector's); an empty operator lands with no value step at all; every other type falls through to the shared PowerSearchValueEditor.

Both sheets are height="tall": the field list resizes as it is searched and the editor's content changes with the operator, so a self-sizing sheet would jump on every keystroke and every step — and tall is the only height that gives mobile-keyboard accommodation, which the text and number editors need. The editor sheet is purpose="form", so a stray scrim tap can't discard a half-built filter.

nested filter groups have no touch editor yet. Fields whose only operators are nested are left out of the list and a dev warning says so, rather than opening a blank sheet.

Accessibility

  • The field label names the group, not the tap target — a <label> pointed at the button would replace its visible text as the accessible name (WCAG 2.5.3). The button is named by its own text, and carries aria-haspopup="dialog" + aria-expanded.
  • disabledMessage keeps the target focusable via aria-disabled and describes it, so the reason is reachable by keyboard; the action stays blocked.
  • Result-count changes are announced through the same polite live region as the desktop variant.

Screenshots

Light and dark, iPhone 15: assets/pr-5314

Tap target Field list Value (enum) Operators
Value (multi) Edit + delete Value (text) Field search
Dark
Tap target Field list Value (enum) Operators
Value (multi) Edit + delete Value (text) Field search

Test plan

  • 23 new tests in PowerSearchMobile.test.tsx, covering the whole flow: field → operator → value, the enum single-tap commit, the multi-select apply, the empty-operator shortcut, edit/delete, clear-all keeping read-only filters, read-only and disabled, the field search and its empty state, the nested-field warning, and the imperative handle.
  • Driven in a real browser at iPhone 15 (light + dark) against built dist: the flow works end to end with no console errors, the tablet sheet caps at 640px, and the read-only / disabled / error states behave.
  • Gates: pnpm lint:strict, pnpm build, pnpm test (7527 core+lab, 2804 cli+apps), typecheck + typecheck:docs across core/lab/charts/cli/storybook, pnpm -F @astryxdesign/storybook build, pnpm lab:readiness:check — all green.

Notes for reviewers

  • Four props describe desktop-only affordances and are inert here — hasAutoFocus, menuWidth, maxOperatorMenuItems, tokenOverflowBehavior — documented on the prop table rather than removed, so one call site can feed both variants.
  • handleRef's focusTypeahead() / blurTypeahead() move focus to and from the tap target; there is no typeahead input on this variant.
  • The seven-field threshold for the search box is the number CheckboxList already uses to send a long list to MultiSelector.

PowerSearch's desktop shape does not survive a phone: the typeahead drops
a popover that fights the on-screen keyboard, and the edit popover lays
field / operator / value out in a row that has nowhere to go at 390px.

PowerSearchMobile keeps the props, the filter model and the tokens, and
moves the building into a pinned-tall bottom sheet that drills down
field -> operator -> value:

- the tap target is the same input shell, showing the filters as tokens;
  tapping one reopens its editor, where Delete removes it
- the field list is grouped, and past seven fields gains a search box
  pinned under the sheet title
- an operator is a drill-down row, shown only when the field defines more
  than one; with one, the header carries it, so the happy path is two taps
- enum commits on a single tap (Selector's mobile pattern), enum_list
  applies from a pinned footer (MultiSelector's), an empty operator lands
  with no value step at all, and every other type falls through to the
  shared value editor
- nested filter groups have no touch editor yet: those fields are left out
  of the list and a dev warning says so

Follows the mobile exploration at
facebook.github.io/astryx/sandbox/pages/mobile-prototypes/?p=powersearch
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Aug 22, 2026
@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
astryx Ready Ready Preview Aug 22, 2026 12:31am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

Modified Components

PowerSearch (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 4720 -
Complexity N/A Very High (480) -

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.8KB 1.2KB

Accessibility Audit

Status: 1 accessibility violation(s) found — 1 serious.

PowerSearch - 1 issue(s)
  • 🟠 serious: Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds
    • Rule: color-contrast · Affects 2/25 stories · Learn more
    • WCAG: 1.4.3 (Level AA)

Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

github-actions Bot added a commit that referenced this pull request Aug 22, 2026
@imdreamrunner
imdreamrunner marked this pull request as draft August 22, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant