Skip to content

refactor(react): trim high-usage boundaries - #5313

Closed
somebody32 wants to merge 1 commit into
codex/f0-bundling-runtime-boundariesfrom
codex/f0-usage-prioritized-boundaries
Closed

refactor(react): trim high-usage boundaries#5313
somebody32 wants to merge 1 commit into
codex/f0-bundling-runtime-boundariesfrom
codex/f0-usage-prioritized-boundaries

Conversation

@somebody32

Copy link
Copy Markdown
Contributor

Description

This draft stacks on #5312 and uses an exact Factorial production-usage audit to trim the highest-value reusable runtime boundaries while preserving public APIs and behavior. It also makes the preserved ESM graph self-contained for Atlaskit consumers and keeps the existing legacy experimental import path tree-shakeable for Factorial without a migration prerequisite.

Implementation details

  • refactor: replace the markdown-capable ellipsis dependency in plain labels with a lightweight, behavior-compatible boundary
  • refactor: keep F0Button tooltip ownership stable while removing its markdown runtime and preserving focus through overflow measurement
  • refactor: split canvas confetti from the generic emoji utility while preserving the public useEmojiConfetti export
  • refactor: narrow F0Card metadata renderer imports to its supported renderer set
  • fix: publish the legacy dist/experimental path through preserved ESM so existing Factorial imports tree-shake
  • fix: embed Atlaskit and its transitive runtime closure in preserved ESM, including packable hashed CSS assets
  • test: expand packed bundle baselines to 20 consumer variants and 5 esbuild Cloudflare probes with strict ceilings
Production usage evidence

The audit used Factorial origin/main at 81a7538e2eb432f2fbf6c27629917109ad9da6d8. It scanned all 4,559 source files mentioning F0 and counted 4,008 production files after excluding tests, stories, generated files, fixtures, and type-only imports.

Highest direct production usage included F0Box at 6,459 references in 969 files, F0Text at 1,511 in 588, F0Dialog at 994 in 470, f0FormField at 937 in 211, and F0Button at 885 in 526. Factorial also has 1,438 production imports from the legacy dist/experimental path.

F0Form was deliberately not made the center of this PR: it has only 27 references in 26 production files despite its large packed boundary.

Packed before and after evidence

Measured Brotli initial JavaScript from the packed package:

  • F0Button: 160,410 to 111,221 bytes, down 30.7 percent
  • F0Dialog: 893,437 to 824,615 bytes, down 7.7 percent
  • F0Select: 866,521 to 797,274 bytes, down 8.0 percent
  • OneDataCollection: 1,043,277 to 1,020,809 bytes, down 2.2 percent
  • F0AiChat: 168,202 to 122,434 bytes, down 27.2 percent
  • F0PdfViewer initial: 1,309,388 to 1,238,072 bytes, down 5.4 percent
  • Legacy Stack: about 1.87 MiB initial and 4.46 MiB total to 46 KiB initial and total

Cloudflare-style esbuild probes now hold F0Button at 392.4 KiB raw, root F0Button at 401.9 KiB, legacy Stack at 165.9 KiB, legacy F0TableOfContent at 2,693.7 KiB, and F0Dialog plus F0Button at 3,653.6 KiB.

An attempted eager SVG URL replacement for the flag registry produced much smaller but invalid post-esbuild URLs. It was rejected and removed before this commit. The reported numbers preserve the correct inline flag components and are the honest release values.

Validation
  • full production build passed, including declarations and published-runtime checks
  • packed consumer matrix passed for all 20 variants
  • all 5 packed esbuild Cloudflare probes passed
  • format, strict TypeScript, lint, and cycle detection passed
  • 598 unit test files passed, with 7,475 passing tests, 3 expected failures, and 13 skips
  • pre-commit and pre-push repository hooks passed
  • independent accessibility, Storybook and docs, test coverage, and code quality reviews reported no blockers
Remaining boundaries

