@usableapp/cardds 0.7.73 → 0.7.74

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 CHANGED
@@ -2,6 +2,26 @@
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.74 — 2026-10-08
6
+
7
+ ### Added
8
+ - **The guide: the few rules no checker sees, in one short text** (Lh 2026-10-08) — `npx cardds guide` prints it, and `npx cardds mcp` hands the same text to every session as the server's instructions. It says WHEN cardds applies in the words of the work (a prototype, a poc, a mock-up, ขึ้นหน้า… — a screen, a sheet, a sticky note, a stamp, a postcard), the order (find → scaffold or get → write → check), and five rules: take cardds from outside and never edit it; adjust by theme → knobs → props; every component is controlled like an input; import, never copy markup; mobile only. Before → after: these lived in a personal skill file outside the repo → they ship with the version you installed.
9
+ - **Four more rules in `npx cardds check`** (and the ESLint plugin):
10
+ - `focus-by-hand` (warning) — an `autoFocus` or a `.focus()` in a file with a `Sheet`, `SheetStep`, `SheetStack`, `Home`, `Modal` or `CallSheet`: cardds places the cursor itself. Remove it; `data-autofocus` on a field picks that field.
11
+ - `control-name-repeat` (warning) — `handle="…"`, `backLabel="…"`, `nextLabel="…"`, `prevLabel="…"`, `skipLabel="…"` (and `PostLetter`'s) written as a plain string: cardds names these controls in the page's language (`<html lang="th">`). Drop it unless the words differ; another language is `setWords(lang, {…})` once.
12
+ - `native-select` (error) — a `<select>`: use `Dropdown`.
13
+ - `raw-value` (warning) — a raw colour or `px` length in a `style` prop: set it in `theme.css`, by a knob, or by a prop. A knob in a style (`'--tile-badge-ink': '#c00'`) is not flagged.
14
+ A deliberate case keeps `// cardds-ignore-next-line` with its reason, as before. Expect new warnings on the next `npm run cardds:check`.
15
+ - **`--menu-max-h`** — the tallest a popover `Menu` / `Dropdown` panel grows (default 60% of the screen, less its margins).
16
+
17
+ ### Changed
18
+ - **`npx cardds check` reads a component by its real name under an import alias** — `import { Home as HomeScreen }` then `<HomeScreen backLabel="กลับ">` passed every rule that looks for a tag; it is checked now.
19
+ - **`npx cardds scaffold <id>` leaves out a name cardds already gives its control** — the starting file no longer carries `backLabel="กลับ"` / `handle="…"` from the gallery's story. `npx cardds get` still shows the story as written.
20
+ - The JSDoc of `Sheet`, `SheetStep`, `StackSheet`, `SheetStack`, `Modal` says that cardds places the cursor, and each cardds-named control prop says it is named by cardds — what `npx cardds get <Name>` returns.
21
+
22
+ ### Fixed
23
+ - **A long `Menu` / `Dropdown` ran off the foot of the screen** (timebank, 2026-10-08) — twenty items made a panel 979px tall on an 812px screen, the last names out of reach. Before → after: the panel grew with its items → it stops at `--menu-max-h` and scrolls inside. Nothing to change in an app.
24
+
5
25
  ## 0.7.73 — 2026-10-08
6
26
 
7
27
  ### Added
package/README.md CHANGED
@@ -149,15 +149,18 @@ npx cardds scaffold <id> # a whole file from a screen: tsx (the code) or
149
149
  npx cardds get <Name> [--html] # one component: its role, props (a ReactNode prop is a slot) + variations with code
150
150
  npx cardds list # every name by what it is for: one · group-brief · group-detail, the show-only first, then by what the member can do
151
151
  npx cardds check <dir> # the rules, before a screen is called done
152
+ npx cardds guide # the few rules no checker sees, in one short text
152
153
  ```
153
154
 
154
- All take `--json` (the function's result) and `--root <path>` (a cardds checkout: rebuilt first, so never stale). The same
155
+ `list` · `get` · `find` · `scaffold` take `--json` (the function's result) and `--root <path>` (a cardds checkout: rebuilt first, so never stale). The same
155
156
  five answers over MCP — `list_components` · `get_component` · `find_components` · `scaffold_screen` · `check_source`:
156
157
 
157
158
  ```json
158
159
  { "mcpServers": { "cardds": { "command": "npx", "args": ["cardds", "mcp"] } } }
159
160
  ```
160
161
 
162
+ The MCP server hands a session the same text as `npx cardds guide` as its instructions, when it starts.
163
+
161
164
  A scaffolded tsx may import `./_story` or `./_*Art`: story glue, not in the package — replace or drop it.
162
165
 
163
166
  ### React adapter — how a component is written
package/bin/cardds.mjs CHANGED
@@ -1,12 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  // `npx cardds init` — set a project up the ONE way (Lh 2026-09-29): the project's theme.css, the check script, the ESLint rules.
3
3
  // `npx cardds check [dir…]` — the rules of lint/rules.mjs over the project's source; exit 1 on an error.
4
+ // `npx cardds guide` — the few rules no checker sees, as text (the MCP server hands the same text over as its instructions).
4
5
  // `npx cardds list | get <Name> | find [words…] [--represents a,b] [--shape s] [--interact k|none] | scaffold [id]` — the component catalog (lib/catalog.mjs) for an AI session; `npx cardds mcp` serves the same over MCP.
5
6
  import { existsSync, readFileSync, writeFileSync, readdirSync, statSync, mkdirSync, copyFileSync } from 'node:fs';
6
7
  import { dirname, join, relative, resolve } from 'node:path';
7
8
  import { fileURLToPath } from 'node:url';
8
9
  import { checkSource } from '../lint/rules.mjs';
9
10
  import * as catalog from '../lib/catalog.mjs';
11
+ import { GUIDE } from '../lib/guide.mjs';
10
12
 
11
13
  const PKG = join(dirname(fileURLToPath(import.meta.url)), '..');
12
14
  const [cmd, ...args] = process.argv.slice(2);
@@ -123,6 +125,6 @@ function ask(cmd, argv) {
123
125
  return 0;
124
126
  }
125
127
 
126
- const code = cmd === 'check' ? check(args) : cmd === 'init' ? init() : ['list', 'get', 'find', 'scaffold', 'mcp'].includes(cmd) ? await ask(cmd, args)
127
- : (console.log('usage: cardds init | check [dir…] | list | get <Name> [--html] | find [words…] [--represents a,b] [--shape s] [--interact k|none] | scaffold [id] [--html [--css <href>]] | mcp (list get find scaffold mcp: --root <path> --json)'), cmd ? 2 : 0);
128
+ const code = cmd === 'check' ? check(args) : cmd === 'init' ? init() : cmd === 'guide' ? (process.stdout.write(GUIDE), 0) : ['list', 'get', 'find', 'scaffold', 'mcp'].includes(cmd) ? await ask(cmd, args)
129
+ : (console.log('usage: cardds init | guide | check [dir…] | list | get <Name> [--html] | find [words…] [--represents a,b] [--shape s] [--interact k|none] | scaffold [id] [--html [--css <href>]] | mcp (list get find scaffold mcp: --root <path> --json)'), cmd ? 2 : 0);
128
130
  process.exitCode = code; // not process.exit: a big answer piped to a reader is cut off by an exit before it is flushed
package/css/layover.css CHANGED
@@ -128,6 +128,10 @@
128
128
  padding: var(--menu-pad);
129
129
  min-width: 12rem;
130
130
  align-content: start; /* rows keep their own height: WebKit stretches a popover grid's rows to the whole room under its anchor (iOS 26.5, 2026-10-08) */
131
+ --_menu-max: min(60dvh, calc(100dvh - 2 * var(--sp-5)));
132
+ max-height: var(--menu-max-h, var(--_menu-max)); /* a long list (twenty neighbours) scrolls inside the panel — it ran off the screen's foot, the last names out of reach (timebank, 2026-10-08) */
133
+ overflow-y: auto;
134
+ overscroll-behavior: contain;
131
135
  background: var(--menu-bg, var(--action-bg));
132
136
  color: var(--menu-ink, var(--action-ink));
133
137
  box-shadow: var(--menu-shadow, var(--shadow-float));
package/dist/cardds.css CHANGED
@@ -4834,6 +4834,10 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
4834
4834
  padding: var(--menu-pad);
4835
4835
  min-width: 12rem;
4836
4836
  align-content: start; /* rows keep their own height: WebKit stretches a popover grid's rows to the whole room under its anchor (iOS 26.5, 2026-10-08) */
4837
+ --_menu-max: min(60dvh, calc(100dvh - 2 * var(--sp-5)));
4838
+ max-height: var(--menu-max-h, var(--_menu-max)); /* a long list (twenty neighbours) scrolls inside the panel — it ran off the screen's foot, the last names out of reach (timebank, 2026-10-08) */
4839
+ overflow-y: auto;
4840
+ overscroll-behavior: contain;
4837
4841
  background: var(--menu-bg, var(--action-bg));
4838
4842
  color: var(--menu-ink, var(--action-ink));
4839
4843
  box-shadow: var(--menu-shadow, var(--shadow-float));