[internals] Move the exported internals to a new folder and remove private Calendar component#4505
Conversation
a7256fc to
fb3711d
Compare
commit: |
fb3711d to
3fe2a58
Compare
Bundle size report
Check out the code infra dashboard for more information about this PR. |
1ded326 to
c4f4dbf
Compare
c4f4dbf to
0ddef06
Compare
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
atomiks
left a comment
There was a problem hiding this comment.
Codex Review (GPT-5.4)
This is primarily a refactor, but it also expands the published subpath surface under ./internals/* and ./localization-provider. The runtime move looks mechanically safe; the remaining risk is in public-contract and guardrail consistency around those new entrypoints.
1. Bugs / Issues
1. 🟡 Temporal type augmentation still points at the old module (non-blocking)
In packages/react/src/internals/temporal/temporal.ts, the example for registering TemporalSupportedObjectLookup still tells consumers to augment @base-ui/react/types, but this PR moves the live augmentation target to @base-ui/react/internals/temporal.
From packages/react/src/internals/temporal/temporal.ts and packages/react/src/temporal-adapter-date-fns/TemporalAdapterDateFns.ts:
// packages/react/src/internals/temporal/temporal.ts
declare module '@base-ui/react/types' {
interface TemporalSupportedObjectLookup {
'date-fns': Date;
}
}
// packages/react/src/temporal-adapter-date-fns/TemporalAdapterDateFns.ts
declare module '@base-ui/react/internals/temporal' {
interface TemporalSupportedObjectLookup {
'date-fns': Date;
}
}This matters because ./internals/temporal is now a published export. Anyone following the example will augment the wrong module and silently fail to register their temporal object type.
Fix: Update the example in packages/react/src/internals/temporal/temporal.ts to match @base-ui/react/internals/temporal.
2. ℹ️ The deep-import lint exemption is broader than the published export map (informational)
In eslint.config.mjs, the new regex exempts every @base-ui/react/internals/... import from the deep-import restriction, while packages/react/package.json only exports a fixed set of one-level ./internals/* entrypoints.
From eslint.config.mjs:
{
regex: '@base-ui/react/(?!internals/).+/.+',
message: OneLevelImportMessage,
}This matters because imports like @base-ui/react/internals/temporal/getDateManager would now lint clean in-repo even though the published package would not resolve them. That weakens the guardrail this refactor is supposed to establish.
Recommendation: Narrow the exemption to exactly one level under internals, or add an explicit restriction for @base-ui/react/internals/*/*.
2. Behavior Preservation Assessment
I did not see evidence of meaningful runtime churn beyond the export-surface move. Most of the diff is mechanical import rewriting, and the targeted validation I ran passed: pnpm typescript, pnpm test:jsdom index --no-watch, and pnpm --filter @base-ui/react build.
3. Ownership / Architecture Assessment
This is no longer just an internal folder move: packages/react/package.json now publishes ownership/context primitives such as ./internals/field-root-context, ./internals/field-register-control, and ./internals/form-context. That may be intentional, but it turns future cleanup of those boundaries into semver-governed work, so I would call that out explicitly rather than framing the PR as only a relocation.
4. Test Coverage Assessment
The main coverage gap is export-surface validation. packages/react/src/index.test.ts now explicitly skips ./localization-provider and every ./internals/* subpath:
![
'.',
'./utils',
'./temporal-adapter-luxon',
'./temporal-adapter-date-fns',
'./localization-provider',
'./types',
].includes(key) &&
!key.startsWith('./unstable-') &&
!key.startsWith('./internals/')That means the new published entrypoints are not being smoke-tested through @base-ui/react/... specifiers for packaged resolution or declaration shape. I would add a small import smoke test for the exported ./internals/* and ./localization-provider subpaths before merging.
Merge Confidence Score
Overall merge confidence is 3/5. The refactor itself looks low-risk and the targeted typecheck, test, and build validation passed, but the new public subpath surface still has one stale consumer-facing type example, one guardrail mismatch, and no direct smoke coverage for the newly published exports. I would fix finding 1 and tighten either the lint rule or the export-surface test coverage before merging.
flaviendelangle
left a comment
There was a problem hiding this comment.
I'm migrating all the other repos to use this PR in order to make sure everything is correctly migrated 👍
| import { animated as springAnimated, useSpring, useSpringRef } from '@react-spring/web'; | ||
| import { SettingsMetadata, useExperimentSettings } from '../_components/SettingsPanel'; | ||
| import { useTransitionStatus } from '../../../../../../packages/react/src/utils/useTransitionStatus'; | ||
| import { useTransitionStatus } from '../../../../../../packages/react/src/internals/useTransitionStatus'; |
There was a problem hiding this comment.
We could use the new internal import now.
But if it's used in an experiment, maybe we could consider moving it to @base-ui/utils
…rnals imports Update @base-ui/react to a build from PR mui/base-ui#4505 which exposes internal utilities under @base-ui/react/internals/*. Replace ~46 files' imports from base-ui-copy/ with proper imports: - useRenderElement → @base-ui/react/internals/useRenderElement - BaseUIComponentProps, NonNativeButtonProps → @base-ui/react/internals/types - useButton → @base-ui/react/internals/use-button - createChangeEventDetails → @base-ui/react/internals/createBaseUIEventDetails - TemporalAdapter, TemporalSupportedObject, TemporalTimezone → @base-ui/react/internals/temporal Delete 11 now-redundant copy files (utils/ and types/ directories). Remaining in base-ui-copy/ (not yet available in internals): - composite/ (CompositeList, CompositeRootContext, useCompositeListItem) - temporal-adapter-date-fns/ (UnstableTemporalAdapterDateFns) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
e7a5b74 to
4e7402b
Compare
Bundle size
Deploy previewhttps://deploy-preview-4505--base-ui.netlify.app/ PerformanceTotal duration: 1,101.13 ms ▼-103.63 ms(-8.6%) | Renders: 53 (+0) | Paint: 1,661.51 ms ▼-183.13 ms(-9.9%)
...and 7 more. View full report Check out the code infra dashboard for more information about this PR. |
1. Missing React import in constants.ts[code-reviewer] packages/react/src/internals/constants.ts:34 — The constant Fix: Add import type * as React from 'react'; at the top of the file. 2. luxon missing from peerDependencies[code-reviewer] packages/react/src/internals/temporal-adapter-luxon/TemporalAdapterLuxon.ts:6 — The export ./internals/temporal-adapter-luxon runtime-imports from luxon, but luxon is only in devDependencies. 3. Roundabout self-referencing imports in labelable-provider/[type-design] Three files inside packages/react/src/internals/labelable-provider/ import from ../../internals/useBaseUiId instead of ../useBaseUiId. Both resolve to the same file, but the longer path navigates up
Suggestions (2 found) 4. Dead re-export shim: utils/serializeValue.ts[code-reviewer] packages/react/src/utils/serializeValue.ts — Contains only export { serializeValue } from '../internals/serializeValue'. Nothing in the codebase imports from this path anymore. Can be removed. |
That one is expected |
Codex Review (GPT-5.4)This is a refactor-dominant PR with public internal export, docs, and test-surface implications. I reviewed the full branch against freshly fetched 1. Bugs / Issues1. 🔴 Branch currently conflicts with latest
|
|
Point 1 is already fixed 1 => ok |
The `date-fns` and `@date-fns/tz` entries in `docs/package.json` are no longer imported anywhere in docs after the Calendar demos were removed in mui#4505.
Applied on external codebases ✔️