@hanzo/ui 8.27.18 → 8.27.20
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/backends/gui/apple-cards-carousel.cjs +1 -1
- package/dist/backends/gui/apple-cards-carousel.d.ts.map +1 -1
- package/dist/backends/gui/apple-cards-carousel.js +1 -1
- package/dist/backends/gui/apple-cards-carousel.js.map +1 -1
- package/dist/backends/gui/dialog.cjs +1 -1
- package/dist/backends/gui/dialog.d.ts.map +1 -1
- package/dist/backends/gui/dialog.js +1 -1
- package/dist/backends/gui/dialog.js.map +1 -1
- package/dist/backends/gui/input.cjs +5 -1
- package/dist/backends/gui/input.d.ts.map +1 -1
- package/dist/backends/gui/input.js +5 -1
- package/dist/backends/gui/input.js.map +1 -1
- package/dist/backends/gui/item.cjs +2 -3
- package/dist/backends/gui/item.d.ts.map +1 -1
- package/dist/backends/gui/item.js +1 -2
- package/dist/backends/gui/item.js.map +1 -1
- package/dist/backends/gui/press.cjs +29 -0
- package/dist/backends/gui/press.d.ts +28 -0
- package/dist/backends/gui/press.d.ts.map +1 -0
- package/dist/backends/gui/press.js +26 -0
- package/dist/backends/gui/press.js.map +1 -0
- package/dist/backends/gui/slider.cjs +5 -1
- package/dist/backends/gui/slider.d.ts.map +1 -1
- package/dist/backends/gui/slider.js +5 -1
- package/dist/backends/gui/slider.js.map +1 -1
- package/dist/backends/gui/toggle-group.cjs +2 -3
- package/dist/backends/gui/toggle-group.d.ts.map +1 -1
- package/dist/backends/gui/toggle-group.js +1 -2
- package/dist/backends/gui/toggle-group.js.map +1 -1
- package/dist/backends/gui/toggle.cjs +3 -4
- package/dist/backends/gui/toggle.d.ts.map +1 -1
- package/dist/backends/gui/toggle.js +1 -2
- package/dist/backends/gui/toggle.js.map +1 -1
- package/dist/catalog/Shelf.cjs +76 -0
- package/dist/catalog/Shelf.d.ts +55 -0
- package/dist/catalog/Shelf.d.ts.map +1 -0
- package/dist/catalog/Shelf.js +74 -0
- package/dist/catalog/Shelf.js.map +1 -0
- package/dist/catalog/Tile.cjs +72 -0
- package/dist/catalog/Tile.d.ts +56 -0
- package/dist/catalog/Tile.d.ts.map +1 -0
- package/dist/catalog/Tile.js +67 -0
- package/dist/catalog/Tile.js.map +1 -0
- package/dist/catalog/index.cjs +23 -0
- package/dist/catalog/index.d.ts +16 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +16 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/chat/Home.cjs +30 -0
- package/dist/chat/Home.d.ts +35 -0
- package/dist/chat/Home.d.ts.map +1 -0
- package/dist/chat/Home.js +28 -0
- package/dist/chat/Home.js.map +1 -0
- package/dist/chat/SessionRail.cjs +165 -37
- package/dist/chat/SessionRail.d.ts +92 -14
- package/dist/chat/SessionRail.d.ts.map +1 -1
- package/dist/chat/SessionRail.js +165 -39
- package/dist/chat/SessionRail.js.map +1 -1
- package/dist/chat/index.cjs +6 -1
- package/dist/chat/index.d.ts +2 -1
- package/dist/chat/index.d.ts.map +1 -1
- package/dist/chat/index.js +2 -1
- package/dist/chat/index.js.map +1 -1
- package/dist/gallery.cjs +72 -1
- package/dist/gallery.d.ts +13 -0
- package/dist/gallery.d.ts.map +1 -1
- package/dist/gallery.html +45 -3
- package/dist/gallery.js +72 -2
- package/dist/gallery.js.map +1 -1
- package/dist/product/ChipSelect.cjs +2 -3
- package/dist/product/ChipSelect.d.ts.map +1 -1
- package/dist/product/ChipSelect.js +1 -2
- package/dist/product/ChipSelect.js.map +1 -1
- package/dist/product/MenuRow.cjs +2 -1
- package/dist/product/MenuRow.d.ts +11 -7
- package/dist/product/MenuRow.d.ts.map +1 -1
- package/dist/product/MenuRow.js +3 -2
- package/dist/product/MenuRow.js.map +1 -1
- package/dist/product/OrgSwitcher.cjs +16 -5
- package/dist/product/OrgSwitcher.d.ts.map +1 -1
- package/dist/product/OrgSwitcher.js +16 -5
- package/dist/product/OrgSwitcher.js.map +1 -1
- package/dist/product/UserMenu.cjs +19 -27
- package/dist/product/UserMenu.d.ts +2 -21
- package/dist/product/UserMenu.d.ts.map +1 -1
- package/dist/product/UserMenu.js +23 -31
- package/dist/product/UserMenu.js.map +1 -1
- package/dist/product/account.cjs +37 -0
- package/dist/product/account.d.ts +55 -0
- package/dist/product/account.d.ts.map +1 -0
- package/dist/product/account.js +35 -0
- package/dist/product/account.js.map +1 -0
- package/dist/product/menu/roving.cjs +4 -1
- package/dist/product/menu/roving.d.ts +8 -3
- package/dist/product/menu/roving.d.ts.map +1 -1
- package/dist/product/menu/roving.js +4 -1
- package/dist/product/menu/roving.js.map +1 -1
- package/dist/settings/Section.cjs +71 -0
- package/dist/settings/Section.d.ts +78 -0
- package/dist/settings/Section.d.ts.map +1 -0
- package/dist/settings/Section.js +62 -0
- package/dist/settings/Section.js.map +1 -0
- package/dist/settings/Settings.cjs +54 -0
- package/dist/settings/Settings.d.ts +50 -0
- package/dist/settings/Settings.d.ts.map +1 -0
- package/dist/settings/Settings.js +52 -0
- package/dist/settings/Settings.js.map +1 -0
- package/dist/settings/index.cjs +26 -0
- package/dist/settings/index.d.ts +15 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +15 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/styles.css +42 -0
- package/package.json +13 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use client';"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Shelf = Shelf;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* Shelf — a catalogue page: what an org has, and what it can add, one kind at a
|
|
8
|
+
* time.
|
|
9
|
+
*
|
|
10
|
+
* Customize
|
|
11
|
+
* What the agent brings to a run …
|
|
12
|
+
* ▢ Skills ⌁ Connectors ⧉ Plugins ☺ Agents the kinds, a tablist
|
|
13
|
+
* ─────────
|
|
14
|
+
* [ Yours | Discover ] [ + New skill ]
|
|
15
|
+
* [ Search skills… ]
|
|
16
|
+
* (the cards — `Tiles` of `Tile`s, a `Featured` first)
|
|
17
|
+
*
|
|
18
|
+
* The kinds are a tab strip underlined at the chosen one: one tab stop, arrows
|
|
19
|
+
* move the choice, Home/End jump. Yours/Discover is the package's one segmented
|
|
20
|
+
* control (`Views`, from `@hanzo/ui/agents`), so it is not drawn twice. The
|
|
21
|
+
* search and the Add are the shelf's; what they find and add is the host's.
|
|
22
|
+
*
|
|
23
|
+
* Presentational: the kind, the half and the query come in, every change goes
|
|
24
|
+
* out, and the cards are `children`. On a phone the column takes the width, the
|
|
25
|
+
* tabs drop their icons, and the grid stacks to one card a row.
|
|
26
|
+
*/
|
|
27
|
+
const gui_1 = require("@hanzo/gui");
|
|
28
|
+
const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
|
|
29
|
+
const react_1 = require("react");
|
|
30
|
+
const Workspace_1 = require("../agents/Workspace.cjs");
|
|
31
|
+
const button_1 = require("../backends/gui/button.cjs");
|
|
32
|
+
const input_1 = require("../backends/gui/input.cjs");
|
|
33
|
+
const press_1 = require("../backends/gui/press.cjs");
|
|
34
|
+
const slot_1 = require("../backends/gui/slot.cjs");
|
|
35
|
+
/** The page's measure, px. Three 280px cards and their gaps, with room. */
|
|
36
|
+
const MEASURE = 1080;
|
|
37
|
+
/** What a shelf shows by default: the org's own, and what it can add. */
|
|
38
|
+
const HALVES = [
|
|
39
|
+
{ id: 'yours', label: 'Yours' },
|
|
40
|
+
{ id: 'discover', label: 'Discover' },
|
|
41
|
+
];
|
|
42
|
+
function Shelf({ title, detail, tabs, tab, onTab, views = HALVES, view, onView, search, query, onQuery, add, onAdd, level = 1, children, ...rest }) {
|
|
43
|
+
const refs = (0, react_1.useRef)([]);
|
|
44
|
+
const id = (0, react_1.useId)();
|
|
45
|
+
const panel = `${id}-panel`;
|
|
46
|
+
// The strip's one tab stop is the open kind — or the first, when `tab` names
|
|
47
|
+
// none, so the strip is never unreachable from the keyboard.
|
|
48
|
+
const stop = Math.max(0, tabs.findIndex((t) => t.id === tab));
|
|
49
|
+
const move = (e, index) => {
|
|
50
|
+
const last = tabs.length - 1;
|
|
51
|
+
const to = e.key === 'ArrowRight' ? (index === last ? 0 : index + 1)
|
|
52
|
+
: e.key === 'ArrowLeft' ? (index === 0 ? last : index - 1)
|
|
53
|
+
: e.key === 'Home' ? 0
|
|
54
|
+
: e.key === 'End' ? last
|
|
55
|
+
: -1;
|
|
56
|
+
if (to < 0) {
|
|
57
|
+
// A tab is a button: Enter and Space choose it, which gui does not do for
|
|
58
|
+
// a stack on its own.
|
|
59
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
60
|
+
e.preventDefault?.();
|
|
61
|
+
onTab(tabs[index].id);
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
e.preventDefault?.();
|
|
66
|
+
onTab(tabs[to].id);
|
|
67
|
+
refs.current[to]?.focus();
|
|
68
|
+
};
|
|
69
|
+
return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('shelf'), flex: 1, minH: 0, overflow: "scroll", px: "$6", py: "$6", "$max-md": { px: '$4', py: '$4' }, ...rest, children: (0, jsx_runtime_1.jsxs)(gui_1.YStack, { width: "100%", maxW: MEASURE, mx: "auto", gap: "$4", children: [(0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$1", children: [(0, jsx_runtime_1.jsx)(gui_1.SizableText, { role: "heading", "aria-level": level, size: "$6", color: "$ink", children: title }), detail ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$2", color: "$soft", children: detail })) : null] }), (0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('shelf-tabs'), role: "tablist", "aria-label": title, gap: "$4", borderBottomWidth: 1, borderColor: "$borderColor", "$max-md": { gap: '$3' }, children: tabs.map((t, index) => {
|
|
70
|
+
const on = t.id === tab;
|
|
71
|
+
const Icon = t.icon;
|
|
72
|
+
return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ref: (el) => {
|
|
73
|
+
refs.current[index] = el;
|
|
74
|
+
}, ...(0, slot_1.slot)('shelf-tab'), id: `${id}-tab-${t.id}`, role: "tab", tabIndex: index === stop ? 0 : -1, "aria-selected": on, "aria-controls": on ? panel : undefined, onPress: () => onTab(t.id), onKeyDown: (e) => move(e, index), items: "center", gap: "$1.5", pb: "$2", mb: -1, cursor: "pointer", borderBottomWidth: 2, borderColor: on ? '$ink' : 'transparent', hoverStyle: { borderColor: on ? '$ink' : '$edge' }, focusVisibleStyle: press_1.RING, children: [Icon ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { opacity: on ? 1 : 0.6, "aria-hidden": true, "$max-md": { display: 'none' }, children: (0, jsx_runtime_1.jsx)(Icon, { size: 15 }) })) : null, (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$3", color: on ? '$ink' : '$soft', children: t.label })] }, t.id));
|
|
75
|
+
}) }), (0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('shelf-panel'), id: panel, role: "tabpanel", "aria-labelledby": tabs.some((t) => t.id === tab) ? `${id}-tab-${tab}` : undefined, "aria-label": tabs.some((t) => t.id === tab) ? undefined : title, gap: "$4", children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { items: "center", gap: "$2", children: [(0, jsx_runtime_1.jsx)(Workspace_1.Views, { views: views, value: view, onChange: onView, label: "Show", labels: "all" }), (0, jsx_runtime_1.jsx)(gui_1.XStack, { flex: 1 }), add && onAdd ? ((0, jsx_runtime_1.jsxs)(button_1.Button, { size: "sm", onPress: onAdd, children: [(0, jsx_runtime_1.jsx)(lucide_icons_2_1.Plus, { size: 14 }), " ", add] })) : null] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: query, onChangeText: onQuery, placeholder: `${search}…`, "aria-label": search }), children] })] }) }));
|
|
76
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shelf — a catalogue page: what an org has, and what it can add, one kind at a
|
|
3
|
+
* time.
|
|
4
|
+
*
|
|
5
|
+
* Customize
|
|
6
|
+
* What the agent brings to a run …
|
|
7
|
+
* ▢ Skills ⌁ Connectors ⧉ Plugins ☺ Agents the kinds, a tablist
|
|
8
|
+
* ─────────
|
|
9
|
+
* [ Yours | Discover ] [ + New skill ]
|
|
10
|
+
* [ Search skills… ]
|
|
11
|
+
* (the cards — `Tiles` of `Tile`s, a `Featured` first)
|
|
12
|
+
*
|
|
13
|
+
* The kinds are a tab strip underlined at the chosen one: one tab stop, arrows
|
|
14
|
+
* move the choice, Home/End jump. Yours/Discover is the package's one segmented
|
|
15
|
+
* control (`Views`, from `@hanzo/ui/agents`), so it is not drawn twice. The
|
|
16
|
+
* search and the Add are the shelf's; what they find and add is the host's.
|
|
17
|
+
*
|
|
18
|
+
* Presentational: the kind, the half and the query come in, every change goes
|
|
19
|
+
* out, and the cards are `children`. On a phone the column takes the width, the
|
|
20
|
+
* tabs drop their icons, and the grid stacks to one card a row.
|
|
21
|
+
*/
|
|
22
|
+
import { YStack } from '@hanzo/gui';
|
|
23
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
24
|
+
import { type View } from '../agents/Workspace.js';
|
|
25
|
+
type Col = Omit<ComponentProps<typeof YStack>, 'children'>;
|
|
26
|
+
export interface ShelfProps extends Col {
|
|
27
|
+
/** The page's title. */
|
|
28
|
+
title: string;
|
|
29
|
+
/** One or two lines on what the page is for. */
|
|
30
|
+
detail?: string;
|
|
31
|
+
/** The kinds, as tabs. An icon is a component, drawn at 15px. */
|
|
32
|
+
tabs: readonly View[];
|
|
33
|
+
/** The open kind's id. */
|
|
34
|
+
tab: string;
|
|
35
|
+
onTab: (id: string) => void;
|
|
36
|
+
/** The halves of a kind. Yours and Discover unless given. */
|
|
37
|
+
views?: readonly View[];
|
|
38
|
+
/** The open half's id. */
|
|
39
|
+
view: string;
|
|
40
|
+
onView: (id: string) => void;
|
|
41
|
+
/** The search's name and placeholder — "Search skills". */
|
|
42
|
+
search: string;
|
|
43
|
+
query: string;
|
|
44
|
+
onQuery: (q: string) => void;
|
|
45
|
+
/** The Add action's words — "New skill". None, and there is no Add. */
|
|
46
|
+
add?: string;
|
|
47
|
+
onAdd?: () => void;
|
|
48
|
+
/** The title's outline level. */
|
|
49
|
+
level?: 1 | 2;
|
|
50
|
+
/** The cards. */
|
|
51
|
+
children?: ReactNode;
|
|
52
|
+
}
|
|
53
|
+
export declare function Shelf({ title, detail, tabs, tab, onTab, views, view, onView, search, query, onQuery, add, onAdd, level, children, ...rest }: ShelfProps): import("react").JSX.Element;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=Shelf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Shelf.d.ts","sourceRoot":"","sources":["../../src/catalog/Shelf.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAuB,MAAM,EAAE,MAAM,YAAY,CAAA;AAExD,OAAO,EAAiB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAE1E,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAMtD,KAAK,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,CAAA;AAW1D,MAAM,WAAW,UAAW,SAAQ,GAAG;IACrC,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iEAAiE;IACjE,IAAI,EAAE,SAAS,IAAI,EAAE,CAAA;IACrB,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,CAAA;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACb,iBAAiB;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,MAAM,EACN,IAAI,EACJ,GAAG,EACH,KAAK,EACL,KAAc,EACd,IAAI,EACJ,MAAM,EACN,MAAM,EACN,KAAK,EACL,OAAO,EACP,GAAG,EACH,KAAK,EACL,KAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,UAAU,+BA8HZ"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Shelf — a catalogue page: what an org has, and what it can add, one kind at a
|
|
5
|
+
* time.
|
|
6
|
+
*
|
|
7
|
+
* Customize
|
|
8
|
+
* What the agent brings to a run …
|
|
9
|
+
* ▢ Skills ⌁ Connectors ⧉ Plugins ☺ Agents the kinds, a tablist
|
|
10
|
+
* ─────────
|
|
11
|
+
* [ Yours | Discover ] [ + New skill ]
|
|
12
|
+
* [ Search skills… ]
|
|
13
|
+
* (the cards — `Tiles` of `Tile`s, a `Featured` first)
|
|
14
|
+
*
|
|
15
|
+
* The kinds are a tab strip underlined at the chosen one: one tab stop, arrows
|
|
16
|
+
* move the choice, Home/End jump. Yours/Discover is the package's one segmented
|
|
17
|
+
* control (`Views`, from `@hanzo/ui/agents`), so it is not drawn twice. The
|
|
18
|
+
* search and the Add are the shelf's; what they find and add is the host's.
|
|
19
|
+
*
|
|
20
|
+
* Presentational: the kind, the half and the query come in, every change goes
|
|
21
|
+
* out, and the cards are `children`. On a phone the column takes the width, the
|
|
22
|
+
* tabs drop their icons, and the grid stacks to one card a row.
|
|
23
|
+
*/
|
|
24
|
+
import { SizableText, XStack, YStack } from '@hanzo/gui';
|
|
25
|
+
import { Plus } from '@hanzogui/lucide-icons-2';
|
|
26
|
+
import { useId, useRef } from 'react';
|
|
27
|
+
import { Views } from '../agents/Workspace.js';
|
|
28
|
+
import { Button } from '../backends/gui/button.js';
|
|
29
|
+
import { Input } from '../backends/gui/input.js';
|
|
30
|
+
import { RING } from '../backends/gui/press.js';
|
|
31
|
+
import { slot } from '../backends/gui/slot.js';
|
|
32
|
+
/** The page's measure, px. Three 280px cards and their gaps, with room. */
|
|
33
|
+
const MEASURE = 1080;
|
|
34
|
+
/** What a shelf shows by default: the org's own, and what it can add. */
|
|
35
|
+
const HALVES = [
|
|
36
|
+
{ id: 'yours', label: 'Yours' },
|
|
37
|
+
{ id: 'discover', label: 'Discover' },
|
|
38
|
+
];
|
|
39
|
+
export function Shelf({ title, detail, tabs, tab, onTab, views = HALVES, view, onView, search, query, onQuery, add, onAdd, level = 1, children, ...rest }) {
|
|
40
|
+
const refs = useRef([]);
|
|
41
|
+
const id = useId();
|
|
42
|
+
const panel = `${id}-panel`;
|
|
43
|
+
// The strip's one tab stop is the open kind — or the first, when `tab` names
|
|
44
|
+
// none, so the strip is never unreachable from the keyboard.
|
|
45
|
+
const stop = Math.max(0, tabs.findIndex((t) => t.id === tab));
|
|
46
|
+
const move = (e, index) => {
|
|
47
|
+
const last = tabs.length - 1;
|
|
48
|
+
const to = e.key === 'ArrowRight' ? (index === last ? 0 : index + 1)
|
|
49
|
+
: e.key === 'ArrowLeft' ? (index === 0 ? last : index - 1)
|
|
50
|
+
: e.key === 'Home' ? 0
|
|
51
|
+
: e.key === 'End' ? last
|
|
52
|
+
: -1;
|
|
53
|
+
if (to < 0) {
|
|
54
|
+
// A tab is a button: Enter and Space choose it, which gui does not do for
|
|
55
|
+
// a stack on its own.
|
|
56
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
57
|
+
e.preventDefault?.();
|
|
58
|
+
onTab(tabs[index].id);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
e.preventDefault?.();
|
|
63
|
+
onTab(tabs[to].id);
|
|
64
|
+
refs.current[to]?.focus();
|
|
65
|
+
};
|
|
66
|
+
return (_jsx(YStack, { ...slot('shelf'), flex: 1, minH: 0, overflow: "scroll", px: "$6", py: "$6", "$max-md": { px: '$4', py: '$4' }, ...rest, children: _jsxs(YStack, { width: "100%", maxW: MEASURE, mx: "auto", gap: "$4", children: [_jsxs(YStack, { gap: "$1", children: [_jsx(SizableText, { role: "heading", "aria-level": level, size: "$6", color: "$ink", children: title }), detail ? (_jsx(SizableText, { size: "$2", color: "$soft", children: detail })) : null] }), _jsx(XStack, { ...slot('shelf-tabs'), role: "tablist", "aria-label": title, gap: "$4", borderBottomWidth: 1, borderColor: "$borderColor", "$max-md": { gap: '$3' }, children: tabs.map((t, index) => {
|
|
67
|
+
const on = t.id === tab;
|
|
68
|
+
const Icon = t.icon;
|
|
69
|
+
return (_jsxs(XStack, { ref: (el) => {
|
|
70
|
+
refs.current[index] = el;
|
|
71
|
+
}, ...slot('shelf-tab'), id: `${id}-tab-${t.id}`, role: "tab", tabIndex: index === stop ? 0 : -1, "aria-selected": on, "aria-controls": on ? panel : undefined, onPress: () => onTab(t.id), onKeyDown: (e) => move(e, index), items: "center", gap: "$1.5", pb: "$2", mb: -1, cursor: "pointer", borderBottomWidth: 2, borderColor: on ? '$ink' : 'transparent', hoverStyle: { borderColor: on ? '$ink' : '$edge' }, focusVisibleStyle: RING, children: [Icon ? (_jsx(XStack, { opacity: on ? 1 : 0.6, "aria-hidden": true, "$max-md": { display: 'none' }, children: _jsx(Icon, { size: 15 }) })) : null, _jsx(SizableText, { size: "$3", color: on ? '$ink' : '$soft', children: t.label })] }, t.id));
|
|
72
|
+
}) }), _jsxs(YStack, { ...slot('shelf-panel'), id: panel, role: "tabpanel", "aria-labelledby": tabs.some((t) => t.id === tab) ? `${id}-tab-${tab}` : undefined, "aria-label": tabs.some((t) => t.id === tab) ? undefined : title, gap: "$4", children: [_jsxs(XStack, { items: "center", gap: "$2", children: [_jsx(Views, { views: views, value: view, onChange: onView, label: "Show", labels: "all" }), _jsx(XStack, { flex: 1 }), add && onAdd ? (_jsxs(Button, { size: "sm", onPress: onAdd, children: [_jsx(Plus, { size: 14 }), " ", add] })) : null] }), _jsx(Input, { value: query, onChangeText: onQuery, placeholder: `${search}…`, "aria-label": search }), children] })] }) }));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=Shelf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Shelf.js","sourceRoot":"","sources":["../../src/catalog/Shelf.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use client';"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Tiles = Tiles;
|
|
5
|
+
exports.Tile = Tile;
|
|
6
|
+
exports.Featured = Featured;
|
|
7
|
+
exports.Add = Add;
|
|
8
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
9
|
+
/**
|
|
10
|
+
* The cards on a `Shelf`.
|
|
11
|
+
*
|
|
12
|
+
* Tiles the cards, in as many columns as fit — one on a phone
|
|
13
|
+
* Tile one card: its mark, what it is, a few lines, a quiet fact, and
|
|
14
|
+
* its one action at the top right
|
|
15
|
+
* Featured the one card a shelf puts first, drawn larger
|
|
16
|
+
* Add a card's action: a plus while it is not yours, a check once it is
|
|
17
|
+
*
|
|
18
|
+
* Pressing a card opens it; its action is its own control BESIDE that press,
|
|
19
|
+
* never inside it — a button in a button is two targets that fight.
|
|
20
|
+
*
|
|
21
|
+
* `Tiles` lays out on the package's one grid (`@hanzo/ui/grid`), whose `{ min }`
|
|
22
|
+
* track is `repeat(auto-fill, minmax(min(280px, 100%), 1fr))`: as many columns
|
|
23
|
+
* as fit, and never a track wider than a phone. That grid is a `div` with
|
|
24
|
+
* `display: grid`, so this module is web-only, like the grid itself.
|
|
25
|
+
*/
|
|
26
|
+
const gui_1 = require("@hanzo/gui");
|
|
27
|
+
const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
|
|
28
|
+
const react_1 = require("react");
|
|
29
|
+
const button_1 = require("../backends/gui/button.cjs");
|
|
30
|
+
const press_1 = require("../backends/gui/press.cjs");
|
|
31
|
+
const slot_1 = require("../backends/gui/slot.cjs");
|
|
32
|
+
const grid_1 = require("../grid.cjs");
|
|
33
|
+
/** A card's narrowest column, px. */
|
|
34
|
+
const MIN = 280;
|
|
35
|
+
/** A press that holds a card's words reads from the left. */
|
|
36
|
+
const LEFT = { textAlign: 'left' };
|
|
37
|
+
/** The cards, in as many columns as fit, one on a phone. A list of `Tile`s. */
|
|
38
|
+
function Tiles({ label, min = MIN, children }) {
|
|
39
|
+
return ((0, jsx_runtime_1.jsx)(grid_1.Grid, { role: "list", "aria-label": label, columns: { min }, gap: 12, children: children }));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The press's name is the title and its description the lines under it: named
|
|
43
|
+
* by `aria-label` alone, a reader heard "git_repos, button" and never what it
|
|
44
|
+
* does or where it comes from.
|
|
45
|
+
*/
|
|
46
|
+
const told = (id, ...parts) => {
|
|
47
|
+
const ids = parts.filter(([, v]) => v).map(([k]) => `${id}-${k}`);
|
|
48
|
+
return ids.length ? ids.join(' ') : undefined;
|
|
49
|
+
};
|
|
50
|
+
/** One card: what it is, a few lines about it, a quiet fact, and its action. */
|
|
51
|
+
function Tile({ title, detail, meta, mark, action, onOpen }) {
|
|
52
|
+
const id = (0, react_1.useId)();
|
|
53
|
+
const body = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [mark, (0, jsx_runtime_1.jsxs)(gui_1.YStack, { flex: 1, minW: 0, gap: "$1", children: [(0, jsx_runtime_1.jsx)(gui_1.SizableText, { id: `${id}-title`, size: "$3", color: "$ink", numberOfLines: 1, children: title }), detail ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { id: `${id}-detail`, size: "$1", color: "$soft", numberOfLines: 3, children: detail })) : null, meta ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { id: `${id}-meta`, size: "$1", color: "$soft", numberOfLines: 1, opacity: 0.8, children: meta })) : null] })] }));
|
|
54
|
+
return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('tile'), role: "listitem", items: "flex-start", gap: "$2", p: "$3", minW: 0, rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", hoverStyle: onOpen ? { borderColor: '$edge' } : undefined, children: [onOpen ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('tile-open'), ...(0, press_1.press)(onOpen), "aria-labelledby": `${id}-title`, "aria-describedby": told(id, ['detail', detail], ['meta', meta]), flex: 1, minW: 0, gap: "$3", items: "flex-start", cursor: "pointer", rounded: "$2", style: LEFT, focusVisibleStyle: press_1.RING, children: body })) : ((0, jsx_runtime_1.jsx)(gui_1.XStack, { flex: 1, minW: 0, gap: "$3", items: "flex-start", children: body })), action] }));
|
|
55
|
+
}
|
|
56
|
+
/** The one card the shelf puts first, drawn larger. Its action wraps under it on a phone. */
|
|
57
|
+
function Featured({ title, detail, meta, mark, action, onOpen, tag = 'Featured' }) {
|
|
58
|
+
const id = (0, react_1.useId)();
|
|
59
|
+
return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('featured'), items: "flex-start", gap: "$4", p: "$4", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", flexWrap: "wrap", rowGap: "$3", children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('featured-open'), ...(0, press_1.press)(onOpen), "aria-labelledby": `${id}-title`, "aria-describedby": told(id, ['tag', tag], ['detail', detail], ['meta', meta]), flex: 1, minW: 220, gap: "$4", items: "flex-start", cursor: "pointer", rounded: "$2", style: LEFT, focusVisibleStyle: press_1.RING, children: [mark, (0, jsx_runtime_1.jsxs)(gui_1.YStack, { flex: 1, minW: 0, gap: "$1.5", children: [(0, jsx_runtime_1.jsx)(gui_1.SizableText, { id: `${id}-tag`, size: "$1", color: "$soft", textTransform: "uppercase", letterSpacing: 1, children: tag }), (0, jsx_runtime_1.jsx)(gui_1.SizableText, { id: `${id}-title`, size: "$6", color: "$ink", numberOfLines: 1, children: title }), (0, jsx_runtime_1.jsx)(gui_1.SizableText, { id: `${id}-detail`, size: "$2", color: "$soft", numberOfLines: 3, children: detail }), meta ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { id: `${id}-meta`, size: "$1", color: "$soft", numberOfLines: 1, children: meta })) : null] })] }), action] }));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A card's add control: a plus while it is not yours, a check once it is.
|
|
63
|
+
*
|
|
64
|
+
* ONE button through all three states, so focus stays where it was: swapping
|
|
65
|
+
* the button for a bare check (or `disabled`, which drops focus) sent a
|
|
66
|
+
* keyboard user back to the top of the page the moment the add landed. Busy and
|
|
67
|
+
* added are `aria-disabled` — still focusable, still named, inert.
|
|
68
|
+
*/
|
|
69
|
+
function Add({ name, added, busy, onPress }) {
|
|
70
|
+
const inert = added || busy;
|
|
71
|
+
return ((0, jsx_runtime_1.jsx)(button_1.Button, { size: "icon-sm", variant: added ? 'ghost' : 'outline', "aria-label": added ? `${name} is added` : `Add ${name}`, "aria-disabled": inert || undefined, "aria-busy": busy || undefined, onPress: inert ? undefined : onPress, opacity: busy ? 0.5 : 1, cursor: inert ? 'default' : 'pointer', hoverStyle: added ? { bg: 'transparent' } : undefined, children: added ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Check, { size: 16 }) : (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Plus, { size: 14 }) }));
|
|
72
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface TilesProps {
|
|
3
|
+
/** Names the list — "Skills to add". */
|
|
4
|
+
label: string;
|
|
5
|
+
/** Narrowest a column gets before the grid drops one, px. */
|
|
6
|
+
min?: number;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/** The cards, in as many columns as fit, one on a phone. A list of `Tile`s. */
|
|
10
|
+
export declare function Tiles({ label, min, children }: TilesProps): import("react").JSX.Element;
|
|
11
|
+
export interface TileProps {
|
|
12
|
+
title: string;
|
|
13
|
+
/** A few lines about it; clamped at three. */
|
|
14
|
+
detail?: string;
|
|
15
|
+
/** A quiet fact under them — where it comes from, when it was saved. */
|
|
16
|
+
meta?: string;
|
|
17
|
+
/** Its picture, ~32px square. */
|
|
18
|
+
mark?: ReactNode;
|
|
19
|
+
/** Its one control, at the top right — an `Add`, a switch. */
|
|
20
|
+
action?: ReactNode;
|
|
21
|
+
/** Pressing the card. None, and the card is words only. */
|
|
22
|
+
onOpen?: () => void;
|
|
23
|
+
}
|
|
24
|
+
/** One card: what it is, a few lines about it, a quiet fact, and its action. */
|
|
25
|
+
export declare function Tile({ title, detail, meta, mark, action, onOpen }: TileProps): import("react").JSX.Element;
|
|
26
|
+
export interface FeaturedProps {
|
|
27
|
+
title: string;
|
|
28
|
+
detail: string;
|
|
29
|
+
meta?: string;
|
|
30
|
+
mark: ReactNode;
|
|
31
|
+
action?: ReactNode;
|
|
32
|
+
onOpen: () => void;
|
|
33
|
+
/** The word over the title. */
|
|
34
|
+
tag?: string;
|
|
35
|
+
}
|
|
36
|
+
/** The one card the shelf puts first, drawn larger. Its action wraps under it on a phone. */
|
|
37
|
+
export declare function Featured({ title, detail, meta, mark, action, onOpen, tag }: FeaturedProps): import("react").JSX.Element;
|
|
38
|
+
export interface AddProps {
|
|
39
|
+
/** What is added — names the control ("Add git_repos") and the check. */
|
|
40
|
+
name: string;
|
|
41
|
+
/** It is already yours: a check, not a control. */
|
|
42
|
+
added: boolean;
|
|
43
|
+
/** A request is in flight. */
|
|
44
|
+
busy?: boolean;
|
|
45
|
+
onPress: () => void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A card's add control: a plus while it is not yours, a check once it is.
|
|
49
|
+
*
|
|
50
|
+
* ONE button through all three states, so focus stays where it was: swapping
|
|
51
|
+
* the button for a bare check (or `disabled`, which drops focus) sent a
|
|
52
|
+
* keyboard user back to the top of the page the moment the add landed. Busy and
|
|
53
|
+
* added are `aria-disabled` — still focusable, still named, inert.
|
|
54
|
+
*/
|
|
55
|
+
export declare function Add({ name, added, busy, onPress }: AddProps): import("react").JSX.Element;
|
|
56
|
+
//# sourceMappingURL=Tile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tile.d.ts","sourceRoot":"","sources":["../../src/catalog/Tile.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAa7C,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,+EAA+E;AAC/E,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,GAAS,EAAE,QAAQ,EAAE,EAAE,UAAU,+BAM/D;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAYD,gFAAgF;AAChF,wBAAgB,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,+BA6D5E;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,6FAA6F;AAC7F,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAgB,EAAE,EAAE,aAAa,+BAkDtG;AAED,MAAM,WAAW,QAAQ;IACvB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,KAAK,EAAE,OAAO,CAAA;IACd,8BAA8B;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,QAAQ,+BAiB3D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* The cards on a `Shelf`.
|
|
5
|
+
*
|
|
6
|
+
* Tiles the cards, in as many columns as fit — one on a phone
|
|
7
|
+
* Tile one card: its mark, what it is, a few lines, a quiet fact, and
|
|
8
|
+
* its one action at the top right
|
|
9
|
+
* Featured the one card a shelf puts first, drawn larger
|
|
10
|
+
* Add a card's action: a plus while it is not yours, a check once it is
|
|
11
|
+
*
|
|
12
|
+
* Pressing a card opens it; its action is its own control BESIDE that press,
|
|
13
|
+
* never inside it — a button in a button is two targets that fight.
|
|
14
|
+
*
|
|
15
|
+
* `Tiles` lays out on the package's one grid (`@hanzo/ui/grid`), whose `{ min }`
|
|
16
|
+
* track is `repeat(auto-fill, minmax(min(280px, 100%), 1fr))`: as many columns
|
|
17
|
+
* as fit, and never a track wider than a phone. That grid is a `div` with
|
|
18
|
+
* `display: grid`, so this module is web-only, like the grid itself.
|
|
19
|
+
*/
|
|
20
|
+
import { SizableText, XStack, YStack } from '@hanzo/gui';
|
|
21
|
+
import { Check, Plus } from '@hanzogui/lucide-icons-2';
|
|
22
|
+
import { useId } from 'react';
|
|
23
|
+
import { Button } from '../backends/gui/button.js';
|
|
24
|
+
import { press, RING } from '../backends/gui/press.js';
|
|
25
|
+
import { slot } from '../backends/gui/slot.js';
|
|
26
|
+
import { Grid } from '../grid.js';
|
|
27
|
+
/** A card's narrowest column, px. */
|
|
28
|
+
const MIN = 280;
|
|
29
|
+
/** A press that holds a card's words reads from the left. */
|
|
30
|
+
const LEFT = { textAlign: 'left' };
|
|
31
|
+
/** The cards, in as many columns as fit, one on a phone. A list of `Tile`s. */
|
|
32
|
+
export function Tiles({ label, min = MIN, children }) {
|
|
33
|
+
return (_jsx(Grid, { role: "list", "aria-label": label, columns: { min }, gap: 12, children: children }));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The press's name is the title and its description the lines under it: named
|
|
37
|
+
* by `aria-label` alone, a reader heard "git_repos, button" and never what it
|
|
38
|
+
* does or where it comes from.
|
|
39
|
+
*/
|
|
40
|
+
const told = (id, ...parts) => {
|
|
41
|
+
const ids = parts.filter(([, v]) => v).map(([k]) => `${id}-${k}`);
|
|
42
|
+
return ids.length ? ids.join(' ') : undefined;
|
|
43
|
+
};
|
|
44
|
+
/** One card: what it is, a few lines about it, a quiet fact, and its action. */
|
|
45
|
+
export function Tile({ title, detail, meta, mark, action, onOpen }) {
|
|
46
|
+
const id = useId();
|
|
47
|
+
const body = (_jsxs(_Fragment, { children: [mark, _jsxs(YStack, { flex: 1, minW: 0, gap: "$1", children: [_jsx(SizableText, { id: `${id}-title`, size: "$3", color: "$ink", numberOfLines: 1, children: title }), detail ? (_jsx(SizableText, { id: `${id}-detail`, size: "$1", color: "$soft", numberOfLines: 3, children: detail })) : null, meta ? (_jsx(SizableText, { id: `${id}-meta`, size: "$1", color: "$soft", numberOfLines: 1, opacity: 0.8, children: meta })) : null] })] }));
|
|
48
|
+
return (_jsxs(XStack, { ...slot('tile'), role: "listitem", items: "flex-start", gap: "$2", p: "$3", minW: 0, rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", hoverStyle: onOpen ? { borderColor: '$edge' } : undefined, children: [onOpen ? (_jsx(XStack, { ...slot('tile-open'), ...press(onOpen), "aria-labelledby": `${id}-title`, "aria-describedby": told(id, ['detail', detail], ['meta', meta]), flex: 1, minW: 0, gap: "$3", items: "flex-start", cursor: "pointer", rounded: "$2", style: LEFT, focusVisibleStyle: RING, children: body })) : (_jsx(XStack, { flex: 1, minW: 0, gap: "$3", items: "flex-start", children: body })), action] }));
|
|
49
|
+
}
|
|
50
|
+
/** The one card the shelf puts first, drawn larger. Its action wraps under it on a phone. */
|
|
51
|
+
export function Featured({ title, detail, meta, mark, action, onOpen, tag = 'Featured' }) {
|
|
52
|
+
const id = useId();
|
|
53
|
+
return (_jsxs(XStack, { ...slot('featured'), items: "flex-start", gap: "$4", p: "$4", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", flexWrap: "wrap", rowGap: "$3", children: [_jsxs(XStack, { ...slot('featured-open'), ...press(onOpen), "aria-labelledby": `${id}-title`, "aria-describedby": told(id, ['tag', tag], ['detail', detail], ['meta', meta]), flex: 1, minW: 220, gap: "$4", items: "flex-start", cursor: "pointer", rounded: "$2", style: LEFT, focusVisibleStyle: RING, children: [mark, _jsxs(YStack, { flex: 1, minW: 0, gap: "$1.5", children: [_jsx(SizableText, { id: `${id}-tag`, size: "$1", color: "$soft", textTransform: "uppercase", letterSpacing: 1, children: tag }), _jsx(SizableText, { id: `${id}-title`, size: "$6", color: "$ink", numberOfLines: 1, children: title }), _jsx(SizableText, { id: `${id}-detail`, size: "$2", color: "$soft", numberOfLines: 3, children: detail }), meta ? (_jsx(SizableText, { id: `${id}-meta`, size: "$1", color: "$soft", numberOfLines: 1, children: meta })) : null] })] }), action] }));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A card's add control: a plus while it is not yours, a check once it is.
|
|
57
|
+
*
|
|
58
|
+
* ONE button through all three states, so focus stays where it was: swapping
|
|
59
|
+
* the button for a bare check (or `disabled`, which drops focus) sent a
|
|
60
|
+
* keyboard user back to the top of the page the moment the add landed. Busy and
|
|
61
|
+
* added are `aria-disabled` — still focusable, still named, inert.
|
|
62
|
+
*/
|
|
63
|
+
export function Add({ name, added, busy, onPress }) {
|
|
64
|
+
const inert = added || busy;
|
|
65
|
+
return (_jsx(Button, { size: "icon-sm", variant: added ? 'ghost' : 'outline', "aria-label": added ? `${name} is added` : `Add ${name}`, "aria-disabled": inert || undefined, "aria-busy": busy || undefined, onPress: inert ? undefined : onPress, opacity: busy ? 0.5 : 1, cursor: inert ? 'default' : 'pointer', hoverStyle: added ? { bg: 'transparent' } : undefined, children: added ? _jsx(Check, { size: 16 }) : _jsx(Plus, { size: 14 }) }));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=Tile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tile.js","sourceRoot":"","sources":["../../src/catalog/Tile.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Tiles = exports.Tile = exports.Featured = exports.Add = exports.Shelf = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @hanzo/ui/catalog — a catalogue page: what an org has, and what it can add.
|
|
6
|
+
*
|
|
7
|
+
* `Shelf` is the page — title, the kinds as tabs, Yours/Discover, one search
|
|
8
|
+
* and one Add over both — and the cards are its `children`: `Tiles` of `Tile`s,
|
|
9
|
+
* a `Featured` first, each with an `Add`.
|
|
10
|
+
*
|
|
11
|
+
* Web-only, and off `@hanzo/ui/product` for it: `Tiles` lays out on
|
|
12
|
+
* `@hanzo/ui/grid` (a `div` with `display: grid`), which the cross-platform
|
|
13
|
+
* product layer cannot promise. The section parts a tab draws around its cards
|
|
14
|
+
* — `Group`, `Soft`, `Note`, `Field` — are `@hanzo/ui/settings`'s, one set for
|
|
15
|
+
* every page.
|
|
16
|
+
*/
|
|
17
|
+
var Shelf_1 = require("./Shelf.cjs");
|
|
18
|
+
Object.defineProperty(exports, "Shelf", { enumerable: true, get: function () { return Shelf_1.Shelf; } });
|
|
19
|
+
var Tile_1 = require("./Tile.cjs");
|
|
20
|
+
Object.defineProperty(exports, "Add", { enumerable: true, get: function () { return Tile_1.Add; } });
|
|
21
|
+
Object.defineProperty(exports, "Featured", { enumerable: true, get: function () { return Tile_1.Featured; } });
|
|
22
|
+
Object.defineProperty(exports, "Tile", { enumerable: true, get: function () { return Tile_1.Tile; } });
|
|
23
|
+
Object.defineProperty(exports, "Tiles", { enumerable: true, get: function () { return Tile_1.Tiles; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hanzo/ui/catalog — a catalogue page: what an org has, and what it can add.
|
|
3
|
+
*
|
|
4
|
+
* `Shelf` is the page — title, the kinds as tabs, Yours/Discover, one search
|
|
5
|
+
* and one Add over both — and the cards are its `children`: `Tiles` of `Tile`s,
|
|
6
|
+
* a `Featured` first, each with an `Add`.
|
|
7
|
+
*
|
|
8
|
+
* Web-only, and off `@hanzo/ui/product` for it: `Tiles` lays out on
|
|
9
|
+
* `@hanzo/ui/grid` (a `div` with `display: grid`), which the cross-platform
|
|
10
|
+
* product layer cannot promise. The section parts a tab draws around its cards
|
|
11
|
+
* — `Group`, `Soft`, `Note`, `Field` — are `@hanzo/ui/settings`'s, one set for
|
|
12
|
+
* every page.
|
|
13
|
+
*/
|
|
14
|
+
export { Shelf, type ShelfProps } from './Shelf.js';
|
|
15
|
+
export { Add, Featured, Tile, Tiles, type AddProps, type FeaturedProps, type TileProps, type TilesProps, } from './Tile.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EACL,GAAG,EACH,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,UAAU,GAChB,MAAM,QAAQ,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hanzo/ui/catalog — a catalogue page: what an org has, and what it can add.
|
|
3
|
+
*
|
|
4
|
+
* `Shelf` is the page — title, the kinds as tabs, Yours/Discover, one search
|
|
5
|
+
* and one Add over both — and the cards are its `children`: `Tiles` of `Tile`s,
|
|
6
|
+
* a `Featured` first, each with an `Add`.
|
|
7
|
+
*
|
|
8
|
+
* Web-only, and off `@hanzo/ui/product` for it: `Tiles` lays out on
|
|
9
|
+
* `@hanzo/ui/grid` (a `div` with `display: grid`), which the cross-platform
|
|
10
|
+
* product layer cannot promise. The section parts a tab draws around its cards
|
|
11
|
+
* — `Group`, `Soft`, `Note`, `Field` — are `@hanzo/ui/settings`'s, one set for
|
|
12
|
+
* every page.
|
|
13
|
+
*/
|
|
14
|
+
export { Shelf } from './Shelf.js';
|
|
15
|
+
export { Add, Featured, Tile, Tiles, } from './Tile.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,KAAK,EAAmB,MAAM,SAAS,CAAA;AAChD,OAAO,EACL,GAAG,EACH,QAAQ,EACR,IAAI,EACJ,KAAK,GAKN,MAAM,QAAQ,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Home = Home;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* Home — a fresh pane: the question, and the field that answers it, together in
|
|
8
|
+
* the middle of the page.
|
|
9
|
+
*
|
|
10
|
+
* The mark and the question are one centred line at the display size ($8); the
|
|
11
|
+
* composer and its chips arrive as `children` and sit under it in the same
|
|
12
|
+
* column, so the eye reads straight down from the one into the other. A run's
|
|
13
|
+
* own page keeps its composer at the foot; this is the page before there is a
|
|
14
|
+
* run.
|
|
15
|
+
*
|
|
16
|
+
* `EmptyPrompt` is the other empty state — a smaller question at the top of the
|
|
17
|
+
* column, for a pane whose composer stays at the foot.
|
|
18
|
+
*
|
|
19
|
+
* The mark is a slot, never a brand this package picks: a surface passes its
|
|
20
|
+
* own (`HanzoMark`, an org mark, nothing), and the heading is the same either
|
|
21
|
+
* way.
|
|
22
|
+
*/
|
|
23
|
+
const gui_1 = require("@hanzo/gui");
|
|
24
|
+
const slot_1 = require("../backends/gui/slot.cjs");
|
|
25
|
+
const EmptyPrompt_1 = require("./EmptyPrompt.cjs");
|
|
26
|
+
/** The composer column's width, so the question and the field share it. */
|
|
27
|
+
const COLUMN = 768;
|
|
28
|
+
function Home({ title = EmptyPrompt_1.NEXT, mark, column = COLUMN, level = 1, children, ...rest }) {
|
|
29
|
+
return ((0, jsx_runtime_1.jsx)(gui_1.ScrollView, { ...(0, slot_1.slot)('home'), flex: 1, minH: 0, minW: 0, overflowY: "auto", showsVerticalScrollIndicator: false, contentContainerStyle: { grow: 1, justify: 'center' }, ...rest, children: (0, jsx_runtime_1.jsx)(gui_1.YStack, { width: "100%", items: "center", px: "$4", pb: "$10", children: (0, jsx_runtime_1.jsxs)(gui_1.YStack, { width: "100%", maxW: column, gap: "$5", children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { justify: "center", items: "center", gap: "$3", flexWrap: "wrap", children: [mark ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('home-mark'), shrink: 0, items: "center", "aria-hidden": true, children: mark })) : null, (0, jsx_runtime_1.jsx)(gui_1.SizableText, { ...(0, slot_1.slot)('home-title'), role: "heading", "aria-level": level, size: "$8", color: "$ink", text: "center", children: title })] }), children ? (0, jsx_runtime_1.jsx)(gui_1.YStack, { gap: "$2", children: children }) : null] }) }) }));
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Home — a fresh pane: the question, and the field that answers it, together in
|
|
3
|
+
* the middle of the page.
|
|
4
|
+
*
|
|
5
|
+
* The mark and the question are one centred line at the display size ($8); the
|
|
6
|
+
* composer and its chips arrive as `children` and sit under it in the same
|
|
7
|
+
* column, so the eye reads straight down from the one into the other. A run's
|
|
8
|
+
* own page keeps its composer at the foot; this is the page before there is a
|
|
9
|
+
* run.
|
|
10
|
+
*
|
|
11
|
+
* `EmptyPrompt` is the other empty state — a smaller question at the top of the
|
|
12
|
+
* column, for a pane whose composer stays at the foot.
|
|
13
|
+
*
|
|
14
|
+
* The mark is a slot, never a brand this package picks: a surface passes its
|
|
15
|
+
* own (`HanzoMark`, an org mark, nothing), and the heading is the same either
|
|
16
|
+
* way.
|
|
17
|
+
*/
|
|
18
|
+
import { ScrollView } from '@hanzo/gui';
|
|
19
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
20
|
+
type Scroll = Omit<ComponentProps<typeof ScrollView>, 'children'>;
|
|
21
|
+
export interface HomeProps extends Scroll {
|
|
22
|
+
/** The question. */
|
|
23
|
+
title?: ReactNode;
|
|
24
|
+
/** Drawn before the question — a surface's own mark, ~26px. */
|
|
25
|
+
mark?: ReactNode;
|
|
26
|
+
/** The column the question and the composer share, px. */
|
|
27
|
+
column?: number;
|
|
28
|
+
/** The heading's outline level; a pane with a page title above it passes 2. */
|
|
29
|
+
level?: 1 | 2 | 3;
|
|
30
|
+
/** The composer, and whatever the surface says beside it. */
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
export declare function Home({ title, mark, column, level, children, ...rest }: HomeProps): import("react").JSX.Element;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=Home.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Home.d.ts","sourceRoot":"","sources":["../../src/chat/Home.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,UAAU,EAA+B,MAAM,YAAY,CAAA;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtD,KAAK,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EAAE,UAAU,CAAC,CAAA;AAKjE,MAAM,WAAW,SAAU,SAAQ,MAAM;IACvC,oBAAoB;IACpB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,wBAAgB,IAAI,CAAC,EAAE,KAAY,EAAE,IAAI,EAAE,MAAe,EAAE,KAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,+BAyCpG"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Home — a fresh pane: the question, and the field that answers it, together in
|
|
5
|
+
* the middle of the page.
|
|
6
|
+
*
|
|
7
|
+
* The mark and the question are one centred line at the display size ($8); the
|
|
8
|
+
* composer and its chips arrive as `children` and sit under it in the same
|
|
9
|
+
* column, so the eye reads straight down from the one into the other. A run's
|
|
10
|
+
* own page keeps its composer at the foot; this is the page before there is a
|
|
11
|
+
* run.
|
|
12
|
+
*
|
|
13
|
+
* `EmptyPrompt` is the other empty state — a smaller question at the top of the
|
|
14
|
+
* column, for a pane whose composer stays at the foot.
|
|
15
|
+
*
|
|
16
|
+
* The mark is a slot, never a brand this package picks: a surface passes its
|
|
17
|
+
* own (`HanzoMark`, an org mark, nothing), and the heading is the same either
|
|
18
|
+
* way.
|
|
19
|
+
*/
|
|
20
|
+
import { ScrollView, SizableText, XStack, YStack } from '@hanzo/gui';
|
|
21
|
+
import { slot } from '../backends/gui/slot.js';
|
|
22
|
+
import { NEXT } from './EmptyPrompt.js';
|
|
23
|
+
/** The composer column's width, so the question and the field share it. */
|
|
24
|
+
const COLUMN = 768;
|
|
25
|
+
export function Home({ title = NEXT, mark, column = COLUMN, level = 1, children, ...rest }) {
|
|
26
|
+
return (_jsx(ScrollView, { ...slot('home'), flex: 1, minH: 0, minW: 0, overflowY: "auto", showsVerticalScrollIndicator: false, contentContainerStyle: { grow: 1, justify: 'center' }, ...rest, children: _jsx(YStack, { width: "100%", items: "center", px: "$4", pb: "$10", children: _jsxs(YStack, { width: "100%", maxW: column, gap: "$5", children: [_jsxs(XStack, { justify: "center", items: "center", gap: "$3", flexWrap: "wrap", children: [mark ? (_jsx(XStack, { ...slot('home-mark'), shrink: 0, items: "center", "aria-hidden": true, children: mark })) : null, _jsx(SizableText, { ...slot('home-title'), role: "heading", "aria-level": level, size: "$8", color: "$ink", text: "center", children: title })] }), children ? _jsx(YStack, { gap: "$2", children: children }) : null] }) }) }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=Home.js.map
|