staffa 0.7.1 → 0.7.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "staffa",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "An opinionated component library for the Aberdeen reactive UI library.",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -28,8 +28,7 @@
28
28
  "build": "npm run build:icons && tsc && tsc -p demo && esbuild src/index.ts --bundle --external:aberdeen --minify --format=esm --outfile=dist/staffa.esm.js",
29
29
  "build:skill": "rm -rf skill ; mkdir skill && readme-tsdoc --create src/index.ts --file skill/REFERENCE.md --split && awk '/^@@include /{while((getline line < $2)>0) print line; close($2); next} 1' skill-template.md > skill/SKILL.md && rm skill/REFERENCE.md",
30
30
  "typecheck": "tsc --noEmit && tsc -p demo --noEmit",
31
- "smoke": "tsc && node smoke.mjs",
32
- "prepublish": "npm run build && shotest test && npm run build:skill",
31
+ "prepublishOnly": "npm run build && npx shotest test --fail-on-visual-changes && npm run build:skill",
33
32
  "test": "shotest test"
34
33
  },
35
34
  "peerDependencies": {
@@ -48,7 +48,7 @@ Accessible label, when the button has only an icon.
48
48
 
49
49
  Aberdeen attr/style string applied to the button. A button is a surface, so
50
50
  pass surface modifier classes here to restyle it, e.g. `".danger"`,
51
- `".danger .outlined"`, or `".nest"` for a neutral button. Defaults to a
51
+ `".danger .outlined"`, or `".neutral"` for a neutral button. Defaults to a
52
52
  filled `.primary` surface.
53
53
 
54
54
  Size is set here too, with `.small` or `.large` (medium is the default and
@@ -14,6 +14,22 @@ Element to anchor the menu to (positioned just below it, flips up if needed).
14
14
 
15
15
  **Type:** `HTMLElement`
16
16
 
17
+ ### floatingMenuOptions.at · member
18
+
19
+ Position the menu at this viewport point (e.g. a pointer location) instead
20
+ of just below the anchor. Used by `addContextMenu` to open at the
21
+ exact click/tap target.
22
+
23
+ **Type:** `{ x: number; y: number; }`
24
+
25
+ ### floatingMenuOptions.closeOnAnchorClick · member
26
+
27
+ Also close the menu when the anchor itself is clicked. By default a click on
28
+ the anchor is ignored (so a trigger button can run its own toggle), but a
29
+ context menu — whose anchor has no click handler — wants the click to close.
30
+
31
+ **Type:** `boolean`
32
+
17
33
  ### floatingMenuOptions.dropdownAttrs · member
18
34
 
19
35
  Aberdeen attr/style string on the floating panel.
package/skill/SKILL.md CHANGED
@@ -82,22 +82,22 @@ S.box({ header: "See the [docs](/docs)", content: () => { ... } });
82
82
 
83
83
  Staffa builds on **surfaces**: elements marked with `.s-s` that have their own background and derived text/border tokens. There are two families:
84
84
 
85
- - **Nesting surfaces** — `.nest` (and the implicit page at `:root`). A calm neutral whose shade steps automatically with nesting depth (page → panel → raised, capped). Use them for cards, bars, popovers — anything that just holds content. No variants.
86
- - **Solid surfaces** — `.primary`, `.danger`, `.success`, `.warning`, `.link` (a bare `.s-s` defaults to primary). A bright fill with white ink, painted as a subtle single-colour gradient. They take a **variant**: `.filled` (default), `.tonal`, or `.outlined`. A surface nested *inside* a solid surface is always rendered filled, so it can't bleed into the vivid parent.
85
+ - **Neutral surfaces** — `.neutral` (and the implicit page at `:root`). A calm neutral whose shade steps automatically with nesting depth (page → panel → raised, capped). Use them for cards, bars, popovers — anything that just holds content. No variants.
86
+ - **Accent surfaces** — `.primary`, `.danger`, `.success`, `.warning`, `.link` (a bare `.s-s` defaults to primary). A bright fill with white ink, painted as a subtle single-colour gradient. They take a **variant**: `.filled` (default), `.tonal`, or `.outlined`. A surface nested *inside* an accent surface is always rendered filled, so it can't bleed into the vivid parent.
87
87
 
88
- Components are built from these (`S.button` is a `.s-s.primary`, `S.box` a `.s-s.nest`, etc.). Because component options include an optional `attrs` string, which has Aberdeen `A()` string semantics, you can easily override it:
88
+ Components are built from these (`S.button` is a `.s-s.primary`, `S.box` a `.s-s.neutral`, etc.). Because component options include an optional `attrs` string, which has Aberdeen `A()` string semantics, you can easily override it:
89
89
 
90
90
  ```ts
91
91
  S.button({ content: "Delete", attrs: ".danger" });
92
- S.button({ content: "Cancel", attrs: ".nest" }); // neutral button
92
+ S.button({ content: "Cancel", attrs: ".neutral" }); // neutral button
93
93
  S.box({ attrs: ".primary", content: () => { ... } });
94
94
  ```
95
95
 
96
- Inside any surface (including `:root`), CSS variables are defined for the background and a set of safe foreground colors: `$s-bg`, `$s-text` (also applied as `color`), `$s-muted`, `$s-accent` (the surface's "pop" — the brand primary on nesting surfaces, the ink on solid surfaces), and `$s-faint`. By using these, components adapt to wherever they're nested.
96
+ Inside any surface (including `:root`), CSS variables are defined for the background and a set of safe foreground colors: `$s-bg`, `$s-text` (also applied as `color`), `$s-muted`, `$s-accent` (the surface's "pop" — the brand primary on neutral surfaces, the ink on accent surfaces), and `$s-faint`. By using these, components adapt to wherever they're nested.
97
97
 
98
- The colour tokens are mode-independent and settable: `$s-primary` (the one brand colour — it tints the neutrals and defines `.s-s.primary`), `$s-danger`, `$s-success`, `$s-warning`, and `$s-link` (the link colour, which is also the fill of the `.s-s.link` surface). Links render in `$s-link` on nesting surfaces and in the ink on solid surfaces.
98
+ The colour tokens are mode-independent and settable: `$s-primary` (the one brand colour — it tints the neutrals and defines `.s-s.primary`), `$s-danger`, `$s-success`, `$s-warning`, and `$s-link` (the link colour, which is also the fill of the `.s-s.link` surface). Links render in `$s-link` on neutral surfaces and in the ink on accent surfaces.
99
99
 
100
- **Borders & shadows.** Nesting surfaces carry a subtle hairline border on their own (so a card looks like a card without any component help). Any surface can be lifted with `.shadow` or `.extra-shadow`: on a nesting surface that's a neutral drop shadow, on a solid surface it's a self-coloured glow (a lit button is just a `.primary` surface with `.shadow`), and on `.tonal`/`.outlined` it's ignored. `.no-shadow` removes a component's built-in shadow:
100
+ **Borders & shadows.** Neutral surfaces carry a subtle hairline border on their own (so a card looks like a card without any component help). Any surface can be lifted with `.shadow` or `.extra-shadow`: on a neutral surface that's a neutral drop shadow, on an accent surface it's a self-coloured glow (a lit button is just a `.primary` surface with `.shadow`), and on `.tonal`/`.outlined` it's ignored. `.no-shadow` removes a component's built-in shadow:
101
101
 
102
102
  ```ts
103
103
  S.box({ attrs: ".extra-shadow", content: () => { ... } }); // a more raised card
@@ -132,7 +132,7 @@ A.cssVars["s-radius"] = "4px";
132
132
 
133
133
  See `src/theme.ts` for what other CSS variables are being used.
134
134
 
135
- If you need further customization, just add some CSS to override the default styling. For instance, to add your own solid surface, set its background (and, if needed, its ink) — the subtle gradient and the rest of the tokens follow automatically:
135
+ If you need further customization, just add some CSS to override the default styling. For instance, to add your own accent surface, set its background (and, if needed, its ink) — the subtle gradient and the rest of the tokens follow automatically:
136
136
 
137
137
  ```ts
138
138
  A.insertGlobalCss({".s-s.my-surface": "--s-bg:#ef6b00 --s-text:#fff"});
@@ -250,7 +250,7 @@ Staffa is designed for extension. A component is simply a plain function taking
250
250
 
251
251
  3. **Reach for reactivity deliberately.** Pass option strings straight to `A` as positional args (the caller's scope). Only wrap a dedicated `A(() => ...)` scope where it matters: input elements (recreation loses focus), or large subtrees you don't want to redraw. Use `A.peek(() => ...)` when you need a value but must not subscribe.
252
252
 
253
- 4. **Build on surfaces.** Mark elements `.s-s` and add `.nest` (neutral) or a solid role (`.primary`, `.danger`, …) plus an optional variant. Inside them, use the contextual CSS variables (`$s-text`, `$s-bg`, `$s-muted`, `$s-accent`, `$s-faint`, ...) so components adapt to wherever they're nested. Hard-coding colors in components shouldn't be needed, but if you must, make sure you set *both* foreground and background.
253
+ 4. **Build on surfaces.** Mark elements `.s-s` and add `.neutral` or an accent role (`.primary`, `.danger`, …) plus an optional variant. Inside them, use the contextual CSS variables (`$s-text`, `$s-bg`, `$s-muted`, `$s-accent`, `$s-faint`, ...) so components adapt to wherever they're nested. Hard-coding colors in components shouldn't be needed, but if you must, make sure you set *both* foreground and background.
254
254
 
255
255
  5. **No outer margins.** Components don't margin themselves; spacing is the parent's job. Content components set default `padding` on the content element; `contentAttrs` overrides it.
256
256
 
@@ -302,13 +302,11 @@ ln -s ../../node_modules/staffa/skill .claude/skills/staffa
302
302
 
303
303
  ## Breaking changes
304
304
 
305
- - **0.7** — the surface model was simplified to two families: **nesting** (`.nest`) and **solid** (`.primary`/`.danger`/`.success`/`.warning`/`.link`).
306
- - Surface levels `.base`/`.panel`/`.raised`/`.neutral` are replaced by a single `.nest` class whose shade steps with nesting depth. Replace them all with `.nest` (a neutral *button* is `.nest` too, in place of `.neutral .outlined`).
307
- - `.secondary` and `.gradient` are gone: there is no more `s-secondary` colour, and the default button is `.primary` (which now carries a subtle auto-gradient). Drop `s-secondary` overrides.
308
- - Solid surfaces now use **white** ink (was near-black), and the brand/semantic colours (`s-primary`/`s-danger`/`s-success`/`s-warning`) are now a single mode-independent value each.
309
- - New: a `s-link` colour and a matching `.s-s.link` surface. Links use `s-link` on nesting surfaces, the ink on solid ones.
310
- - Nesting surfaces now carry their own hairline border, and `.shadow`/`.extra-shadow`/`.no-shadow` utilities work on any surface. `S.box` no longer draws its own border/shadow (they come from the surface); pass `.no-shadow` to `S.box`/`S.button` to drop the default elevation.
311
- - Contextual tokens were renamed/trimmed: `--s-fg`→`--s-text`, `--s-fg-muted`→`--s-muted`, `--s-border`→`--s-faint`; `--s-strong`, `--s-fg-faint`, `--s-border-strong`, `--s-on-accent`, `--s-ink`, `--s-page`/`--s-panel`/`--s-raised`, `--s-tint`, `--s-glow`, `--s-shadow`, `--s-gradient-surface`, and the `--s-a`/`--s-b` anchors were removed. Custom solid surfaces now set `--s-bg`/`--s-text`.
305
+ - **0.7** — the surface model was reduced to two families: **neutral** (`.neutral`) and **accent** (`.primary`/`.danger`/`.success`/`.warning`/`.link`). Apps that only use the high-level `S.*` components need no changes. Code that uses surface classes or tokens directly must update:
306
+ - **Surface levels gone.** Replace `.base`/`.panel`/`.raised`/`.neutral`/`.nest` with the single `.neutral` class.
307
+ - **`.secondary` and `.gradient` gone.** Drop any `s-secondary` colour override; there's no `s-secondary` anymore. The default button is now `.primary`.
308
+ - **Tokens renamed.** `--s-fg`→`--s-text`, `--s-fg-muted`→`--s-muted`, `--s-border`→`--s-faint`. Removed: `--s-fg-faint`, `--s-border-strong`, `--s-ink`, `--s-on-accent`, `--s-page`/`--s-panel`/`--s-raised`, `--s-neutral`, `--s-tint`, `--s-glow`, `--s-shadow`, `--s-gradient-surface`. A custom surface now sets `--s-bg`/`--s-text` (was the `--s-a`/`--s-b` anchors).
309
+ - **Borders/shadows moved onto surfaces.** Components no longer draw their own border/shadow. If you relied on `S.box`/`S.dialog`/etc. elevation, it now comes from the surface; pass `.no-shadow` to drop it, or `.shadow`/`.extra-shadow` to add it on any surface.
312
310
 
313
311
  - **0.6**: None.
314
312
 
@@ -480,7 +478,7 @@ Options for `showFloatingMenu`.
480
478
  Options for `addContextMenu` — like `FloatingMenuOptions`, but
481
479
  the anchor is the element the handler is attached to.
482
480
 
483
- **Type:** `Omit<FloatingMenuOptions, "anchor">`
481
+ **Type:** `Omit<FloatingMenuOptions, "anchor" | "at" | "closeOnAnchorClick">`
484
482
 
485
483
  ## [dialog](dialog.md) · function
486
484
 
package/skill/button.md CHANGED
@@ -24,7 +24,7 @@ S.button({ href: "/dashboard", content: "Dashboard" }); // navigates via router
24
24
 
25
25
  ```ts
26
26
  S.button({ content: "Save", click: S.alert("Saved.") });
27
- S.button({ content: "Cancel", attrs: ".nest", click: cancel }); // neutral button
27
+ S.button({ content: "Cancel", attrs: ".neutral", click: cancel }); // neutral button
28
28
  S.button({ content: "Delete", attrs: ".danger .outlined", click: del });
29
29
  S.button("Cancel"); // shorthand for { content: "Cancel" }
30
30
  S.button({ href: "/docs", content: "Docs" }); // renders an <a role=button>
@@ -15,8 +15,8 @@ If you want a single button to be *selected*, use `buttonChooser`.
15
15
 
16
16
  ```ts
17
17
  S.buttonGroup({ buttons: [
18
- { content: "Day", attrs: ".nest" },
19
- { content: "Week", attrs: ".nest" },
20
- { content: "Month", attrs: ".nest" },
18
+ { content: "Day", attrs: ".neutral" },
19
+ { content: "Week", attrs: ".neutral" },
20
+ { content: "Month", attrs: ".neutral" },
21
21
  ]});
22
22
  ```
package/skill/dialog.md CHANGED
@@ -22,7 +22,7 @@ S.dialog({
22
22
  content: (close) => {
23
23
  A("p #Are you sure?");
24
24
  S.button({ content: "Yes", click: () => { S.alert("Nice!"); close(); } });
25
- S.button({ content: "Cancel", attrs: ".nest", click: close });
25
+ S.button({ content: "Cancel", attrs: ".neutral", click: close });
26
26
  },
27
27
  });
28
28
  ```
@@ -17,7 +17,7 @@ for SPA navigation — active items are highlighted automatically.
17
17
 
18
18
  ```ts
19
19
  S.menuButton({
20
- button: { content: "Actions", attrs: ".nest" },
20
+ button: { content: "Actions", attrs: ".neutral" },
21
21
  items: [
22
22
  { label: "Edit", icon: () => A("#✎"), click: () => edit() },
23
23
  { separator: true },