You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Merge origin/main (0.2.0 release, stickers extraction) into expander branch
Conflict resolutions:
- src/elements/index.ts, src/jsx-runtime.ts, src/general_types.ts: keep
the a-expander exports/types, follow main's removal of the sticker
elements (now @antadesign/stickers).
- CHANGELOG.md: the auto-merge landed the Expander bullet inside the
already-released 0.2.0 section; moved it to a new Unreleased section.
Verified post-merge: anta build + typecheck + site build pass; React 19
and Preact smoke suites (17 assertions each) all pass against the
merged dist.
https://claude.ai/code/session_01A9PoyMtVzmBJshb5gneqVQ
Copy file name to clipboardExpand all lines: CLAUDE.md
+33-10Lines changed: 33 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,11 @@
2
2
3
3
Published as `@antadesign/anta` on npm. Portable UI component library. Works in React apps out of the box, in Preact via compat aliasing (`react` → `preact/compat`), and in custom runtimes via `configure()`.
4
4
5
+
This repo is a pnpm workspace with **two publishable packages** plus the docs site:
6
+
-`@antadesign/anta` — this package, at the repo root (`src/`, `dist/`).
7
+
-`@antadesign/stickers` — the sticker pack, in top-level [`stickers/`](stickers/CLAUDE.md). It owns the `<a-sticker>` / `<a-sticker-animated>` elements, the `Sticker` / `StickerAnimated` wrappers, the artwork, and the **only**`lottie-web` dependency. It depends on `@antadesign/anta` for the JSX runtime and shared helpers. Kept separate so anta carries no animation runtime. **Anything sticker-related — components, tokens, docs page, the generator — lives there, not here.**
8
+
-`site/` — the docs site (not published).
9
+
5
10
## Architecture
6
11
7
12
Two tiers per component:
@@ -13,11 +18,14 @@ The tiers are decoupled — JSX wrappers emit `<a-*>` tags but never import elem
13
18
14
19
### Key files
15
20
16
-
-`src/jsx-runtime.ts` — Custom JSX runtime. Defaults to `React.createElement`. Call `configure(h)` to swap.
17
-
-`src/types.d.ts` — CSS module type declarations and `JSX.IntrinsicElements` for `a-*` custom elements.
21
+
-`src/jsx-runtime.ts` — Custom JSX runtime. Defaults to `React.createElement`. Call `configure(h)` to swap. **Owns the `JSX.IntrinsicElements` declarations for `a-*` tags** — they must live here (not elsewhere) because tsc's `jsxImportSource` mechanism resolves JSX element types from the `JSX` namespace exported by `<source>/jsx-runtime`, and because companion packages augment this exact module (`@antadesign/stickers` does `declare module '@antadesign/anta/jsx-runtime'` to add its tags).
22
+
-`src/general_types.ts` — Shared `BaseProps` / `BaseAttributes` plus the per-element `A{Name}Attributes` interfaces. A regular `.ts` module (never a `.d.ts` — tsc doesn't copy declaration inputs to `dist`) published as the `@antadesign/anta/general_types` subpath; `@antadesign/stickers` and all JSX wrappers import from it.
23
+
-`src/types.d.ts` — Internal-only ambient declarations: the wildcard `declare module '*.module.css'`. Can't merge into the files above — wildcard ambient module declarations are only legal in a global (non-module) declaration file. Not shipped to `dist`.
18
24
-`src/elements/index.ts` — Barrel export that auto-registers all web components in browser contexts. **Must only be imported client-side** — `HTMLElement` does not exist in Node/SSR.
19
25
-`src/index.ts` — Barrel export for JSX components and `configure()`.
20
26
27
+
These three type locations are each pinned by a different TypeScript mechanism (see above) — don't try to consolidate them.
28
+
21
29
## Build & dev
22
30
23
31
Source lives in `src/`. Build output goes to `dist/`. `dist/` is gitignored — `pnpm install` regenerates it via the `prepare` lifecycle script, and `npm publish` regenerates it via `prepublishOnly` so the published tarball is always fresh. The package is distributed only through npm; the GitHub-URL install path is not supported.
@@ -34,7 +42,7 @@ pnpm run typecheck # Type check without emit
34
42
35
43
**For any dev work — editing the anta package *or* the docs site — run `pnpm run dev` from the repo root** (run it in the background; it's long-lived). It does both halves together:
36
44
37
-
- a `nodemon -w src` watcher that **rebuilds `dist`** (and regenerates the site's `docs:*` artifacts) on every change to anta's `src/**/*.{ts,tsx,css}`, and
45
+
- a `nodemon -w src -w stickers/src` watcher that **rebuilds `dist`** (anta, then `@antadesign/stickers`) and regenerates the site's `docs:*` artifacts on every change to either package's `src/**/*.{ts,tsx,css}`, and
38
46
- the docs site's `astro dev` (HMR for `site/`).
39
47
40
48
The docs site consumes anta from the built `dist/` (workspace symlink), so this is what propagates an anta-source change through to the running site. **Do not** run `cd site && pnpm run dev` for package work — that starts only the site's Astro dev and will *not* rebuild `dist`, so anta `src` edits won't show up and you'd be stuck manually rebuilding + restarting. Pure `site/` edits (`.mdx`, Astro/Preact components) HMR fine under either, but the root command is the one to use so package edits Just Work too.
Two packages publish from this repo: **`@antadesign/anta`** (root) and **`@antadesign/stickers`** (`stickers/`). Both go out as prereleases under the npm `dev` dist-tag. Each version string is immutable on npm — **always bump before publishing**.
86
+
87
+
> **If asked to publish — or to recall how — walk the user through this, in order.** The order and the `pnpm` vs `npm` distinction are the two easy things to get wrong.
88
+
89
+
**Publish anta first, then stickers.**`@antadesign/stickers` depends on `@antadesign/anta` via `workspace:*`, which pnpm rewrites to anta's **exact current version** at pack time. So the anta version stickers will pin must already be on npm — and it must be the version that carries whatever exports stickers imports (e.g. `./anta_helpers`, `./general_types`). Publishing stickers against an anta version that isn't published yet (or predates an export it needs) makes `npm install @antadesign/stickers` unresolvable.
90
+
77
91
```sh
78
-
npm version prerelease --preid=dev # Bump: 0.1.1-dev.1 → 0.1.1-dev.2
79
-
npm publish --access public --tag dev # Publish prerelease under "dev" tag
92
+
# 1) anta — from repo root
93
+
npm version prerelease --preid=dev # 0.1.1-dev.8 → 0.1.1-dev.9 (or bump the version field by hand)
94
+
npm publish --access public --tag dev # prepublishOnly rebuilds dist
95
+
96
+
# 2) stickers — from stickers/
97
+
cd stickers
98
+
pnpm publish --no-git-checks # access/tag come from its publishConfig
80
99
```
81
100
82
-
Each version string is immutable on npm — always bump before publishing.
101
+
-**Use `pnpm publish` for `stickers`, not `npm publish`.** Only pnpm rewrites the `workspace:*` protocol to a real version; `npm publish` would leave `workspace:*` in the tarball and the package would be uninstallable. (anta has no workspace deps, so `npm publish` is fine there.)
102
+
-`stickers/package.json` has `publishConfig: { access: "public", tag: "dev" }`, so its publish needs no `--access` / `--tag` flags. anta passes them explicitly.
103
+
-`prepublishOnly` (anta) / `prepare` (both) rebuild `dist` before the tarball is created, so published output is always fresh.
104
+
- Bumping the `version` field by hand (vs `npm version`) skips the auto git commit + tag. If you tag releases, create the tag manually; otherwise no action needed.
105
+
- 2FA: append `--otp=<code>` if your npm account requires it.
83
106
84
107
## Changelog
85
108
86
-
`CHANGELOG.md` at the repo root documents changes to **the `@antadesign/anta` package only** — code shipped to npm consumers (anything under `src/` and `dist/`, plus root files in the published tarball). The docs site under `site/` is its own thing and **does not** belong in the changelog. New site pages, component-docs polish, demos, layout tweaks — all of that ships only on `antadesign.dev` and isn't a consumer-facing change.
109
+
`CHANGELOG.md` at the repo root documents changes to **the `@antadesign/anta` package only** — code shipped to npm consumers (anything under `src/` and `dist/`, plus root files in the published tarball). The docs site under `site/` is its own thing and **does not** belong in the changelog. New site pages, component-docs polish, demos, layout tweaks — all of that ships only on `anta.design` and isn't a consumer-facing change.
87
110
88
111
When in doubt: would a consumer who installs this version see this change in their app? If no, leave it out of `CHANGELOG.md`. Use commit messages and PR descriptions for the docs-site narrative.
89
112
@@ -143,8 +166,8 @@ The same rule applies anywhere we lighten/darken/desaturate a color: prefer `col
143
166
-**Default variant in union types** — Include default value explicitly in the type union (e.g. `tone?: 'neutral' | 'info'`).
144
167
-**CSS modules only on JSX wrappers**, plain CSS for web components. Use `.container` as the top-level class in CSS modules.
145
168
-**Types** — Use React global types (e.g. `React.CSSProperties`) without importing React. Components must be compatible with both React and Preact.
146
-
-**Auto-registration (granular + barrel)** — each `a-{name}` module self-registers and imports its own CSS when loaded, so a granular `import '@antadesign/anta/elements/a-{name}'` registers just that element (and won't drag in other elements' deps — e.g. only `a-sticker-animated` pulls `lottie-web`). The `elements/index.ts` barrel re-exports every module, so `import '@antadesign/anta/elements'` registers them all. Registration is guarded against missing `customElements` (SSR-safe), but elements should still only be imported client-side.
147
-
-**Component-token-first** — Each component defines its own CSS custom properties. Global tokens will be added later.
169
+
-**Auto-registration (granular + barrel)** — each `a-{name}` module self-registers and imports its own CSS when loaded, so a granular `import '@antadesign/anta/elements/a-{name}'` registers just that element (and won't drag in other elements' code or deps). The `elements/index.ts` barrel re-exports every module, so `import '@antadesign/anta/elements'` registers them all. Registration is guarded against missing `customElements` (SSR-safe), but elements should still only be imported client-side. (The same pattern powers `@antadesign/stickers/elements` — its granular `a-sticker` path keeps `lottie-web` out, since only `a-sticker-animated` pulls it.)
170
+
- **Component-token-first; the only global tokens are color roles.** The global token vocabulary is deliberately tiny and lives in `src/tokens.css`: theme-aware *role* scales for **text** (`--text-*`), **container background** (`--bg-*`), and **container border** (`--border-*`), per tone, plus fonts and link colors. A component points at these roles only when a value clearly *is* one of those three things (see `a-tag.css` — that's also what makes its dark mode free). Everything else — sizes, spacing, radii, interaction-state colors, timings — is defined per component as `--{component}-*` with literal values, **on purpose**: values are still being tuned back and forth, and component-level definitions keep every part independently changeable. Component-local literal values are policy, not debt — do **not** "clean them up" by routing them through global tokens, and do **not** introduce primitive palette tokens or global spacing/size scales. New global role families (e.g. interactive fills) only by explicit decision, once the values have actually stabilized across components.
148
171
-**Document defaults with `@defaultValue`** — Every optional prop whose default isn't obvious (enums, numbers like `size`/`level`/`max`, a default tone/priority) **must** carry a `@defaultValue <value>` TSDoc tag on its declaration in `src/components/<Name>.tsx`. This is the single source of truth: TypeDoc captures it into `site/src/api.json`, `PropsTable.astro` renders it as the **Default** column, and the playground's `props-form.ts` reads it for control defaults. State the default *only* in the tag — don't also write "Defaults to …" in the prose description (the Default column would duplicate it). Skip the tag for booleans that default to `false` (obvious) and for required props (no default).
149
172
-**Docs-in-sync** — When you rename a component prop, rename a `--{component}-*` token, add a token, or remove one, **update `site/src/pages/components/{name}.mdx` in the same change** so the docs page tracks the source of truth. The same applies to default values, prop type unions, and to any consumer-facing API note in `README.md`. Drift between the source and the docs site is the single most common bug report — easier to keep them in lockstep than to chase the divergence later.
150
173
@@ -156,7 +179,7 @@ The same rule applies anywhere we lighten/darken/desaturate a color: prefer `col
5. Create `src/components/{Name}.module.css` — scoped styles for wrapper layout
158
181
6. Add to `src/index.ts` — re-export the component
159
-
7.Add `a-{name}` to `JSX.IntrinsicElements` in `src/types.d.ts`
182
+
7.Define `A{Name}Attributes` in `src/general_types.ts` (extending `BaseAttributes`), then add `a-{name}` to `JSX.IntrinsicElements` in `src/jsx-runtime.ts`
160
183
8. Add entry points to `build:js` script in `package.json`
161
184
9. Add CSS files to `build:css` script in `package.json`
Copy file name to clipboardExpand all lines: DESIGN.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -48,7 +48,7 @@ components:
48
48
49
49
Anta is a portable UI component library built on a two-tier architecture: web components (`elements/`) provide the rendering layer via shadow DOM, and JSX wrappers (`components/`) provide a typed component API. The tiers are decoupled — wrappers emit custom element tags but never import element definitions.
50
50
51
-
Anta follows a **component-token-first** philosophy. Each component defines its own CSS custom properties (e.g., `--progress-indicator-bg`) rather than depending on a global token system. Global tokens will be introduced later for cross-component consistency, but component tokens remain the primary styling mechanism.
51
+
Anta follows a **component-token-first** philosophy. Each component defines its own CSS custom properties (e.g., `--progress-indicator-bg`) as the primary styling mechanism. The only global tokens are the theme-aware color *roles* in `src/tokens.css` — text (`--text-*`), container background (`--bg-*`), and container border (`--border-*`) scales, plus fonts and link colors — which components consume when a value is clearly one of those roles. There is deliberately no primitive color palette and no global spacing/size scales: while the system is young and values are still being tuned, component-local definitions keep every part independently changeable.
Copy file name to clipboardExpand all lines: README.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@ This constraint shapes the architecture: the web components carry the core styli
10
10
11
11
`@antadesign/anta` is an NPM package, so you can `npm install @antadesign/anta` or do that with `pnpm` / `bun`.
12
12
13
-
Since Anta is in active development we suggest using the latest dev version: `"@antadesign/anta": "dev"` in your `package.json`. For production builds we suggest pinning to a stable version from npm.
13
+
Use the latest version from npm, but **always pin an exact version** — `"@antadesign/anta": "0.2.0"` in your `package.json` — rather than a floating tag like `"latest"` or `"dev"`, which can change between installs.
14
14
15
15
### Usage
16
16
@@ -36,7 +36,7 @@ Anta exposes four independent imports. Tokens + elements + the JSX layer are the
36
36
37
37
The chain matters: the per-element CSS that ships with `/elements` references variables like `var(--text-1)` and `var(--bg-2)`. Those variables are *only defined* by `tokens.css`. Skip the tokens import and the components render with whatever the surrounding cascade provides — usually nothing styled at all.
38
38
39
-
`@antadesign/anta/elements` registers **all** elements — convenient, but it includes every element's code (and deps). To keep your bundle lean, import only the elements you use from their per-element entry points instead: `import '@antadesign/anta/elements/a-tooltip'` registers just `<a-tooltip>`**and loads just its CSS**. Unused elements — and their dependencies, e.g. `lottie-web` (needed only by `<a-sticker-animated>`) — then never enter your bundle. See [Registering elements](#registering-elements).
39
+
`@antadesign/anta/elements` registers **all** elements — convenient, but it includes every element's code (and deps). To keep your bundle lean, import only the elements you use from their per-element entry points instead: `import '@antadesign/anta/elements/a-tooltip'` registers just `<a-tooltip>`**and loads just its CSS**. Unused elements — and any dependencies they pull in — then never enter your bundle. See [Registering elements](#registering-elements).
40
40
41
41
### Cascade layers
42
42
@@ -79,7 +79,7 @@ import '@antadesign/anta/elements/a-tooltip' // only <a-tooltip> + its CSS
79
79
import '@antadesign/anta/elements/a-button' // only <a-button>+ its CSS
80
80
```
81
81
82
-
Both styles are side-effect imports (the act of importing registers the element), and both are idempotent and SSR-safe. The granular form keeps unused elements — and their dependencies, e.g. `lottie-web`, which only `<a-sticker-animated>` pulls in — out of your bundle.
82
+
Both styles are side-effect imports (the act of importing registers the element), and both are idempotent and SSR-safe. The granular form keeps unused elements — and any dependencies they pull in — out of your bundle.
83
83
84
84
The cleanest pattern is a**static, synchronous import at your app's entry file** — outside any component, outside any hook:
0 commit comments