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
22 changes: 16 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,19 @@ jobs:
- name: Type-check
run: npx tsc --noEmit

- name: Test
run: npm test -- --run

# BUILD BEFORE TEST, deliberately. `tests/cdn-artifacts.test.ts` asserts
# properties of the published artifacts that source cannot show — that
# SibuJS is absent from the CDN bundle's bytes, that diagnostics are
# compiled out of the production build, that the stylesheet carries the
# utilities the components use. With no `dist/` those tests have nothing
# to read, and they are written to FAIL rather than skip on CI, because a
# silent skip is how the gap they cover would come back.
- name: Build
run: npm run build

- name: Test
run: npm test -- --run

- name: Packaging check
run: npm pack --dry-run

Expand Down Expand Up @@ -101,12 +108,15 @@ jobs:
- name: Type-check against SibuJS ${{ matrix.sibujs }}
run: npx tsc --noEmit

- name: Test against SibuJS ${{ matrix.sibujs }}
run: npm test -- --run

# Built first for the same reason as above: the artifact tests read
# `dist/`, and here they also run the CDN bundle against THIS matrix
# entry's runtime, which is the point of the job.
- name: Build against SibuJS ${{ matrix.sibujs }}
run: npm run build

- name: Test against SibuJS ${{ matrix.sibujs }}
run: npm test -- --run