The generic AvatarVariant contract still makes F0Card, F0Dialog, and F0Select retain the complete flag registry when any runtime avatar variant is accepted. Removing that cost safely requires an API or asset-delivery redesign; this PR does not hide it behind relocation-unsafe URLs.

F0Form remains about 1.33 MiB Brotli but is low production usage. Both are better follow-up targets than expanding this review surface further.

@github-actions github-actions Bot added refactor react Changes affect packages/react labels Aug 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Review policy: Code change

Default rule: any other change needs one approval from f0-devs (rule 4).

Module ownership (via CODEOWNERS)

Module Code owner Files touched
sds/Home @factorialco/foundations 1
sds/chat @factorialco/platform-ai-building-blocks 3
sds/social @factorialco/talent-spaces 1

Declared in each module's package.yml. Wrong owner? Edit the manifest and run pnpm ownership.

Required approvals

Team Why Status
@factorialco/f0-devs Every code change needs a dev approval ⏳ pending
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

📦 Alpha Package Version Published

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

Use pnpm i github:factorialco/f0#0e785f6175730f873c803811541f628b52cab100 to install this specific commit

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Visual review for your branch is published 🔍

Here are the links to:

@github-actions

Copy link
Copy Markdown
Contributor

♿ Accessibility (axe) — components changed in this PR

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

Story Rule WCAG Impact Nodes Mode
Kits/AI/F0AiChatTextArea / Transition Demo color-contrast WCAG 1.4.3 AA (2.0) serious 2 🟡 todo
Kits/AI/F0AiChatTextArea / With Disclaimer color-contrast WCAG 1.4.3 AA (2.0) serious 2 🟡 todo
Kits/AI/F0AiChatTextArea / With Footer color-contrast WCAG 1.4.3 AA (2.0) serious 1 🟡 todo
Kits/AI/F0AiChatTextArea / With Disclaimer And Footer color-contrast WCAG 1.4.3 AA (2.0) serious 2 🟡 todo
Kits/AI/F0AiChatTextArea / Fullscreen Welcome color-contrast WCAG 1.4.3 AA (2.0) serious 1 🟡 todo
Kits/AI/F0AiChatTextArea / With Welcome Suggestions Inside color-contrast WCAG 1.4.3 AA (2.0) serious 2 🟡 todo
Kits/AI/F0AiChatTextArea / With Many Welcome Suggestions Inside color-contrast WCAG 1.4.3 AA (2.0) serious 2 🟡 todo
Kits/AI/F0AiChatTextArea / With Collapsed Welcome Suggestions color-contrast WCAG 1.4.3 AA (2.0) serious 2 🟡 todo
Kits/AI/F0AiChatTextArea / Clarifying color-contrast WCAG 1.4.3 AA (2.0) serious 5 🟡 todo
Kits/AI/F0AiChatTextArea / Clarifying Multi Select color-contrast WCAG 1.4.3 AA (2.0) serious 5 🟡 todo
Kits/AI/F0AiChatTextArea / Everything color-contrast WCAG 1.4.3 AA (2.0) serious 2 🟡 todo
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/EntitySelect/EntitySelect / With Deactivated Entities color-contrast WCAG 1.4.3 AA (2.0) serious 1 🟡 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
Domain specific/Home/ClockInControls / Horizontal Bar With Optional Pickers target-size WCAG 2.5.8 AA (2.2) serious 2 🟡 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 / Multiple Paginated As List nested-interactive WCAG 4.1.2 A (2.0) serious 12 🟡 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

Copy link
Copy Markdown
Contributor

Coverage Report for packages/react

