@usableapp/cardds 0.3.0 → 0.4.0
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/README.md +9 -5
- package/css/actions.css +38 -27
- package/css/base.css +9 -9
- package/css/card.css +24 -23
- package/css/choice.css +50 -50
- package/css/forms.css +18 -18
- package/css/journey.css +16 -16
- package/css/layover.css +45 -45
- package/css/lists.css +43 -43
- package/css/media.css +33 -33
- package/css/numbers.css +25 -25
- package/css/people.css +11 -11
- package/css/sheet.css +21 -21
- package/css/theme.template.css +6 -3
- package/dist/actions/Btn.d.ts +109 -108
- package/dist/actions/BtnRow.d.ts +2 -2
- package/dist/actions/Chip.d.ts +102 -101
- package/dist/actions/Dot.d.ts +2 -2
- package/dist/actions/Dropdown.d.ts +4 -4
- package/dist/actions/Fab.d.ts +2 -2
- package/dist/actions/IconBtn.d.ts +107 -106
- package/dist/actions/Link.d.ts +105 -104
- package/dist/actions/Segment.d.ts +3 -3
- package/dist/cardds.css +333 -321
- package/dist/cards/Card.d.ts +99 -98
- package/dist/cards/CardFoot.d.ts +2 -2
- package/dist/cards/CardHead.d.ts +2 -2
- package/dist/cards/CardParts.d.ts +7 -7
- package/dist/cards/Placeholder.d.ts +2 -2
- package/dist/cards/Stat.d.ts +7 -5
- package/dist/cards/Stat.js +2 -2
- package/dist/choice/Calendar.d.ts +2 -2
- package/dist/choice/Check.d.ts +3 -3
- package/dist/choice/DayStrip.d.ts +3 -3
- package/dist/choice/Mood.d.ts +2 -2
- package/dist/choice/Slider.d.ts +2 -2
- package/dist/forms/AddRow.d.ts +2 -2
- package/dist/forms/Composer.d.ts +2 -2
- package/dist/forms/Field.d.ts +2 -2
- package/dist/forms/FileBtn.d.ts +2 -2
- package/dist/forms/Pin.d.ts +2 -2
- package/dist/journey/NoteRow.d.ts +2 -2
- package/dist/journey/Route.d.ts +2 -2
- package/dist/journey/TileBadge.d.ts +2 -2
- package/dist/layover/Banner.d.ts +2 -2
- package/dist/layover/Callout.d.ts +2 -2
- package/dist/layover/Deck.d.ts +3 -3
- package/dist/lists/Bubble.d.ts +3 -3
- package/dist/lists/Kv.d.ts +5 -5
- package/dist/lists/Legend.d.ts +3 -3
- package/dist/lists/Row.d.ts +5 -4
- package/dist/lists/Timeline.d.ts +3 -3
- package/dist/media/MapArea.d.ts +2 -2
- package/dist/media/Mosaic.d.ts +3 -3
- package/dist/media/Postcard.d.ts +2 -2
- package/dist/media/Quote.d.ts +2 -2
- package/dist/media/Tile.d.ts +5 -4
- package/dist/numbers/Badge.d.ts +2 -2
- package/dist/numbers/Band.d.ts +3 -3
- package/dist/numbers/Bars.d.ts +3 -3
- package/dist/numbers/DotGrid.d.ts +2 -2
- package/dist/numbers/Picker.d.ts +3 -3
- package/dist/numbers/Ring.d.ts +2 -2
- package/dist/numbers/Track.d.ts +3 -3
- package/dist/people/Avatar.d.ts +100 -99
- package/dist/people/AvatarPick.d.ts +3 -3
- package/dist/scaffold/ActionBar.d.ts +3 -3
- package/dist/scaffold/AppBar.d.ts +2 -2
- package/dist/scaffold/BaseContent.d.ts +3 -3
- package/dist/scaffold/Centre.d.ts +3 -3
- package/dist/scaffold/EmptyState.d.ts +2 -2
- package/dist/scaffold/FilterRow.d.ts +2 -2
- package/dist/scaffold/FloatBar.d.ts +105 -104
- package/dist/scaffold/PagerAt.d.ts +2 -2
- package/dist/scaffold/Screen.d.ts +100 -99
- package/dist/scaffold/TopBar.d.ts +2 -2
- package/dist/sheets/CardBack.d.ts +2 -2
- package/dist/sheets/Drawer.d.ts +5 -5
- package/dist/sheets/Sheet.d.ts +2 -2
- package/dist/sheets/SheetBody.d.ts +2 -2
- package/dist/sheets/SheetHead.d.ts +2 -2
- package/dist/sheets/SheetStack.d.ts +2 -2
- package/dist/sheets/SheetStage.d.ts +2 -2
- package/dist/sheets/Step.d.ts +2 -2
- package/dist/type/Icon.d.ts +22 -7
- package/dist/type/Icon.js +27 -4
- package/dist/type/Text.d.ts +7 -1
- package/dist/type/Text.js +2 -2
- package/package.json +3 -2
package/dist/type/Icon.d.ts
CHANGED
|
@@ -1,16 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type IconName as StockIconName } from './icons.js';
|
|
3
|
+
/** an icon's name: one of the stock symbols (autocompleted) — or any name a project registered with `registerIcons` */
|
|
4
|
+
export type IconName = StockIconName | (string & {});
|
|
5
|
+
/**
|
|
6
|
+
* registerIcons — a project's OWN icons, by name: after this, `icon="map-pin"` works on every component that takes an icon (Icon, IconBtn,
|
|
7
|
+
* Field, MenuItem, Tile…), exactly like a stock one. Call it once at startup. A drawing is the INSIDE of the `<svg>` as a string (paths on a
|
|
8
|
+
* 24×24 box, drawn with the shared stroke), or `{ body, attrs }` to bring its own viewBox / fill. A registered name wins over a stock one —
|
|
9
|
+
* that is how a project swaps a symbol for its own. Returns nothing; safe to call again (later drawings replace earlier ones).
|
|
10
|
+
*/
|
|
11
|
+
export declare function registerIcons(icons: Record<string, string | {
|
|
12
|
+
body: string;
|
|
13
|
+
attrs?: Record<string, string>;
|
|
14
|
+
}>): void;
|
|
15
|
+
export interface IconProps extends Omit<React.ComponentProps<'svg'>, 'children' | 'name'> {
|
|
16
|
+
/** a stock symbol (arrow-left, bell, check, chevron-down, id-card, plus, x, …) or a name the project registered (`registerIcons`). Omit it to draw with `children`. */
|
|
17
|
+
name?: IconName;
|
|
18
|
+
/** a ONE-OFF drawing: the svg's own children (`<path d="…" />`), on a 24×24 box with the shared stroke — for an icon not worth registering */
|
|
19
|
+
children?: ReactNode;
|
|
6
20
|
/** xs = 16px, inside captions, chips and links · sm = in a small icon button or a field (28px today — one size everywhere, tokens.css) · md (default) = the 28px icon · lg = 32px, empty states */
|
|
7
21
|
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
8
22
|
/** an accessible name makes the icon meaningful (role="img"); without one it is decorative and hidden from assistive tech */
|
|
9
23
|
label?: string;
|
|
10
24
|
}
|
|
11
25
|
/**
|
|
12
|
-
* Icon — a
|
|
26
|
+
* Icon — a stroke icon, inlined (no sprite file at runtime): one of the stock Lucide symbols, one of the project's OWN (`registerIcons`), or a
|
|
27
|
+
* one-off drawn with `children`. The set is open — a project never comes to cardds for an icon.
|
|
13
28
|
* Sizes are the tokens the CSS defines: `.icon` 28px, `--sm` 28px (a semantic size, same as md today), `--xs` 16px, `--lg` 32px.
|
|
14
29
|
* Keep it big: inside a button or a row the default 28px icon is the norm; xs only sits in text.
|
|
15
30
|
*/
|
|
16
|
-
export declare function Icon({ name, size, label, className, ...rest }: IconProps): import("react").JSX.Element;
|
|
31
|
+
export declare function Icon({ name, children, size, label, className, ...rest }: IconProps): import("react").JSX.Element;
|
package/dist/type/Icon.js
CHANGED
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from '../cx.js';
|
|
3
3
|
import { ICONS } from './icons.js';
|
|
4
|
+
/* the stroke style every stock symbol shares (Lucide): a project's drawing takes it unless it brings its own attrs */
|
|
5
|
+
const STROKE = { viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' };
|
|
6
|
+
const OWN = new Map();
|
|
4
7
|
/**
|
|
5
|
-
*
|
|
8
|
+
* registerIcons — a project's OWN icons, by name: after this, `icon="map-pin"` works on every component that takes an icon (Icon, IconBtn,
|
|
9
|
+
* Field, MenuItem, Tile…), exactly like a stock one. Call it once at startup. A drawing is the INSIDE of the `<svg>` as a string (paths on a
|
|
10
|
+
* 24×24 box, drawn with the shared stroke), or `{ body, attrs }` to bring its own viewBox / fill. A registered name wins over a stock one —
|
|
11
|
+
* that is how a project swaps a symbol for its own. Returns nothing; safe to call again (later drawings replace earlier ones).
|
|
12
|
+
*/
|
|
13
|
+
export function registerIcons(icons) {
|
|
14
|
+
for (const [name, d] of Object.entries(icons))
|
|
15
|
+
OWN.set(name, typeof d === 'string' ? { attrs: STROKE, body: d } : { attrs: { ...STROKE, ...d.attrs }, body: d.body });
|
|
16
|
+
}
|
|
17
|
+
const warned = new Set();
|
|
18
|
+
/**
|
|
19
|
+
* Icon — a stroke icon, inlined (no sprite file at runtime): one of the stock Lucide symbols, one of the project's OWN (`registerIcons`), or a
|
|
20
|
+
* one-off drawn with `children`. The set is open — a project never comes to cardds for an icon.
|
|
6
21
|
* Sizes are the tokens the CSS defines: `.icon` 28px, `--sm` 28px (a semantic size, same as md today), `--xs` 16px, `--lg` 32px.
|
|
7
22
|
* Keep it big: inside a button or a row the default 28px icon is the norm; xs only sits in text.
|
|
8
23
|
*/
|
|
9
|
-
export function Icon({ name, size = 'md', label, className, ...rest }) {
|
|
10
|
-
const icon = ICONS[name];
|
|
11
|
-
|
|
24
|
+
export function Icon({ name, children, size = 'md', label, className, ...rest }) {
|
|
25
|
+
const icon = name === undefined ? undefined : OWN.get(name) ?? ICONS[name];
|
|
26
|
+
if (name !== undefined && !icon && !warned.has(name)) {
|
|
27
|
+
warned.add(name);
|
|
28
|
+
console.warn(`cardds Icon: no icon named "${name}" — a stock name is misspelt, or the project has not registered it (registerIcons)`);
|
|
29
|
+
}
|
|
30
|
+
const shared = { className: cx('icon', size !== 'md' && `icon--${size}`, className), role: label ? 'img' : undefined, 'aria-label': label, 'aria-hidden': label ? undefined : true };
|
|
31
|
+
// an unknown name draws nothing but keeps its box — a missing icon never takes a screen down
|
|
32
|
+
if (!icon)
|
|
33
|
+
return _jsx("svg", { ...STROKE, ...shared, ...rest, children: children });
|
|
34
|
+
return _jsx("svg", { ...icon.attrs, ...shared, dangerouslySetInnerHTML: { __html: icon.body }, ...rest });
|
|
12
35
|
}
|
package/dist/type/Text.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type TextLevel = 'display' | 'h1' | 'h2' | 'title' | 'body' | 'label' | 'caption' | 'overline' | 'stat';
|
|
2
2
|
export interface TextProps extends React.HTMLAttributes<HTMLElement> {
|
|
3
|
+
/** the element it renders (React 19 passes `ref` as a prop) */
|
|
4
|
+
ref?: React.Ref<HTMLElement>;
|
|
3
5
|
/** the type level: display (hero words) · h1 · h2 (a card's heading) · title · body · label · caption · overline (small caps above a heading) · stat (a big number) */
|
|
4
6
|
level: TextLevel;
|
|
5
7
|
/** stat only: the one giant number on a sheet (`.t-stat--xl`) */
|
|
@@ -8,6 +10,8 @@ export interface TextProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
8
10
|
mono?: boolean;
|
|
9
11
|
/** muted ink — follows the card it sits in */
|
|
10
12
|
muted?: boolean;
|
|
13
|
+
/** takes the remaining room of a row (a heading beside a chip in a flex head) */
|
|
14
|
+
grow?: boolean;
|
|
11
15
|
/** uppercase */
|
|
12
16
|
caps?: boolean;
|
|
13
17
|
/** the element; defaults per level (h2 for display/h1/h2, p for title/body/stat, span for the rest) */
|
|
@@ -18,7 +22,9 @@ export interface TextProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
18
22
|
* Headings inside a card head are h2 by default; a screen title in a TopBar is h1.
|
|
19
23
|
* Everything scales from the root font-size, so there are no pixel sizes to pick.
|
|
20
24
|
*/
|
|
21
|
-
export declare function Text({ level, xl, mono, muted, caps, as, className, ...rest }: TextProps): import("react").DetailedReactHTMLElement<{
|
|
25
|
+
export declare function Text({ level, xl, mono, muted, caps, grow, as, className, ...rest }: TextProps): import("react").DetailedReactHTMLElement<{
|
|
26
|
+
/** the element it renders (React 19 passes `ref` as a prop) */
|
|
27
|
+
ref?: React.Ref<HTMLElement>;
|
|
22
28
|
defaultChecked?: boolean | undefined;
|
|
23
29
|
defaultValue?: string | number | readonly string[] | undefined;
|
|
24
30
|
suppressContentEditableWarning?: boolean | undefined;
|
package/dist/type/Text.js
CHANGED
|
@@ -8,9 +8,9 @@ const DEFAULT_AS = {
|
|
|
8
8
|
* Headings inside a card head are h2 by default; a screen title in a TopBar is h1.
|
|
9
9
|
* Everything scales from the root font-size, so there are no pixel sizes to pick.
|
|
10
10
|
*/
|
|
11
|
-
export function Text({ level, xl, mono, muted, caps, as, className, ...rest }) {
|
|
11
|
+
export function Text({ level, xl, mono, muted, caps, grow, as, className, ...rest }) {
|
|
12
12
|
return createElement(as ?? DEFAULT_AS[level] ?? 'span', {
|
|
13
|
-
className: cx(`t-${level}`, level === 'stat' && xl && 't-stat--xl', level === 'stat' && mono && 't-stat--mono', muted && 't-muted', caps && 't-caps', className),
|
|
13
|
+
className: cx(`t-${level}`, level === 'stat' && xl && 't-stat--xl', level === 'stat' && mono && 't-stat--mono', muted && 't-muted', caps && 't-caps', grow && 'grow', className),
|
|
14
14
|
...rest,
|
|
15
15
|
});
|
|
16
16
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usableapp/cardds",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
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.",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"build": "node scripts/build-icons.mjs && tsc -p tsconfig.json && node scripts/flatten-css.mjs",
|
|
14
14
|
"test": "playwright test",
|
|
15
15
|
"validate:inbox": "node scripts/validate-inbox.mjs",
|
|
16
|
-
"prepack": "npm run build"
|
|
16
|
+
"prepack": "npm run build",
|
|
17
|
+
"knobs": "node scripts/knobs.mjs"
|
|
17
18
|
},
|
|
18
19
|
"devDependencies": {
|
|
19
20
|
"@playwright/test": "1.58.2",
|