feat(ui): build @d2e/ui as a distributable component library - #3251
Merged
khairul-syazwan merged 2 commits intoSep 2, 2026
Merged
Conversation
The portal is moving to Vue and will share these components, so the library needs a real contract rather than a source export that every consumer compiles itself. - Build with vite lib mode into `dist/index.js` + `dist/index.css`, types via `vue-tsc`. Not the rollup/babel chain libs/portal-components uses: that is rollup 2 plus six babel packages for React/TSX, and vite handles Vue SFCs natively. - `vue` and `vuetify` stay external as peer dependencies. - Components now import the Vuetify pieces they use, so the package works without the consumer running vite-plugin-vuetify. - Entry points move to dist; `./tokens.css` stays on source because it is generated from tokens.ts and guarded by tokens:check. - `scripts/verify-dist.mjs` checks the artifact in CI. Two things this surfaced: Adding the Vuetify imports broke three unit tests, which imported their constant maps from the `.vue` files and so began loading Vuetify's CSS under vitest's node environment. Moved those maps into plain modules (`buttonVariants`, `iconButtonSizes`, `statusChipVariants`, `explorationCardStatus`), following the existing `dialogSizes.ts` pattern. The public API is unchanged; tests no longer touch Vuetify. The obvious smoke test — importing dist in plain node — cannot work, because vuetify's ESM pulls in .css. `verify:dist` checks statically instead, and asserts *positively* that vue and vuetify are still imported: when a peer gets bundled it stops appearing as an import, so looking only for unexpected imports misses the case that matters. Verified by dropping vuetify from `external` — the check fails on both the missing import and a 197 kB bundle against the 150 kB ceiling. Verified: 25 lib tests, tokens:check, dist verify, all three vue-mri build variants, explorer 8 stories / 30 variants, and every component still renders in the browser with no console errors.
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 01:43 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 01:43 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 01:43 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 01:43 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 01:43 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 01:43 — with
GitHub Actions
Inactive
khairul-syazwan
marked this pull request as ready for review
September 2, 2026 02:15
khairul-syazwan
requested review from
SantanM,
brandantck,
hengxian-jiang,
mwaiyee,
p-hoffmann and
suwarnoong
as code owners
September 2, 2026 02:15
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:15 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:15 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:15 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:15 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:15 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:15 — with
GitHub Actions
Inactive
7 tasks
`verify-dist.mjs` checked 13 names while `src/index.ts` exports 17 values. The check is a subset test, so the four constant maps this branch added — VARIANT_MAP, SIZE_MAP, STATUS_CHIP_VARIANT_MAP and ICON_BUTTON_SIZE_MAP — went unguarded. Dropping or renaming any of them would not have failed the build. The guard now reports 17 exports. The README header still said the application uses the source and there is no build step, directly above the new section on consuming the built package. Say what is true of both: the application reads source through vite aliases, and every other consumer uses the artifact. Found in review of #3251.
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:36 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:36 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:36 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:36 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:36 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 02:37 — with
GitHub Actions
Inactive
khairul-syazwan
merged commit Sep 2, 2026
751d245
into
khairul-syazwan/d2e-ui-library
60 of 63 checks passed
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 03:28 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 03:28 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 03:28 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 03:28 — with
GitHub Actions
Inactive
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 03:28 — with
GitHub Actions
Inactive
Collaborator
Author
|
Folded into #3204 rather than reviewed separately. The packaging change was small — 25 files, +323/-121 — against #3204's +7448, and 8 of those files are components #3204 itself introduces. Splitting them meant a reviewer read those SFCs twice: once with the constant maps inline, then again with the maps extracted for the packaging refactor. The final state is clearer reviewed once. The commits are unchanged and now sit on |
khairul-syazwan
temporarily deployed
to
github
September 2, 2026 03:29 — with
GitHub Actions
Inactive
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.
Stack 2 of 5 for the D2E data-exploration redesign (#3116). Stacked on #3204 — review that first.
Packages
@d2e/uias a built library so the portal can share it once it moves to Vue, instead of every consumer compiling the Vue SFCs itself.What changed
dist/index.js+dist/index.css, types viavue-tsc. Not the rollup/babel chainlibs/portal-componentsuses: that is rollup 2 plus six babel packages for React/TSX, and vite handles Vue SFCs natively.vueandvuetifystay external as peer dependencies.vite-plugin-vuetify.dist../tokens.cssstays on source — it is generated fromtokens.tsand guarded bytokens:check.scripts/verify-dist.mjschecks the artifact, wired into the CI step added in feat(ui): add the d2e component library and the Histoire explorer #3204.Two things worth a reviewer's attention
Adding the Vuetify imports broke three unit tests: they imported their constant maps from the
.vuefiles, so they began loading Vuetify's CSS under vitest's node environment. The maps moved into plain modules (buttonVariants,iconButtonSizes,statusChipVariants,explorationCardStatus), following the existingdialogSizes.tspattern. Public API unchanged.The obvious smoke test — importing
distin plain node — cannot work, because vuetify's ESM pulls in.css.verify:distchecks statically instead and asserts positively that vue and vuetify are still imported: when a peer gets bundled it stops appearing as an import at all, so checking only for unexpected imports misses the case that matters. Verified by dropping vuetify fromexternal— it fails on both the missing import and a 197 kB bundle against the 150 kB ceiling.Not in scope
The vite aliases in
apps/vue-mri-ui-libstay. The package is private and unpublished, so the ATLAS job'snpm install --workspaces=falsecannot resolve it from the registry regardless of a dist. The application keeps consuming source, which also preserves hot reload.Validation
25 library tests,
tokens:check,verify:dist, all three vue-mri build variants, explorer 8 stories / 30 variants, and every component re-checked in the browser with no console errors.