@usableapp/cardds 0.6.12 → 0.6.14
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 +36 -0
- package/css/actions.css +21 -0
- package/css/layover.css +7 -3
- package/css/tokens.css +1 -1
- package/dist/actions/ActionNote.d.ts +11 -0
- package/dist/actions/ActionNote.js +12 -0
- package/dist/cardds.css +29 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/templates/CallSheet.d.ts +22 -12
- package/dist/templates/CallSheet.js +12 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
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.6.14 — 2026-09-24
|
|
6
|
+
|
|
7
|
+
### ActionNote (new, the bottom)
|
|
8
|
+
- The main button's place and size, but lying on the ground: no fill, no border, no rounding. It holds one line of muted
|
|
9
|
+
words, and an inline `Icon` is allowed. Nothing to press.
|
|
10
|
+
- For when there is nothing to press here. Example (iPhone install):
|
|
11
|
+
`<ActionNote>กดที่ <Icon name="share" /> ด้านล่างนี้</ActionNote>`, pointing at Safari's own share button.
|
|
12
|
+
- Put it in a `CardFoot` (so a `CallSheet`'s `sheet.foot`) or an `ActionBar`, in place of the button, never beside one.
|
|
13
|
+
A `link` / `ctaLink` still goes under it.
|
|
14
|
+
- One fixed shape, never styled per use.
|
|
15
|
+
|
|
16
|
+
### Modal in Safari (iOS 18) — fixed
|
|
17
|
+
- Before: in Safari/WebKit the Modal stretched to the whole stage and its dark drawer (the question + buttons) was pushed out of
|
|
18
|
+
sight; Chrome was right. After: the same in both — the card its own height at the centre, the drawer shown.
|
|
19
|
+
- CSS only, nothing to change in a project: `.modal` is a flex column (was a grid of `minmax(0, 1fr) auto`, which WebKit sized
|
|
20
|
+
to 0) and takes its own height by `align-self: center` (was `height: fit-content`).
|
|
21
|
+
|
|
22
|
+
- Tests can run in WebKit: `CARDDS_BROWSER=webkit npm test` (the 131% text-size cases are Chrome-only — they use CDP).
|
|
23
|
+
|
|
24
|
+
## 0.6.13 — 2026-09-24
|
|
25
|
+
|
|
26
|
+
### `CallSheet ways`: several ways in, each calling its own sheet (new)
|
|
27
|
+
- Before: `CallSheet` took one `action` + one `sheet`. After: it can also take `ways: [{ action, sheet }]`. Each way gets a button
|
|
28
|
+
sized to its words, and the buttons wrap like a `CtaPack` (the first is primary, the rest quiet). Each button brings up its own
|
|
29
|
+
sheet (away → full), and only one sheet is up at a time. Each sheet holds that way's WHOLE form, with its submit on `foot`.
|
|
30
|
+
- `open` / `defaultOpen` = the way's index, or `null` for none (`true` = the first). `onOpenChange(open, way)` gets the index as a
|
|
31
|
+
second argument. `action` + `sheet` still work unchanged.
|
|
32
|
+
- Gallery screen **SignIn**: เข้าใช้งาน with three ways (register · code · face scan).
|
|
33
|
+
|
|
34
|
+
### `--scrim` is always black
|
|
35
|
+
- Before: the scrim was 50% of `--card-3-bg` (the brand), so a coloured theme dimmed in its brand colour. After: 50% black in
|
|
36
|
+
every palette (dim stage, the cover and postcard gradients, the gallery drawer). A project can still set `--scrim` in its theme.css.
|
|
37
|
+
|
|
38
|
+
- Gallery only: Palette and the Layout / Boxes / Keyboard switches sit above Settings, which now holds only the base sliders. The
|
|
39
|
+
nav widens with the text size. The Page · OneMove story is removed (the Install screen shows it).
|
|
40
|
+
|
|
5
41
|
## 0.6.12 — 2026-09-23
|
|
6
42
|
|
|
7
43
|
- Gallery only (nothing changes in the package's components or CSS):
|
package/css/actions.css
CHANGED
|
@@ -310,3 +310,24 @@
|
|
|
310
310
|
fixed to the viewport wherever it sits. (.screen--fill reserves nothing:
|
|
311
311
|
its .step carries the bar's room itself, step.css.) */
|
|
312
312
|
:has(> .action-bar) .screen:not(.screen--fill) { padding-bottom: var(--bar-reserve); }
|
|
313
|
+
|
|
314
|
+
/* ---- action note (Lh 2026-09-24): the main button's place, the main button's size, but ON the ground — no fill, no border, no
|
|
315
|
+
rounding — one line of muted words, an inline icon allowed; nothing to press. In a CardFoot or an ActionBar row it takes the
|
|
316
|
+
button's share (the whole width), so a foot or a bar keeps its height whether it holds a button or the note. ---- */
|
|
317
|
+
.action-note {
|
|
318
|
+
flex: 1 1 0;
|
|
319
|
+
min-width: 0;
|
|
320
|
+
min-height: var(--btn-h);
|
|
321
|
+
display: flex;
|
|
322
|
+
align-items: center;
|
|
323
|
+
justify-content: center;
|
|
324
|
+
gap: var(--action-note-gap, var(--sp-1));
|
|
325
|
+
padding-inline: var(--sp-2);
|
|
326
|
+
font: var(--action-note-font, var(--type-body));
|
|
327
|
+
color: var(--action-note-ink, var(--on-surface-muted));
|
|
328
|
+
text-align: center;
|
|
329
|
+
cursor: default;
|
|
330
|
+
}
|
|
331
|
+
.card .action-note { color: var(--action-note-ink, var(--card-muted)); }
|
|
332
|
+
.action-note__words { display: block; } /* ONE run of words: an icon inside sits in the line, the spaces around it kept */
|
|
333
|
+
.action-note__words > .icon { display: inline-block; vertical-align: -0.2em; width: 1.25em; height: 1.25em; margin-inline: 0.15em; color: inherit; }
|
package/css/layover.css
CHANGED
|
@@ -34,14 +34,16 @@
|
|
|
34
34
|
position: absolute; /* at the stage's centre, and kept there as it grows: absolute + margin auto re-centres on every height */
|
|
35
35
|
inset: 0;
|
|
36
36
|
margin: auto;
|
|
37
|
-
height:
|
|
37
|
+
height: auto;
|
|
38
|
+
align-self: center; /* inset 0 alone would stretch it to the stage: centre self-alignment gives it its own height, the margins
|
|
39
|
+
share the rest. NOT `height: fit-content` — WebKit/Safari sizes it wrong (Lh 2026-09-24, iOS 18.6) */
|
|
38
40
|
width: calc(100% - 2 * var(--screen-pad));
|
|
39
41
|
z-index: 2; /* over the dim stage's scrim (z 1) */
|
|
40
42
|
max-height: calc(100cqh - 2 * var(--sp-5)); /* cqh: the stage (a size container) */
|
|
41
43
|
padding: 0; /* the parts pad themselves */
|
|
42
44
|
border: 0; /* no frame on the modal (Lh 2026-09-16) — its edge is the shadow */
|
|
43
|
-
display: grid
|
|
44
|
-
|
|
45
|
+
display: flex; /* a column: the lift shrinks (and scrolls) under max-height, the drawer keeps its height. NOT a grid */
|
|
46
|
+
flex-direction: column; /* of minmax(0, 1fr) + auto — WebKit/Safari sizes that 1fr row to 0 (Lh 2026-09-24, iOS 18.6) */
|
|
45
47
|
overflow: clip;
|
|
46
48
|
box-shadow: var(--modal-shadow, var(--shadow-sheet));
|
|
47
49
|
}
|
|
@@ -50,11 +52,13 @@
|
|
|
50
52
|
display: grid;
|
|
51
53
|
gap: var(--card-gap);
|
|
52
54
|
align-content: start;
|
|
55
|
+
flex: 0 1 auto;
|
|
53
56
|
min-height: 0;
|
|
54
57
|
overflow-y: auto; /* tall content scrolls inside; the drawer stays */
|
|
55
58
|
overscroll-behavior: contain;
|
|
56
59
|
}
|
|
57
60
|
.modal__drawer {
|
|
61
|
+
flex-shrink: 0;
|
|
58
62
|
height: var(--drawer-h);
|
|
59
63
|
box-sizing: border-box;
|
|
60
64
|
padding: var(--modal-drawer-pad, var(--sp-5));
|
package/css/tokens.css
CHANGED
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
--ink-rail: color-mix(in srgb, currentColor 30%, transparent); /* todo steps, ghost edges */
|
|
196
196
|
--accent-soft: color-mix(in srgb, var(--accent) 22%, transparent); /* calendar marks */
|
|
197
197
|
--accent-mid: color-mix(in srgb, var(--accent) 50%, transparent);
|
|
198
|
-
--scrim: color-mix(in srgb,
|
|
198
|
+
--scrim: color-mix(in srgb, #000 50%, transparent); /* dim stage, cover gradient — ALWAYS black, never the brand (Lh 2026-09-24) */
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
/* ============================================================
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
export interface ActionNoteProps extends ComponentProps<'div'> {
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* ActionNote — the words that stand WHERE THE MAIN BUTTON WOULD BE when there is nothing to press: a block exactly the main button's
|
|
6
|
+
* size (full width, `--btn-h` tall), lying on the ground — no fill, no border, no rounding — holding one line of muted words, an
|
|
7
|
+
* inline `Icon` allowed ("กดที่ <Icon name="share" /> ด้านล่างนี้" — the member does the thing elsewhere). It does nothing on a tap.
|
|
8
|
+
* A member of the BOTTOM: a `CardFoot`'s row or an `ActionBar`'s, in place of the button, never beside one; a `link` still goes under
|
|
9
|
+
* it (CardFoot `link`, ActionBar `ctaLink`). One fixed shape — never styled per use (Lh 2026-09-24).
|
|
10
|
+
*/
|
|
11
|
+
export declare function ActionNote({ className, children, ...rest }: ActionNoteProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from '../cx.js';
|
|
3
|
+
/**
|
|
4
|
+
* ActionNote — the words that stand WHERE THE MAIN BUTTON WOULD BE when there is nothing to press: a block exactly the main button's
|
|
5
|
+
* size (full width, `--btn-h` tall), lying on the ground — no fill, no border, no rounding — holding one line of muted words, an
|
|
6
|
+
* inline `Icon` allowed ("กดที่ <Icon name="share" /> ด้านล่างนี้" — the member does the thing elsewhere). It does nothing on a tap.
|
|
7
|
+
* A member of the BOTTOM: a `CardFoot`'s row or an `ActionBar`'s, in place of the button, never beside one; a `link` still goes under
|
|
8
|
+
* it (CardFoot `link`, ActionBar `ctaLink`). One fixed shape — never styled per use (Lh 2026-09-24).
|
|
9
|
+
*/
|
|
10
|
+
export function ActionNote({ className, children, ...rest }) {
|
|
11
|
+
return _jsx("div", { role: "note", className: cx('action-note', className), ...rest, children: _jsx("span", { className: "action-note__words", children: children }) });
|
|
12
|
+
}
|
package/dist/cardds.css
CHANGED
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
--ink-rail: color-mix(in srgb, currentColor 30%, transparent); /* todo steps, ghost edges */
|
|
237
237
|
--accent-soft: color-mix(in srgb, var(--accent) 22%, transparent); /* calendar marks */
|
|
238
238
|
--accent-mid: color-mix(in srgb, var(--accent) 50%, transparent);
|
|
239
|
-
--scrim: color-mix(in srgb,
|
|
239
|
+
--scrim: color-mix(in srgb, #000 50%, transparent); /* dim stage, cover gradient — ALWAYS black, never the brand (Lh 2026-09-24) */
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
/* ============================================================
|
|
@@ -2143,6 +2143,27 @@ button { font: inherit; cursor: pointer; }
|
|
|
2143
2143
|
its .step carries the bar's room itself, step.css.) */
|
|
2144
2144
|
:has(> .action-bar) .screen:not(.screen--fill) { padding-bottom: var(--bar-reserve); }
|
|
2145
2145
|
|
|
2146
|
+
/* ---- action note (Lh 2026-09-24): the main button's place, the main button's size, but ON the ground — no fill, no border, no
|
|
2147
|
+
rounding — one line of muted words, an inline icon allowed; nothing to press. In a CardFoot or an ActionBar row it takes the
|
|
2148
|
+
button's share (the whole width), so a foot or a bar keeps its height whether it holds a button or the note. ---- */
|
|
2149
|
+
.action-note {
|
|
2150
|
+
flex: 1 1 0;
|
|
2151
|
+
min-width: 0;
|
|
2152
|
+
min-height: var(--btn-h);
|
|
2153
|
+
display: flex;
|
|
2154
|
+
align-items: center;
|
|
2155
|
+
justify-content: center;
|
|
2156
|
+
gap: var(--action-note-gap, var(--sp-1));
|
|
2157
|
+
padding-inline: var(--sp-2);
|
|
2158
|
+
font: var(--action-note-font, var(--type-body));
|
|
2159
|
+
color: var(--action-note-ink, var(--on-surface-muted));
|
|
2160
|
+
text-align: center;
|
|
2161
|
+
cursor: default;
|
|
2162
|
+
}
|
|
2163
|
+
.card .action-note { color: var(--action-note-ink, var(--card-muted)); }
|
|
2164
|
+
.action-note__words { display: block; } /* ONE run of words: an icon inside sits in the line, the spaces around it kept */
|
|
2165
|
+
.action-note__words > .icon { display: inline-block; vertical-align: -0.2em; width: 1.25em; height: 1.25em; margin-inline: 0.15em; color: inherit; }
|
|
2166
|
+
|
|
2146
2167
|
/* ---- css/numbers.css — ring, track, band, dot grid, picker, badge, bars ---- */
|
|
2147
2168
|
/* ============================================================
|
|
2148
2169
|
cardds/numbers.css — big numbers inside cards:
|
|
@@ -3357,14 +3378,16 @@ button { font: inherit; cursor: pointer; }
|
|
|
3357
3378
|
position: absolute; /* at the stage's centre, and kept there as it grows: absolute + margin auto re-centres on every height */
|
|
3358
3379
|
inset: 0;
|
|
3359
3380
|
margin: auto;
|
|
3360
|
-
height:
|
|
3381
|
+
height: auto;
|
|
3382
|
+
align-self: center; /* inset 0 alone would stretch it to the stage: centre self-alignment gives it its own height, the margins
|
|
3383
|
+
share the rest. NOT `height: fit-content` — WebKit/Safari sizes it wrong (Lh 2026-09-24, iOS 18.6) */
|
|
3361
3384
|
width: calc(100% - 2 * var(--screen-pad));
|
|
3362
3385
|
z-index: 2; /* over the dim stage's scrim (z 1) */
|
|
3363
3386
|
max-height: calc(100cqh - 2 * var(--sp-5)); /* cqh: the stage (a size container) */
|
|
3364
3387
|
padding: 0; /* the parts pad themselves */
|
|
3365
3388
|
border: 0; /* no frame on the modal (Lh 2026-09-16) — its edge is the shadow */
|
|
3366
|
-
display: grid
|
|
3367
|
-
|
|
3389
|
+
display: flex; /* a column: the lift shrinks (and scrolls) under max-height, the drawer keeps its height. NOT a grid */
|
|
3390
|
+
flex-direction: column; /* of minmax(0, 1fr) + auto — WebKit/Safari sizes that 1fr row to 0 (Lh 2026-09-24, iOS 18.6) */
|
|
3368
3391
|
overflow: clip;
|
|
3369
3392
|
box-shadow: var(--modal-shadow, var(--shadow-sheet));
|
|
3370
3393
|
}
|
|
@@ -3373,11 +3396,13 @@ button { font: inherit; cursor: pointer; }
|
|
|
3373
3396
|
display: grid;
|
|
3374
3397
|
gap: var(--card-gap);
|
|
3375
3398
|
align-content: start;
|
|
3399
|
+
flex: 0 1 auto;
|
|
3376
3400
|
min-height: 0;
|
|
3377
3401
|
overflow-y: auto; /* tall content scrolls inside; the drawer stays */
|
|
3378
3402
|
overscroll-behavior: contain;
|
|
3379
3403
|
}
|
|
3380
3404
|
.modal__drawer {
|
|
3405
|
+
flex-shrink: 0;
|
|
3381
3406
|
height: var(--drawer-h);
|
|
3382
3407
|
box-sizing: border-box;
|
|
3383
3408
|
padding: var(--modal-drawer-pad, var(--sp-5));
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -10,6 +10,13 @@ export interface CallSheetSheet {
|
|
|
10
10
|
/** a small link UNDER that button (a `Link sm`, e.g. details for developers) */
|
|
11
11
|
footLink?: ReactNode;
|
|
12
12
|
}
|
|
13
|
+
/** one way in: its button and the sheet it calls */
|
|
14
|
+
export interface CallSheetWay {
|
|
15
|
+
/** the button's words */
|
|
16
|
+
action: ReactNode;
|
|
17
|
+
/** what that button brings up */
|
|
18
|
+
sheet: CallSheetSheet;
|
|
19
|
+
}
|
|
13
20
|
export interface CallSheetProps extends Omit<ComponentProps<typeof Screen>, 'children' | 'fill' | 'top' | 'bottom' | 'title'> {
|
|
14
21
|
/** a picture above the words (optional) */
|
|
15
22
|
media?: ReactNode;
|
|
@@ -17,22 +24,25 @@ export interface CallSheetProps extends Omit<ComponentProps<typeof Screen>, 'chi
|
|
|
17
24
|
heading: ReactNode;
|
|
18
25
|
/** the words: a string is one paragraph */
|
|
19
26
|
body?: ReactNode;
|
|
20
|
-
/** the button that calls the sheet */
|
|
21
|
-
action
|
|
22
|
-
/** what
|
|
23
|
-
sheet
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
defaultOpen
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
/** ONE way in: the button that calls the sheet (with `sheet`) */
|
|
28
|
+
action?: ReactNode;
|
|
29
|
+
/** what that button brings up */
|
|
30
|
+
sheet?: CallSheetSheet;
|
|
31
|
+
/** SEVERAL ways in (instead of `action` + `sheet`): one button each, sized to its words, wrapping like a CtaPack (the first primary, the rest quiet), each calling its own sheet */
|
|
32
|
+
ways?: CallSheetWay[];
|
|
33
|
+
/** CONTROLLED: which way's sheet is up — an index, or null for none (`true` = the first); with `onOpenChange`; or `defaultOpen` */
|
|
34
|
+
open?: number | boolean | null;
|
|
35
|
+
defaultOpen?: number | boolean | null;
|
|
36
|
+
onOpenChange?: (open: boolean, way: number | null) => void;
|
|
37
|
+
/** the sheets' resting states once up (default "peek full") */
|
|
29
38
|
states?: string;
|
|
30
39
|
/** layers over the screen */
|
|
31
40
|
children?: ReactNode;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
43
|
* CallSheet — TEMPLATE, a `Screen` with its parts filled — no top · content: a `Step` holding ONE `Page` (picture · heading (the h1) ·
|
|
35
|
-
* words · the button) and the `Sheet`
|
|
36
|
-
* screen's lead (15%). The
|
|
44
|
+
* words · the button, or several — `ways`) and the `Sheet` each button calls · no bottom (a sheet finishes on its own foot). The page
|
|
45
|
+
* starts at the screen's lead (15%). The sheets wait `away`; a button brings its own up full; the handle takes it down to peek.
|
|
46
|
+
* One sheet up at a time — a sheet holds that way's WHOLE form.
|
|
37
47
|
*/
|
|
38
|
-
export declare function CallSheet({ media, heading, body, action, sheet, open: openProp, defaultOpen, onOpenChange, states, children, ...rest }: CallSheetProps): import("react").JSX.Element;
|
|
48
|
+
export declare function CallSheet({ media, heading, body, action, sheet, ways, open: openProp, defaultOpen, onOpenChange, states, children, ...rest }: CallSheetProps): import("react").JSX.Element;
|
|
@@ -9,19 +9,22 @@ import { CardHead } from '../cards/CardHead.js';
|
|
|
9
9
|
import { CardFoot } from '../cards/CardFoot.js';
|
|
10
10
|
import { Text } from '../type/Text.js';
|
|
11
11
|
import { Btn } from '../actions/Btn.js';
|
|
12
|
+
const index = (o) => (o === true ? 0 : typeof o === 'number' ? o : null);
|
|
12
13
|
/**
|
|
13
14
|
* CallSheet — TEMPLATE, a `Screen` with its parts filled — no top · content: a `Step` holding ONE `Page` (picture · heading (the h1) ·
|
|
14
|
-
* words · the button) and the `Sheet`
|
|
15
|
-
* screen's lead (15%). The
|
|
15
|
+
* words · the button, or several — `ways`) and the `Sheet` each button calls · no bottom (a sheet finishes on its own foot). The page
|
|
16
|
+
* starts at the screen's lead (15%). The sheets wait `away`; a button brings its own up full; the handle takes it down to peek.
|
|
17
|
+
* One sheet up at a time — a sheet holds that way's WHOLE form.
|
|
16
18
|
*/
|
|
17
|
-
export function CallSheet({ media, heading, body, action, sheet, open: openProp, defaultOpen =
|
|
18
|
-
const [
|
|
19
|
-
const
|
|
19
|
+
export function CallSheet({ media, heading, body, action, sheet, ways, open: openProp, defaultOpen = null, onOpenChange, states = 'peek full', children, ...rest }) {
|
|
20
|
+
const list = ways ?? (sheet ? [{ action, sheet }] : []);
|
|
21
|
+
const [own, setOwn] = useState(index(defaultOpen));
|
|
22
|
+
const on = openProp === undefined ? own : index(openProp);
|
|
20
23
|
const [at, setAt] = useState('full');
|
|
21
24
|
const set = (next) => { if (openProp === undefined)
|
|
22
|
-
setOwn(next); onOpenChange?.(next); };
|
|
23
|
-
return (_jsxs(Screen, { fill: true, ...rest, children: [_jsxs(Step, { children: [_jsxs(Page, { children: [media, _jsx(CardHead, { level: "h1", heading: heading }), typeof body === 'string' ? _jsx(Text, { level: "body", children: body }) : body, _jsx(CtaPack, { children: _jsx(Btn, { primary:
|
|
24
|
-
set(
|
|
25
|
+
setOwn(next); onOpenChange?.(next !== null, next); };
|
|
26
|
+
return (_jsxs(Screen, { fill: true, ...rest, children: [_jsxs(Step, { children: [_jsxs(Page, { children: [media, _jsx(CardHead, { level: "h1", heading: heading }), typeof body === 'string' ? _jsx(Text, { level: "body", children: body }) : body, _jsx(CtaPack, { children: list.map((w, i) => (_jsx(Btn, { primary: i === 0, quiet: i > 0, "aria-expanded": on === i, onClick: () => { setAt('full'); set(i); }, children: w.action }, i))) })] }), list.map(({ sheet: sh }, i) => (_jsxs(Sheet, { state: on === i ? at : 'away', onStateChange: (s) => { if (s === 'away')
|
|
27
|
+
set(null);
|
|
25
28
|
else
|
|
26
|
-
setAt(s); }, states: states, children: [_jsx(CardHead, { heading:
|
|
29
|
+
setAt(s); }, states: states, children: [_jsx(CardHead, { heading: sh.title }), _jsx(SheetBody, { children: on === i ? (typeof sh.body === 'function' ? sh.body() : sh.body) : null }), (sh.foot != null || sh.footLink != null) && _jsx(CardFoot, { link: sh.footLink, children: sh.foot })] }, i)))] }), children] }));
|
|
27
30
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usableapp/cardds",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.14",
|
|
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.",
|