@usableapp/cardds 0.7.43 → 0.7.44
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/CHANGELOG.md +9 -0
- package/README.md +6 -1
- package/css/actions.css +5 -0
- package/css/layover.css +5 -5
- package/css/theme.template.css +2 -0
- package/css/tokens.css +13 -2
- package/dist/actions/Chip.d.ts +3 -2
- package/dist/actions/Chip.js +1 -1
- package/dist/actions/Dot.d.ts +4 -1
- package/dist/actions/Dot.js +2 -2
- package/dist/cardds.css +23 -7
- package/dist/layover/Snackbar.d.ts +3 -3
- package/dist/layover/Snackbar.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
> For: a project that consumes `@usableapp/cardds` and its AI — what changed between versions, written as before → after, so a screen can be brought up to date without reading the source. Newest first. A consumer never edits cardds; if something here leaves you without a way to do what you did before, report the gap.
|
|
4
4
|
|
|
5
|
+
## 0.7.44 — 2026-10-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **The signal set is the standard** (Lh 2026-10-02): four colours, four meanings, in every project and in the wireframe — `--signal-ok` green (it went right) · `--signal-warn` yellow (look out) · `--signal-error` red (it went wrong) · `--signal-info` blue (for your information). A theme may retune a shade in its `theme.css`, never a meaning. New: `--signal-ok-soft` · `--signal-warn-soft` · `--signal-error-soft` · `--signal-info-soft` — the light ground of each (the signal washed 14% into the surface); it follows the shade you set. Never the colour alone: an icon or words say it too.
|
|
9
|
+
- **`Dot tone`** and **`Chip dot`**: `ok` · `warn` · `error` · `info` — `<Chip dot="ok">พร้อม</Chip>`. `dot="a"` / `"b"` are unchanged. Story `Dot · Tones`.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- **`Snackbar` stands on the ok signal**: its ground is `--signal-ok-soft` with no border (was white with a border), and its glyph is `check` in `--signal-ok` by default — before, no `icon` meant no glyph; now pass `icon={false}` for none. New knob `--snackbar-icon-ink`. A screen that passed `icon="check"` needs no change.
|
|
13
|
+
|
|
5
14
|
## 0.7.43 — 2026-10-02
|
|
6
15
|
|
|
7
16
|
### Added
|
package/README.md
CHANGED
|
@@ -306,6 +306,11 @@ whose markup has rules, because the sheet's box is the step itself:
|
|
|
306
306
|
opened, a `SheetStack` sheet opened, a `Modal` arrived. Once it has settled: the field marked `data-autofocus`, else its
|
|
307
307
|
first field, else its heading (a step's title, a modal's question) or, for a sheet come onto the screen, its handle. A field
|
|
308
308
|
that already has the cursor keeps it. One mechanic for all of them (`focusWhenActive`, src/state.ts); an app writes no focus code.
|
|
309
|
+
- **The signal set — four colours, four meanings, everywhere** (Lh 2026-10-02): `--signal-ok` green (it went right) ·
|
|
310
|
+
`--signal-warn` yellow (look out) · `--signal-error` red (it went wrong) · `--signal-info` blue (for your information).
|
|
311
|
+
The wireframe has them too. A theme may retune a shade, never a meaning. Each is dark enough for words and edges;
|
|
312
|
+
`--signal-*-soft` is its light ground (the signal washed 14% into the surface). Never the colour alone: an icon or
|
|
313
|
+
words say it too. Read by: `Field`/`Pin`/`FormNote` error, `Dot tone` / `Chip dot="ok|warn|error|info"`, `Snackbar` (ok).
|
|
309
314
|
- **Good news is a `Snackbar`, a warning or a question is a `Modal`** (Lh 2026-10-02): a `Snackbar` is a quick line over the
|
|
310
315
|
screen — something went well, said in passing. A child of the `Screen`; it slides in from the top (or `bottom`, above the
|
|
311
316
|
bottom layer), stays `duration` (4 s), slides out, never takes the cursor, never stops the member. `open` +
|
|
@@ -623,7 +628,7 @@ That file is where a project's look lives. Bases and roles:
|
|
|
623
628
|
| the size **of** things | `--tap-base` (3rem = 48) | `--tap*`, `--btn-h`, `--chip-h`, `--bar-h`, `--header-h`, `--fab`, `--icon*`, `--avatar*`, `--dot*`, `--ring*`, `--tile-*`. `--tap*` never under `--tap-floor` (44px) |
|
|
624
629
|
| faces | `--font-ui`, `--font-display` | |
|
|
625
630
|
| colour | `--color-surface`, `--color-ink`, `--color-paper`, `--color-brand`, `--color-on-brand` — no default: unset = the wireframe | every role: surface / words, the three card tones (paper · the brand washed 14% into the surface · the brand), the muted inks (the ink washed into their ground), accent, neutral actions, `--dot-a` |
|
|
626
|
-
| colour roles (the escape hatch) | `--surface`, `--on-surface(-muted)`, `--card-{1,2,3}-{bg,ink}`, `--card-border`, `--card-muted`, `--card-2-muted`, `--accent`, `--on-accent`, `--action-{bg,ink,border}`, `--pos`, `--neg`, `--dot-{a,b}` | a role set directly wins over its derivation; the tints derive from the roles |
|
|
631
|
+
| colour roles (the escape hatch) | `--surface`, `--on-surface(-muted)`, `--card-{1,2,3}-{bg,ink}`, `--card-border`, `--card-muted`, `--card-2-muted`, `--accent`, `--on-accent`, `--action-{bg,ink,border}`, `--pos`, `--neg`, `--dot-{a,b}`, `--signal-{ok,warn,error,info}` | a role set directly wins over its derivation; the tints derive from the roles |
|
|
627
632
|
|
|
628
633
|
Rules:
|
|
629
634
|
|
package/css/actions.css
CHANGED
|
@@ -179,6 +179,11 @@
|
|
|
179
179
|
The drop: a line box is centred on its ascender room (Thai marks), the letters beside the dot sit lower — the dot rides down to the
|
|
180
180
|
letters' own middle, in em so it follows the text size (Lh 2026-09-22: "ตัวหนังสือกับไฟเสมอกัน") */
|
|
181
181
|
.dot--b { background: var(--dot-b); }
|
|
182
|
+
/* the signal set on a dot (Lh 2026-10-02): the words beside it say what — never the colour alone */
|
|
183
|
+
.dot--ok { background: var(--signal-ok); }
|
|
184
|
+
.dot--warn { background: var(--signal-warn); }
|
|
185
|
+
.dot--error { background: var(--signal-error); }
|
|
186
|
+
.dot--info { background: var(--signal-info); }
|
|
182
187
|
.chip--on { background: var(--chip-on-bg, var(--accent)); color: var(--chip-on-ink, var(--on-accent)); border-color: transparent; }
|
|
183
188
|
/* muted: an untouched default — the words wash out, the edge stays; emphasis is the difference from the neighbours (README 13) */
|
|
184
189
|
.chip--muted { color: var(--chip-muted-ink, var(--card-muted)); }
|
package/css/layover.css
CHANGED
|
@@ -312,7 +312,7 @@
|
|
|
312
312
|
<div class="snackbar snackbar--open" role="status"><div class="snackbar__body"><svg class="icon"/>
|
|
313
313
|
<span class="snackbar__words"><span class="snackbar__text">…</span><span class="snackbar__caption">…</span></span></div></div>
|
|
314
314
|
A LAYER of the screen (its child), over the top bar; --bottom = at the foot, above the screen's bottom layer (--bottom-h).
|
|
315
|
-
Rigid like a sheet: `translate` only. `button.snackbar__body` = it can be tapped. Never a warning — that is a Modal. */
|
|
315
|
+
Its ground is the OK signal's soft ground (--signal-ok-soft), its glyph the signal itself: the sign that it went right. Rigid like a sheet: `translate` only. `button.snackbar__body` = it can be tapped. Never a warning — that is a Modal. */
|
|
316
316
|
.snackbar {
|
|
317
317
|
--_out: -1;
|
|
318
318
|
position: fixed; inset-inline: 0; top: calc(var(--sp-3) + var(--safe-top));
|
|
@@ -330,15 +330,15 @@
|
|
|
330
330
|
display: flex; align-items: center; gap: var(--snackbar-gap, var(--sp-3));
|
|
331
331
|
max-width: 100%; min-height: var(--snackbar-min-h, var(--tap));
|
|
332
332
|
padding: var(--snackbar-pad-y, var(--sp-2)) var(--snackbar-pad-x, var(--sp-5));
|
|
333
|
-
border: var(--border-w) solid var(--snackbar-border,
|
|
333
|
+
border: var(--border-w) solid var(--snackbar-border, transparent);
|
|
334
334
|
border-radius: var(--snackbar-radius, var(--r-card));
|
|
335
|
-
background: var(--snackbar-bg, var(--
|
|
336
|
-
color: var(--snackbar-ink, var(--
|
|
335
|
+
background: var(--snackbar-bg, var(--signal-ok-soft));
|
|
336
|
+
color: var(--snackbar-ink, var(--on-surface));
|
|
337
337
|
box-shadow: var(--snackbar-shadow, var(--shadow-float));
|
|
338
338
|
font: inherit; text-align: start;
|
|
339
339
|
pointer-events: auto;
|
|
340
340
|
}
|
|
341
|
-
.snackbar__body > .icon { flex: none; }
|
|
341
|
+
.snackbar__body > .icon { flex: none; color: var(--snackbar-icon-ink, var(--signal-ok)); }
|
|
342
342
|
.snackbar__words { display: grid; min-width: 0; overflow-wrap: anywhere; }
|
|
343
343
|
.snackbar__text { font: var(--snackbar-text-font, var(--type-body)); }
|
|
344
344
|
.snackbar__caption { font: var(--snackbar-caption-font, var(--type-caption)); opacity: var(--dim); }
|
package/css/theme.template.css
CHANGED
|
@@ -49,5 +49,7 @@
|
|
|
49
49
|
--card-border --card-muted --card-2-muted
|
|
50
50
|
--accent --on-accent --action-bg --action-ink --action-border
|
|
51
51
|
--pos --neg --dot-a --dot-b
|
|
52
|
+
--signal-ok --signal-warn --signal-error --signal-info (the signal set: green · yellow · red · blue — retune the shade,
|
|
53
|
+
keep the meaning; dark enough for words. --signal-*-soft, the light ground of each, follows by itself)
|
|
52
54
|
--dim (0.7: how far secondary words fade on a dark card, a drawer, a tile's sub line — one share for all) */
|
|
53
55
|
}
|
package/css/tokens.css
CHANGED
|
@@ -210,12 +210,15 @@
|
|
|
210
210
|
--neg: #3d3d3d;
|
|
211
211
|
--dot-a: var(--color-brand, #141414);
|
|
212
212
|
--dot-b: #8a8a8a;
|
|
213
|
-
|
|
213
|
+
/* THE SIGNAL SET (Lh 2026-09-25; the standard, Lh 2026-10-02): ok (green) · warn (yellow) · error (red) · info (blue) — the same four
|
|
214
|
+
meanings in every project, wireframe included; a theme may retune the shade, never the meaning. Each is dark enough for words and
|
|
215
|
+
edges and comes with an icon and words, never the colour alone. `--signal-*-soft` (below :root) = its light ground. */
|
|
216
|
+
--signal-warn: #8a6d00;
|
|
214
217
|
--signal-ok: #2e7d32;
|
|
215
218
|
--signal-info: #2f5f9e;
|
|
216
219
|
/* highlights (Lh 2026-09-25): four atmosphere colours a palette may set for decoration — a count, a mark, a chart dot; the wireframe keeps them grey */
|
|
217
220
|
--highlight-1: #3d3d3d; --highlight-2: #8a8a8a; --highlight-3: #5f5f5f; --highlight-4: #b0b0b0;
|
|
218
|
-
--signal-error: #c62828; /*
|
|
221
|
+
--signal-error: #c62828; /* something went wrong — a field's edge, the words that say what */
|
|
219
222
|
|
|
220
223
|
/* derived tints — read the element's own ink, so they work on any slot */
|
|
221
224
|
--outline: var(--action-border); /* control edges (palette.css softens) */
|
|
@@ -244,6 +247,14 @@
|
|
|
244
247
|
bars take over the page when the app runs edge to edge (viewport-fit=cover: Android Chrome, an iPhone home-screen app).
|
|
245
248
|
PUBLISHED: backgrounds still run to the edge; what the member reads or taps stands clear of them. 0 without cover.
|
|
246
249
|
--_safe-b-open = the bottom inset the keyboard does NOT already cover (a keyboard up hides the gesture bar). */
|
|
250
|
+
/* a signal's SOFT ground: the signal washed 14% into the surface (tone 2's formula) — what a Snackbar stands on. Re-derived where a
|
|
251
|
+
palette is set, so a palette's own signal shade gives its own soft */
|
|
252
|
+
:root, [data-palette] {
|
|
253
|
+
--signal-ok-soft: color-mix(in srgb, var(--signal-ok) 14%, var(--surface));
|
|
254
|
+
--signal-warn-soft: color-mix(in srgb, var(--signal-warn) 14%, var(--surface));
|
|
255
|
+
--signal-error-soft: color-mix(in srgb, var(--signal-error) 14%, var(--surface));
|
|
256
|
+
--signal-info-soft: color-mix(in srgb, var(--signal-info) 14%, var(--surface));
|
|
257
|
+
}
|
|
247
258
|
:root { --safe-top: env(safe-area-inset-top, 0px); --safe-bottom: env(safe-area-inset-bottom, 0px); }
|
|
248
259
|
* { --_safe-b-open: max(0px, var(--safe-bottom) - var(--kb, 0px)); }
|
|
249
260
|
|
package/dist/actions/Chip.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
+
import { type DotTone } from './Dot.js';
|
|
2
3
|
export interface ChipProps extends ComponentProps<'span'> {
|
|
3
4
|
/** filled accent: the selected / live state */
|
|
4
5
|
on?: boolean;
|
|
5
6
|
/** quiet: an untouched default value — muted words, the thin edge, nothing to find the eye (README rule 13) */
|
|
6
7
|
muted?: boolean;
|
|
7
|
-
/** a leading signal dot: `a` (the accent signal)
|
|
8
|
-
dot?: 'a' | 'b';
|
|
8
|
+
/** a leading signal dot: `a` (the accent signal), `b` (the secondary), or one of the signal set — ok · warn · error · info */
|
|
9
|
+
dot?: 'a' | 'b' | DotTone;
|
|
9
10
|
/** the element: span (default), a link, or a button */
|
|
10
11
|
as?: 'span' | 'a' | 'button';
|
|
11
12
|
href?: string;
|
package/dist/actions/Chip.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Dot } from './Dot.js';
|
|
|
5
5
|
/** Chip — a status or attribute tag (with an optional signal Dot), or a small tap target; `on` when it is the live one. For a choice use ChipPick (`sign` for the +/× interest picker). */
|
|
6
6
|
export function Chip({ on, muted, dot, as, href, className, children, ...rest }) {
|
|
7
7
|
const el = as ?? (href ? 'a' : 'span');
|
|
8
|
-
return createElement(el, { href, type: el === 'button' ? 'button' : undefined, className: cx('chip', on && 'chip--on', muted && 'chip--muted', className), ...rest }, dot && _jsx(Dot, { b: dot === 'b' }), children);
|
|
8
|
+
return createElement(el, { href, type: el === 'button' ? 'button' : undefined, className: cx('chip', on && 'chip--on', muted && 'chip--muted', className), ...rest }, dot && _jsx(Dot, { b: dot === 'b', tone: dot === 'a' || dot === 'b' ? undefined : dot }), children);
|
|
9
9
|
}
|
|
10
10
|
/** ChipPick — a chip that is a choice: full-width in a ChipGrid (9:00 · 9:30 · …), or `sign` on a ChipRow (+ off, × on — the
|
|
11
11
|
* interest picker); the picked one fills with accent. A native radio/checkbox inside the label carries the state. */
|
package/dist/actions/Dot.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { ComponentProps } from 'react';
|
|
2
|
+
export type DotTone = 'ok' | 'warn' | 'error' | 'info';
|
|
2
3
|
export interface DotProps extends ComponentProps<'span'> {
|
|
3
4
|
/** the secondary signal colour */
|
|
4
5
|
b?: boolean;
|
|
6
|
+
/** a signal from the standard set: ok (green) · warn (yellow) · error (red) · info (blue) — the words beside it say what */
|
|
7
|
+
tone?: DotTone;
|
|
5
8
|
}
|
|
6
9
|
/** Dot — the signal dot in chips, legends and row metas. */
|
|
7
|
-
export declare function Dot({ b, className, ...rest }: DotProps): import("react").JSX.Element;
|
|
10
|
+
export declare function Dot({ b, tone, className, ...rest }: DotProps): import("react").JSX.Element;
|
package/dist/actions/Dot.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from '../cx.js';
|
|
3
3
|
/** Dot — the signal dot in chips, legends and row metas. */
|
|
4
|
-
export function Dot({ b, className, ...rest }) {
|
|
5
|
-
return _jsx("span", { className: cx('dot', b && 'dot--b', className), ...rest });
|
|
4
|
+
export function Dot({ b, tone, className, ...rest }) {
|
|
5
|
+
return _jsx("span", { className: cx('dot', b && 'dot--b', tone && `dot--${tone}`, className), ...rest });
|
|
6
6
|
}
|
package/dist/cardds.css
CHANGED
|
@@ -251,12 +251,15 @@
|
|
|
251
251
|
--neg: #3d3d3d;
|
|
252
252
|
--dot-a: var(--color-brand, #141414);
|
|
253
253
|
--dot-b: #8a8a8a;
|
|
254
|
-
|
|
254
|
+
/* THE SIGNAL SET (Lh 2026-09-25; the standard, Lh 2026-10-02): ok (green) · warn (yellow) · error (red) · info (blue) — the same four
|
|
255
|
+
meanings in every project, wireframe included; a theme may retune the shade, never the meaning. Each is dark enough for words and
|
|
256
|
+
edges and comes with an icon and words, never the colour alone. `--signal-*-soft` (below :root) = its light ground. */
|
|
257
|
+
--signal-warn: #8a6d00;
|
|
255
258
|
--signal-ok: #2e7d32;
|
|
256
259
|
--signal-info: #2f5f9e;
|
|
257
260
|
/* highlights (Lh 2026-09-25): four atmosphere colours a palette may set for decoration — a count, a mark, a chart dot; the wireframe keeps them grey */
|
|
258
261
|
--highlight-1: #3d3d3d; --highlight-2: #8a8a8a; --highlight-3: #5f5f5f; --highlight-4: #b0b0b0;
|
|
259
|
-
--signal-error: #c62828; /*
|
|
262
|
+
--signal-error: #c62828; /* something went wrong — a field's edge, the words that say what */
|
|
260
263
|
|
|
261
264
|
/* derived tints — read the element's own ink, so they work on any slot */
|
|
262
265
|
--outline: var(--action-border); /* control edges (palette.css softens) */
|
|
@@ -285,6 +288,14 @@
|
|
|
285
288
|
bars take over the page when the app runs edge to edge (viewport-fit=cover: Android Chrome, an iPhone home-screen app).
|
|
286
289
|
PUBLISHED: backgrounds still run to the edge; what the member reads or taps stands clear of them. 0 without cover.
|
|
287
290
|
--_safe-b-open = the bottom inset the keyboard does NOT already cover (a keyboard up hides the gesture bar). */
|
|
291
|
+
/* a signal's SOFT ground: the signal washed 14% into the surface (tone 2's formula) — what a Snackbar stands on. Re-derived where a
|
|
292
|
+
palette is set, so a palette's own signal shade gives its own soft */
|
|
293
|
+
:root, [data-palette] {
|
|
294
|
+
--signal-ok-soft: color-mix(in srgb, var(--signal-ok) 14%, var(--surface));
|
|
295
|
+
--signal-warn-soft: color-mix(in srgb, var(--signal-warn) 14%, var(--surface));
|
|
296
|
+
--signal-error-soft: color-mix(in srgb, var(--signal-error) 14%, var(--surface));
|
|
297
|
+
--signal-info-soft: color-mix(in srgb, var(--signal-info) 14%, var(--surface));
|
|
298
|
+
}
|
|
288
299
|
:root { --safe-top: env(safe-area-inset-top, 0px); --safe-bottom: env(safe-area-inset-bottom, 0px); }
|
|
289
300
|
* { --_safe-b-open: max(0px, var(--safe-bottom) - var(--kb, 0px)); }
|
|
290
301
|
|
|
@@ -2234,6 +2245,11 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
2234
2245
|
The drop: a line box is centred on its ascender room (Thai marks), the letters beside the dot sit lower — the dot rides down to the
|
|
2235
2246
|
letters' own middle, in em so it follows the text size (Lh 2026-09-22: "ตัวหนังสือกับไฟเสมอกัน") */
|
|
2236
2247
|
.dot--b { background: var(--dot-b); }
|
|
2248
|
+
/* the signal set on a dot (Lh 2026-10-02): the words beside it say what — never the colour alone */
|
|
2249
|
+
.dot--ok { background: var(--signal-ok); }
|
|
2250
|
+
.dot--warn { background: var(--signal-warn); }
|
|
2251
|
+
.dot--error { background: var(--signal-error); }
|
|
2252
|
+
.dot--info { background: var(--signal-info); }
|
|
2237
2253
|
.chip--on { background: var(--chip-on-bg, var(--accent)); color: var(--chip-on-ink, var(--on-accent)); border-color: transparent; }
|
|
2238
2254
|
/* muted: an untouched default — the words wash out, the edge stays; emphasis is the difference from the neighbours (README 13) */
|
|
2239
2255
|
.chip--muted { color: var(--chip-muted-ink, var(--card-muted)); }
|
|
@@ -3939,7 +3955,7 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
3939
3955
|
<div class="snackbar snackbar--open" role="status"><div class="snackbar__body"><svg class="icon"/>
|
|
3940
3956
|
<span class="snackbar__words"><span class="snackbar__text">…</span><span class="snackbar__caption">…</span></span></div></div>
|
|
3941
3957
|
A LAYER of the screen (its child), over the top bar; --bottom = at the foot, above the screen's bottom layer (--bottom-h).
|
|
3942
|
-
Rigid like a sheet: `translate` only. `button.snackbar__body` = it can be tapped. Never a warning — that is a Modal. */
|
|
3958
|
+
Its ground is the OK signal's soft ground (--signal-ok-soft), its glyph the signal itself: the sign that it went right. Rigid like a sheet: `translate` only. `button.snackbar__body` = it can be tapped. Never a warning — that is a Modal. */
|
|
3943
3959
|
.snackbar {
|
|
3944
3960
|
--_out: -1;
|
|
3945
3961
|
position: fixed; inset-inline: 0; top: calc(var(--sp-3) + var(--safe-top));
|
|
@@ -3957,15 +3973,15 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
3957
3973
|
display: flex; align-items: center; gap: var(--snackbar-gap, var(--sp-3));
|
|
3958
3974
|
max-width: 100%; min-height: var(--snackbar-min-h, var(--tap));
|
|
3959
3975
|
padding: var(--snackbar-pad-y, var(--sp-2)) var(--snackbar-pad-x, var(--sp-5));
|
|
3960
|
-
border: var(--border-w) solid var(--snackbar-border,
|
|
3976
|
+
border: var(--border-w) solid var(--snackbar-border, transparent);
|
|
3961
3977
|
border-radius: var(--snackbar-radius, var(--r-card));
|
|
3962
|
-
background: var(--snackbar-bg, var(--
|
|
3963
|
-
color: var(--snackbar-ink, var(--
|
|
3978
|
+
background: var(--snackbar-bg, var(--signal-ok-soft));
|
|
3979
|
+
color: var(--snackbar-ink, var(--on-surface));
|
|
3964
3980
|
box-shadow: var(--snackbar-shadow, var(--shadow-float));
|
|
3965
3981
|
font: inherit; text-align: start;
|
|
3966
3982
|
pointer-events: auto;
|
|
3967
3983
|
}
|
|
3968
|
-
.snackbar__body > .icon { flex: none; }
|
|
3984
|
+
.snackbar__body > .icon { flex: none; color: var(--snackbar-icon-ink, var(--signal-ok)); }
|
|
3969
3985
|
.snackbar__words { display: grid; min-width: 0; overflow-wrap: anywhere; }
|
|
3970
3986
|
.snackbar__text { font: var(--snackbar-text-font, var(--type-body)); }
|
|
3971
3987
|
.snackbar__caption { font: var(--snackbar-caption-font, var(--type-caption)); opacity: var(--dim); }
|
|
@@ -10,8 +10,8 @@ export interface SnackbarProps extends Omit<ComponentProps<'div'>, 'onClick'> {
|
|
|
10
10
|
onOpenChange?: (open: boolean, reason: SnackbarReason) => void;
|
|
11
11
|
/** how long it stays, in ms (default 4000); 0 = until the app closes it */
|
|
12
12
|
duration?: number;
|
|
13
|
-
/**
|
|
14
|
-
icon?: IconName;
|
|
13
|
+
/** the glyph before the words — `check` by default (it went right); `false` = none */
|
|
14
|
+
icon?: IconName | false;
|
|
15
15
|
/** a second, smaller line under the words */
|
|
16
16
|
caption?: ReactNode;
|
|
17
17
|
/** at the screen's foot, above its bottom layer, instead of the top */
|
|
@@ -22,7 +22,7 @@ export interface SnackbarProps extends Omit<ComponentProps<'div'>, 'onClick'> {
|
|
|
22
22
|
onClosed?: () => void;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* Snackbar — a quick GOOD-NEWS line laid over the screen: something went well, said in passing. It slides in from the screen's top
|
|
25
|
+
* Snackbar — a quick GOOD-NEWS line laid over the screen: something went well, said in passing: a check and the words on the soft tone. It slides in from the screen's top
|
|
26
26
|
* (or `bottom`), stays `duration`, slides out, never takes the cursor and never stops the member. Not for a warning or a question —
|
|
27
27
|
* that is a `Modal`. A child of the `Screen`. Controlled like an input: `open` + `onOpenChange(open, reason)`, or `defaultOpen`;
|
|
28
28
|
* ONE at a time — the queue is the app's (what it shows is the app's own notification, kept in the app's list; a tap = `onTap`).
|
package/dist/layover/Snackbar.js
CHANGED
|
@@ -4,12 +4,12 @@ import { cx } from '../cx.js';
|
|
|
4
4
|
import { Icon } from '../type/Icon.js';
|
|
5
5
|
import { reducedMotion, useControlled, useLatest } from '../state.js';
|
|
6
6
|
/**
|
|
7
|
-
* Snackbar — a quick GOOD-NEWS line laid over the screen: something went well, said in passing. It slides in from the screen's top
|
|
7
|
+
* Snackbar — a quick GOOD-NEWS line laid over the screen: something went well, said in passing: a check and the words on the soft tone. It slides in from the screen's top
|
|
8
8
|
* (or `bottom`), stays `duration`, slides out, never takes the cursor and never stops the member. Not for a warning or a question —
|
|
9
9
|
* that is a `Modal`. A child of the `Screen`. Controlled like an input: `open` + `onOpenChange(open, reason)`, or `defaultOpen`;
|
|
10
10
|
* ONE at a time — the queue is the app's (what it shows is the app's own notification, kept in the app's list; a tap = `onTap`).
|
|
11
11
|
*/
|
|
12
|
-
export function Snackbar({ open, defaultOpen = true, onOpenChange, duration = 4000, icon, caption, bottom, onTap, onClosed, className, children, ...rest }) {
|
|
12
|
+
export function Snackbar({ open, defaultOpen = true, onOpenChange, duration = 4000, icon = 'check', caption, bottom, onTap, onClosed, className, children, ...rest }) {
|
|
13
13
|
const [shown, request] = useControlled(open, defaultOpen, onOpenChange);
|
|
14
14
|
const [entered, setEntered] = useState(false); // its first frame is out of sight, so one mounted open slides in
|
|
15
15
|
const closed = useLatest(onClosed);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usableapp/cardds",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.44",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "card-first mobile design system, React-first: the components in src/ are thin wrappers over the CSS contract (css/*.css stays the only truth); gallery/ shows every story live (npm run dev), tests/ measures the geometry.",
|