@ponchia/ui 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -79
- package/behaviors/index.d.ts +53 -0
- package/behaviors/index.js +745 -34
- package/classes/index.d.ts +216 -3
- package/classes/index.js +85 -10
- package/classes/vscode.css-custom-data.json +407 -0
- package/css/app.css +53 -44
- package/css/base.css +14 -23
- package/css/content.css +37 -2
- package/css/core.css +5 -5
- package/css/disclosure.css +17 -5
- package/css/dots.css +1 -1
- package/css/feedback.css +87 -2
- package/css/forms.css +128 -2
- package/css/navigation.css +16 -85
- package/css/overlay.css +73 -2
- package/css/primitives.css +100 -3
- package/css/site.css +295 -0
- package/css/table.css +59 -0
- package/css/tokens.css +79 -24
- package/dist/bronto.css +1 -1
- package/dist/css/app.css +1 -0
- package/dist/css/base.css +1 -0
- package/dist/css/content.css +1 -0
- package/dist/css/disclosure.css +1 -0
- package/dist/css/dots.css +1 -0
- package/dist/css/feedback.css +1 -0
- package/dist/css/fonts.css +1 -0
- package/dist/css/forms.css +1 -0
- package/dist/css/motion.css +1 -0
- package/dist/css/navigation.css +1 -0
- package/dist/css/overlay.css +1 -0
- package/dist/css/primitives.css +1 -0
- package/dist/css/site.css +1 -0
- package/dist/css/table.css +1 -0
- package/dist/css/tokens.css +1 -0
- package/package.json +60 -30
- package/shiki/nothing.json +83 -0
- package/tokens/index.d.ts +18 -10
- package/tokens/index.js +49 -16
- package/tokens/index.json +98 -32
- package/tokens/tokens.dtcg.json +241 -22
- package/css/cards.css +0 -336
- package/css/index.css +0 -5
- package/css/layout.css +0 -219
- package/css/responsive.css +0 -157
- package/css/typography.css +0 -139
- package/dist/bronto-core.css +0 -1
package/README.md
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
# @ponchia/ui
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@ponchia/ui)
|
|
4
|
+
[](https://www.npmjs.com/package/@ponchia/ui#provenance)
|
|
5
|
+
[](package.json)
|
|
6
|
+
[](scripts/check-dist.mjs)
|
|
7
|
+
[](https://github.com/Ponchia/bronto-ui/actions/workflows/ci.yml)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
3
10
|
Shared UI framework for Bronto personal projects. Nothing-inspired:
|
|
4
11
|
monochrome surfaces, a single red accent, dot-matrix display type (Doto),
|
|
5
12
|
flat hairline borders, restrained motion. CSS-first and framework-agnostic.
|
|
6
13
|
|
|
14
|
+
**New here?** → [Getting started](#getting-started) ·
|
|
15
|
+
[Reference](docs/reference.md) · [Theming](docs/theming.md) ·
|
|
16
|
+
[Roadmap](ROADMAP.md) · [Contributing](CONTRIBUTING.md)
|
|
17
|
+
|
|
18
|
+
> **Editor IntelliSense.** The package ships a VS Code CSS Custom Data
|
|
19
|
+
> file so every design token autocompletes inside `var(--…)`. Add to
|
|
20
|
+
> your `.vscode/settings.json`:
|
|
21
|
+
>
|
|
22
|
+
> ```json
|
|
23
|
+
> {
|
|
24
|
+
> "css.customData": ["node_modules/@ponchia/ui/classes/vscode.css-custom-data.json"]
|
|
25
|
+
> }
|
|
26
|
+
> ```
|
|
27
|
+
|
|
28
|
+
**[Live demo →](https://ponchia.github.io/bronto-ui/)** — the kitchen
|
|
29
|
+
sink (every component, light/dark, RTL, theming) deployed from `demo/`.
|
|
30
|
+
|
|
7
31
|
## Use
|
|
8
32
|
|
|
9
33
|
Install from npm (public, no registry config):
|
|
@@ -18,30 +42,33 @@ npm i @ponchia/ui
|
|
|
18
42
|
> deliberately distinct from the package name. See
|
|
19
43
|
> [`docs/architecture.md`](docs/architecture.md).
|
|
20
44
|
|
|
21
|
-
Import the
|
|
22
|
-
|
|
23
|
-
```css
|
|
24
|
-
@import '@ponchia/ui/css';
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Or the core bundle if the app manages its own responsive layer:
|
|
45
|
+
Import the theme (one bundle — `ui-*` components carry their own
|
|
46
|
+
breakpoints, so there is no separate core/full split as of 0.3.0):
|
|
28
47
|
|
|
29
48
|
```css
|
|
30
|
-
@import '@ponchia/ui/css/core.css
|
|
49
|
+
@import '@ponchia/ui/css'; /* === @ponchia/ui/css/core.css */
|
|
31
50
|
```
|
|
32
51
|
|
|
33
52
|
**Prebuilt single file (recommended for apps without a CSS bundler).**
|
|
34
|
-
`@ponchia/ui/css` is a
|
|
35
|
-
a load waterfall over plain HTTP. The
|
|
36
|
-
minified
|
|
53
|
+
`@ponchia/ui/css` is a wide `@import` fan-out (~14 leaves, one level
|
|
54
|
+
deep) — fine through a bundler, a load waterfall over plain HTTP. The
|
|
55
|
+
package also ships one flattened, minified bundle with no `@import`
|
|
56
|
+
chain:
|
|
37
57
|
|
|
38
58
|
```css
|
|
39
|
-
@import '@ponchia/ui';
|
|
40
|
-
@import '@ponchia/ui/dist/bronto-core.css'; /* core, no responsive */
|
|
59
|
+
@import '@ponchia/ui'; /* → dist/bronto.css, the whole framework */
|
|
41
60
|
```
|
|
42
61
|
|
|
43
|
-
~
|
|
44
|
-
|
|
62
|
+
~54 kB raw / ~10 kB gzip, one request, same `@layer bronto`. (The
|
|
63
|
+
enforced ceiling lives in `scripts/check-dist.mjs`, not this prose —
|
|
64
|
+
treat these figures as indicative.) Source CSS, tokens/classes/behaviors
|
|
65
|
+
entrypoints are unchanged — use whichever fits.
|
|
66
|
+
|
|
67
|
+
> **The package root is CSS-only.** `@ponchia/ui` (the `.` export)
|
|
68
|
+
> resolves to a stylesheet — `@import '@ponchia/ui'` in CSS, never
|
|
69
|
+
> `import '@ponchia/ui'` in JS. There is no JS module at the root; the
|
|
70
|
+
> JS entrypoints are the explicit subpaths `@ponchia/ui/tokens`,
|
|
71
|
+
> `/classes`, and `/behaviors` (see [Entrypoints](#entrypoints)).
|
|
45
72
|
|
|
46
73
|
### Browser support
|
|
47
74
|
|
|
@@ -59,10 +86,14 @@ font instead, import everything except `fonts.css` and override `--display` /
|
|
|
59
86
|
|
|
60
87
|
Everything ships inside a single `@layer bronto`, so any un-layered CSS in
|
|
61
88
|
your app overrides the framework without a specificity fight or `!important`.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
89
|
+
|
|
90
|
+
> **Leaf imports are layer-safe by default.** Every per-leaf export —
|
|
91
|
+
> `@ponchia/ui/css/primitives.css`, etc. — is self-wrapped in
|
|
92
|
+
> `@layer bronto`, so mixing the bundle with individual leaves (e.g.
|
|
93
|
+
> per-route CSS splitting in SvelteKit/Astro) is safe: no silent
|
|
94
|
+
> cascade inversion. The deliberate full-specificity escape hatch is
|
|
95
|
+
> the explicit `@ponchia/ui/css/unlayered/<leaf>.css` path — use it
|
|
96
|
+
> only when you *want* an unlayered override, never by accident.
|
|
66
97
|
|
|
67
98
|
Set `data-theme="light"` or `data-theme="dark"` on `<html>`; defaults follow
|
|
68
99
|
`prefers-color-scheme`.
|
|
@@ -90,7 +121,9 @@ themeColor('dark').accent; // → "#ff3b41"
|
|
|
90
121
|
```
|
|
91
122
|
|
|
92
123
|
`behaviors` wires `[data-bronto-theme-toggle]`, `[data-bronto-dismiss]` /
|
|
93
|
-
`[data-bronto-dismissible]`, `[data-bronto-disclosure]`,
|
|
124
|
+
`[data-bronto-dismissible]`, `[data-bronto-disclosure]`,
|
|
125
|
+
`[data-bronto-menu]` (`initMenu`: Escape / outside-click /
|
|
126
|
+
close-on-activate for a `<details>` `.ui-menu` dropdown), and native
|
|
94
127
|
`<dialog>` glue (`initDialog`: `[data-bronto-open]` / `[data-bronto-close]`
|
|
95
128
|
/ `[data-bronto-dialog-light]`). `toast(message, { tone, title, duration })`
|
|
96
129
|
pushes into a shared, body-anchored stack. Each initializer is SSR-safe and
|
|
@@ -112,74 +145,70 @@ modules, so it is also a live integration test.
|
|
|
112
145
|
| `overlay.css` | modal + drawer (native `<dialog>`), dropdown menu |
|
|
113
146
|
| `disclosure.css` | tabs, accordion (`<details>`), segmented, breadcrumb, pagination, avatar |
|
|
114
147
|
| `table.css` | `ui-table` dense / comfortable |
|
|
115
|
-
| `app.css` | admin shell: rail
|
|
116
|
-
| `navigation.css` |
|
|
117
|
-
| `
|
|
118
|
-
| `content.css` | `.ui-prose`
|
|
119
|
-
| `cards.css` | semantic content cards (token-driven) |
|
|
120
|
-
| `layout.css` | site shell, hero, grids |
|
|
121
|
-
| `responsive.css` | breakpoint overrides |
|
|
148
|
+
| `app.css` | admin shell: `ui-app-shell`/`-rail`/`-topbar`/`-toolbar`/`-panel`/`-nav`/`-metrics` |
|
|
149
|
+
| `navigation.css` | `ui-themetoggle` (dot-thumb switch) |
|
|
150
|
+
| `site.css` | content-site shell: `ui-container`, `ui-siteheader`/`ui-sitenav` (aria-current), `ui-sitemenu`, `ui-sitefooter`, `ui-skiplink`, `ui-tags`, `ui-meta` |
|
|
151
|
+
| `content.css` | `.ui-prose` Markdown/raw-HTML long-form (zero classes) + `ui-quote` pull-quote |
|
|
122
152
|
|
|
123
|
-
##
|
|
153
|
+
## Getting started
|
|
124
154
|
|
|
125
|
-
|
|
126
|
-
|
|
155
|
+
| Consumer | Guide |
|
|
156
|
+
| ----------------------- | ------------------------------------------------------------------ |
|
|
157
|
+
| Astro | [`docs/getting-started/astro.md`](docs/getting-started/astro.md) |
|
|
158
|
+
| SvelteKit | [`docs/getting-started/sveltekit.md`](docs/getting-started/sveltekit.md) |
|
|
159
|
+
| Vanilla / Vite / plain | [`docs/getting-started/vanilla.md`](docs/getting-started/vanilla.md) |
|
|
160
|
+
| React / Solid (snippet) | [`docs/getting-started/react-solid.md`](docs/getting-started/react-solid.md) |
|
|
161
|
+
| Tailwind / cascade-layer interop | [`docs/interop/tailwind.md`](docs/interop/tailwind.md) |
|
|
127
162
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
163
|
+
Each covers the CSS import location, the **no-flash** `applyStoredTheme`
|
|
164
|
+
head-script pattern, behavior init/cleanup in that framework's lifecycle,
|
|
165
|
+
and SSR caveats. Index: [`docs/integration.md`](docs/integration.md).
|
|
131
166
|
|
|
132
|
-
##
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
npm install # stylelint + jsdom (test only)
|
|
136
|
-
npm run check # lint + 5 integrity checks (exports, tokens, classes, dist, pack)
|
|
137
|
-
npm test # node:test — pure modules + jsdom behavior tests
|
|
138
|
-
npm run lint:fix # auto-fix the safe stylistic rules + logical properties
|
|
139
|
-
npm run tokens:build # regenerate tokens/index.json from tokens/index.js
|
|
140
|
-
npm run dist:build # rebuild the flattened dist/ bundles
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
`npm run check` enforces that the data mirrors cannot drift from the CSS:
|
|
144
|
-
exports/import-graph integrity, `tokens.css` ⇄ `tokens/index.{js,json}`, the
|
|
145
|
-
`classes` registry ⇄ the `.ui-*` selectors, `dist/` ⇄ `css/` (fresh + in
|
|
146
|
-
budget), and that the published tarball ships only the intended files.
|
|
147
|
-
|
|
148
|
-
Visual + a11y regression is a separate suite (real browser, so not in the
|
|
149
|
-
zero-dep core check):
|
|
150
|
-
|
|
151
|
-
```bash
|
|
152
|
-
npx playwright test # demo screenshots (light/dark/RTL) + axe-core WCAG
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
It is pinned to a Playwright container so baselines are byte-stable; the
|
|
156
|
-
committed baselines under `test/e2e/__screenshots__` were authored in that
|
|
157
|
-
same image. CI (`.github/workflows/ci.yml`) runs both the `check` job and a
|
|
158
|
-
containerised `visual` job on every branch push and PR. It never publishes —
|
|
159
|
-
a push to `main` ships nothing.
|
|
160
|
-
|
|
161
|
-
## Release
|
|
167
|
+
## Demo
|
|
162
168
|
|
|
163
|
-
|
|
169
|
+
`demo/index.html` is a kitchen sink covering every primitive in both
|
|
170
|
+
themes — it drives itself with the real behavior modules, so it is also a
|
|
171
|
+
live integration test. Serve the package root and open `/demo/`:
|
|
164
172
|
|
|
165
173
|
```bash
|
|
166
|
-
|
|
167
|
-
git tag vX.Y.Z && git push origin vX.Y.Z
|
|
174
|
+
python3 -m http.server -d . 8080 # then open http://localhost:8080/demo/
|
|
168
175
|
```
|
|
169
176
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
## Develop & release
|
|
178
|
+
|
|
179
|
+
Contributor setup, the 14 `check` gates, the e2e suite, the visual-
|
|
180
|
+
baseline workflow, the deprecation policy and the tag-driven release
|
|
181
|
+
flow all live in **[CONTRIBUTING.md](CONTRIBUTING.md)**. Direction and
|
|
182
|
+
scope: **[ROADMAP.md](ROADMAP.md)**.
|
|
183
|
+
|
|
184
|
+
## Versioning
|
|
185
|
+
|
|
186
|
+
Pre-1.0 and deliberately so. **Until `1.0.0`, breaking changes ship in
|
|
187
|
+
the _minor_** (`0.x.0`); patches (`0.x.y`) are non-breaking. This is the
|
|
188
|
+
standard 0.x reading of SemVer, stated explicitly because this framework
|
|
189
|
+
dresses several apps:
|
|
190
|
+
|
|
191
|
+
- Because breaking changes bump the **minor**, the protective range is
|
|
192
|
+
the patch range. At `0.x` npm resolves **both** `^0.3.0` and `~0.3.0`
|
|
193
|
+
to `>=0.3.0 <0.4.0` — they are equivalent here, and either gives you
|
|
194
|
+
only non-breaking `0.3.x` patches while holding back the next
|
|
195
|
+
(breaking) `0.4.0`. Pin either; pin an **exact** version if you want
|
|
196
|
+
zero surprise and to adopt each minor deliberately.
|
|
197
|
+
- Every breaking change is called out in [`CHANGELOG.md`](CHANGELOG.md)
|
|
198
|
+
under a **BREAKING** heading with a migration note.
|
|
199
|
+
|
|
200
|
+
**What is contractual** (changes are breaking): the `--accent`
|
|
201
|
+
derivation and token **names** (incl. `--accent-text`, `--focus-ring`);
|
|
202
|
+
the `.ui-*` class names and `cls`/recipe names; the `data-bronto-*`
|
|
203
|
+
behavior attributes; each behavior's return-cleanup contract. **What is
|
|
204
|
+
not** (may change in any release): token _values_ (visual tuning), the
|
|
205
|
+
internal leaf-file boundaries and `@layer` internals, and anything
|
|
206
|
+
explicitly marked legacy/deprecated. Full token contract:
|
|
207
|
+
[`docs/theming.md`](docs/theming.md).
|
|
180
208
|
|
|
181
209
|
## Consumers
|
|
182
210
|
|
|
183
|
-
Built for two shapes of app: a content/marketing site (
|
|
184
|
-
|
|
185
|
-
`@ponchia/ui/css`)
|
|
211
|
+
Built for two shapes of app: a content/marketing site (`ui-site*`,
|
|
212
|
+
`ui-prose`) and an admin dashboard (`ui-app-*` shell). Both import the
|
|
213
|
+
one bundle `@ponchia/ui` (or `@ponchia/ui/css`); consuming apps depend
|
|
214
|
+
on it via `@ponchia/ui`.
|
package/behaviors/index.d.ts
CHANGED
|
@@ -39,6 +39,59 @@ export declare function dismissible(opts?: DelegateOpts): Cleanup;
|
|
|
39
39
|
/** Wire `[data-bronto-disclosure]` triggers. Returns a cleanup function. */
|
|
40
40
|
export declare function initDisclosure(opts?: DelegateOpts): Cleanup;
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Close affordances (Escape, outside-click, close-on-activate) for a
|
|
44
|
+
* native `<details data-bronto-menu>` dropdown holding a `.ui-menu`.
|
|
45
|
+
* Not a full ARIA menu by design. Returns a cleanup function.
|
|
46
|
+
*/
|
|
47
|
+
export declare function initMenu(opts?: DelegateOpts): Cleanup;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Accessible validation glue for `<form data-bronto-validate>`:
|
|
51
|
+
* progressive enhancement over the Constraint Validation API. Sets
|
|
52
|
+
* `aria-invalid`, writes `validationMessage` into the field's
|
|
53
|
+
* `[data-bronto-error]` / `.ui-hint` slot (linked via
|
|
54
|
+
* `aria-describedby`), and on invalid submit fills the form's
|
|
55
|
+
* `[data-bronto-error-summary]` with focusable links and blocks submit.
|
|
56
|
+
* Works without JS (native validation). Returns a cleanup function.
|
|
57
|
+
*/
|
|
58
|
+
export declare function initFormValidation(opts?: DelegateOpts): Cleanup;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Editable combobox with a filtered listbox popup (WAI-ARIA APG
|
|
62
|
+
* pattern), dependency-free and CSS-anchored. Wires
|
|
63
|
+
* `[data-bronto-combobox]` (input `role=combobox` +
|
|
64
|
+
* `.ui-combobox__list` of `role=option`): ids, `aria-expanded` /
|
|
65
|
+
* `aria-controls` / `aria-activedescendant`, type-to-filter, full
|
|
66
|
+
* keyboard, pointer select, outside-click close. Emits `bronto:change`
|
|
67
|
+
* ({ detail: { value } }) on selection. SSR-safe, idempotent per
|
|
68
|
+
* instance. Returns a cleanup function.
|
|
69
|
+
*/
|
|
70
|
+
export declare function initCombobox(opts?: DelegateOpts): Cleanup;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Collision-aware popover, dependency-free. A `[data-bronto-popover]`
|
|
74
|
+
* trigger toggles the `.ui-popover` panel it names; the panel flips
|
|
75
|
+
* above when it would overflow the viewport and its inline edge is
|
|
76
|
+
* clamped on-screen. Uses the native top layer when the panel has
|
|
77
|
+
* `popover` and the Popover API exists, else an `.is-open` class.
|
|
78
|
+
* Manages `aria-expanded`/`aria-controls`, Escape + outside-click
|
|
79
|
+
* close, scroll/resize reposition. Returns a cleanup function.
|
|
80
|
+
*/
|
|
81
|
+
export declare function initPopover(opts?: DelegateOpts): Cleanup;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Client-side sortable + selectable data table for
|
|
85
|
+
* `[data-bronto-sortable]`. Header `.ui-table__sort` / `th[data-sort]`
|
|
86
|
+
* cycles `aria-sort` and reorders the tbody (numeric- or
|
|
87
|
+
* locale-string-aware); `[data-bronto-select-all]` toggles
|
|
88
|
+
* `[data-bronto-select]` rows + `aria-selected` with synced
|
|
89
|
+
* checked/indeterminate state. Emits `bronto:selectionchange`
|
|
90
|
+
* ({ detail: { count } }). SSR-safe, idempotent per table. Returns a
|
|
91
|
+
* cleanup function.
|
|
92
|
+
*/
|
|
93
|
+
export declare function initTableSort(opts?: DelegateOpts): Cleanup;
|
|
94
|
+
|
|
42
95
|
/**
|
|
43
96
|
* Wire `[data-bronto-tabs]` groups with the WAI-ARIA Tabs keyboard
|
|
44
97
|
* pattern (roving tabindex, Arrow/Home/End, aria-selected, panel sync).
|