Skip to content

feat(F0Select): add inline variant - #5095

Merged
pedroruizpareja merged 13 commits into
mainfrom
feat/f0select-inline-variant
Aug 28, 2026
Merged

feat(F0Select): add inline variant#5095
pedroruizpareja merged 13 commits into
mainfrom
feat/f0select-inline-variant

Conversation

@pedroruizpareja

@pedroruizpareja pedroruizpareja commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a compact, borderless inline variant to F0Select for row-level role and access controls. Inline uses one fixed 32px trigger aligned with F0 typography, icon, and radius tokens; its popup, option rows, selection indicator, and action footer reuse the existing F0Select implementation, leaving the field variant and Dropdown unchanged. Footer actions also honor their existing disabled state in both select variants.

Type of change

  • Component enhancement / variant (existing component, no breaking change)

Screenshots (if applicable)

  • Prototype reference
  • Visual coverage is captured by the Components/Select/Inline Open, Dark Mode, and Snapshot stories.

Implementation details

  • feat: add a compact, borderless variant="inline" for single, non-clearable row controls
  • fix: align the inline trigger with F0 using a fixed 32px height, 14px label typography, 10px radius, and the default icon token
  • refactor: keep size exclusive to the field variant instead of redefining the field size scale for inline
  • refactor: reuse the standard F0Select popup, option rows, selected indicator, and action footer without changing Dropdown
  • feat: make inline popups content-sized by default while preserving the explicit fitContentWidth=false override
  • fix: forward the existing disabled state to footer action buttons and prevent their callbacks from running
  • docs: document inline usage, fixed trigger geometry, limitations, shared popup behavior, footer action states, keyboard interaction, and accessibility guidance
  • test: cover field compatibility, the inline type contract, controlled selection, trigger tokens, popup sizing, standard popup reuse, enabled and disabled footer actions, and Storybook interactions

Known accessibility debt

The Open and Snapshot stories keep axe running in todo mode for the shared popup's existing aria-hidden-focus violation. This PR adds no accessibility skip and does not change the shared popup implementation.

Context


Factorial is conducting an analysis on the impact of the used skills. This was autogenerated, please don't delete:

  • factorial-f0
  • factorial-dev-workflow
  • f0-pr
  • factorial-ci
  • f0-unit-testing
  • f0-component-patterns
  • f0-quality-gate

@pedroruizpareja
pedroruizpareja marked this pull request as ready for review August 19, 2026 09:32
@pedroruizpareja
pedroruizpareja requested a review from a team as a code owner August 19, 2026 09:32
@github-actions github-actions Bot added feat new-component Adds a new component (story file) to packages/react — must meet the full Definition of Done react Changes affect packages/react labels Aug 19, 2026
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

🔍 Review policy: Feature

The PR title starts with feat, so this is a feature: it needs one approval from f0-devs AND one from f0-designers (rule 3).

Required approvals

Team Why Status
@factorialco/f0-devs Features need a dev approval ✅ approved by @sauldom102
@factorialco/f0-designers Features need a design approval ✅ approved by @desiree-np
How this was decided
  • PRs touching only sds/ modules require their owners and nothing else.
  • Otherwise, docs-only changes (*.md, *.mdx, *.stories.tsx, anything in __stories__/) → one f0-general approval.
  • Otherwise, feat: titles → one f0-devs and one f0-designers approval. Not a feature? Fix the title prefix.
  • Anything else → one f0-devs approval.
  • Add the needs-design-review label to also request a design approval on any PR.
  • Creating a new sds/ module (new package.yml) additionally requires an f0-general approval.

Policy source: ownership/review-policy.ts · Team members: ownership/teams.yml

@github-actions

Copy link
Copy Markdown
Contributor

✅ No New Circular Dependencies

No new circular dependencies detected. Current count: 0

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

🔍 Visual review for your branch is published 🔍

Here are the links to:

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

📦 Alpha Package Version Published

Use pnpm i github:factorialco/f0#npm/alpha-pr-5095 to install the package

Use pnpm i github:factorialco/f0#18a81c6a9c4268b45d5177785645d88f6ea3cf64 to install this specific commit

@github-actions

Copy link
Copy Markdown
Contributor

✅ No breaking public API changes

No public exports were removed, renamed, or had existing props/types changed in a breaking way compared to main.

Comparing f0, experimental and ai against main. Adding components, types, or optional props is safe. This check is non-blocking.

➕ Additive changes (safe) — 4
  • f0: F0SelectVariant, selectVariants
  • experimental: F0SelectVariant, selectVariants

⚠️ Could not analyze component-status (no-base) — a build may have failed; results may be incomplete.

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

♿ Accessibility (axe) — components changed in this PR

16 issues across 16 stories — all non-blocking (todo).

Story Rule WCAG Impact Nodes Mode
Components/Select/Inline / Open aria-hidden-focus WCAG 4.1.2 A (2.0) serious 1 🟡 todo
Components/Select/Inline / Snapshot aria-hidden-focus WCAG 4.1.2 A (2.0) serious 5 🟡 todo
Components/Select / Clearable target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Not Paginated target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Paginated target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Paginated With Preview target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Paginated With Apply target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple With Apply target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple With Apply Custom Label target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Paginated As List aria-input-field-name WCAG 4.1.2 A (2.0) serious 1 🟡 todo
Components/Select / As List aria-input-field-name WCAG 4.1.2 A (2.0) serious 1 🟡 todo
Components/Select / Multiple Manual Selection Only target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Preserve Selections target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Clear Selections On Dataset Change target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Multiple Select All With Filters target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo
Components/Select / Single Select With Filters target-size WCAG 2.5.8 AA (2.2) serious 1 🟡 todo

