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 +2 -3
- package/skill/ButtonOptions.md +1 -1
- package/skill/FloatingMenuOptions.md +16 -0
- package/skill/SKILL.md +15 -17
- package/skill/button.md +1 -1
- package/skill/buttonGroup.md +3 -3
- package/skill/dialog.md +1 -1
- package/skill/menuButton.md +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "staffa",
|
|
3
|
-
"version": "0.7.
|
|
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
|
-
"
|
|
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": {
|
package/skill/ButtonOptions.md
CHANGED
|
@@ -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 `".
|
|
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
|
-
- **
|
|
86
|
-
- **
|
|
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.
|
|
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: ".
|
|
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
|
|
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
|
|
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.**
|
|
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
|
|
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 `.
|
|
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
|
|
306
|
-
- Surface levels `.base`/`.panel`/`.raised`/`.neutral
|
|
307
|
-
-
|
|
308
|
-
-
|
|
309
|
-
-
|
|
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: ".
|
|
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>
|
package/skill/buttonGroup.md
CHANGED
|
@@ -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: ".
|
|
19
|
-
{ content: "Week", attrs: ".
|
|
20
|
-
{ content: "Month", attrs: ".
|
|
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: ".
|
|
25
|
+
S.button({ content: "Cancel", attrs: ".neutral", click: close });
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
```
|
package/skill/menuButton.md
CHANGED
|
@@ -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: ".
|
|
20
|
+
button: { content: "Actions", attrs: ".neutral" },
|
|
21
21
|
items: [
|
|
22
22
|
{ label: "Edit", icon: () => A("#✎"), click: () => edit() },
|
|
23
23
|
{ separator: true },
|