@usableapp/cardds 0.4.1 → 0.4.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/CHANGELOG.md ADDED
@@ -0,0 +1,95 @@
1
+ # Changelog
2
+
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
+
5
+ ## 0.4.2 — 2026-09-22
6
+
7
+ ### Words on the base: a picture and the dots
8
+ Screens that only tell (onboarding, a walk of pages) live on the base — `Step › BaseContent` — never in a `Card centre` on an empty base. Two things the base could not hold well are fixed:
9
+ - an `<img>` (or `Placeholder`) among the words is capped by `--base-content-media-h` (14rem) so a tall picture never pushes the words under the bar.
10
+ - `PagerAt` as the last child of a `BaseContent` is centred under the words (it used to sit left).
11
+ Story: `Step · WalksWithArt` — pages of words with a picture and the dots, a slider in the bar's upper tier, the round pager below.
12
+
13
+ Where things go on such a screen (answers given to timebank): a `Postcard` shown with the words is a child of `BaseContent` after them (the picture's slot; never wrapped in a Card) · a summary the system hands over (an address, a ticket) stays a `Card centre` · a walk's progress is the `CardHead` overline ("ขั้นที่ 2 จาก 5") or a `Track` as the first child of `BaseContent` — nothing sits between the TopBar and the Step.
14
+
15
+ ## 0.4.1 — 2026-09-22
16
+
17
+ Breaking renames and removals. No aliases (nobody had installed 0.4.0).
18
+
19
+ ### `CardBack` → `StackBack`
20
+ The back button a tapped stack sheet reveals belongs to the stack, not the card.
21
+ - import: `CardBack` → `StackBack`
22
+ - class (if you styled it): `.card__back` → `.sheet-stack__back`
23
+ - where it goes: unchanged — first child of the open stack sheet's `CardHead`.
24
+
25
+ ### `SheetStage`: `ask` prop removed
26
+ The stage only does the ground; the thing in front places itself.
27
+ - `<SheetStage ask>` → `<SheetStage dim>` — the `Modal` inside centres itself now.
28
+ - A Modal on a clean ground (no scrim) is allowed: `<SheetStage>` with no `dim`.
29
+ - CSS: `.sheet-stage--ask` is gone; `--drawer-h` now lives on `.modal`.
30
+
31
+ ### `Sheet`: `raised` prop removed
32
+ A sheet always stands on the floor and never has a dim behind it.
33
+ - `<SheetStage dim><Sheet raised …>` → that screen is a `Modal`: `<SheetStage dim><Modal><Lift>…</Lift><Drawer>…</Drawer></Modal>`
34
+ - `.sheet--raised`, `--sheet-raised-radius` are gone. `SheetStage foot` (the footnote strip) stays.
35
+
36
+ ### `Postcard` reshaped
37
+ The shape of `Card cover`: the photo fills it, a band at the bottom names it. Not a 3:2 card inside a card any more.
38
+ - props kept: `photo` `alt` `name` `caption` `flipped` `defaultFlipped` `onFlip` `frontLabel` `backLabel`
39
+ - new: `line` (the words under the name, `t-body`) · `liked` + `onLike(liked)` (the member's own heart in the band; no heart without them) · `likeLabel` · `voice` (a voice note instead of words: whatever you put there stands at the middle of the back — the app plays it; see Progress)
40
+ - the band (`name` · `line` · heart) turns WITH the face. The back: `name` a fifth of the way down, `line`, then `caption` (or `voice`).
41
+ - a tap on the photo still turns it. The turn is `.postcard__turn` (a button filling the face); the faces are divs now.
42
+ - Don't wrap a Postcard in a `Card`. Its min-height is the cover's (`--postcard-min-h` 22.5rem); as a `SheetStage hero` it fills the band the sheet leaves open, with the screen's inset at both ends.
43
+ - Who liked it is YOUR data, shown outside the card — see `Row more`.
44
+
45
+ ### `Row`: `more` (new)
46
+ A row that expands: it becomes the summary of a `<details class="row-expand">`, `more` comes out under it.
47
+ - `<Row lead={…} meta="4 คนถูกใจ" end={<Icon name="chevron-down" />} open={open} onOpenChange={setOpen} more={<Rows>…one Row per person…</Rows>} />`
48
+ - `open` + `onOpenChange`, or `defaultOpen`. An `end` chevron turns when open. You fetch the list; the row shows it.
49
+
50
+ ### `Progress` (new)
51
+ One straight line, the done share solid, the rest faint.
52
+ - `<Progress at={0.4} label="0:05 of 0:12" />` — `at` 0–1; you keep the value (a timer, a download).
53
+ - knobs: `--progress-h` · `--progress-radius` · `--progress-done-ink` · `--progress-rest-bg`.
54
+
55
+ ### Stage hero
56
+ `.sheet-stage__hero` is now as tall as the band a half sheet leaves open, less `--screen-pad` at both ends, and what it holds fills it (a child's `min-height` gives way). If your hero relied on its own height, check it.
57
+
58
+ ### Gallery
59
+ One page per thing you name (Card, Sheet, Btn…); inner parts (CardHead, CardBody, SheetBody, MenuItem, BtnRow…) are variations on the parent's page. Nav groups by use. `/Parent/Part` URLs are gone.
60
+
61
+ ## 0.4.0 — 2026-09-21
62
+
63
+ Knobs, open icons, theme bases, gallery. Nothing removed from the component API.
64
+ - **Knobs**: every component reads its look through `--<component>-<what>` custom properties with the default as fallback (363, listed in `docs/knobs.md`). Set one on `:root` (your `theme.css`) to retune everywhere, on any element to retune what is inside it. Declared nowhere: unset = nothing moved.
65
+ - **Icons are open**: `registerIcons({ name: '<path…/>' })` → usable by name on every component that takes an icon; `<Icon>` draws a one-off from children; an unknown name warns once instead of throwing.
66
+ - **Theme bases** (`css/theme.template.css`): four size bases (`--sp-base` `--fs-base` `--r-base` `--tap-base`) and five colour bases (`--color-surface` `--color-ink` `--color-paper` `--color-brand` `--color-on-brand`) on `:root`. A project sets a base, never a multiplier. `<html data-palette="own">` for own colours.
67
+ - `Stat centre`; the pager places what sits between its two buttons in the middle; every component types its `ref`.
68
+
69
+ ## 0.3.0 — 2026-09-21
70
+
71
+ **Components only — the app wires them.** The biggest change since 0.1: every component with a state is controlled like an input (`x` + `onXChange`, or `defaultX`), keeps its own behaviour inside, and none knows another. `cardds.js` no longer does anything between components — it is `--kb` (the keyboard's height) and `.bleed`'s scrollbar, 35 lines. If your screen relied on cardds.js to connect two things, the app connects them now.
72
+
73
+ ### Gone
74
+ - `aria-controls` on a button calling a sheet → the app: `useState` of the sheet's state, the button sets it, `<Sheet state onStateChange>`.
75
+ - events `cardds:sheet` · `cardds:pin` · `cardds:modal` · `cardds:flip`, and the Dropdown's native `change` → the components' own `onXChange` callbacks.
76
+ - `window.carddsSheetSet` / `carddsSheetReveal` / `carddsStepSync`, `--sheet-room`, the bar guard → the Sheet does all of it itself.
77
+ - `data-answer` on Modal buttons → plain `onClick`s; `<Modal open onClosed>`.
78
+ - `IconBtn menu` / `menuId` / `menuStart` → any button opens a popover `Menu` with the platform's `popoverTarget={id}`.
79
+ - `SheetStack mode="tap"` + hand-set `is-open` / `is-before` / `is-after` → `open` (index | null) + `onOpenChange`, or `defaultOpen`; the component paints the classes.
80
+
81
+ ### Each component, before → after
82
+ - **Sheet**: `state="half"` alone used to be a starting point the sheet then moved from; now a fixed `state` PINS it (the sheet asks through `onStateChange` and stays if you don't answer). A sheet the member drags or taps the handle of: `defaultState="half"` (it keeps its own), or `state` + `onStateChange` (you keep it). Own behaviour, inside: handle tap ↔ peek, drag-snap to `states`, the raise when a field in a peeked sheet takes focus, the climb when the keyboard comes up. The `away` state (a called sheet, off-screen) is set-only.
83
+ - **SheetStack**: `open` + `onOpenChange` / `defaultOpen`. A peeked head's tap and the back button only ask.
84
+ - **Modal**: `open` + `onClosed` (it plays its opening backwards, then says so; you unmount it). Buttons are yours.
85
+ - **Menu**: `actions` (plain onClicks) or `value` + `onChange`; picking closes it. **Dropdown**: one component like `<select>`, `value` + `onChange`, the pill named by the chosen item.
86
+ - **Pin**: `value` + `onChange(code, complete)` or `defaultValue`; auto-advance, Backspace, arrows, paste inside. Tests that listened for `cardds:pin` type into the cells instead.
87
+ - **Slider**: publishes its own `--slider-at`. **Postcard**: `flipped` + `onFlip` or `defaultFlipped`.
88
+ - **Calendar**: `selected` + `onSelect` or `defaultSelected`; `onPrev` / `onNext`; label props (its buttons had no handlers before).
89
+ - **Picker**: `value` + `onChange` or `defaultValue` — the value IS the item at the rail's centre (it had no way to report one).
90
+
91
+ Guidance, no longer enforced: "pager or sheet", "a sheet finishes on its foot", "a form lives whole in one sheet".
92
+
93
+ ## 0.2.2 — 2026-09-21
94
+
95
+ One sheet shape: the head stays pinned, the body scrolls without limit, the foot's button stands at the bottom above the keyboard — at every state, on a step and on a stage. Stage sheets ride `--kb` too. (`carddsSheetSet` / `carddsSheetReveal` on `window` — removed again in 0.3.0.)
package/css/base.css CHANGED
@@ -118,6 +118,11 @@ button { font: inherit; cursor: pointer; }
118
118
  padding-block: var(--base-content-pad-y, var(--sp-4));
119
119
  }
120
120
  .base-content > .t-body { color: var(--on-surface-muted); max-width: 34ch; }
121
+ /* an illustration among the words (Lh 2026-09-22): capped, so a tall picture never pushes the words under the bar;
122
+ the "where am I" dots under the words, centred — the same dots the centred card has under it */
123
+ .base-content > :is(img, .ph) { max-height: var(--base-content-media-h, 14rem); width: auto; max-width: 100%; object-fit: contain; justify-self: start; }
124
+ .base-content > .ph { width: 100%; height: var(--base-content-media-h, 14rem); }
125
+ .base-content > .pager__at { justify-self: center; }
121
126
  .base-content .cta-pack {
122
127
  display: flex;
123
128
  align-items: start; /* buttons keep their own height, never the row's */
package/dist/cardds.css CHANGED
@@ -492,6 +492,11 @@ button { font: inherit; cursor: pointer; }
492
492
  padding-block: var(--base-content-pad-y, var(--sp-4));
493
493
  }
494
494
  .base-content > .t-body { color: var(--on-surface-muted); max-width: 34ch; }
495
+ /* an illustration among the words (Lh 2026-09-22): capped, so a tall picture never pushes the words under the bar;
496
+ the "where am I" dots under the words, centred — the same dots the centred card has under it */
497
+ .base-content > :is(img, .ph) { max-height: var(--base-content-media-h, 14rem); width: auto; max-width: 100%; object-fit: contain; justify-self: start; }
498
+ .base-content > .ph { width: 100%; height: var(--base-content-media-h, 14rem); }
499
+ .base-content > .pager__at { justify-self: center; }
495
500
  .base-content .cta-pack {
496
501
  display: flex;
497
502
  align-items: start; /* buttons keep their own height, never the row's */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usableapp/cardds",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
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.",
@@ -48,7 +48,8 @@
48
48
  "cardds.css",
49
49
  "cardds.js",
50
50
  "icons.svg",
51
- "README.md"
51
+ "README.md",
52
+ "CHANGELOG.md"
52
53
  ],
53
54
  "peerDependencies": {
54
55
  "react": ">=18",