Scope: only stories in the files/component folders this PR changed. It can't yet flag downstream ripple from shared-code/token changes, or diff against main (planned: base-vs-head delta).

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for packages/react

Status Category Percentage Covered / Total
🔵 Lines 69.15% 29295 / 42360
🔵 Statements 68.11% 30993 / 45502
🔵 Functions 61.96% 6980 / 11264
🔵 Branches 61.85% 21999 / 35566
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/react/src/components/F0SearchInput/F0SearchInput.tsx 96.96% 96% 87.5% 100% 48
packages/react/src/components/F0Select/F0Select.tsx 90.64% 82.71% 90% 90.85% 291-293, 333, 357, 490, 493, 642-644, 657, 659, 690, 756, 762-763, 849, 879-887, 967-976, 1097, 1145, 1208-1236
packages/react/src/components/F0Select/types.ts 100% 100% 100% 100%
packages/react/src/components/F0Select/components/SelectBottomActions.tsx 100% 91.66% 100% 100%
packages/react/src/experimental/Navigation/Header/Breadcrumbs/internal/BreadcrumbSelect/index.tsx 73.33% 62.5% 25% 73.33% 24-25, 45, 51
packages/react/src/ui/Select/components/SelectContent.tsx 95.29% 90% 95.65% 96.34% 234, 418, 543-544
packages/react/src/ui/Select/components/radix-ui/index.ts 100% 100% 100% 100%
packages/react/src/ui/Select/components/radix-ui/select.tsx 69.04% 62.56% 71.85% 69.98% 235-237, 287-293, 340, 352, 370-377, 411-433, 452-456, 674-675, 707, 729, 748-750, 772, 802, 810, 867-868, 893, 997-1000, 1018, 1041, 1151-1283, 1312-1315, 1474-1503, 1530-1540, 1559-1562, 1618, 1637-1639, 1681, 1700, 1718, 1721, 1850-1884, 1910-1947, 1965-2021, 2065-2075, 2096, 2099, 2118, 2184, 2225
Generated in workflow #17554 for commit a332069 by the Vitest Coverage Report Action

@albertcalasanzs

Copy link
Copy Markdown
Contributor

Good catch on focusSelectedItem, it feels both natural and optimal to place the containment guard there, and good UX improvement. I was also concerned about this from yesterday when i've noticed strange autofocus behaviours. I tested out your changes but that old setTimeout(50) in F0SearchInput is now unnecessary due to your new fix. That's because effects run child before parent, and thus, the input should just take the focus on mount. Like:
useEffect(() => { if(!props.autoFocus || props.disabled) return; input.current?.focus() }, [props.autoFocus, props.disabled])
What we gain if we delete those timeout+listener+cancel bookkeeping, besides the vestigial 50ms window for fast typing users is to cover autoFocus's flip false->true.
I have it on a local branch on top of yours, plus two new tests: one asserting focus on mount with no timer advanced, one for the false -> true flip. Red/green checked: both fail with the change reverted.
Happy to push it as a follow-up once this lands, or whatever outcome you prefer.

@albertcalasanzs

Copy link
Copy Markdown
Contributor

Here's my follow-up PR: #5194

Implemented-with: factorial-f0

Implemented-with: factorial-dev-workflow/frontend

@sauldom102 sauldom102 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We seem to be introducing another mdx file for the Select component instead of introducing that in existing docs, now we can't access https://66a7a8d7d124220c363457cc-icfinfcjuh.chromatic.com/?path=/docs/components-select--documentation

You can compare it with https://f0.factorial.dev/?path=/docs/components-select--documentation

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

✅ Storybook docs — no pages lost

Every page reachable on main is still reachable here.

➕ 6 added · ✏️ 45 updated

➕ Added (6)

✏️ Updated — 45 page(s)/story/stories across 1 file(s)

The source file behind each of these changed. Detection is per file, so editing one story flags its siblings too.

🔇 Added but not in the sidebar — 1

Expected for snapshot-only and internal stories (no-sidebar / !dev). Listed in case one was meant to be visible.

  • Components/Select/Inline › Snapshotexperimental

Links point at this PR's Storybook build — browse the full Storybook.

Snapshot of the Storybook index (docs pages + stories) compared against main. Non-blocking.

@sauldom102 sauldom102 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When having variant="inline" we're seeing it like this:

Image

@github-actions

Copy link
Copy Markdown
Contributor

✅ No untranslated copy added

Every user-visible string in this PR comes from the i18n layer. Codebase total unchanged at 133.

@pedroruizpareja
pedroruizpareja requested a review from a team August 28, 2026 07:36
desiree-np
desiree-np approved these changes Aug 28, 2026
@pedroruizpareja
pedroruizpareja merged commit 74f7de5 into main Aug 28, 2026
63 of 65 checks passed
@pedroruizpareja
pedroruizpareja deleted the feat/f0select-inline-variant branch August 28, 2026 07:54
@eliseo-juan eliseo-juan mentioned this pull request Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat new-component Adds a new component (story file) to packages/react — must meet the full Definition of Done react Changes affect packages/react

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants