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
1 change: 1 addition & 0 deletions .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 format:check
- run: bun test
- run: bun run build
- run: bun run contrast-test
Expand Down
13 changes: 10 additions & 3 deletions .ladle/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ import "../src/styles.css";
// colour.
const Provider: GlobalProvider = ({ globalState, children }) => {
useEffect(() => {
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const isDark = globalState.theme === "dark" || (globalState.theme === "auto" && prefersDark);
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
const isDark =
globalState.theme === "dark" ||
(globalState.theme === "auto" && prefersDark);
document.documentElement.classList.toggle("dark", isDark);
// theme.css now follows the OS when neither class is set, so "light" must
// be pinned explicitly — removing `.dark` alone still renders dark on a
// dark-OS dev box.
document.documentElement.classList.toggle("light", globalState.theme === "light");
document.documentElement.classList.toggle(
"light",
globalState.theme === "light",
);
}, [globalState.theme]);

return children;
Expand Down
4 changes: 4 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"printWidth": 80
}
6 changes: 6 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"categories": {
"correctness": "error"
}
}
86 changes: 44 additions & 42 deletions ARCHITECTURE.md

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ consumer's data layer, not in a component — data arrives as props.
```sh
bun run build # tsc (JS + types) → Tailwind
bun run typecheck # tsc --noEmit
bun run lint # eslint .
bun run lint # oxlint
bun run format:check # oxfmt --check (`bun run format` rewrites)
bun run dep-guard # forbidden-import checks over src/
```

All four must be clean before a change lands. There is no CI in this repository yet, so
All five must be clean before a change lands. There is no CI in this repository yet, so
running them locally is the only thing standing between a change and a release.
`typecheck` is not negotiable and `any` is not a way past it: the escapes that exist each
carry a comment explaining why the type system leaves no alternative, and a new one needs
Expand All @@ -46,7 +47,7 @@ Two things follow:

- **Change tokens in `src/theme.css`, then run `bun run build`.** Editing `dist/` changes
nothing — it is generated output and is gitignored.
- **Do not add hex pairs to the test.** The pairs are derived from token *names*. If a
- **Do not add hex pairs to the test.** The pairs are derived from token _names_. If a
token you added is not covered, the fix is a naming rule in `checksFor`, not a
hardcoded pair.

Expand All @@ -62,7 +63,7 @@ secret is a guard nobody can comply with.

1. **No `@workbench/*`.** A published file that imports an unpublished scope is
uninstallable for everyone outside the project that defines it, and the failure lands
in the *consumer's* install, where they cannot fix it.
in the _consumer's_ install, where they cannot fix it.
2. **Nothing reachable from the root barrel imports an optional peer.** Re-exporting a
module that statically imports an optional peer makes that peer mandatory for every
root import, so such a module must be kept out of the barrel and given its own `exports` entry.
Expand All @@ -81,7 +82,7 @@ around it.
2. If it is public API, add `export * from "./<dir>/<name>.js";` to `src/index.ts`.
Machinery stays unlisted: keeping something internal is cheap; taking an export back
after it ships is not.
3. If it is public but statically imports an *optional* peer, leave it out of
3. If it is public but statically imports an _optional_ peer, leave it out of
`src/index.ts` and add a `./<dir>/<name>` entry to `exports` in `package.json` instead.
`dep-guard` fails if it reaches the barrel.
4. If a `ui/` or `blocks/` module calls a hook, creates a context, defines an inline
Expand Down Expand Up @@ -166,7 +167,7 @@ not a follow-up.
accessible name; an icon-only button needs `aria-label`.
- **Colour is never the only channel.** Anything encoded in colour is encoded a second way
too — a shape, an icon, a dash pattern, a label. Charts are the sharp case: the
palette's dark-mode separation is compliant only *because* every chart ships a legend,
palette's dark-mode separation is compliant only _because_ every chart ships a legend,
direct labels and a data table.
- Respect `prefers-reduced-motion` for anything that animates.

Expand All @@ -180,12 +181,12 @@ Check your item in both modes and at 200% zoom before opening a change.
major version.
- **The minimum that works.** No wrapper that only forwards props, no config indirection,
no speculative extension point. No CLI, no component generator, no docs site.
- Comments explain *why*. The code already says what.
- Comments explain _why_. The code already says what.

## Pull requests

- Keep commits focused, and keep the diff to the change you are describing.
- Explain *why* in the commit message; the code already says what.
- Explain _why_ in the commit message; the code already says what.
- Run the gates locally and say so in the pull request: `dep-guard`, `typecheck`, `lint`,
and `build` including the contrast gate. Nothing runs them for you yet.
- Contributions are accepted under the repository's LGPL-2.1-only licence.
Expand Down
10 changes: 5 additions & 5 deletions IMPLEMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ Why the library exists lives in [PRODUCT.md](./PRODUCT.md).

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

| Step | Tool | Output |
| --- | --- | --- |
| `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 |
| Step | Tool | Output |
| ----------- | ---------------------------- | ----------------------------------------------------------- |
| `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 |

Source imports are relative and carry `.js` extensions. There is no path
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),
Other scripts: `bun run typecheck`, `bun run lint` (oxlint), `bun run format` / `format:check` (oxfmt),
`bun run dep-guard` (`scripts/dep-guard.mjs` — fails if any file imports
`@workbench/*`), `bun test`, `bun run stories` / `stories:build`
([Ladle](https://ladle.dev) over `stories/`).
Expand Down
2 changes: 1 addition & 1 deletion PRODUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ It is not a design-system starter, not a CLI, and not a template app.
## What a host can do

- Import from the root (`@corbits/react-ui`) and bundle only what they used.
- Render collection surfaces against *their* data. Components never fetch.
- Render collection surfaces against _their_ data. Components never fetch.
Data arrives as props. Pieces that take no collection need no extra
host wiring.
- Style with a single prebuilt sheet (`@corbits/react-ui/styles.css`) and no
Expand Down
6 changes: 3 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ Defects in the components this package ships:
- credentials, tokens, internal hostnames or real data in a shipped file or a
fixture;
- a declared dependency the package does not actually need, an undeclared one it
does, or anything that runs at install time — the package has no install scripts,
and adding one would be a supply-chain change.
does, or anything that runs at install time — the package has no install scripts,
and adding one would be a supply-chain change.

## What is not

- **Authentication and authorization.** This package ships no auth. The `login` and
`access-notice` blocks are *presentation*: they render a form and a message. What
`access-notice` blocks are _presentation_: they render a form and a message. What
a submission does, whether a session is valid, and who may see a route are the
host's, and a host that trusts a client-side check owns that decision.
- **Fetching, caching and transport.** Components never fetch. A `DataPort`
Expand Down
Loading
Loading