feat: re-export MUI primitives so consuming apps drop the direct dependency - #1
Open
kaiomagalhaes wants to merge 3 commits into
Open
feat: re-export MUI primitives so consuming apps drop the direct dependency#1kaiomagalhaes wants to merge 3 commits into
kaiomagalhaes wants to merge 3 commits into
Conversation
…ndency The app depends on @mui/material directly for 29 components and 10 icons, even though this kit is itself built on MUI. Expose those primitives here so consumers import from the kit only. - Add passthrough components for the 24 MUI primitives the app uses that had no kit equivalent (Box, Stack, IconButton, Tooltip, InputAdornment, TextField, the Dialog family, Divider, Alert, FormControl, Select, Paper, Chip, Card, InputLabel, Radio, RadioGroup, FormControlLabel, CircularProgress, MenuItem). - Add MuiCheckbox for the raw, unlabeled checkbox. The existing Checkbox requires a text label and wraps in <label>, so it is not a drop-in for checkboxes rendered inside table rows. - Add components/icons re-exporting the 10 glyphs in use, suffixed with Icon to avoid colliding with component names exported from the root. - Move @mui/material and @mui/icons-material from peerDependencies to dependencies. Consumers no longer supply MUI, so the kit must own it. - Emit a "use client" banner. Every component here wraps MUI, which is client-only; without it a React Server Component importing the kit pulls the whole bundle (incl. react-hook-form) into the server graph, where react-hook-form's react-server build has no Controller export. - Fix Button dropping a caller-supplied className. It was destructured out of props but never passed to classNames(), so the documented prop was silently ignored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both wrappers set their own props *after* the prop spread, so a caller passing color, underline, fontSize, variant or disableRipple had it silently discarded. Consuming call sites that set color="text.secondary" on a Link, or variant on a Button, were being ignored. Move those props before the spread so they act as defaults the caller can override. className stays after the spread in Button because it is merged rather than replaced. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Member
Author
|
Follow-up commit |
…ency move
Review of this PR found two defects in the earlier commits.
MUI was left declared in both dependencies and devDependencies, and
package-lock.json was never regenerated after the peer -> dependency move. The
lock still carried @mui/material as a dev/peer entry pinned to 7.3.9, which
does not satisfy the newly declared ^7.3.11, so `npm ci` built and typechecked
CI against a version the package does not claim to support. Removed the
duplicate devDependencies entries and re-locked; `npm ci` now installs 7.3.11.
The previous commit moved Button's and Link's own props before the spread so
callers could override them. That fixed the discard but introduced the
opposite bug: a JSX spread writes the key even when the value is undefined, so
`variant={undefined}` or `underline={undefined}` fell through to MUI's own
destructuring default ('text', 'always') instead of the kit's. Resolve with ??
instead of by ordering, which handles both absent and explicitly-undefined.
Also corrects the Button comment, which implied className merging makes kit
styling overridable. It does not: kit rules are written as
[class*=MuiButton-root] (specificity 0,2,0), so a caller's plain class still
loses. Merging is still right, it just buys less than the comment claimed.
README told consumers to install MUI as a peer dependency, contradicting the
purpose of this PR. It now documents importing MUI primitives from the kit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Why
box-bridge-appimports@mui/materialdirectly across 74 files (29 distinct components + 10 icons) even though this kit is itself built on MUI. That leaves MUI as a direct app dependency and splits the design system across two import sources.This PR exposes the missing primitives here so the app can import from the kit only. The companion app PR removes
@mui/*from itspackage.jsonentirely.What
Box,Stack,IconButton,Tooltip,InputAdornment,TextField, theDialogfamily,Divider,Alert,FormControl,Select,Paper,Chip,Card,InputLabel,Radio,RadioGroup,FormControlLabel,CircularProgress,MenuItem. These are typed re-exports — no styling opinion — so consumers get identical rendering.MuiCheckboxfor the raw, unlabeled checkbox. The existingCheckboxrequires a text label and wraps in<label>, so it is not a drop-in for checkboxes rendered inside table rows.components/iconsre-exporting the 10 glyphs in use, suffixed withIconto avoid colliding with component names exported from the root (Link,Menu).@mui/material/@mui/icons-materialmoved frompeerDependenciestodependencies. Consumers no longer supply MUI, so the kit must own it.Two fixes worth a closer look
"use client"banner (vite.config.ts). Every component here wraps MUI, which is client-only. Without the directive, a React Server Component importing the kit pulls the whole bundle — includingreact-hook-form— into the server graph, wherereact-hook-form'sreact-serverexport condition resolves to a trimmed build with noController. That broke the app's build ondocument-signed/page.tsx. MUI ships the same directive for the same reason.ButtondroppedclassName. It was destructured out of props but never passed toclassNames(), so the prop was accepted by the type and silently ignored. Now merged. Note this means any existing caller passingclassNamewill start having it applied — in the app that affects the sign-in button, which was passingstyles["sign-in-button"]into the void.Verification
npm run lint(tsc --noEmit) cleannpm run buildclean; all 38 new exports verified present indist/index.jsanddist/index.d.ts🤖 Generated with Claude Code