@usableapp/cardds 0.7.76 → 0.7.78

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/dist/index.d.ts CHANGED
@@ -24,6 +24,7 @@ export * from './cards/Card.js';
24
24
  export * from './cards/CardHead.js';
25
25
  export * from './cards/CardFoot.js';
26
26
  export * from './cards/CardParts.js';
27
+ export * from './cards/CardFeed.js';
27
28
  export * from './cards/Stat.js';
28
29
  export * from './cards/Placeholder.js';
29
30
  export * from './sheets/SheetStack.js';
package/dist/index.js CHANGED
@@ -28,6 +28,7 @@ export * from './cards/Card.js';
28
28
  export * from './cards/CardHead.js';
29
29
  export * from './cards/CardFoot.js';
30
30
  export * from './cards/CardParts.js';
31
+ export * from './cards/CardFeed.js';
31
32
  export * from './cards/Stat.js';
32
33
  export * from './cards/Placeholder.js';
33
34
  export * from './sheets/SheetStack.js';
@@ -28,5 +28,8 @@ export interface StampPlaceProps extends Omit<ComponentProps<'span'>, 'onClick'>
28
28
  /** the place is a button ("make yours"): it renders a `<button>` */
29
29
  onClick?: () => void;
30
30
  }
31
- /** StampPlace — an empty place for a stamp: a dashed 4:5 frame the size a Stamp would be, a word or an Icon inside. */
32
- export declare function StampPlace({ faint, onClick, className, ...rest }: StampPlaceProps): import("react").JSX.Element;
31
+ /**
32
+ * StampPlace — an empty place for a stamp: a dashed 4:5 frame the size a Stamp would be, a word or an Icon inside.
33
+ * The dashes are a stroke, not a border: `--stamp-place-dash` and `--stamp-place-gap` set them.
34
+ */
35
+ export declare function StampPlace({ faint, onClick, className, children, ...rest }: StampPlaceProps): import("react").JSX.Element;
@@ -12,10 +12,13 @@ export function Stamp({ pictures, tone = 'custard', name, words, bare, tilt, onC
12
12
  const boxProps = (tap ? { type: 'button', onClick, ...rest } : rest);
13
13
  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
14
  }
15
- /** StampPlace — an empty place for a stamp: a dashed 4:5 frame the size a Stamp would be, a word or an Icon inside. */
16
- export function StampPlace({ faint, onClick, className, ...rest }) {
15
+ /**
16
+ * StampPlace — an empty place for a stamp: a dashed 4:5 frame the size a Stamp would be, a word or an Icon inside.
17
+ * The dashes are a stroke, not a border: `--stamp-place-dash` and `--stamp-place-gap` set them.
18
+ */
19
+ export function StampPlace({ faint, onClick, className, children, ...rest }) {
17
20
  const tap = onClick != null;
18
21
  const Box = (tap ? 'button' : 'span');
19
22
  const boxProps = (tap ? { type: 'button', onClick, ...rest } : rest);
20
- return _jsx(Box, { className: cx('stamp-place', faint && 'stamp-place--faint', className), ...boxProps });
23
+ return (_jsxs(Box, { className: cx('stamp-place', faint && 'stamp-place--faint', className), ...boxProps, children: [_jsx("svg", { className: "stamp-place__edge", "aria-hidden": "true", focusable: "false", children: _jsx("rect", {}) }), children] }));
21
24
  }
@@ -5,7 +5,7 @@ import { Icon } from '../type/Icon.js';
5
5
  import { StampPlace } from './Stamp.js';
6
6
  /** StampBook — the album page: StampCells three across on an album ground, the free places drawn empty up to `places`. */
7
7
  export function StampBook({ places = 0, strip, bare, className, children, ...rest }) {
8
- const free = Math.max(0, places - Children.count(children));
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))] }));
10
10
  }
11
11
  /** StampCell — one place of a StampBook: a Stamp (the child) and a short label under it. */
@@ -13,8 +13,12 @@ export interface HomeSheet {
13
13
  paper?: boolean;
14
14
  /** the sheet's pages as icon tabs in its head (a count shows as a small circle over the icon) — see `StackSheet` */
15
15
  tabs?: StackSheetTab[];
16
- /** the tab shown first (default: the first) */
16
+ /** CONTROLLED: the tab this sheet shows (its id) — with `onTabChange`. The app sets it to bring the sheet up on a named tab; without it the Home keeps the sheet's tab itself */
17
+ tab?: string;
18
+ /** UNCONTROLLED: the tab shown first (default: the first); the Home then keeps its own. Pair of `tab` */
17
19
  defaultTab?: string;
20
+ /** a tab of this sheet was tapped: its id */
21
+ onTabChange?: (tab: string) => void;
18
22
  /** the SHEET BODY — rendered only while the sheet is open (or kept, with `keep`); a function gets the chosen tab */
19
23
  body: ReactNode | ((tab?: string) => ReactNode);
20
24
  /** the SHEET FOOT: the CTA at the sheet's bottom (one row); a function gets the chosen tab */
@@ -50,5 +50,6 @@ export function Home({ top, title, sheets, open: openProp, defaultOpen = null, o
50
50
  }, [leaving]);
51
51
  const [tabs, setTabs] = useState(() => Object.fromEntries(sheets.map((x, i) => [i, x.defaultTab ?? x.tabs?.[0]?.id])));
52
52
  const shows = (i) => i === shown || i === leaving || (keep && seen.has(i));
53
- return (_jsxs(Screen, { fill: true, top: top, ...rest, children: [_jsx(Text, { level: "h1", as: "h1", sr: true, children: title }), _jsx(SheetStack, { closed: true, open: shown, onOpenChange: request, onRefresh: onRefresh, refreshing: refreshing, mark: mark, rise: rise, base: base, children: sheets.map((s, i) => (_jsx(StackSheet, { tone: s.tone ?? TONES[i], paper: s.paper, title: s.title, icon: s.icon, tabs: s.tabs, tab: tabs[i], onTabChange: (t) => setTabs((v) => ({ ...v, [i]: t })), backLabel: backLabel, backAt: backAt, foot: typeof s.foot === 'function' ? s.foot(tabs[i]) : s.foot, children: shows(i) ? (typeof s.body === 'function' ? s.body(tabs[i]) : s.body) : null }, i))) }), children] }));
53
+ const tabOf = (i) => sheets[i].tab ?? tabs[i];
54
+ return (_jsxs(Screen, { fill: true, top: top, ...rest, children: [_jsx(Text, { level: "h1", as: "h1", sr: true, children: title }), _jsx(SheetStack, { closed: true, open: shown, onOpenChange: request, onRefresh: onRefresh, refreshing: refreshing, mark: mark, rise: rise, base: base, children: sheets.map((s, i) => (_jsx(StackSheet, { tone: s.tone ?? TONES[i], paper: s.paper, title: s.title, icon: s.icon, tabs: s.tabs, tab: tabOf(i), onTabChange: (t) => { setTabs((v) => ({ ...v, [i]: t })); s.onTabChange?.(t); }, backLabel: backLabel, backAt: backAt, foot: typeof s.foot === 'function' ? s.foot(tabOf(i)) : s.foot, children: shows(i) ? (typeof s.body === 'function' ? s.body(tabOf(i)) : s.body) : null }, i))) }), children] }));
54
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usableapp/cardds",
3
- "version": "0.7.76",
3
+ "version": "0.7.78",
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.",