@usableapp/cardds 0.6.4 → 0.6.6

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +72 -26
  3. package/css/actions.css +15 -0
  4. package/css/base.css +9 -6
  5. package/css/card.css +4 -4
  6. package/css/choice.css +11 -0
  7. package/css/layover.css +3 -0
  8. package/css/lists.css +4 -0
  9. package/css/sheet.css +8 -1
  10. package/css/stack.css +55 -0
  11. package/css/step.css +43 -13
  12. package/css/tokens.css +2 -1
  13. package/dist/actions/Btn.d.ts +1 -1
  14. package/dist/actions/IconBtn.d.ts +1 -1
  15. package/dist/actions/Link.d.ts +3 -1
  16. package/dist/actions/Link.js +2 -2
  17. package/dist/cardds.css +154 -25
  18. package/dist/choice/Check.d.ts +6 -3
  19. package/dist/choice/Check.js +7 -4
  20. package/dist/index.d.ts +4 -1
  21. package/dist/index.js +4 -1
  22. package/dist/scaffold/ActionBar.d.ts +3 -2
  23. package/dist/scaffold/ActionBar.js +3 -2
  24. package/dist/scaffold/AppBar.d.ts +4 -1
  25. package/dist/scaffold/AppBar.js +4 -3
  26. package/dist/scaffold/Centre.d.ts +1 -1
  27. package/dist/scaffold/Centre.js +1 -1
  28. package/dist/scaffold/Page.d.ts +17 -0
  29. package/dist/scaffold/Page.js +24 -0
  30. package/dist/scaffold/Screen.d.ts +13 -8
  31. package/dist/scaffold/Screen.js +24 -7
  32. package/dist/sheets/SheetStack.d.ts +1 -1
  33. package/dist/sheets/SheetStack.js +6 -1
  34. package/dist/sheets/SheetStage.d.ts +4 -1
  35. package/dist/sheets/SheetStage.js +2 -2
  36. package/dist/sheets/StackBack.d.ts +2 -1
  37. package/dist/sheets/StackBack.js +3 -2
  38. package/dist/sheets/StackSheet.d.ts +35 -0
  39. package/dist/sheets/StackSheet.js +24 -0
  40. package/dist/sheets/Step.d.ts +4 -4
  41. package/dist/sheets/Step.js +4 -4
  42. package/dist/templates/Home.d.ts +48 -0
  43. package/dist/templates/Home.js +40 -0
  44. package/dist/templates/Walkthrough.d.ts +42 -0
  45. package/dist/templates/Walkthrough.js +35 -0
  46. package/dist/type/Text.d.ts +3 -1
  47. package/dist/type/Text.js +2 -2
  48. package/dist/type/icons.d.ts +1 -1
  49. package/dist/type/icons.js +2 -2
  50. package/icons.svg +2 -0
  51. package/package.json +1 -1
  52. package/dist/scaffold/BaseContent.d.ts +0 -17
  53. package/dist/scaffold/BaseContent.js +0 -18
@@ -1,11 +1,28 @@
1
- import { createElement } from 'react';
1
+ import { createElement, useEffect, useRef } from 'react';
2
2
  import { cx } from '../cx.js';
3
+ let warnedSheetBar = false;
3
4
  /**
4
- * Screen — the mobile screen column: max 25rem wide, the standard horizontal inset, NO vertical padding
5
- * (bars reserve their own room). Every screen is base · top menu · bottom menu · content.
6
- * `fill` makes it one phone height for a Step or a SheetStack; a plain Screen scrolls.
7
- * Put an AppBar/TopBar first, the content next, and an ActionBar AFTER the screen (outside it).
5
+ * Screen — the mobile screen in THREE parts: **top** and **content** (the children) in one flex column, the content down to the
6
+ * screen's foot; **bottom** a LAYER over it there (Lh 2026-09-23). Top = `TopBar` / `AppBar`, or `top="lead"` (no bar, the words start
7
+ * 15% down). Content = a box of components one after another — a `Step` (`Pages` of `Page`s / a `Page` [+ `Sheet`]), a `Centre`, a
8
+ * `SheetStack`… Bottom = an `ActionBar` (the walk's `PagerAt` its first row) or a `FloatBar`, covering the content's foot on purpose. Max 25rem wide, the standard inset, no vertical padding. A plain Screen (no `fill`) scrolls.
9
+ * The slots set the order; children laid by hand in the same order still work.
8
10
  */
