@usableapp/cardds 0.6.11 → 0.6.13
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 +24 -0
- package/css/tokens.css +1 -1
- package/dist/cardds.css +1 -1
- 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,30 @@
|
|
|
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.13 — 2026-09-24
|
|
6
|
+
|
|
7
|
+
### `CallSheet ways`: several ways in, each calling its own sheet (new)
|
|
8
|
+
- Before: `CallSheet` took one `action` + one `sheet`. After: it can also take `ways: [{ action, sheet }]`. Each way gets a button
|
|
9
|
+
sized to its words, and the buttons wrap like a `CtaPack` (the first is primary, the rest quiet). Each button brings up its own
|
|
10
|
+
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`.
|
|
11
|
+
- `open` / `defaultOpen` = the way's index, or `null` for none (`true` = the first). `onOpenChange(open, way)` gets the index as a
|
|
12
|
+
second argument. `action` + `sheet` still work unchanged.
|
|
13
|
+
- Gallery screen **SignIn**: เข้าใช้งาน with three ways (register · code · face scan).
|
|
14
|
+
|
|
15
|
+
### `--scrim` is always black
|
|
16
|
+
- Before: the scrim was 50% of `--card-3-bg` (the brand), so a coloured theme dimmed in its brand colour. After: 50% black in
|
|
17
|
+
every palette (dim stage, the cover and postcard gradients, the gallery drawer). A project can still set `--scrim` in its theme.css.
|
|
18
|
+
|
|
19
|
+
- Gallery only: Palette and the Layout / Boxes / Keyboard switches sit above Settings, which now holds only the base sliders. The
|
|
20
|
+
nav widens with the text size. The Page · OneMove story is removed (the Install screen shows it).
|
|
21
|
+
|
|
22
|
+
## 0.6.12 — 2026-09-23
|
|
23
|
+
|
|
24
|
+
- Gallery only (nothing changes in the package's components or CSS):
|
|
25
|
+
- The *layout* group is merged into *screen*: Walkthrough · Home · Install · Requests (the new EmptyState screen).
|
|
26
|
+
- A **Layout** button in Settings draws top · content · bottom on every fill screen.
|
|
27
|
+
- Layout, Boxes and Keyboard are buttons that switch themselves on and off (filled = on).
|
|
28
|
+
|
|
5
29
|
## 0.6.11 — 2026-09-23
|
|
6
30
|
|
|
7
31
|
### A small link under a foot's buttons: `CardFoot link` (new, like an ActionBar's `ctaLink`)
|
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
|
/* ============================================================
|
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
|
/* ============================================================
|
|
@@ -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.13",
|
|
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.",
|