a2ui-project / a2ui-project/a2ui
[react@0.9.1] Published bundle ships empty CSS-module class refs — Button / TextField / ChoicePicker render unstyled
- 主要言語
- TypeScript
- スター
- 16.4k
- フォーク
- 1.3k
- 平均マージ
- 2日 13時間
- マージ済み PR(30日)
- 134
説明
## Symptom
Components emitted by `@a2ui/react/v0_9` render with no padding, border, color, or hover state when used via the published npm tarball (`@a2ui/react@0.9.1`, sha `ea8e3a3c7d3dca12921cb230ef06144d95454098`). Three components reproduce:
- `` → `label`
- `` → `
- `` → similar empty class refs
``, ``, ``, ``, ``, ``, ``, ``, `` are unaffected — they use inline-style objects in source (no `.module.css` import) or rely on the `.a2uiText` / `.a2uiCaption` plain class names that DO ship in `v0_9/index.css`.
## Reproduction (minimal, deterministic)
```bash
mkdir /tmp/a2ui-repro && cd /tmp/a2ui-repro
npm init -y
npm install @a2ui/react@0.9.1
grep -A6 'var Button_default' node_modules/@a2ui/react/v0_9/index.js | head -8
```
Output (verified 2026-04-30 against the published tarball):
```js
// src/v0_9/catalog/basic/components/Button.module.css
var Button_default = {};
var Button = createComponentImplementation(ButtonApi, ({ props, buildChild }) => {
useBasicCatalogStyles();
const classes = [Button_default.button];
if (props.variant === "primary") {
classes.push(Button_default.primary);
```
`Button_default` is the JS-side object that should hold the CSS-module-hashed class names from `Button.module.css` (e.g. `{button: "Button-button-abc123", primary: "Button-primary-def456"}`). It's empty in the published tarball, so `classes.join(" ")` produces the literal string `"undefined undefined"`. Same applies to `TextField_default` and `ChoicePicker_default` (grep them in the same file to confirm).
The published `package.json` exports `"./styles/structural.css": "./structural.css"`, but `find node_modules/@a2ui/react -name structural.css` returns nothing — the file isn't actually shipped in the tarball. `node_modules/@a2ui/react/v0_9/index.css` exists but contains only `.a2uiText` / `.a2uiCaption` rules (no `.a2uiButton`, `.a2uiPrimary`, `.a2uiBorderless`, etc.).
## Why the official `samples/client/react/shell/` works (and users see broken output)
`samples/client/react/shell/package.json` declares:
```json
"@a2ui/react": "file:../../../../renderers/react"
```
This is a `file:` dep pointing at local source, so Vite handles `.module.css` natively at build time and class names get populated correctly. The shell sample never goes through the npm publish/install path, so its visual parity tests don't catch this regression. Users running `npm install @a2ui/react` get the broken bundle.
The shell's `App.css` ships **zero** `[data-a2ui-surface] button` rules — confirms the renderer is *supposed* to be self-styled by its CSS modules. There's no documented "you must also import `@a2ui/react/styles/...`" step that would compensate.
## Source vs published bundle (root cause)
Source: `renderers/react/src/v0_9/catalog/basic/components/Button.tsx`
```tsx
import styles from './Button.module.css';
export const Button = createComponentImplementation(ButtonApi, ({props, buildChild}) => {
useBasicCatalogStyles();
const classes = [styles.button];
if (props.variant === 'primary') classes.push(styles.primary);
// ...
});
```
The source `import styles from './Button.module.css'` is preserved as `var Button_default` in the bundle, but the build pipeline (`tsup` per `renderers/react/package.json` `scripts.build`) is publishing it as `{}` — the module's exports aren't being captured. CheckBox/Slider work because their source uses `const containerStyle = {...}` inline objects rather than CSS-module imports.
## Related issues
- #1306 (`[ci] npm publishing manifest format is malformed`, opened 2026-04-29) — confirms the publishing pipeline is currently broken; manifest lists `@a2ui/react: 0.9.1` and `@a2ui/web_core: 0.9.2`. Likely the upstream root cause but a different symptom.
- #1285 (`Component Style Overrides Missing in React Renderer`) — feature request for override API; orthogonal to this rendering bug.
- #977 (`Wire up theme in React renderer basic catalog`) — about `--a2ui-primary-color` theme wiring; separate concern.
- #867 (`Publish @a2ui/react to npm`) — still open as P1, suggesting stable v0.9 publish hasn't formally landed.
## Workaround for users
Two options:
1. **Use `file:` dep** like the official shell sample (requires `git clone https://github.com/google/A2UI.git` + building locally on each consumer machine):
```json
"@a2ui/react": "file:../path/to/A2UI/renderers/react"
```
2. **Element-selector CSS shim** scoped to the surface wrapper. Doesn't reproduce SDK branding exactly but restores baseline visual feedback:
```css
[data-a2ui-surface] button { padding: 0.5rem 1rem; border: 1px solid var(--border); border-radius: 0.5rem; ... }
[data-a2ui-surface] input,
[data-a2ui-surface] textarea { padding: 0.5rem 0.75rem; border: 1px solid var(--border); ... }
```
## Environment
- `@a2ui/react@0.9.1` (latest published; `0.9.0`, `0.9.0-alpha.3/4` show same shape per `npm view`)
- `@a2ui/web_core@0.9.2`
- `@a2ui/markdown-it@0.0.3`
- Next.js 16 + React 19 + Tailwind v4 host application
- Node 20.20.2 / npm 10
---
This report was prepared with AI assistance (Claude Code). Repro commands and source/bundle excerpts above were executed against the public tarball and the v0.9 source on `main`.
コントリビューションガイド
評価
この issue はまだ評価されていません。