Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new set of Lit-based “v2” Web Components (header + auth buttons) and wires them into the build/test pipeline so they can be consumed via package subpath exports (solid-ui/components/*).
Changes:
- Add Lit Web Components:
<solid-ui-header>,<solid-ui-login-button>,<solid-ui-signup-button>plus READMEs and unit tests. - Update webpack to emit per-component bundles under
dist/components/<component>/index.*and updatepackage.jsonsubpath exports accordingly. - Adjust Jest/TypeScript test configuration and update existing unit snapshots.
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| webpack.config.mjs | Builds multiple entrypoints and emits component bundles under dist/components/*. |
| tsconfig.test.json | Includes src/**/*.test.ts in the test TS project. |
| test/unit/index.test.ts | Updates index export contract test. |
| test/unit/header/snapshots/index.test.ts.snap | Snapshot updates for legacy header DOM output. |
| test/helpers/setup.ts | Minor cleanup in test setup. |
| src/v2/components/header/Header.ts | New Lit-based header component implementation. |
| src/v2/components/header/index.ts | Registers <solid-ui-header> and exports types. |
| src/v2/components/header/README.md | Documents header component usage and API. |
| src/v2/components/header/header.test.ts | Adds unit tests for the new header component. |
| src/v2/components/loginButton/LoginButton.ts | New Lit-based login button with popup flow. |
| src/v2/components/loginButton/index.ts | Registers <solid-ui-login-button>. |
| src/v2/components/loginButton/README.md | Documents login button component usage and API. |
| src/v2/components/signupButton/SignupButton.ts | New Lit-based signup button. |
| src/v2/components/signupButton/index.ts | Registers <solid-ui-signup-button>. |
| src/v2/components/signupButton/README.md | Documents signup button component usage and API. |
| src/utils/headerFooterHelpers.ts | Changes ns import and tweaks getPod() behavior. |
| src/pad.ts | Formatting / string quoting adjustments. |
| src/footer/index.ts | Refactors footer link creation and styling placement. |
| src/acl/access-groups.ts | Minor string concatenation tweak. |
| scripts/build-component-dts.mjs | Adds a postbuild script to generate dist/components/* type wrappers. |
| README.md | Adds top-level documentation for Web Components and build pipeline. |
| package.json | Adds subpath exports for components and adjusts build scripts/deps. |
| jest.config.mjs | Expands transform ignore patterns for Lit packages + CSS mock mapping. |
| babel.config.mjs | Enables allowDeclareFields for TS preset (needed for declare). |
| mocks/styleMock.js | Adds Jest mock for CSS imports. |
Comments suppressed due to low confidence (1)
webpack.config.mjs:33
- With multiple new entrypoints (
header,loginButton,signupButton) sharing the sameoutput.library.name: 'UI', loading more than one of the emitted UMD bundles via script tags will overwritewindow.UI(last bundle wins). Consider omitting the global name for component bundles or using a per-entry library name to avoid clobbering the mainUIglobal.
const common = {
entry: {
main: './src/index.ts',
header: './src/v2/components/header/index.ts',
loginButton: './src/v2/components/loginButton/index.ts',
signupButton: './src/v2/components/signupButton/index.ts'
},
output: {
path: path.resolve(process.cwd(), 'dist'),
library: {
name: 'UI',
type: 'umd'
},
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| expect(brandLink?.href).toContain('/home') | ||
|
|
||
| const authButtons = shadow?.querySelectorAll('.auth-button') | ||
| expect(authButtons).toHaveLength(2) | ||
|
|
There was a problem hiding this comment.
The header component’s logged-out template renders <solid-ui-login-button> / <solid-ui-signup-button> and does not include any elements with the .auth-button class, so these queries will return an empty NodeList and the assertions will fail. Update the selectors/assertions to target the custom elements (or their shadow parts) instead of .auth-button.
| const shadow = header.shadowRoot | ||
| const authButtons = shadow?.querySelectorAll('.auth-button') | ||
| const loginButton = authButtons?.[0] as HTMLButtonElement | ||
| const signUpLink = authButtons?.[1] as HTMLAnchorElement | ||
|
|
||
| expect(authButtons).toHaveLength(2) | ||
| expect(loginButton.textContent?.trim()).toBe('Log in') | ||
| expect(signUpLink.textContent?.trim()).toBe('Sign Up') | ||
|
|
||
| loginButton.click() | ||
|
|
||
| expect(authActionSelected).toHaveBeenCalledWith({ | ||
| role: 'login', | ||
| item: { label: 'Log in', action: 'login' } | ||
| }) | ||
| }) |
There was a problem hiding this comment.
This test clicks the first “login button” and expects an auth-action-select event immediately. In the component implementation, auth-action-select is dispatched only when the nested <solid-ui-login-button> emits login-success (i.e. after a successful login flow), not on click. The test should simulate/dispatch login-success on the nested element (or adjust expectations) to match the actual behavior.
| <li | ||
| style="border-bottom: solid 1px #000000;" | ||
| class="headerUserMenuListItem" | ||
| > | ||
| <a | ||
| class="headerUserMenuLink" | ||
| href="https://reflectechblog.wordpress.com/" | ||
| style="background: none; border: 0; color: black; cursor: pointer; display: block; font-family: Arial; font-size: 1em; text-align: left; padding: 1em; width: 100%; text-decoration: none;" | ||
| id="headerUserMenuLink" | ||
| /> |
There was a problem hiding this comment.
The rendered markup includes multiple elements with the same id="headerUserMenuLink" within the same banner. Duplicate IDs make the DOM invalid and can break getElementById/CSS targeting. Prefer removing these IDs or generating unique IDs per instance/menu item.
| "dependencies": { | ||
| "@noble/curves": "^2.0.1", | ||
| "@noble/hashes": "^2.0.1", | ||
| "copy-webpack-plugin": "^14.0.0", | ||
| "escape-html": "^1.0.3", | ||
| "lit": "^3.3.2", | ||
| "mime-types": "^3.0.2", | ||
| "pane-registry": "^3.0.2", | ||
| "pane-registry": "^3.1.0", | ||
| "solid-namespace": "^0.5.4", | ||
| "uuid": "^13.0.0" |
There was a problem hiding this comment.
copy-webpack-plugin was added as a runtime dependency, but it isn’t referenced anywhere in the repo (including webpack.config.mjs). If it’s not needed for the build, it should be removed to avoid pulling in an extra dependency tree (and its Node engine constraints) unnecessarily.
| "description": "UI library for Solid applications", | ||
| "main": "dist/solid-ui.js", | ||
| "types": "dist/index.d.ts", | ||
| "sideEffects": false, | ||
| "exports": { | ||
| ".": { |
There was a problem hiding this comment.
Removing "sideEffects": false disables tree-shaking for the entire package. If this was done to preserve custom-element registration side effects, consider using a sideEffects allowlist (e.g. only the component entrypoints) so consumers can still tree-shake the rest of the library.
| declare label: string | ||
| declare theme: 'light' | 'dark' | ||
| declare issuerUrl: string | ||
| declare _popupOpen: boolean | ||
| declare _issuerInputValue: string | ||
|
|
||
| private _errorMsg = '' | ||
|
|
||
| constructor () { | ||
| super() | ||
| this.label = 'Log In' | ||
| this.issuerUrl = '' | ||
| this._popupOpen = false | ||
| this._issuerInputValue = '' | ||
| } |
There was a problem hiding this comment.
theme is declared as 'light' | 'dark' but is never initialized in the constructor, so at runtime it can be undefined when the component is used standalone. Either initialize this.theme = 'light' (to match the documented default) or widen the type to include undefined/absence to keep TS types accurate.
|
|
||
| constructor () { | ||
| super() | ||
| this.label = 'Sign Up' |
There was a problem hiding this comment.
theme is declared as 'light' | 'dark' but isn’t initialized, so standalone usage yields theme === undefined at runtime. To match the README’s default 'light' and keep typings correct, initialize this.theme = 'light' or allow undefined in the type.
| this.label = 'Sign Up' | |
| this.label = 'Sign Up' | |
| this.theme = 'light' |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/SolidOS/solid-ui/sessions/f1601da9-e96e-4f6f-abc0-31ad9f363929 Co-authored-by: timea-solid <4144203+timea-solid@users.noreply.github.com>
This is an artificial branch for test ci only. Actual work is done on milestone2k. -> DO NOT ADD any change or feedback here!
Changes allowed are ONLY for test branch building purposes.
Any code logic should be commented on: #740