Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- run: bun install --frozen-lockfile
- run: bun run typecheck
- run: bun run lint
- run: bun run dep-guard
- run: bun test
- run: bun run build
- run: bun run contrast-test
- run: bun run dep-guard
10 changes: 0 additions & 10 deletions .swcrc

This file was deleted.

17 changes: 7 additions & 10 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,23 @@ points. There is no CLI, no component generator and no docs site, and that is de

## The build

`bun run build` is four steps and a gate, joined by `&&`, in order:
`bun run build` is three steps, joined by `&&`, in order:

| Step | Tool | Output |
| --- | --- | --- |
| `build:js` | SWC | `dist/**/*.js`, one per source file |
| `build:types` | `tsc -p tsconfig.build.json` | `dist/**/*.d.ts` |
| `build:js` | `tsc -p tsconfig.build.json` | `dist/**/*.js` and `dist/**/*.d.ts`, one per source file |
| `build:css` | Tailwind v4 CLI | `dist/styles.css`, plus `dist/theme.css` copied from source |
| `contrast-test` | `scripts/contrast-test.mjs` | the gate — reads `dist/styles.css` |

SWC does the JavaScript because it is fast and per-file; `tsc` does the declarations
because SWC does not emit them. Nothing bundles, so nothing can merge two modules into
one chunk. `prepack` runs the whole thing, so a failing gate cannot be packed or
published.
`tsc` emits the JavaScript and the declarations in one pass. Nothing bundles, so nothing
can merge two modules into one chunk. `prepack` runs the build, so npm publishes a fresh
`dist/`. The gates (`contrast-test`, `dep-guard`) run in CI after the build.

Source imports are relative and carry `.js` extensions. There is no path alias, so the
emitted files are valid ESM for Node as well as for every bundler.

Every component module that calls a hook, creates a context, defines an inline event
handler, or imports an optional peer (Radix dialog, dropdown-menu or tooltip, or
`sonner`) starts with `"use client"`, and SWC carries the directive into `dist/`. A React Server Components consumer renders any
`sonner`) starts with `"use client"`, and `tsc` carries the directive into `dist/`. A React Server Components consumer renders any
component directly; stateless components stay server-renderable. Plain-React bundlers
ignore the directive. `dep-guard` enforces the rule, and checks `dist/` after a build.

Expand Down Expand Up @@ -114,7 +111,7 @@ provider; every other component does not.

### Contrast is gated

`contrast-test` is the last step of the build. It parses the **built** `dist/styles.css`
`contrast-test` runs in CI after the build. It parses the **built** `dist/styles.css`
for the `:root` and `.dark` custom properties and derives its pairs from token *names*,
never from listed hexes, so a new `--warning` / `--warning-foreground` is covered on the
next run with no edit. Six rules:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ contract, and so is everything the root re-exports — modules that are not expo
`ui/menu`, `ui/tooltip` and `ui/toast` leave the root barrel; import them by subpath
(`import { Toaster, toast } from "@corbits/react-ui/ui/toast"`).

### Changed

- **Build emits JavaScript with `tsc`.** SWC is gone; one `tsc` pass writes `dist/**/*.js`
and `.d.ts`. `contrast-test` and `dep-guard` run in CI instead of inside `build`.

### Added

- **`"use client"` on stateful components.** The 45 `ui/` and `blocks/` modules that call
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ consumer's data layer, not in a component — data arrives as props.
## Gates

```sh
bun run build # SWC → tsc → Tailwind → the contrast gate
bun run build # tsc (JS + types) → Tailwind
bun run typecheck # tsc --noEmit
bun run lint # eslint .
bun run dep-guard # forbidden-import checks over src/
Expand Down
10 changes: 4 additions & 6 deletions IMPLEMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,16 @@ Why the library exists lives in [PRODUCT.md](./PRODUCT.md).

## Toolchain

Development uses **bun**. `bun run build` is four steps and a gate, joined
by `&&`:
Development uses **bun**. `bun run build` is three steps, joined by `&&`:

| Step | Tool | Output |
| --- | --- | --- |
| `build:js` | SWC (`@swc/cli`, `@swc/core`) | `dist/**/*.js`, one per source file |
| `build:types` | `tsc -p tsconfig.build.json` | `dist/**/*.d.ts` |
| `build:js` | `tsc -p tsconfig.build.json` | `dist/**/*.js` and `dist/**/*.d.ts`, one per source file |
| `build:css` | Tailwind v4 CLI | `dist/styles.css`, plus `dist/theme.css` copied from source |
| `contrast-test` | `scripts/contrast-test.mjs` | the gate — reads `dist/styles.css` |

Source imports are relative and carry `.js` extensions. There is no path
alias. `prepack` runs the whole build so a failing gate cannot be packed.
alias. `prepack` runs the build. CI runs `contrast-test` (reads `dist/styles.css`)
and `dep-guard` after it.

Other scripts: `bun run typecheck`, `bun run lint` (eslint),
`bun run dep-guard` (`scripts/dep-guard.mjs` — fails if any file imports
Expand Down
Loading
Loading