9
- export function Screen({ fill, palette, as = 'div', className, ...rest }) {
10
- return createElement(as, { className: cx('screen', fill && 'screen--fill', className), 'data-palette': palette, ...rest });
11
+ export function Screen({ fill, palette, as = 'div', top, bottom, className, children, ref, ...rest }) {
12
+ const own = useRef(null);
13
+ useEffect(() => {
14
+ const el = own.current;
15
+ if (warnedSheetBar || !el || !el.querySelector(':scope > .action-bar') || !el.querySelector(':scope > .step > .sheet'))
16
+ return;
17
+ warnedSheetBar = true;
18
+ console.warn('cardds Screen: a bottom bar on a screen with a Sheet — the sheet finishes on its own foot (CardFoot); drop the bar.');
19
+ });
20
+ const setRef = (node) => {
21
+ own.current = node;
22
+ if (typeof ref === 'function')
23
+ ref(node);
24
+ else if (ref)
25
+ ref.current = node;
26
+ };
27
+ return createElement(as, { className: cx('screen', fill && 'screen--fill', top === 'lead' && 'screen--lead', className), 'data-palette': palette, ref: setRef, ...rest }, top !== 'lead' ? top : null, children, bottom);
11
28
  }
@@ -27,7 +27,7 @@ export interface SheetStackProps extends ComponentProps<'div'> {
27
27
  *
28
28
  * A COMPONENT, not a wiring: WHICH sheet is open is the app's (`open` + `onOpenChange`, or `defaultOpen`) — so a button anywhere, a route or
29
29
  * the phone's back button can open and close a section. Its own behaviour stays inside and only asks: a tap on a peeked head, the open
30
- * sheet's StackBack. How the sheets MOVE is its own too: sheets are rigid — the tapped one slides up, the ones after it leave below, the ones
30
+ * sheet's StackBack or its title (folds it). How the sheets MOVE is its own too: sheets are rigid — the tapped one slides up, the ones after it leave below, the ones
31
31
  * before tuck under nearest-first; closing reverses in two beats. Only `translate` (stack.css); it sets classes, never a size.
32
32
  */
33
33
  export declare function SheetStack({ mode, open, defaultOpen, onOpenChange, fanned, closed, base, className, children, onClick, ...rest }: SheetStackProps): import("react").JSX.Element;
@@ -19,7 +19,7 @@ const sheetsOf = (stack) => [...stack.children]
19
19
  *
20
20
  * A COMPONENT, not a wiring: WHICH sheet is open is the app's (`open` + `onOpenChange`, or `defaultOpen`) — so a button anywhere, a route or
21
21
  * the phone's back button can open and close a section. Its own behaviour stays inside and only asks: a tap on a peeked head, the open
22
- * sheet's StackBack. How the sheets MOVE is its own too: sheets are rigid — the tapped one slides up, the ones after it leave below, the ones
22
+ * sheet's StackBack or its title (folds it). How the sheets MOVE is its own too: sheets are rigid — the tapped one slides up, the ones after it leave below, the ones
23
23
  * before tuck under nearest-first; closing reverses in two beats. Only `translate` (stack.css); it sets classes, never a size.
24
24
  */
25
25
  export function SheetStack({ mode = 'tap', open, defaultOpen = null, onOpenChange, fanned, closed, base, className, children, onClick, ...rest }) {
@@ -79,6 +79,11 @@ export function SheetStack({ mode = 'tap', open, defaultOpen = null, onOpenChang
79
79
  request(null);
80
80
  return;
81
81
  }
82
+ // the open sheet's TITLE folds it too (Lh 2026-09-23) — a bigger target than the back button; the back stays the keyboard's way
83
+ if (current != null && at === current && target.closest('.card__head > :is(h1, h2, h3)')) {
84
+ request(null);
85
+ return;
86
+ }
82
87
  if (at >= 0 && current == null)
83
88
  request(at);
84
89
  };
@@ -6,6 +6,9 @@ export interface SheetStageProps extends ComponentProps<'div'> {
6
6
  hero?: ReactNode;
7
7
  /** blur and darken the background (the dim page sheet) */
8
8
  dim?: boolean;
9
+ /** laid OVER the screen it sits in (a Modal a link or button opened): no ground of its own, the page shows through
10
+ * (dimmed with `dim`), above the screen's bar */
11
+ over?: boolean;
9
12
  /** a footnote strip at the stage's bottom, on the scrim */
10
13
  foot?: ReactNode;
11
14
  }
@@ -15,4 +18,4 @@ export interface SheetStageProps extends ComponentProps<'div'> {
15
18
  * (`dim` + a `Modal`), the ask (`dim` + a `Modal`, which centres itself — or a Modal on a clean ground, no `dim`). Full stops under the top bar's line.
16
19
  * NEVER inside a Step — an app screen where the member acts is a Step.
17
20
  */
18
- export declare function SheetStage({ bg, hero, dim, foot, className, children, ...rest }: SheetStageProps): import("react").JSX.Element;
21
+ export declare function SheetStage({ bg, hero, dim, over, foot, className, children, ...rest }: SheetStageProps): import("react").JSX.Element;
@@ -6,6 +6,6 @@ import { cx } from '../cx.js';
6
6
  * (`dim` + a `Modal`), the ask (`dim` + a `Modal`, which centres itself — or a Modal on a clean ground, no `dim`). Full stops under the top bar's line.
7
7
  * NEVER inside a Step — an app screen where the member acts is a Step.
8
8
  */
9
- export function SheetStage({ bg, hero, dim, foot, className, children, ...rest }) {
10
- return (_jsxs("div", { className: cx('sheet-stage', dim && 'sheet-stage--dim', className), ...rest, children: [bg != null && _jsx("div", { className: "sheet-stage__bg", children: bg }), hero != null && _jsx("div", { className: "sheet-stage__hero", children: hero }), children, foot != null && _jsx("p", { className: "sheet-stage__foot", children: foot })] }));
9
+ export function SheetStage({ bg, hero, dim, over, foot, className, children, ...rest }) {
10
+ return (_jsxs("div", { className: cx('sheet-stage', dim && 'sheet-stage--dim', over && 'sheet-stage--over', className), ...rest, children: [bg != null && _jsx("div", { className: "sheet-stage__bg", children: bg }), hero != null && _jsx("div", { className: "sheet-stage__hero", children: hero }), children, foot != null && _jsx("p", { className: "sheet-stage__foot", children: foot })] }));
11
11
  }
@@ -3,5 +3,6 @@ export interface StackBackProps extends ComponentProps<'button'> {
3
3
  /** accessible name */
4
4
  label?: string;
5
5
  }
6
- /** StackBack — the back button a tapped stack sheet reveals in its head; first child of that sheet's CardHead. Hidden until the sheet is open. */
6
+ /** StackBack — the back button a tapped stack sheet reveals in its head; first child of that sheet's CardHead. Hidden until the sheet is open.
7
+ * A SMALL disc (Lh 2026-09-23): 32px with a chevron — the head keeps its room for the title and the tabs; the 44px tap target stays. */
7
8
  export declare function StackBack({ label, className, ...rest }: StackBackProps): import("react").JSX.Element;
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cx } from '../cx.js';
3
3
  import { Icon } from '../type/Icon.js';
4
- /** StackBack — the back button a tapped stack sheet reveals in its head; first child of that sheet's CardHead. Hidden until the sheet is open. */
4
+ /** StackBack — the back button a tapped stack sheet reveals in its head; first child of that sheet's CardHead. Hidden until the sheet is open.
5
+ * A SMALL disc (Lh 2026-09-23): 32px with a chevron — the head keeps its room for the title and the tabs; the 44px tap target stays. */
5
6
  export function StackBack({ label = 'Back', className, ...rest }) {
6
- return (_jsx("button", { type: "button", className: cx('icon-btn icon-btn--sm sheet-stack__back', className), "aria-label": label, ...rest, children: _jsx(Icon, { name: "arrow-left" }) }));
7
+ return (_jsx("button", { type: "button", className: cx('icon-btn icon-btn--sm sheet-stack__back', className), "aria-label": label, ...rest, children: _jsx(Icon, { name: "chevron-left" }) }));
7
8
  }
@@ -0,0 +1,35 @@
1
+ import { type ComponentProps, type ReactNode } from 'react';
2
+ import { type IconName } from '../type/Icon.js';
3
+ export interface StackSheetTab {
4
+ id: string;
5
+ icon: IconName;
6
+ /** the tab's name, read aloud (the head shows the icon only) */
7
+ label: string;
8
+ /** a small count over the icon: what waits there (alerts, new asks); 0 or none = no circle */
9
+ count?: number;
10
+ }
11
+ export interface StackSheetProps extends Omit<ComponentProps<'article'>, 'title'> {
12
+ /** the SHEET HEAD's title — an h2 (the page's h1 is its own) */
13
+ title: ReactNode;
14
+ /** the paper: 1 light · 2 tinted · 3 dark */
15
+ tone?: 1 | 2 | 3;
16
+ /** the head's end when the sheet has no tabs: an Icon, an IconRow */
17
+ icon?: ReactNode;
18
+ /** TABS in the head: icon buttons at the end — the sheet's pages. A tap on one in a peeked head opens the sheet on it */
19
+ tabs?: StackSheetTab[];
20
+ /** CONTROLLED: the tab shown (its id) — with `onTabChange`; or `defaultTab` (default: the first) */
21
+ tab?: string;
22
+ defaultTab?: string;
23
+ onTabChange?: (tab: string) => void;
24
+ /** the SHEET FOOT: the CTA at the sheet's bottom (one row) */
25
+ foot?: ReactNode;
26
+ /** the back button's label (shown once the sheet is open) */
27
+ backLabel?: string;
28
+ }
29
+ /**
30
+ * StackSheet — ONE sheet of a `SheetStack`, in the one sheet shape: SHEET HEAD (back · title · tabs or an icon) pinned at the top ·
31
+ * SHEET BODY (the children; scrolls) · SHEET FOOT (`foot`, the CTA) at the bottom. Its tabs are icon buttons, the chosen one filled;
32
+ * a count shows as a small circle over its icon. The body is the app's: render the page of the chosen tab (and nothing while the sheet
33
+ * is closed — see `Home`). A direct child of `SheetStack`.
34
+ */
35
+ export declare function StackSheet({ title, tone, icon, tabs, tab: tabProp, defaultTab, onTabChange, foot, backLabel, className, children, ...rest }: StackSheetProps): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { cx } from '../cx.js';
4
+ import { Card } from '../cards/Card.js';
5
+ import { CardHead } from '../cards/CardHead.js';
6
+ import { CardFoot } from '../cards/CardFoot.js';
7
+ import { SheetBody } from './SheetBody.js';
8
+ import { StackBack } from './StackBack.js';
9
+ import { Text } from '../type/Text.js';
10
+ import { Icon } from '../type/Icon.js';
11
+ import { Badge } from '../numbers/Badge.js';
12
+ /**
13
+ * StackSheet — ONE sheet of a `SheetStack`, in the one sheet shape: SHEET HEAD (back · title · tabs or an icon) pinned at the top ·
14
+ * SHEET BODY (the children; scrolls) · SHEET FOOT (`foot`, the CTA) at the bottom. Its tabs are icon buttons, the chosen one filled;
15
+ * a count shows as a small circle over its icon. The body is the app's: render the page of the chosen tab (and nothing while the sheet
16
+ * is closed — see `Home`). A direct child of `SheetStack`.
17
+ */
18
+ export function StackSheet({ title, tone, icon, tabs, tab: tabProp, defaultTab, onTabChange, foot, backLabel = 'Back', className, children, ...rest }) {
19
+ const [own, setOwn] = useState(defaultTab ?? tabs?.[0]?.id);
20
+ const tab = tabProp ?? own;
21
+ const pick = (id) => { if (tabProp === undefined)
22
+ setOwn(id); onTabChange?.(id); };
23
+ return (_jsxs(Card, { tone: tone, className: cx('stack-sheet', className), ...rest, children: [_jsxs(CardHead, { children: [_jsx(StackBack, { label: backLabel }), _jsx(Text, { level: "h2", children: title }), tabs?.length ? (_jsx("span", { className: "stack-sheet__tabs", role: "tablist", children: tabs.map((t) => (_jsxs("button", { type: "button", role: "tab", "aria-selected": t.id === tab, "aria-label": t.label, className: cx('icon-btn icon-btn--sm stack-sheet__tab', t.id === tab && 'icon-btn--invert'), onClick: () => pick(t.id), children: [_jsx(Icon, { name: t.icon }), t.count ? _jsx(Badge, { className: "stack-sheet__count", children: t.count > 99 ? '99+' : t.count }) : null] }, t.id))) })) : icon] }), _jsx(SheetBody, { role: tabs?.length ? 'tabpanel' : undefined, children: children }), foot != null && _jsx(CardFoot, { children: foot })] }));
24
+ }
@@ -2,9 +2,9 @@ import type { ComponentProps } from 'react';
2
2
  export interface StepProps extends ComponentProps<'section'> {
3
3
  }
4
4
  /**
5
- * Step — one screen, one task. Children: a BaseContent first (what the member READS — words on the base, not a card), an optional Sheet last
6
- * (what the member DOES); the ActionBar goes OUTSIDE, after the Step. It fills a `Screen fill` between the top bar
7
- * and the bar's room, bleeds to the screen's edges (the sheet is full-width), and follows its TopBar/AppBar directly.
8
- * Reads → BaseContent only. Acts → BaseContent + Sheet. Never hand-lay a step, never write a sheet height.
5
+ * Step — one screen, one task. Children: a Page first (what the member READS — words on the base, not a card), an optional Sheet last
6
+ * (what the member DOES); the ActionBar is the Screen's `bottom`, after the Step. It is a `Screen fill`'s content: it takes
7
+ * all the height the top and the bottom leave (one flex column), bleeds to the screen's edges (the sheet is full-width), and follows its TopBar/AppBar directly.
8
+ * Reads → Page only. Acts → Page + Sheet. Never hand-lay a step, never write a sheet height.
9
9
  */
10
10
  export declare function Step({ className, ...rest }: StepProps): import("react").JSX.Element;
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cx } from '../cx.js';
3
3
  /**
4
- * Step — one screen, one task. Children: a BaseContent first (what the member READS — words on the base, not a card), an optional Sheet last
5
- * (what the member DOES); the ActionBar goes OUTSIDE, after the Step. It fills a `Screen fill` between the top bar
6
- * and the bar's room, bleeds to the screen's edges (the sheet is full-width), and follows its TopBar/AppBar directly.
7
- * Reads → BaseContent only. Acts → BaseContent + Sheet. Never hand-lay a step, never write a sheet height.
4
+ * Step — one screen, one task. Children: a Page first (what the member READS — words on the base, not a card), an optional Sheet last
5
+ * (what the member DOES); the ActionBar is the Screen's `bottom`, after the Step. It is a `Screen fill`'s content: it takes
6
+ * all the height the top and the bottom leave (one flex column), bleeds to the screen's edges (the sheet is full-width), and follows its TopBar/AppBar directly.
7
+ * Reads → Page only. Acts → Page + Sheet. Never hand-lay a step, never write a sheet height.
8
8
  */
9
9
  export function Step({ className, ...rest }) {
10
10
  return _jsx("section", { className: cx('step', className), ...rest });
@@ -0,0 +1,48 @@
1
+ import { type ComponentProps, type ReactNode } from 'react';
2
+ import { Screen } from '../scaffold/Screen.js';
3
+ import { type StackSheetTab } from '../sheets/StackSheet.js';
4
+ export interface HomeSheet {
5
+ /** the sheet head's title — an h2 (the page's one h1 is in `base`) */
6
+ title: ReactNode;
7
+ /** the sheet head's end when it has no tabs: an Icon, an IconRow */
8
+ icon?: ReactNode;
9
+ /** the paper: 1 light · 2 tinted · 3 dark (default: 2, 3, 1, 2, 3 by place) */
10
+ tone?: 1 | 2 | 3;
11
+ /** the sheet's pages as icon tabs in its head (a count shows as a small circle over the icon) — see `StackSheet` */
12
+ tabs?: StackSheetTab[];
13
+ /** the tab shown first (default: the first) */
14
+ defaultTab?: string;
15
+ /** the SHEET BODY — rendered only while the sheet is open (or kept, with `keep`); a function gets the chosen tab */
16
+ body: ReactNode | ((tab?: string) => ReactNode);
17
+ /** the SHEET FOOT: the CTA at the sheet's bottom (one row); a function gets the chosen tab */
18
+ foot?: ReactNode | ((tab?: string) => ReactNode);
19
+ }
20
+ export interface HomeProps extends Omit<ComponentProps<typeof Screen>, 'children' | 'fill' | 'bottom' | 'title'> {
21
+ /** TOP: the AppBar (the app, the member) */
22
+ top: ReactNode;
23
+ /** the page's title — its one h1, READ BY A SCREEN READER, NOT SHOWN (the design needs no "Home" on the home; the structure does) */
24
+ title: string;
25
+ /** the sections, back of the stack first, at most five */
26
+ sheets: HomeSheet[];
27
+ /** CONTROLLED: the open sheet's index, or null — with `onOpenChange`; or `defaultOpen` */
28
+ open?: number | null;
29
+ defaultOpen?: number | null;
30
+ onOpenChange?: (open: number | null) => void;
31
+ /** CONTENT above the sheet heads — one `Page`: a welcome, the news, a picture. It reads
32
+ * from the top; a sheet coming up covers it */
33
+ base?: ReactNode;
34
+ /** keep a sheet's body mounted after it closes (it opens again at once, scrolled where it was); default: dropped */
35
+ keep?: boolean;
36
+ /** the open sheet's back button label */
37
+ backLabel?: string;
38
+ /** layers over the screen (a SheetStage over + Modal) */
39
+ children?: ReactNode;
40
+ }
41
+ /**
42
+ * Home — TEMPLATE, a `Screen` with its parts filled — top: the AppBar · content: the `base` (title, welcome…) over a closed `SheetStack` · no bottom
43
+ * (the stack is content, never the bottom: open, a sheet fills everything under the top).
44
+ * Every section is a `StackSheet` of three parts: SHEET HEAD (title + icon tabs, a count over a tab; the back button once open) · SHEET BODY (scrolls) · SHEET FOOT (the CTA,
45
+ * at the bottom). A tap on a head brings that sheet up to fill everything under the top. Only the open sheet's body is rendered — three
46
+ * sections on one home never cost three pages (`keep` holds a body once opened).
47
+ */
48
+ export declare function Home({ top, title, sheets, open: openProp, defaultOpen, onOpenChange, base, keep, backLabel, children, ...rest }: HomeProps): import("react").JSX.Element;
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Screen } from '../scaffold/Screen.js';
4
+ import { SheetStack } from '../sheets/SheetStack.js';
5
+ import { StackSheet } from '../sheets/StackSheet.js';
6
+ import { Text } from '../type/Text.js';
7
+ const TONES = [2, 3, 1, 2, 3];
8
+ const LEAVE = 800; // ms: a closing sheet keeps its body until it has slid home
9
+ /**
10
+ * Home — TEMPLATE, a `Screen` with its parts filled — top: the AppBar · content: the `base` (title, welcome…) over a closed `SheetStack` · no bottom
11
+ * (the stack is content, never the bottom: open, a sheet fills everything under the top).
12
+ * Every section is a `StackSheet` of three parts: SHEET HEAD (title + icon tabs, a count over a tab; the back button once open) · SHEET BODY (scrolls) · SHEET FOOT (the CTA,
13
+ * at the bottom). A tap on a head brings that sheet up to fill everything under the top. Only the open sheet's body is rendered — three
14
+ * sections on one home never cost three pages (`keep` holds a body once opened).
15
+ */
16
+ export function Home({ top, title, sheets, open: openProp, defaultOpen = null, onOpenChange, base, keep, backLabel = 'Back', children, ...rest }) {
17
+ const [own, setOwn] = useState(defaultOpen);
18
+ const open = openProp !== undefined ? openProp : own;
19
+ const [leaving, setLeaving] = useState(null);
20
+ const [seen, setSeen] = useState(() => new Set(open != null ? [open] : []));
21
+ const [was, setWas] = useState(open);
22
+ if (was !== open) { // derived during render: which body must stay while its sheet slides home
23
+ if (was != null && open == null)
24
+ setLeaving(was);
25
+ if (open != null && !seen.has(open))
26
+ setSeen(new Set(seen).add(open));
27
+ setWas(open);
28
+ }
29
+ useEffect(() => {
30
+ if (leaving == null)
31
+ return;
32
+ const t = setTimeout(() => setLeaving(null), LEAVE);
33
+ return () => clearTimeout(t);
34
+ }, [leaving]);
35
+ const change = (next) => { if (openProp === undefined)
36
+ setOwn(next); onOpenChange?.(next); };
37
+ const [tabs, setTabs] = useState(() => Object.fromEntries(sheets.map((x, i) => [i, x.defaultTab ?? x.tabs?.[0]?.id])));
38
+ const shows = (i) => i === open || i === leaving || (keep && seen.has(i));
39
+ return (_jsxs(Screen, { fill: true, top: top, ...rest, children: [_jsx(Text, { level: "h1", as: "h1", sr: true, children: title }), _jsx(SheetStack, { closed: true, open: open, onOpenChange: change, base: base, children: sheets.map((s, i) => (_jsx(StackSheet, { tone: s.tone ?? TONES[i], title: s.title, icon: s.icon, tabs: s.tabs, tab: tabs[i], onTabChange: (t) => setTabs((v) => ({ ...v, [i]: t })), backLabel: backLabel, 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] }));
40
+ }
@@ -0,0 +1,42 @@
1
+ import { type ComponentProps, type ReactNode } from 'react';
2
+ import { Screen } from '../scaffold/Screen.js';
3
+ export interface WalkthroughPage {
4
+ /** the picture that opens the page — stays put while the words scroll */
5
+ media: ReactNode;
6
+ /** the page's one heading (h1, no top bar on this screen) */
7
+ heading: ReactNode;
8
+ /** the words: a string is one paragraph; anything else is laid as given */
9
+ body: ReactNode;
10
+ }
11
+ export interface WalkthroughCta {
12
+ at: number;
13
+ count: number;
14
+ /** turn to a page (it slides) */
15
+ go: (to: number) => void;
16
+ }
17
+ export interface WalkthroughProps extends Omit<ComponentProps<typeof Screen>, 'children' | 'fill' | 'top' | 'bottom'> {
18
+ pages: WalkthroughPage[];
19
+ /** the page shown (0-based), controlled — with `onAtChange`; or `defaultAt` */
20
+ at?: number;
21
+ defaultAt?: number;
22
+ onAtChange?: (at: number) => void;
23
+ /** the ONE row of the bottom panel. Omitted: the round pager (back · next). A function gets `{ at, count, go }`,
24
+ * e.g. the pager until the last page, then one wide Btn. */
25
+ cta?: ReactNode | ((c: WalkthroughCta) => ReactNode);
26
+ /** rows of controls ABOVE the CTA row (a text-size Slider…), one row each, top to bottom — keep them few */
27
+ controls?: ReactNode[];
28
+ /** a line UNDER the row: a `Link sm` (e.g. "developer details" that opens a Modal) — centred, one short line */
29
+ ctaLink?: ReactNode;
30
+ /** layers over the screen: the app's `SheetStage dim` + `Modal` that a link or button opens (the app wires it) */
31
+ children?: ReactNode;
32
+ /** the pager's labels */
33
+ backLabel?: string;
34
+ nextLabel?: string;
35
+ }
36
+ /**
37
+ * Walkthrough — TEMPLATE, a `Screen` with its three parts filled — top: `lead` · content: `Pages` (down to the screen's foot) · bottom: a LAYER over it — the dots, then the `ActionBar` rows.
38
+ * A walk of pages that tell (onboarding, an introduction). Each page = a picture, a heading,
39
+ * the words; the dots at the foot; one row of calls to action at the bottom. No top bar. Fixed: the order, the picture
40
+ * first and fixed while the words scroll, one CTA row. Yours: the pages, the row, the state.
41
+ */
42
+ export declare function Walkthrough({ pages, at: atProp, defaultAt, onAtChange, cta, controls, ctaLink, children, backLabel, nextLabel, ...rest }: WalkthroughProps): import("react").JSX.Element;
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useRef, useState } from 'react';
3
+ import { Screen } from '../scaffold/Screen.js';
4
+ import { Step } from '../sheets/Step.js';
5
+ import { Page } from '../scaffold/Page.js';
6
+ import { Pages, slideTo } from '../scaffold/Centre.js';
7
+ import { PagerAt } from '../scaffold/PagerAt.js';
8
+ import { ActionBar, ActionBarTier } from '../scaffold/ActionBar.js';
9
+ import { CardHead } from '../cards/CardHead.js';
10
+ import { Text } from '../type/Text.js';
11
+ import { IconBtn } from '../actions/IconBtn.js';
12
+ /**
13
+ * Walkthrough — TEMPLATE, a `Screen` with its three parts filled — top: `lead` · content: `Pages` (down to the screen's foot) · bottom: a LAYER over it — the dots, then the `ActionBar` rows.
14
+ * A walk of pages that tell (onboarding, an introduction). Each page = a picture, a heading,
15
+ * the words; the dots at the foot; one row of calls to action at the bottom. No top bar. Fixed: the order, the picture
16
+ * first and fixed while the words scroll, one CTA row. Yours: the pages, the row, the state.
17
+ */
18
+ export function Walkthrough({ pages, at: atProp, defaultAt = 0, onAtChange, cta, controls = [], ctaLink, children, backLabel = 'Back', nextLabel = 'Next', ...rest }) {
19
+ const [own, setOwn] = useState(defaultAt);
20
+ const at = atProp ?? own;
21
+ const step = useRef(null);
22
+ const count = pages.length;
23
+ const go = (to) => {
24
+ if (to < 0 || to >= count || to === at)
25
+ return;
26
+ slideTo(to > at ? 'next' : 'back', () => { if (atProp === undefined)
27
+ setOwn(to); onAtChange?.(to); }, step.current ?? document);
28
+ };
29
+ const row = typeof cta === 'function' ? cta({ at, count, go }) : cta;
30
+ const custom = row !== undefined && row !== null;
31
+ const pager = (_jsxs(_Fragment, { children: [_jsx(IconBtn, { icon: "arrow-left", label: backLabel, disabled: at === 0, onClick: () => go(at - 1) }), _jsx(IconBtn, { invert: true, icon: "arrow-right", label: nextLabel, disabled: at === count - 1, onClick: () => go(at + 1) })] }));
32
+ const dots = count > 1 ? _jsx(PagerAt, { at: at + 1, of: count }) : null;
33
+ const bottom = dots || controls.length || ctaLink != null ? (_jsxs(ActionBar, { variant: "tiers", children: [dots, controls.map((c, i) => _jsx(ActionBarTier, { children: c }, i)), _jsx(ActionBarTier, { pager: true, children: custom ? row : pager }), ctaLink != null && _jsx(ActionBarTier, { className: "action-bar__tier--link", children: ctaLink })] })) : (_jsx(ActionBar, { variant: "pager", children: custom ? row : pager }));
34
+ return (_jsxs(Screen, { fill: true, top: "lead", bottom: bottom, ...rest, children: [_jsx(Step, { ref: step, children: _jsx(Pages, { children: pages.map((p, i) => (_jsxs(Page, { "aria-current": i === at ? 'step' : undefined, inert: i !== at || undefined, children: [p.media, _jsx(CardHead, { level: "h1", heading: p.heading }), typeof p.body === 'string' ? _jsx(Text, { level: "body", children: p.body }) : p.body] }, i))) }) }), children] }));
35
+ }
@@ -15,6 +15,8 @@ export interface TextProps extends React.HTMLAttributes<HTMLElement> {
15
15
  /** uppercase */
16
16
  caps?: boolean;
17
17
  /** the element; defaults per level (h2 for display/h1/h2, p for title/body/stat, span for the rest) */
18
+ /** READ, NOT SHOWN: the words stay in the page for a screen reader (a page's h1 that the design does not show), and take no room */
19
+ sr?: boolean;
18
20
  as?: 'h1' | 'h2' | 'h3' | 'p' | 'span' | 'strong' | 'div';
19
21
  }
20
22
  /**
@@ -22,7 +24,7 @@ export interface TextProps extends React.HTMLAttributes<HTMLElement> {
22
24
  * Headings inside a card head are h2 by default; a screen title in a TopBar is h1.
23
25
  * Everything scales from the root font-size, so there are no pixel sizes to pick.
24
26
  */
25
- export declare function Text({ level, xl, mono, muted, caps, grow, as, className, ...rest }: TextProps): import("react").DetailedReactHTMLElement<{
27
+ export declare function Text({ level, xl, mono, muted, caps, grow, sr, as, className, ...rest }: TextProps): import("react").DetailedReactHTMLElement<{
26
28
  /** the element it renders (React 19 passes `ref` as a prop) */
27
29
  ref?: React.Ref<HTMLElement>;
28
30
  defaultChecked?: 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, grow, as, className, ...rest }) {
11
+ export function Text({ level, xl, mono, muted, caps, grow, sr, 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', grow && 'grow', 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', sr && 't-sr', className),
14
14
  ...rest,
15
15
  });
16
16
  }
@@ -1,4 +1,4 @@
1
- export type IconName = "arrow-left" | "arrow-right" | "arrow-up" | "arrow-up-right" | "bell" | "briefcase" | "calendar-days" | "car" | "check" | "chevron-down" | "chevron-left" | "chevron-right" | "chevron-up" | "circle-help" | "clock" | "droplet" | "ellipsis" | "file-text" | "gift" | "handshake" | "heart" | "hourglass" | "house" | "id-card" | "image" | "layout-grid" | "lightbulb" | "luggage" | "map" | "menu" | "message-circle" | "mic" | "music" | "package" | "pencil" | "percent" | "phone-call" | "plane" | "play" | "plus" | "search" | "share" | "shopping-bag" | "siren" | "sliders" | "star" | "store" | "sun" | "thermometer" | "ticket" | "trash" | "truck" | "upload" | "user" | "users" | "wallet" | "x";
1
+ export type IconName = "arrow-left" | "arrow-right" | "arrow-up" | "arrow-up-right" | "bell" | "briefcase" | "calendar-days" | "car" | "check" | "chevron-down" | "chevron-left" | "chevron-right" | "chevron-up" | "circle-help" | "clock" | "droplet" | "ellipsis" | "file-text" | "gift" | "handshake" | "heart" | "hourglass" | "house" | "id-card" | "image" | "layout-grid" | "lightbulb" | "log-out" | "luggage" | "map" | "megaphone" | "menu" | "message-circle" | "mic" | "music" | "package" | "pencil" | "percent" | "phone-call" | "plane" | "play" | "plus" | "search" | "share" | "shopping-bag" | "siren" | "sliders" | "star" | "store" | "sun" | "thermometer" | "ticket" | "trash" | "truck" | "upload" | "user" | "users" | "wallet" | "x";
2
2
  export declare const ICON_NAMES: readonly IconName[];
3
3
  export declare const ICONS: Record<IconName, {
4
4
  attrs: Record<string, string>;
@@ -1,2 +1,2 @@
1
- export const ICON_NAMES = ["arrow-left", "arrow-right", "arrow-up", "arrow-up-right", "bell", "briefcase", "calendar-days", "car", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "circle-help", "clock", "droplet", "ellipsis", "file-text", "gift", "handshake", "heart", "hourglass", "house", "id-card", "image", "layout-grid", "lightbulb", "luggage", "map", "menu", "message-circle", "mic", "music", "package", "pencil", "percent", "phone-call", "plane", "play", "plus", "search", "share", "shopping-bag", "siren", "sliders", "star", "store", "sun", "thermometer", "ticket", "trash", "truck", "upload", "user", "users", "wallet", "x"];
2
- export const ICONS = { "arrow-left": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m12 19-7-7 7-7\" /><path d=\"M19 12H5\" />" }, "arrow-right": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M5 12h14\"/><path d=\"m12 5 7 7-7 7\"/>" }, "arrow-up": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m5 12 7-7 7 7\"/><path d=\"M12 19V5\"/>" }, "arrow-up-right": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M7 7h10v10\" /><path d=\"M7 17 17 7\" />" }, "bell": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M10.268 21a2 2 0 0 0 3.464 0\" /><path d=\"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\" />" }, "briefcase": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\" /><rect width=\"20\" height=\"14\" x=\"2\" y=\"6\" rx=\"2\" />" }, "calendar-days": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M8 2v4\" /><path d=\"M16 2v4\" /><rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\" /><path d=\"M3 10h18\" /><path d=\"M8 14h.01\" /><path d=\"M12 14h.01\" /><path d=\"M16 14h.01\" /><path d=\"M8 18h.01\" /><path d=\"M12 18h.01\" /><path d=\"M16 18h.01\" />" }, "car": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\"/><circle cx=\"7\" cy=\"17\" r=\"2\"/><path d=\"M9 17h6\"/><circle cx=\"17\" cy=\"17\" r=\"2\"/>" }, "check": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M20 6 9 17l-5-5\"/>" }, "chevron-down": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m6 9 6 6 6-6\" />" }, "chevron-left": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m15 18-6-6 6-6\"/>" }, "chevron-right": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m9 18 6-6-6-6\"/>" }, "chevron-up": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m18 15-6-6-6 6\"/>" }, "circle-help": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"/><path d=\"M12 17h.01\"/>" }, "clock": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M12 6v6l4 2\" /><circle cx=\"12\" cy=\"12\" r=\"10\" />" }, "droplet": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z\"/>" }, "ellipsis": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"12\" cy=\"12\" r=\"1\"/><circle cx=\"19\" cy=\"12\" r=\"1\"/><circle cx=\"5\" cy=\"12\" r=\"1\"/>" }, "file-text": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\"/><path d=\"M14 2v4a2 2 0 0 0 2 2h4\"/><path d=\"M10 9H8\"/><path d=\"M16 13H8\"/><path d=\"M16 17H8\"/>" }, "gift": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<rect x=\"3\" y=\"8\" width=\"18\" height=\"4\" rx=\"1\"/><path d=\"M12 8v13\"/><path d=\"M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7\"/><path d=\"M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5\"/>" }, "handshake": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m11 17 2 2a1 1 0 1 0 3-3\"/><path d=\"m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4\"/><path d=\"m21 3 1 11h-2\"/><path d=\"M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3\"/><path d=\"M3 4h8\"/>" }, "heart": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\" />" }, "hourglass": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M5 22h14\"/><path d=\"M5 2h14\"/><path d=\"M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22\"/><path d=\"M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2\"/>" }, "house": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\"/><path d=\"M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>" }, "id-card": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 10h2\"/><path d=\"M16 14h2\"/><path d=\"M6.17 15a3 3 0 0 1 5.66 0\"/><circle cx=\"9\" cy=\"11\" r=\"2\"/><rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\"/>" }, "image": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"/>" }, "layout-grid": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<rect width=\"7\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"/><rect width=\"7\" height=\"7\" x=\"14\" y=\"3\" rx=\"1\"/><rect width=\"7\" height=\"7\" x=\"14\" y=\"14\" rx=\"1\"/><rect width=\"7\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"/>" }, "lightbulb": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1.3.5 2.6 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/>" }, "luggage": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M6 20a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2\" /><path d=\"M8 18V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v14\" /><path d=\"M10 20h4\" /><circle cx=\"16\" cy=\"20\" r=\"2\" /><circle cx=\"8\" cy=\"20\" r=\"2\" />" }, "map": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z\" /><path d=\"M15 5.764v15\" /><path d=\"M9 3.236v15\" />" }, "menu": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M4 12h16\" /><path d=\"M4 18h16\" /><path d=\"M4 6h16\" />" }, "message-circle": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/>" }, "mic": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\"/><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/><line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\"/>" }, "music": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M9 18V5l12-2v13\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><circle cx=\"18\" cy=\"16\" r=\"3\"/>" }, "package": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m7.5 4.27 9 5.15\"/><path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\"/><path d=\"m3.3 7 8.7 5 8.7-5\"/><path d=\"M12 22V12\"/>" }, "pencil": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\"/><path d=\"m15 5 4 4\"/>" }, "percent": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<line x1=\"19\" x2=\"5\" y1=\"5\" y2=\"19\" /><circle cx=\"6.5\" cy=\"6.5\" r=\"2.5\" /><circle cx=\"17.5\" cy=\"17.5\" r=\"2.5\" />" }, "phone-call": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M13 2a9 9 0 0 1 9 9\" /><path d=\"M13 6a5 5 0 0 1 5 5\" /><path d=\"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384\" />" }, "plane": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z\" />" }, "play": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<polygon points=\"6 3 20 12 6 21 6 3\"/>" }, "plus": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M5 12h14\" /><path d=\"M12 5v14\" />" }, "search": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/>" }, "share": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\"/><polyline points=\"16 6 12 2 8 6\"/><line x1=\"12\" x2=\"12\" y1=\"2\" y2=\"15\"/>" }, "shopping-bag": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 10a4 4 0 0 1-8 0\" /><path d=\"M3.103 6.034h17.794\" /><path d=\"M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z\" />" }, "siren": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M7 18v-6a5 5 0 1 1 10 0v6\" /><path d=\"M5 21a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2z\" /><path d=\"M21 12h1\" /><path d=\"M18.5 4.5 18 5\" /><path d=\"M2 12h1\" /><path d=\"M12 2v1\" /><path d=\"m4.929 4.929.707.707\" /><path d=\"M12 12v6\" />" }, "sliders": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<line x1=\"21\" x2=\"14\" y1=\"4\" y2=\"4\"/><line x1=\"10\" x2=\"3\" y1=\"4\" y2=\"4\"/><line x1=\"21\" x2=\"12\" y1=\"12\" y2=\"12\"/><line x1=\"8\" x2=\"3\" y1=\"12\" y2=\"12\"/><line x1=\"21\" x2=\"16\" y1=\"20\" y2=\"20\"/><line x1=\"12\" x2=\"3\" y1=\"20\" y2=\"20\"/><line x1=\"14\" x2=\"14\" y1=\"2\" y2=\"6\"/><line x1=\"8\" x2=\"8\" y1=\"10\" y2=\"14\"/><line x1=\"16\" x2=\"16\" y1=\"18\" y2=\"22\"/>" }, "star": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"/>" }, "store": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m2 7 4.41-4.41A2 2 0 0 1 7.83 2h8.34a2 2 0 0 1 1.42.59L22 7\" /><path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\" /><path d=\"M15 22v-4a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2v4\" /><path d=\"M2 7h20\" /><path d=\"M22 7v3a2 2 0 0 1-2 2a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 16 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 12 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 8 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 4 12a2 2 0 0 1-2-2V7\" />" }, "sun": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2\"/><path d=\"M12 20v2\"/><path d=\"m4.93 4.93 1.41 1.41\"/><path d=\"m17.66 17.66 1.41 1.41\"/><path d=\"M2 12h2\"/><path d=\"M20 12h2\"/><path d=\"m6.34 17.66-1.41 1.41\"/><path d=\"m19.07 4.93-1.41 1.41\"/>" }, "thermometer": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z\"/>" }, "ticket": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\" /><path d=\"M13 5v2\" /><path d=\"M13 17v2\" /><path d=\"M13 11v2\" />" }, "trash": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M3 6h18\"/><path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"/><path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"/><line x1=\"10\" x2=\"10\" y1=\"11\" y2=\"17\"/><line x1=\"14\" x2=\"14\" y1=\"11\" y2=\"17\"/>" }, "truck": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2\"/><path d=\"M15 18H9\"/><path d=\"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14\"/><circle cx=\"17\" cy=\"18\" r=\"2\"/><circle cx=\"7\" cy=\"18\" r=\"2\"/>" }, "upload": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\"/>" }, "user": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\"/><circle cx=\"12\" cy=\"7\" r=\"4\"/>" }, "users": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\"/><circle cx=\"9\" cy=\"7\" r=\"4\"/><path d=\"M22 21v-2a4 4 0 0 0-3-3.87\"/><path d=\"M16 3.13a4 4 0 0 1 0 7.75\"/>" }, "wallet": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1\"/><path d=\"M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4\"/>" }, "x": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />" } };
1
+ export const ICON_NAMES = ["arrow-left", "arrow-right", "arrow-up", "arrow-up-right", "bell", "briefcase", "calendar-days", "car", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "circle-help", "clock", "droplet", "ellipsis", "file-text", "gift", "handshake", "heart", "hourglass", "house", "id-card", "image", "layout-grid", "lightbulb", "log-out", "luggage", "map", "megaphone", "menu", "message-circle", "mic", "music", "package", "pencil", "percent", "phone-call", "plane", "play", "plus", "search", "share", "shopping-bag", "siren", "sliders", "star", "store", "sun", "thermometer", "ticket", "trash", "truck", "upload", "user", "users", "wallet", "x"];
2
+ export const ICONS = { "arrow-left": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m12 19-7-7 7-7\" /><path d=\"M19 12H5\" />" }, "arrow-right": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M5 12h14\"/><path d=\"m12 5 7 7-7 7\"/>" }, "arrow-up": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m5 12 7-7 7 7\"/><path d=\"M12 19V5\"/>" }, "arrow-up-right": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M7 7h10v10\" /><path d=\"M7 17 17 7\" />" }, "bell": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M10.268 21a2 2 0 0 0 3.464 0\" /><path d=\"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\" />" }, "briefcase": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\" /><rect width=\"20\" height=\"14\" x=\"2\" y=\"6\" rx=\"2\" />" }, "calendar-days": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M8 2v4\" /><path d=\"M16 2v4\" /><rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\" /><path d=\"M3 10h18\" /><path d=\"M8 14h.01\" /><path d=\"M12 14h.01\" /><path d=\"M16 14h.01\" /><path d=\"M8 18h.01\" /><path d=\"M12 18h.01\" /><path d=\"M16 18h.01\" />" }, "car": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\"/><circle cx=\"7\" cy=\"17\" r=\"2\"/><path d=\"M9 17h6\"/><circle cx=\"17\" cy=\"17\" r=\"2\"/>" }, "check": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M20 6 9 17l-5-5\"/>" }, "chevron-down": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m6 9 6 6 6-6\" />" }, "chevron-left": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m15 18-6-6 6-6\"/>" }, "chevron-right": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m9 18 6-6-6-6\"/>" }, "chevron-up": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m18 15-6-6-6 6\"/>" }, "circle-help": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"/><path d=\"M12 17h.01\"/>" }, "clock": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M12 6v6l4 2\" /><circle cx=\"12\" cy=\"12\" r=\"10\" />" }, "droplet": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z\"/>" }, "ellipsis": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"12\" cy=\"12\" r=\"1\"/><circle cx=\"19\" cy=\"12\" r=\"1\"/><circle cx=\"5\" cy=\"12\" r=\"1\"/>" }, "file-text": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\"/><path d=\"M14 2v4a2 2 0 0 0 2 2h4\"/><path d=\"M10 9H8\"/><path d=\"M16 13H8\"/><path d=\"M16 17H8\"/>" }, "gift": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<rect x=\"3\" y=\"8\" width=\"18\" height=\"4\" rx=\"1\"/><path d=\"M12 8v13\"/><path d=\"M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7\"/><path d=\"M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5\"/>" }, "handshake": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m11 17 2 2a1 1 0 1 0 3-3\"/><path d=\"m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4\"/><path d=\"m21 3 1 11h-2\"/><path d=\"M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3\"/><path d=\"M3 4h8\"/>" }, "heart": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\" />" }, "hourglass": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M5 22h14\"/><path d=\"M5 2h14\"/><path d=\"M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22\"/><path d=\"M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2\"/>" }, "house": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\"/><path d=\"M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>" }, "id-card": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 10h2\"/><path d=\"M16 14h2\"/><path d=\"M6.17 15a3 3 0 0 1 5.66 0\"/><circle cx=\"9\" cy=\"11\" r=\"2\"/><rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\"/>" }, "image": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"/>" }, "layout-grid": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<rect width=\"7\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"/><rect width=\"7\" height=\"7\" x=\"14\" y=\"3\" rx=\"1\"/><rect width=\"7\" height=\"7\" x=\"14\" y=\"14\" rx=\"1\"/><rect width=\"7\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"/>" }, "lightbulb": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1.3.5 2.6 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/>" }, "log-out": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\"/><polyline points=\"16 17 21 12 16 7\"/><line x1=\"21\" x2=\"9\" y1=\"12\" y2=\"12\"/>" }, "luggage": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M6 20a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2\" /><path d=\"M8 18V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v14\" /><path d=\"M10 20h4\" /><circle cx=\"16\" cy=\"20\" r=\"2\" /><circle cx=\"8\" cy=\"20\" r=\"2\" />" }, "map": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z\" /><path d=\"M15 5.764v15\" /><path d=\"M9 3.236v15\" />" }, "megaphone": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m3 11 18-5v12L3 14v-3z\"/><path d=\"M11.6 16.8a3 3 0 1 1-5.8-1.6\"/>" }, "menu": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M4 12h16\" /><path d=\"M4 18h16\" /><path d=\"M4 6h16\" />" }, "message-circle": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/>" }, "mic": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\"/><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/><line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\"/>" }, "music": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M9 18V5l12-2v13\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><circle cx=\"18\" cy=\"16\" r=\"3\"/>" }, "package": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m7.5 4.27 9 5.15\"/><path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\"/><path d=\"m3.3 7 8.7 5 8.7-5\"/><path d=\"M12 22V12\"/>" }, "pencil": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\"/><path d=\"m15 5 4 4\"/>" }, "percent": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<line x1=\"19\" x2=\"5\" y1=\"5\" y2=\"19\" /><circle cx=\"6.5\" cy=\"6.5\" r=\"2.5\" /><circle cx=\"17.5\" cy=\"17.5\" r=\"2.5\" />" }, "phone-call": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M13 2a9 9 0 0 1 9 9\" /><path d=\"M13 6a5 5 0 0 1 5 5\" /><path d=\"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384\" />" }, "plane": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z\" />" }, "play": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<polygon points=\"6 3 20 12 6 21 6 3\"/>" }, "plus": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M5 12h14\" /><path d=\"M12 5v14\" />" }, "search": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/>" }, "share": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\"/><polyline points=\"16 6 12 2 8 6\"/><line x1=\"12\" x2=\"12\" y1=\"2\" y2=\"15\"/>" }, "shopping-bag": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 10a4 4 0 0 1-8 0\" /><path d=\"M3.103 6.034h17.794\" /><path d=\"M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z\" />" }, "siren": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M7 18v-6a5 5 0 1 1 10 0v6\" /><path d=\"M5 21a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2z\" /><path d=\"M21 12h1\" /><path d=\"M18.5 4.5 18 5\" /><path d=\"M2 12h1\" /><path d=\"M12 2v1\" /><path d=\"m4.929 4.929.707.707\" /><path d=\"M12 12v6\" />" }, "sliders": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<line x1=\"21\" x2=\"14\" y1=\"4\" y2=\"4\"/><line x1=\"10\" x2=\"3\" y1=\"4\" y2=\"4\"/><line x1=\"21\" x2=\"12\" y1=\"12\" y2=\"12\"/><line x1=\"8\" x2=\"3\" y1=\"12\" y2=\"12\"/><line x1=\"21\" x2=\"16\" y1=\"20\" y2=\"20\"/><line x1=\"12\" x2=\"3\" y1=\"20\" y2=\"20\"/><line x1=\"14\" x2=\"14\" y1=\"2\" y2=\"6\"/><line x1=\"8\" x2=\"8\" y1=\"10\" y2=\"14\"/><line x1=\"16\" x2=\"16\" y1=\"18\" y2=\"22\"/>" }, "star": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"/>" }, "store": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"m2 7 4.41-4.41A2 2 0 0 1 7.83 2h8.34a2 2 0 0 1 1.42.59L22 7\" /><path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\" /><path d=\"M15 22v-4a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2v4\" /><path d=\"M2 7h20\" /><path d=\"M22 7v3a2 2 0 0 1-2 2a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 16 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 12 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 8 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 4 12a2 2 0 0 1-2-2V7\" />" }, "sun": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2\"/><path d=\"M12 20v2\"/><path d=\"m4.93 4.93 1.41 1.41\"/><path d=\"m17.66 17.66 1.41 1.41\"/><path d=\"M2 12h2\"/><path d=\"M20 12h2\"/><path d=\"m6.34 17.66-1.41 1.41\"/><path d=\"m19.07 4.93-1.41 1.41\"/>" }, "thermometer": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z\"/>" }, "ticket": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\" /><path d=\"M13 5v2\" /><path d=\"M13 17v2\" /><path d=\"M13 11v2\" />" }, "trash": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M3 6h18\"/><path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"/><path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"/><line x1=\"10\" x2=\"10\" y1=\"11\" y2=\"17\"/><line x1=\"14\" x2=\"14\" y1=\"11\" y2=\"17\"/>" }, "truck": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2\"/><path d=\"M15 18H9\"/><path d=\"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14\"/><circle cx=\"17\" cy=\"18\" r=\"2\"/><circle cx=\"7\" cy=\"18\" r=\"2\"/>" }, "upload": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\"/>" }, "user": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\"/><circle cx=\"12\" cy=\"7\" r=\"4\"/>" }, "users": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\"/><circle cx=\"9\" cy=\"7\" r=\"4\"/><path d=\"M22 21v-2a4 4 0 0 0-3-3.87\"/><path d=\"M16 3.13a4 4 0 0 1 0 7.75\"/>" }, "wallet": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1\"/><path d=\"M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4\"/>" }, "x": { "attrs": { "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "strokeWidth": "2", "strokeLinecap": "round", "strokeLinejoin": "round" }, "body": "<path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />" } };