Status Category Percentage Covered / Total
🔵 Lines 69.79% 30320 / 43442
🔵 Statements 68.75% 32142 / 46751
🔵 Functions 62.47% 7200 / 11524
🔵 Branches 62.61% 22794 / 36406
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/react/src/components/F0Button/internal.tsx 100% 86.66% 100% 100%
packages/react/src/components/F0Button/components/ButtonLabel.tsx 94.11% 50% 100% 100% 21
packages/react/src/components/F0Card/CardInternal.tsx 89.65% 89.28% 90% 89.65% 379, 394-395
packages/react/src/components/F0Card/types.ts 100% 100% 100% 100%
packages/react/src/components/F0Card/components/CardMetadata.tsx 85.71% 50% 100% 85.71% 55-61
packages/react/src/components/F0InputField/AppendTag.tsx 100% 100% 100% 100%
packages/react/src/components/F0InputField/components/Label.tsx 100% 100% 100% 100%
packages/react/src/components/F0Select/F0Select.tsx 90.67% 82.71% 90% 90.88% 301-303, 343, 367, 500, 503, 652-654, 667, 669, 700, 766, 772-773, 859, 889-897, 977-986, 1107, 1155, 1221-1249
packages/react/src/components/F0Select/components/SelectAll.tsx 63.63% 57.14% 60% 63.63% 33-36, 86
packages/react/src/components/F0Select/components/SelectItem.tsx 100% 87.87% 100% 100%
packages/react/src/components/F0Select/components/SelectedItems.tsx 88.88% 84.61% 100% 88.46% 86, 90-95, 127
packages/react/src/components/F0Select/components/SelectionPreview.tsx 7.69% 0% 0% 8.33% 33-131
packages/react/src/components/avatars/F0AvatarFlag/F0AvatarFlag.tsx 100% 75% 100% 100%
packages/react/src/components/tags/internal/BaseTag/index.tsx 100% 75.86% 100% 100%
packages/react/src/deprecated/EntitySelect/Trigger/index.tsx 0% 0% 0% 0% 14-164
packages/react/src/experimental/Navigation/F0TableOfContent/TOCFooter/index.tsx 100% 100% 100% 100%
packages/react/src/kits/F0DataChart/components/FunnelChart/FunnelChart.tsx 95.23% 70.58% 100% 100% 22
packages/react/src/kits/ai/Banners/F0AiBanner/AiBannerInternal.tsx 50% 0% 0% 50% 19-75, 80-110
packages/react/src/kits/ai/Banners/F0Callout/CalloutInternal.tsx 0% 0% 0% 0% 13-151
packages/react/src/kits/ai/F0AiChat/components/markdownRenderers/components/Table.tsx 0% 0% 0% 0% 16-114
packages/react/src/kits/ai/F0AiChatHeader/F0AiChatHeader.tsx 90% 81.08% 100% 94.73% 39-43, 45
packages/react/src/kits/ai/F0AiChatHeader/components/CreditsPopover.tsx 0% 0% 0% 0% 21-180
packages/react/src/kits/ai/F0AiChatHeader/components/EmployeeCreditsPopover.tsx 100% 83.33% 100% 100%
packages/react/src/kits/ai/F0AiChatHistory/F0AiChatHistory.tsx 0% 0% 0% 0% 22-207
packages/react/src/kits/ai/F0AiChatHistory/components/ThreadItem.tsx 53.84% 54.54% 42.85% 53.84% 58-64, 96-104
packages/react/src/kits/ai/F0AiChatTextArea/F0AiChatTextArea.tsx 90.22% 79.7% 91.66% 94.19% 49, 130-135, 271, 275, 306, 307, 324, 325, 328-330, 340-341, 421, 441, 681
packages/react/src/kits/ai/F0AiChatTextArea/components/MentionPopover.tsx 56.52% 26.92% 42.85% 52.38% 54-56, 65-115
packages/react/src/kits/ai/F0AiTableCard/F0AiTableCard.tsx 57.14% 61.53% 50% 57.89% 19-21, 61-64, 104-109
packages/react/src/kits/ai/F0ClarifyingPanel/components/StepHeader.tsx 100% 100% 100% 100%
packages/react/src/kits/ai/canvas/F0CanvasCard/F0CanvasCard.tsx 100% 100% 100% 100%
packages/react/src/lib/emoji-confetti.ts 40% 0% 50% 40% 11-30
packages/react/src/lib/emojis.tsx 100% 100% 100% 100%
packages/react/src/lib/exports.ts 100% 100% 100% 100%
packages/react/src/lib/OneEllipsis/OneEllipsis.tsx 100% 82.92% 100% 100%
packages/react/src/lib/OneEllipsis/PlainEllipsis.tsx 100% 96.29% 100% 100%
packages/react/src/lib/OneEllipsis/index.tsx 100% 100% 100% 100%
packages/react/src/lib/OneEllipsis/types.ts 100% 100% 100% 100%
packages/react/src/lib/OneEllipsis/use-ellipsis-overflow.ts 100% 100% 100% 100%
packages/react/src/patterns/F0AnalyticsDashboard/components/DashboardItem/DashboardItem.tsx 80.7% 87.96% 60% 84% 204, 225, 452-477, 529-530
packages/react/src/patterns/Navigation/Sidebar/Chats/SidebarChatItem.tsx 90% 91.37% 66.66% 89.47% 16-25
packages/react/src/patterns/Navigation/Sidebar/CompanySelector/index.tsx 0% 0% 0% 0% 43-186
packages/react/src/patterns/Navigation/Sidebar/Footer/index.tsx 0% 0% 0% 0% 35-76
packages/react/src/patterns/Navigation/Sidebar/Menu/index.tsx 0% 0% 0% 0% 64-715
packages/react/src/patterns/OneDataCollection/components/ActionBar/OneDataCollectionActionBar.tsx 90% 89.79% 80% 90.62% 32-35, 57, 66, 135
packages/react/src/patterns/OneDataCollection/visualizations/collection/List/components/ItemTeaser.tsx 100% 71.42% 100% 100%
packages/react/src/patterns/OneDataCollection/visualizations/collection/Table/components/SortAndHideList/SortAndHideList.tsx 89.65% 92.2% 80% 91.22% 32, 120, 225-228, 280, 284
packages/react/src/patterns/OneFilterPicker/components/FilterList.tsx 100% 94.44% 100% 100%
packages/react/src/patterns/OneFilterPicker/filterTypes/InFilter/InFilter.tsx 86.02% 81.33% 81.48% 86.66% 129, 145, 195-204, 244-247, 254, 258, 263-264
packages/react/src/patterns/OneFilterPicker/filterTypes/InFilter/components/InFilterFlatOption.tsx 100% 100% 100% 100%
packages/react/src/patterns/OneFilterPicker/filterTypes/InFilter/components/InFilterOptionRow.tsx 92.59% 83.33% 87.5% 96% 56, 64
packages/react/src/sds/Home/ClockIn/ClockInControls/index.tsx 81.25% 86.88% 50% 82.6% 288-295, 300-306, 311-313
packages/react/src/sds/chat/F0Chat/components/ChatEmojiAutocomplete.tsx 85% 72.22% 100% 83.33% 50-52
packages/react/src/sds/chat/F0Chat/components/ChatMentionPopover.tsx 82.14% 78.78% 87.5% 80% 62-64, 110-111
packages/react/src/sds/chat/F0Chat/components/ChatReactionPill.tsx 84.21% 76% 80% 83.78% 100-106
packages/react/src/sds/social/Reactions/reaction.tsx 76.47% 65.51% 66.66% 75.75% 54, 78-84, 98
packages/react/src/ui/value-display/types/country/country.tsx 33.33% 0% 0% 33.33% 22-30
packages/react/src/ui/value-display/types/longText/longText.tsx 100% 77.77% 100% 100%
packages/react/src/ui/value-display/types/person/person.tsx 100% 75% 100% 100%
packages/react/src/ui/value-display/types/text/text.tsx 100% 66.66% 100% 100%
Generated in workflow #17686 for commit 98b66b4 by the Vitest Coverage Report Action

@somebody32 somebody32 closed this Sep 1, 2026
@somebody32
somebody32 deleted the codex/f0-usage-prioritized-boundaries branch September 1, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

react Changes affect packages/react refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant