@usableapp/cardds 0.7.83 → 0.7.84
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 +18 -0
- package/README.md +33 -13
- package/css/card.css +4 -4
- package/css/people.css +3 -2
- package/css/post.css +16 -4
- package/css/stamp.css +23 -21
- package/css/sticky.css +1 -2
- package/dist/cardds.css +47 -33
- package/dist/catalog.json +1 -1
- package/dist/post/PostBox.d.ts +1 -1
- package/dist/post/PostDesk.d.ts +2 -2
- package/dist/post/PostLetter.d.ts +1 -1
- package/dist/post/Postmark.d.ts +1 -1
- package/dist/post/Postmark.js +1 -1
- package/dist/post/postCorner.js +1 -1
- package/dist/scaffold/LayerHistory.d.ts +2 -0
- package/dist/scaffold/LayerHistory.js +2 -0
- package/dist/sheets/Modal.d.ts +3 -0
- package/dist/sheets/Modal.js +3 -0
- package/dist/stamp/Stamp.d.ts +4 -3
- package/dist/stamp/Stamp.js +3 -2
- package/dist/stamp/StampBook.d.ts +3 -3
- package/dist/stamp/StampBook.js +1 -1
- package/dist/stamp/StampOn.d.ts +1 -0
- package/dist/stamp/StampOn.js +1 -0
- package/package.json +1 -1
package/dist/post/PostBox.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export interface PostBoxCardProps extends Omit<ComponentProps<'li'>, 'id'> {
|
|
|
20
20
|
from: ReactNode;
|
|
21
21
|
/** where and when — the edge's small line ("เชียงใหม่ · 3 ม.ค. 69") */
|
|
22
22
|
when?: ReactNode;
|
|
23
|
-
/** the corner's stamp — a `Stamp` */
|
|
23
|
+
/** the corner's stamp — a `Stamp`, shown at the postcard's own size (72 × 90, `--post-corner-stamp-w`) */
|
|
24
24
|
stamp?: ReactNode;
|
|
25
25
|
/** the mark struck over the stamp — a `Postmark`; behind another card only its place shows */
|
|
26
26
|
postmark?: ReactNode;
|
package/dist/post/PostDesk.d.ts
CHANGED
|
@@ -30,9 +30,9 @@ export interface PostDeskProps extends ComponentProps<'div'> {
|
|
|
30
30
|
placeholder?: string;
|
|
31
31
|
/** the address lines — `PostDeskLine`s; their values are the app's, like any input's */
|
|
32
32
|
address?: ReactNode;
|
|
33
|
-
/** the sender's own stamps, shown under the card on the address half */
|
|
33
|
+
/** the sender's own stamps, shown under the card on the address half: each the standard size (96 × 120, `--stamp-size`), in one line that scrolls sideways when they outrun the screen */
|
|
34
34
|
stamps?: PostDeskStamp[];
|
|
35
|
-
/** CONTROLLED: the `id` of the stamp in the stamp box, `null` = none — with `onStampChange` */
|
|
35
|
+
/** CONTROLLED: the `id` of the stamp in the stamp box, `null` = none — with `onStampChange`. The box and its stamp are the postcard's own size (72 × 90, `--post-corner-stamp-w`); the empty box shows its word */
|
|
36
36
|
stamp?: string | null;
|
|
37
37
|
/** UNCONTROLLED: the stamp it starts with */
|
|
38
38
|
defaultStamp?: string | null;
|
|
@@ -24,7 +24,7 @@ export interface PostLetterProps extends ComponentProps<'div'> {
|
|
|
24
24
|
kicker?: ReactNode;
|
|
25
25
|
/** the address lines, top down: the first is the name, the rest where they live */
|
|
26
26
|
to?: ReactNode[];
|
|
27
|
-
/** the corner's stamp — a `Stamp` */
|
|
27
|
+
/** the corner's stamp — a `Stamp`, shown at the postcard's own size (72 × 90, `--post-corner-stamp-w`) */
|
|
28
28
|
stamp?: ReactNode;
|
|
29
29
|
/** the mark struck over the stamp — a `Postmark` */
|
|
30
30
|
postmark?: ReactNode;
|
package/dist/post/Postmark.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ export interface PostmarkProps extends ComponentProps<'div'> {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Postmark — the round mark the post strikes: where and when, two rings, turned a little, its cancel lines running on to the side.
|
|
10
|
-
* On a card's corner (`postmark` of PostLetter · PostDesk · PostBoxCard) it lies over the edge of the stamp. Information: nothing to press.
|
|
10
|
+
* On a card's corner (`postmark` of PostLetter · PostDesk · PostBoxCard) it lies over the edge of the stamp, by 0.4 of its own size. Information: nothing to press.
|
|
11
11
|
*/
|
|
12
12
|
export declare function Postmark({ place, date, className, ...rest }: PostmarkProps): import("react").JSX.Element;
|
package/dist/post/Postmark.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { cx } from '../cx.js';
|
|
3
3
|
/**
|
|
4
4
|
* Postmark — the round mark the post strikes: where and when, two rings, turned a little, its cancel lines running on to the side.
|
|
5
|
-
* On a card's corner (`postmark` of PostLetter · PostDesk · PostBoxCard) it lies over the edge of the stamp. Information: nothing to press.
|
|
5
|
+
* On a card's corner (`postmark` of PostLetter · PostDesk · PostBoxCard) it lies over the edge of the stamp, by 0.4 of its own size. Information: nothing to press.
|
|
6
6
|
*/
|
|
7
7
|
export function Postmark({ place, date, className, ...rest }) {
|
|
8
8
|
return (_jsxs("div", { className: cx('postmark', className), ...rest, children: [_jsx("span", { children: place }), date != null && _jsx("span", { children: date })] }));
|
package/dist/post/postCorner.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/* the corner of a card that proves the journey: the stamp (a `Stamp`, the app's), the postmark struck over its edge.
|
|
3
|
-
A part of the three post views, never exported: a stamp here shows its pictures only (stamp.css). */
|
|
3
|
+
A part of the three post views, never exported: a stamp here is the postcard's own size, `--post-corner-stamp-w` (72 × 90, outside the stamp's two sizes), and shows its pictures only (stamp.css, post.css). */
|
|
4
4
|
export function PostCorner({ stamp, postmark, ...rest }) {
|
|
5
5
|
if (stamp == null && postmark == null)
|
|
6
6
|
return null;
|
|
@@ -41,6 +41,8 @@ export interface LayerApi {
|
|
|
41
41
|
* `const way = useLayer('way')` → `<CallSheet open={way.value} onOpenChange={(up, i) => (up ? way.open(i!) : way.close())}>`.
|
|
42
42
|
* A Modal: `open={ask.value !== null}` + the app's own `mounted` flag cleared in `onClosed`. Opened again a layer starts anew —
|
|
43
43
|
* give what is inside a new `key` per opening.
|
|
44
|
+
* ONE LAYER PER TICK: `open` builds the new state from the layers read at render, so two layers opened in the same handler lose the
|
|
45
|
+
* first — `a.open(1); b.open(2)` gives `a.value` null and `b.value` 2, and two new entries. Open the second in a later tick.
|
|
44
46
|
*/
|
|
45
47
|
export declare function useLayer(name: string): LayerApi;
|
|
46
48
|
/** useOptionalLayer — the same layer as `useLayer`, or `null` when no `LayerHistory` is above. A missing provider does not warn. */
|
|
@@ -58,6 +58,8 @@ const layerApi = (name, handle) => {
|
|
|
58
58
|
* `const way = useLayer('way')` → `<CallSheet open={way.value} onOpenChange={(up, i) => (up ? way.open(i!) : way.close())}>`.
|
|
59
59
|
* A Modal: `open={ask.value !== null}` + the app's own `mounted` flag cleared in `onClosed`. Opened again a layer starts anew —
|
|
60
60
|
* give what is inside a new `key` per opening.
|
|
61
|
+
* ONE LAYER PER TICK: `open` builds the new state from the layers read at render, so two layers opened in the same handler lose the
|
|
62
|
+
* first — `a.open(1); b.open(2)` gives `a.value` null and `b.value` 2, and two new entries. Open the second in a later tick.
|
|
61
63
|
*/
|
|
62
64
|
export function useLayer(name) {
|
|
63
65
|
const handle = useHistory();
|
package/dist/sheets/Modal.d.ts
CHANGED
|
@@ -16,6 +16,9 @@ export interface ModalProps extends ComponentProps<'article'> {
|
|
|
16
16
|
* A COMPONENT, not a wiring: it does not know its buttons. They are plain `IconBtn`s / `Btn`s with the app's `onClick` — the app
|
|
17
17
|
* records the answer and sets `open={false}`; the modal's one behaviour is how it leaves. `onDismiss` asks to leave unanswered (a tap on
|
|
18
18
|
* the scrim, Esc). When it has arrived, cardds puts the cursor in the field marked `data-autofocus`, else the first field, else the question — write no focus code.
|
|
19
|
+
* MOUNT IT ONLY WHEN IT IS TO SHOW. First mounted with `open={false}` it is drawn in place, then leaves, and calls `onClosed` after about 700ms
|
|
20
|
+
* (measured at 375, 2026-10-11). KNOWN FAULT, not fixed: under React StrictMode `onClosed` is never called for a Modal mounted that way — the
|
|
21
|
+
* effect's first run sets `shown` to false, its cleanup drops the wait, and the second run returns early.
|
|
19
22
|
*/
|
|
20
23
|
export declare function Modal({ open, onClosed, onDismiss, className, ...rest }: ModalProps): import("react").JSX.Element;
|
|
21
24
|
export interface ModalBodyProps extends ComponentProps<'div'> {
|
package/dist/sheets/Modal.js
CHANGED
|
@@ -9,6 +9,9 @@ import { cx } from '../cx.js';
|
|
|
9
9
|
* A COMPONENT, not a wiring: it does not know its buttons. They are plain `IconBtn`s / `Btn`s with the app's `onClick` — the app
|
|
10
10
|
* records the answer and sets `open={false}`; the modal's one behaviour is how it leaves. `onDismiss` asks to leave unanswered (a tap on
|
|
11
11
|
* the scrim, Esc). When it has arrived, cardds puts the cursor in the field marked `data-autofocus`, else the first field, else the question — write no focus code.
|
|
12
|
+
* MOUNT IT ONLY WHEN IT IS TO SHOW. First mounted with `open={false}` it is drawn in place, then leaves, and calls `onClosed` after about 700ms
|
|
13
|
+
* (measured at 375, 2026-10-11). KNOWN FAULT, not fixed: under React StrictMode `onClosed` is never called for a Modal mounted that way — the
|
|
14
|
+
* effect's first run sets `shown` to false, its cleanup drops the wait, and the second run returns early.
|
|
12
15
|
*/
|
|
13
16
|
export function Modal({ open = true, onClosed, onDismiss, className, ...rest }) {
|
|
14
17
|
const ref = useRef(null);
|
package/dist/stamp/Stamp.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface StampProps extends Omit<ComponentProps<'span'>, 'onClick'> {
|
|
|
7
7
|
tone?: StickyTone;
|
|
8
8
|
/** the big line at the foot, on the picture — whose stamp it is */
|
|
9
9
|
name?: ReactNode;
|
|
10
|
-
/** a small line above the name (the pictures' words)
|
|
10
|
+
/** a small line above the name (the pictures' words). It shows only on a stamp WIDER than the standard size (`--stamp-size` set above 6rem): at 96 it would be under 5px, so it is not drawn and the name is larger */
|
|
11
11
|
words?: ReactNode;
|
|
12
12
|
/** the pictures alone: `name` and `words` are not drawn. For a stamp stuck on something (a postcard's corner); in a `StampOn` every stamp is bare already. The words are for the album */
|
|
13
13
|
bare?: boolean;
|
|
@@ -18,7 +18,8 @@ export interface StampProps extends Omit<ComponentProps<'span'>, 'onClick'> {
|
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Stamp — a perforated paper stamp, 4:5: the pictures fill the inner frame on a tone, the words sit on the picture's foot.
|
|
21
|
-
*
|
|
21
|
+
* Every stamp is ONE size wherever it stands (`--stamp-size`, two taps wide: 96 × 120) — what holds it only places it; a holder narrower than that shows it whole, smaller.
|
|
22
|
+
* The one small stamp is a stamp stuck on something (`StampOn`). Every inner length follows the stamp's width.
|
|
22
23
|
* The outer box holds the size and the shadow; the paper inside is the one whose edge is punched (a mask would cut the shadow too).
|
|
23
24
|
*/
|
|
24
25
|
export declare function Stamp({ pictures, tone, name, words, bare, tilt, onClick, className, ...rest }: StampProps): import("react").JSX.Element;
|
|
@@ -29,7 +30,7 @@ export interface StampPlaceProps extends Omit<ComponentProps<'span'>, 'onClick'>
|
|
|
29
30
|
onClick?: () => void;
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
|
-
* StampPlace — an empty place for a stamp: a 4:5 frame of round dots the size a Stamp
|
|
33
|
+
* StampPlace — an empty place for a stamp: a 4:5 frame of round dots the size a Stamp is (`--stamp-size`), a word or an Icon inside.
|
|
33
34
|
* The dots are a stroke, not a border: `--stamp-place-dot` is their width, `--stamp-place-gap` the distance from one centre to the next,
|
|
34
35
|
* and a `--stamp-place-dash` above 0 stretches each dot into a dash.
|
|
35
36
|
*/
|
package/dist/stamp/Stamp.js
CHANGED
|
@@ -2,7 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { cx } from '../cx.js';
|
|
3
3
|
/**
|
|
4
4
|
* Stamp — a perforated paper stamp, 4:5: the pictures fill the inner frame on a tone, the words sit on the picture's foot.
|
|
5
|
-
*
|
|
5
|
+
* Every stamp is ONE size wherever it stands (`--stamp-size`, two taps wide: 96 × 120) — what holds it only places it; a holder narrower than that shows it whole, smaller.
|
|
6
|
+
* The one small stamp is a stamp stuck on something (`StampOn`). Every inner length follows the stamp's width.
|
|
6
7
|
* The outer box holds the size and the shadow; the paper inside is the one whose edge is punched (a mask would cut the shadow too).
|
|
7
8
|
*/
|
|
8
9
|
export function Stamp({ pictures, tone = 'custard', name, words, bare, tilt, onClick, className, ...rest }) {
|
|
@@ -13,7 +14,7 @@ export function Stamp({ pictures, tone = 'custard', name, words, bare, tilt, onC
|
|
|
13
14
|
return (_jsx(Box, { className: cx('stamp', `stamp--${shown.length}`, bare && 'stamp--bare', tilt && `stamp--tilt-${tilt}`, tap && 'stamp--tap', className), ...boxProps, children: _jsx("span", { className: "stamp__paper", children: _jsxs("span", { className: cx('stamp__pic', `sticky--${tone}`), children: [shown.map((picture, i) => _jsx("span", { className: "stamp__art", "aria-hidden": "true", children: picture }, i)), (name != null || words != null) && (_jsxs("span", { className: "stamp__cap", children: [words != null && _jsx("span", { className: "stamp__words", children: words }), name != null && _jsx("span", { className: "stamp__name", children: name })] }))] }) }) }));
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
|
-
* StampPlace — an empty place for a stamp: a 4:5 frame of round dots the size a Stamp
|
|
17
|
+
* StampPlace — an empty place for a stamp: a 4:5 frame of round dots the size a Stamp is (`--stamp-size`), a word or an Icon inside.
|
|
17
18
|
* The dots are a stroke, not a border: `--stamp-place-dot` is their width, `--stamp-place-gap` the distance from one centre to the next,
|
|
18
19
|
* and a `--stamp-place-dash` above 0 stretches each dot into a dash.
|
|
19
20
|
*/
|
|
@@ -2,12 +2,12 @@ import { type ComponentProps, type ReactNode } from 'react';
|
|
|
2
2
|
export interface StampBookProps extends ComponentProps<'div'> {
|
|
3
3
|
/** how many places the page shows: the ones no StampCell fills are drawn empty */
|
|
4
4
|
places?: number;
|
|
5
|
-
/** ONE line of
|
|
5
|
+
/** ONE line of stamps that scrolls sideways, no ground — the tray a member picks from. Each stamp is its own size, as everywhere */
|
|
6
6
|
strip?: boolean;
|
|
7
|
-
/** the page with NO ground — no fill, no padding, no round:
|
|
7
|
+
/** the page with NO ground — no fill, no padding, no round: the stamps lie on what holds the book, three across, each its own size in the middle of its third. Put the name INSIDE the stamp (`Stamp name`), not under it */
|
|
8
8
|
bare?: boolean;
|
|
9
9
|
}
|
|
10
|
-
/** StampBook — the album page: StampCells three across on an album ground, the free places drawn empty up to `places`. */
|
|
10
|
+
/** StampBook — the album page: StampCells three across on an album ground, the free places drawn empty up to `places`. The book places its stamps and never sizes them: each is the one size of a stamp, in the middle of its third. */
|
|
11
11
|
export declare function StampBook({ places, strip, bare, className, children, ...rest }: StampBookProps): import("react").JSX.Element;
|
|
12
12
|
export interface StampCellProps extends Omit<ComponentProps<'span'>, 'onClick'> {
|
|
13
13
|
/** a short line under the stamp — who it is from */
|
package/dist/stamp/StampBook.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Children } from 'react';
|
|
|
3
3
|
import { cx } from '../cx.js';
|
|
4
4
|
import { Icon } from '../type/Icon.js';
|
|
5
5
|
import { StampPlace } from './Stamp.js';
|
|
6
|
-
/** StampBook — the album page: StampCells three across on an album ground, the free places drawn empty up to `places`. */
|
|
6
|
+
/** StampBook — the album page: StampCells three across on an album ground, the free places drawn empty up to `places`. The book places its stamps and never sizes them: each is the one size of a stamp, in the middle of its third. */
|
|
7
7
|
export function StampBook({ places = 0, strip, bare, className, children, ...rest }) {
|
|
8
8
|
const free = Math.max(0, places - Children.toArray(children).length); // toArray drops null / undefined / booleans: `{owned && <StampCell/>}` that is false holds no place (Children.count counts it)
|
|
9
9
|
return (_jsxs("div", { className: cx('stamp-book', strip && 'stamp-book--strip', bare && 'stamp-book--bare', className), ...rest, children: [children, Array.from({ length: free }, (_, i) => _jsx(StampPlace, { faint: true, "aria-hidden": "true" }, i))] }));
|
package/dist/stamp/StampOn.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export interface StampOnProps extends ComponentProps<'div'> {
|
|
|
19
19
|
/**
|
|
20
20
|
* StampOn — a Stamp (the child) stuck on a surface at the place the member chose. The surface is the nearest positioned box:
|
|
21
21
|
* a Sticky's `stuck`, a postcard's face. `at` is the stamp's middle as a share of that surface, so the note reads the same at any size.
|
|
22
|
+
* The stamp is the SMALL size: 48 × 60 on any surface, whatever the surface's size (`--stamp-sm-size`, one tap wide).
|
|
22
23
|
* With `onAtChange` the member drags it (finger or mouse; the arrow keys move it too): while the finger holds, the stamp writes its
|
|
23
24
|
* own place, and on letting go it ASKS — the app owns `at`. It never leaves the surface.
|
|
24
25
|
*/
|
package/dist/stamp/StampOn.js
CHANGED
|
@@ -19,6 +19,7 @@ const write = (el, at) => { el.style.setProperty('--stamp-on-x', String(at.x));
|
|
|
19
19
|
/**
|
|
20
20
|
* StampOn — a Stamp (the child) stuck on a surface at the place the member chose. The surface is the nearest positioned box:
|
|
21
21
|
* a Sticky's `stuck`, a postcard's face. `at` is the stamp's middle as a share of that surface, so the note reads the same at any size.
|
|
22
|
+
* The stamp is the SMALL size: 48 × 60 on any surface, whatever the surface's size (`--stamp-sm-size`, one tap wide).
|
|
22
23
|
* With `onAtChange` the member drags it (finger or mouse; the arrow keys move it too): while the finger holds, the stamp writes its
|
|
23
24
|
* own place, and on letting go it ASKS — the app owns `at`. It never leaves the surface.
|
|
24
25
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usableapp/cardds",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.84",
|
|
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.",
|