audit:
name: Audit (production deps)
runs-on: ubuntu-latest
Expand Down
72 changes: 71 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,76 @@ This project follows [Semantic Versioning](https://semver.org/).

---

## [1.6.0] — 2026-09-07

### Added — a CDN build

`sibujs-ui` had no no-build story: the package shipped ESM and CJS only, so a
page without a bundler could use the SibuJS runtime from a `<script>` tag but
none of these components. It now ships its own IIFE pair, installing `SibuUI`:

```html
<script src="https://unpkg.com/sibujs@latest/dist/cdn.global.js"></script>
<script src="https://unpkg.com/sibujs-ui@latest/dist/cdn.global.js"></script>
<script>
const { Button, Card, Dialog } = window.SibuUI;
</script>
```

New export paths: `sibujs-ui/cdn`, `sibujs-ui/cdn-dev` and `sibujs-ui/cdn-css`.
`npm run build` produces all three; `npm run build:cdn` and `npm run build:css`
build them separately.

**A compiled stylesheet ships with it, and it is not optional.** Every component
carries Tailwind utility classes — 29 on a single `Button` — and the theme files
are custom properties only, so a page that loaded just the script tag got
correct behaviour and raw browser defaults: `display: inline-block`,
`background: rgb(240,240,240)`, `padding: 6px`, no radius. Nothing threw, which
makes that harder to diagnose, not easier. A no-build consumer has no build step
by definition, so `dist/sibujs-ui.css` is now compiled from the components'
actual class usage plus the base and default themes — 113.7 KB, 17.7 KB gzip.
With it linked, the same `Button` renders `inline-flex`, `oklch(0.205 0 0)`,
16px padding, 8px radius, 36px tall, and dark mode inverts correctly.

It includes Tailwind's Preflight, matching what bundler consumers get from
`@import "tailwindcss"` — the components are designed against that reset, and
without it buttons keep their native chrome. It therefore restyles the host
page, which the README states plainly.

**SibuJS is not bundled in.** It stays a peer dependency in this artifact too:
the build resolves `sibujs` to the `window.Sibu` that the runtime tag installs,
so a page that already loaded the framework does not download it again. Loading
`sibujs-ui`'s tag without the runtime throws a message naming the problem and
the fix, rather than surfacing later as an undefined property inside whichever
component ran first.

| bundle | size |
| --- | --- |
| `cdn.global.js` | 573.5 KB raw / 132.2 KB gzip |
| `cdn.dev.global.js` | 574.1 KB raw / 132.4 KB gzip |

The CDN build carries the whole package — every component and the full icon
set — because a `<script>` tag cannot tree-shake, and the icons are roughly
79 KB gzip of that total. Bundler users are unaffected: the ESM/CJS entry
points are untouched and still tree-shake per import.

`tests/cdn-artifacts.test.ts` runs the published bundles against the installed
runtime and pins the properties that source cannot show: SibuJS absent from the
bytes, the ordering guard firing, `SibuUI` registered without disturbing
`Sibu`, and diagnostics compiled out of the production file.

### Fixed — the dev gate is now foldable

`components/types.ts` tested `globalThis.__SIBU_DEV__` first. A member
expression is not a `define` target, so no bundler could replace it: the branch
stayed live and its warning text rode along into builds that could never print
it. It now leads with a bare `__SIBU_DEV__`, mirroring the framework's own
convention, so `define: { __SIBU_DEV__: "false" }` folds it away. Behaviour is
unchanged everywhere the flag was already correct — the fallbacks it used
before are still consulted in the same order after it.

---

## [1.5.3] — 2026-09-07

Verified against `sibujs@4.3.0`. No component, styling or API change — the
Expand All @@ -14,7 +84,7 @@ published package is byte-identical in behaviour to 1.5.2.
### Changed

- Development dependency `sibujs` → `^4.3.0`, so the suite and the type
declarations build against the release consumers will actually install
declarations build against the release that consumers will actually install
alongside this package. It is a devDependency, so nothing changes for
consumers: the peer range `>=3.2.0 <5.0.0` already admitted 4.3.0.

Expand Down
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,56 @@ CI runs the full test suite, type-check and build against sibujs `3.2.0`, `3.4.1

Building and testing the repository needs `>=22.12.0`, because the dev toolchain (Vite 7 / rolldown) ships a native binding that declares `^20.19.0 || >=22.12.0`. That is a contributor requirement only — rolldown is a devDependency and is never published. CI runs the full verification on Node 22.12, 22 and 24.

### Without a bundler (CDN)

One stylesheet and two script tags, **the runtime first**:

```html
<link rel="stylesheet" href="https://unpkg.com/sibujs-ui@latest/dist/sibujs-ui.css" />
<script src="https://unpkg.com/sibujs@latest/dist/cdn.global.js"></script>
<script src="https://unpkg.com/sibujs-ui@latest/dist/cdn.global.js"></script>
<script>
const { Button, Card, Dialog } = window.SibuUI;
document.body.appendChild(Button({ variant: "default" }, ["Click me"]));
</script>
```

That is the whole setup — no build step, and no separate theme import.

This is what makes the components usable from a SibuJS **island**: build them
inside a `registerIsland` setup and append them to the server-rendered markup.
Components create their signals through the same runtime the island uses, so a
click handler on a `Button` drives the island's own state with no wiring.

SibuJS is **not** bundled into `sibujs-ui`'s CDN file. It stays a peer
dependency there too: the build resolves `sibujs` to the `window.Sibu` that the
runtime tag installs, so a page never downloads the framework twice. That is
also why the order matters — loading `sibujs-ui` alone throws an error saying
exactly that, rather than failing later inside a component.

Use `cdn.dev.global.js` while developing to get the package's warnings; the
production file has them compiled out, not merely disabled. Both are also
reachable as `sibujs-ui/cdn` and `sibujs-ui/cdn-dev`.

The CDN build carries the whole package — every component **and** the full icon
set — because a `<script>` tag cannot tree-shake. Bundler users are unaffected
and still pay only for what they import.

**The stylesheet is not optional.** Every component carries Tailwind utility
classes — 29 of them on a single `Button` — and the theme files are custom
properties only. Without `sibujs-ui.css`, the components behave correctly and
render as raw browser defaults: nothing throws, so it looks like a styling bug
rather than a missing file.

It is 113.7 KB (17.7 KB gzip), contains the utilities the components actually
use plus the base and default themes, and is reachable as `sibujs-ui/cdn-css`.
It includes Tailwind's Preflight reset, exactly as the bundler setup below
does — so it will restyle the surrounding page. Dark mode works by putting
`class="dark"` on `<html>` or any ancestor.

Using a different theme? Link the stylesheet and then override the tokens with
one of `sibujs-ui/themes/*.css`, or your own values.

## Setup

Add the required theme CSS to your project's stylesheet:
Expand Down
Loading
Loading