@tai42/studio-sdk 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -94,11 +94,16 @@ export interface ExplorerViewProps<T> {
|
|
|
94
94
|
readonly renderRow: (item: T) => ReactNode;
|
|
95
95
|
/** The item's `<Card>` — wrapped in a keyed `listitem` by the explorer. */
|
|
96
96
|
readonly renderCard: (item: T) => ReactNode;
|
|
97
|
+
/** Open an item on a pointer click anywhere on its row/card — a convenience
|
|
98
|
+
* ONLY. The accessible activation path stays the interactive element inside
|
|
99
|
+
* the cell (the name link), so the row is never a focusable button; a click
|
|
100
|
+
* originating on a nested control is left to that control. */
|
|
101
|
+
readonly onOpenItem?: (item: T) => void;
|
|
97
102
|
readonly tags?: ExplorerTags<T>;
|
|
98
103
|
readonly search?: ExplorerSearch<T>;
|
|
99
104
|
/** Per-folder actions rendered on the folder's row/card (e.g. a kebab). */
|
|
100
105
|
readonly renderFolderActions?: (folder: Folder) => ReactNode;
|
|
101
106
|
readonly emptyStates: ExplorerEmptyStates;
|
|
102
107
|
}
|
|
103
|
-
export declare function ExplorerView<T>({ items, getItemKey, getFolderId, folders, currentFolderId, onNavigate, rootLabel, viewSurface, label, columns, renderRow, renderCard, tags, search, renderFolderActions, emptyStates, }: ExplorerViewProps<T>): ReactNode;
|
|
108
|
+
export declare function ExplorerView<T>({ items, getItemKey, getFolderId, folders, currentFolderId, onNavigate, rootLabel, viewSurface, label, columns, renderRow, renderCard, onOpenItem, tags, search, renderFolderActions, emptyStates, }: ExplorerViewProps<T>): ReactNode;
|
|
104
109
|
//# sourceMappingURL=explorer-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-view.d.ts","sourceRoot":"","sources":["../../src/components/explorer-view.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"explorer-view.d.ts","sourceRoot":"","sources":["../../src/components/explorer-view.tsx"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { childFolders, FolderBreadcrumb, FolderRow } from './folder-nav';
|
|
|
4
4
|
import { SearchIcon } from './icons';
|
|
5
5
|
import { TextInput } from './inputs';
|
|
6
6
|
import { Card, EmptyState } from './primitives';
|
|
7
|
+
import { ScrollRegion } from './scroll-region';
|
|
7
8
|
import { Table, TBody, TD, TH, THead, TR } from './table';
|
|
8
9
|
import { useViewMode, ViewToggle } from './view-toggle';
|
|
9
10
|
/** Reserved filter token for items carrying NO tag; namespaced so it never
|
|
@@ -83,7 +84,7 @@ function TagFilterRow({ vocabulary, selectedSet, onToggle, filterLabel, maxVisib
|
|
|
83
84
|
function FolderEntry({ folder, onNavigate, renderFolderActions, }) {
|
|
84
85
|
return (_jsxs("div", { className: "tai-explorer-folder", children: [_jsx(FolderRow, { folder: folder, onOpen: onNavigate }), renderFolderActions ? renderFolderActions(folder) : null] }));
|
|
85
86
|
}
|
|
86
|
-
export function ExplorerView({ items, getItemKey, getFolderId, folders, currentFolderId, onNavigate, rootLabel, viewSurface, label, columns, renderRow, renderCard, tags, search, renderFolderActions, emptyStates, }) {
|
|
87
|
+
export function ExplorerView({ items, getItemKey, getFolderId, folders, currentFolderId, onNavigate, rootLabel, viewSurface, label, columns, renderRow, renderCard, onOpenItem, tags, search, renderFolderActions, emptyStates, }) {
|
|
87
88
|
const [viewMode, setViewMode] = useViewMode(viewSurface);
|
|
88
89
|
if (viewSurface === '')
|
|
89
90
|
throw new Error('ExplorerView requires a non-empty viewSurface key.');
|
|
@@ -119,6 +120,30 @@ export function ExplorerView({ items, getItemKey, getFolderId, folders, currentF
|
|
|
119
120
|
: [...tags.selected, token];
|
|
120
121
|
tags.onChange(next);
|
|
121
122
|
};
|
|
123
|
+
// The pointer-open props for one item's row/card, present only when `onOpenItem`
|
|
124
|
+
// is set. The handler yields to any nested interactive element the click landed
|
|
125
|
+
// on (a name link, an actions kebab) so it never hijacks its activation; a
|
|
126
|
+
// portalled menu (Radix) never bubbles here, so the role selectors are defensive
|
|
127
|
+
// for an inline menu only.
|
|
128
|
+
const openProps = (item) => {
|
|
129
|
+
if (onOpenItem === undefined)
|
|
130
|
+
return {};
|
|
131
|
+
return {
|
|
132
|
+
onClick: (event) => {
|
|
133
|
+
// A press-drag that selects the name text also fires a click; that is a
|
|
134
|
+
// selection, not an open intent.
|
|
135
|
+
if (window.getSelection()?.isCollapsed === false)
|
|
136
|
+
return;
|
|
137
|
+
const target = event.target;
|
|
138
|
+
if (target instanceof Element &&
|
|
139
|
+
target.closest('button, a, [role="menu"], [role="menuitem"]') !== null) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
onOpenItem(item);
|
|
143
|
+
},
|
|
144
|
+
style: { cursor: 'pointer' },
|
|
145
|
+
};
|
|
146
|
+
};
|
|
122
147
|
const hasEntries = subfolders.length > 0 || filtered.length > 0;
|
|
123
148
|
let body;
|
|
124
149
|
if (!hasEntries) {
|
|
@@ -127,12 +152,13 @@ export function ExplorerView({ items, getItemKey, getFolderId, folders, currentF
|
|
|
127
152
|
body = (_jsx(EmptyState, { ...(inFolder.length > 0 ? emptyStates.noMatch : emptyStates.emptyFolder) }));
|
|
128
153
|
}
|
|
129
154
|
else if (viewMode === 'cards') {
|
|
130
|
-
body = (_jsxs(EntityCardGrid, { "aria-label": label, children: [subfolders.map((folder) => (_jsx("div", { role: "listitem", children: _jsx(Card, { interactive: true, children: _jsx(FolderEntry, { folder: folder, onNavigate: onNavigate, renderFolderActions: renderFolderActions }) }) }, `folder:${folder.id}`))), filtered.map((item) => (_jsx("div", { role: "listitem", children: renderCard(item) }, `item:${getItemKey(item)}`)))] }));
|
|
155
|
+
body = (_jsxs(EntityCardGrid, { "aria-label": label, children: [subfolders.map((folder) => (_jsx("div", { role: "listitem", children: _jsx(Card, { interactive: true, children: _jsx(FolderEntry, { folder: folder, onNavigate: onNavigate, renderFolderActions: renderFolderActions }) }) }, `folder:${folder.id}`))), filtered.map((item) => (_jsx("div", { role: "listitem", ...openProps(item), children: renderCard(item) }, `item:${getItemKey(item)}`)))] }));
|
|
131
156
|
}
|
|
132
157
|
else {
|
|
133
158
|
// Folder rows share the item table, spanning every column, sorted above items —
|
|
134
159
|
// so a folder-with-only-subfolders is folder ROWS, never a header-only table.
|
|
135
|
-
|
|
160
|
+
// A too-wide table scrolls inside its own box rather than widening the page.
|
|
161
|
+
body = (_jsx(ScrollRegion, { label: label, children: _jsxs(Table, { children: [_jsx(THead, { children: _jsx(TR, { children: columns.map((column) => (_jsx(TH, { numeric: column.numeric, children: column.header }, column.key))) }) }), _jsxs(TBody, { children: [subfolders.map((folder) => (_jsx(TR, { children: _jsx(TD, { colSpan: columns.length, children: _jsx(FolderEntry, { folder: folder, onNavigate: onNavigate, renderFolderActions: renderFolderActions }) }) }, `folder:${folder.id}`))), filtered.map((item) => (_jsx(TR, { ...openProps(item), children: renderRow(item) }, `item:${getItemKey(item)}`)))] })] }) }));
|
|
136
162
|
}
|
|
137
163
|
return (_jsxs("div", { className: "tai-explorer", children: [_jsxs("div", { className: "tai-explorer-controls", children: [search !== undefined ? (_jsxs("span", { className: "tai-row", children: [_jsx(SearchIcon, {}), _jsx(TextInput, { value: search.value, "aria-label": search.label, placeholder: search.placeholder, onChange: (event) => {
|
|
138
164
|
search.onChange(event.target.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-view.js","sourceRoot":"","sources":["../../src/components/explorer-view.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAExD;gCACgC;AAChC,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAQ7C;;mEAEmE;AACnE,MAAM,UAAU,kBAAkB,CAChC,KAAmB,EACnB,OAAuC,EACvC,YAA+B,EAC/B,aAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,QAAQ,IAAI,CAAC,CAAC;YACd,SAAS;QACX,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,UAAU,GAAyB,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SAC3D,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7D,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;YACvD,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK;gBACL,KAAK,EAAE,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK;gBACvD,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;mBAEmB;AACnB,MAAM,UAAU,mBAAmB,CACjC,QAA2B,EAC3B,QAA6B;IAE7B,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC/D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC;
|
|
1
|
+
{"version":3,"file":"explorer-view.js","sourceRoot":"","sources":["../../src/components/explorer-view.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tai42/studio-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "The Studio plugin contract, shared UI components, and hooks that every feature builds on.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "tai42 <oss@tai42.ai>",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@radix-ui/react-select": "^2.3.2",
|
|
90
90
|
"@radix-ui/react-tabs": "^1.1.16",
|
|
91
91
|
"@radix-ui/react-tooltip": "^1.2.11",
|
|
92
|
-
"@tai42/api-client": "0.
|
|
92
|
+
"@tai42/api-client": "0.9.0"
|
|
93
93
|
},
|
|
94
94
|
"scripts": {
|
|
95
95
|
"build": "tsc -b tsconfig.build.json && node scripts/copy-assets.mjs",
|
|
@@ -12,13 +12,14 @@
|
|
|
12
12
|
* {@link matchesSelectedTags}, {@link UNTAGGED_TOKEN}) so every consuming screen
|
|
13
13
|
* shares one vocabulary/untagged-sentinel/OR-match rule rather than copying it.
|
|
14
14
|
*/
|
|
15
|
-
import type { ReactNode } from 'react';
|
|
15
|
+
import type { MouseEvent, ReactNode } from 'react';
|
|
16
16
|
|
|
17
17
|
import { EntityCardGrid } from './entity-card-grid';
|
|
18
18
|
import { childFolders, FolderBreadcrumb, FolderRow, type Folder } from './folder-nav';
|
|
19
19
|
import { SearchIcon } from './icons';
|
|
20
20
|
import { TextInput } from './inputs';
|
|
21
21
|
import { Card, EmptyState } from './primitives';
|
|
22
|
+
import { ScrollRegion } from './scroll-region';
|
|
22
23
|
import { Table, TBody, TD, TH, THead, TR } from './table';
|
|
23
24
|
import { useViewMode, ViewToggle } from './view-toggle';
|
|
24
25
|
|
|
@@ -154,6 +155,12 @@ export interface ExplorerViewProps<T> {
|
|
|
154
155
|
/** The item's `<Card>` — wrapped in a keyed `listitem` by the explorer. */
|
|
155
156
|
readonly renderCard: (item: T) => ReactNode;
|
|
156
157
|
|
|
158
|
+
/** Open an item on a pointer click anywhere on its row/card — a convenience
|
|
159
|
+
* ONLY. The accessible activation path stays the interactive element inside
|
|
160
|
+
* the cell (the name link), so the row is never a focusable button; a click
|
|
161
|
+
* originating on a nested control is left to that control. */
|
|
162
|
+
readonly onOpenItem?: (item: T) => void;
|
|
163
|
+
|
|
157
164
|
readonly tags?: ExplorerTags<T>;
|
|
158
165
|
readonly search?: ExplorerSearch<T>;
|
|
159
166
|
|
|
@@ -268,6 +275,7 @@ export function ExplorerView<T>({
|
|
|
268
275
|
columns,
|
|
269
276
|
renderRow,
|
|
270
277
|
renderCard,
|
|
278
|
+
onOpenItem,
|
|
271
279
|
tags,
|
|
272
280
|
search,
|
|
273
281
|
renderFolderActions,
|
|
@@ -311,6 +319,33 @@ export function ExplorerView<T>({
|
|
|
311
319
|
tags.onChange(next);
|
|
312
320
|
};
|
|
313
321
|
|
|
322
|
+
// The pointer-open props for one item's row/card, present only when `onOpenItem`
|
|
323
|
+
// is set. The handler yields to any nested interactive element the click landed
|
|
324
|
+
// on (a name link, an actions kebab) so it never hijacks its activation; a
|
|
325
|
+
// portalled menu (Radix) never bubbles here, so the role selectors are defensive
|
|
326
|
+
// for an inline menu only.
|
|
327
|
+
const openProps = (
|
|
328
|
+
item: T,
|
|
329
|
+
): { onClick?: (event: MouseEvent<HTMLElement>) => void; style?: { cursor: 'pointer' } } => {
|
|
330
|
+
if (onOpenItem === undefined) return {};
|
|
331
|
+
return {
|
|
332
|
+
onClick: (event) => {
|
|
333
|
+
// A press-drag that selects the name text also fires a click; that is a
|
|
334
|
+
// selection, not an open intent.
|
|
335
|
+
if (window.getSelection()?.isCollapsed === false) return;
|
|
336
|
+
const target = event.target;
|
|
337
|
+
if (
|
|
338
|
+
target instanceof Element &&
|
|
339
|
+
target.closest('button, a, [role="menu"], [role="menuitem"]') !== null
|
|
340
|
+
) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
onOpenItem(item);
|
|
344
|
+
},
|
|
345
|
+
style: { cursor: 'pointer' },
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
|
|
314
349
|
const hasEntries = subfolders.length > 0 || filtered.length > 0;
|
|
315
350
|
|
|
316
351
|
let body: ReactNode;
|
|
@@ -335,7 +370,7 @@ export function ExplorerView<T>({
|
|
|
335
370
|
</div>
|
|
336
371
|
))}
|
|
337
372
|
{filtered.map((item) => (
|
|
338
|
-
<div role="listitem" key={`item:${getItemKey(item)}`}>
|
|
373
|
+
<div role="listitem" key={`item:${getItemKey(item)}`} {...openProps(item)}>
|
|
339
374
|
{renderCard(item)}
|
|
340
375
|
</div>
|
|
341
376
|
))}
|
|
@@ -344,34 +379,39 @@ export function ExplorerView<T>({
|
|
|
344
379
|
} else {
|
|
345
380
|
// Folder rows share the item table, spanning every column, sorted above items —
|
|
346
381
|
// so a folder-with-only-subfolders is folder ROWS, never a header-only table.
|
|
382
|
+
// A too-wide table scrolls inside its own box rather than widening the page.
|
|
347
383
|
body = (
|
|
348
|
-
<
|
|
349
|
-
<
|
|
350
|
-
<
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
{column.
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
</THead>
|
|
358
|
-
<TBody>
|
|
359
|
-
{subfolders.map((folder) => (
|
|
360
|
-
<TR key={`folder:${folder.id}`}>
|
|
361
|
-
<TD colSpan={columns.length}>
|
|
362
|
-
<FolderEntry
|
|
363
|
-
folder={folder}
|
|
364
|
-
onNavigate={onNavigate}
|
|
365
|
-
renderFolderActions={renderFolderActions}
|
|
366
|
-
/>
|
|
367
|
-
</TD>
|
|
384
|
+
<ScrollRegion label={label}>
|
|
385
|
+
<Table>
|
|
386
|
+
<THead>
|
|
387
|
+
<TR>
|
|
388
|
+
{columns.map((column) => (
|
|
389
|
+
<TH key={column.key} numeric={column.numeric}>
|
|
390
|
+
{column.header}
|
|
391
|
+
</TH>
|
|
392
|
+
))}
|
|
368
393
|
</TR>
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
394
|
+
</THead>
|
|
395
|
+
<TBody>
|
|
396
|
+
{subfolders.map((folder) => (
|
|
397
|
+
<TR key={`folder:${folder.id}`}>
|
|
398
|
+
<TD colSpan={columns.length}>
|
|
399
|
+
<FolderEntry
|
|
400
|
+
folder={folder}
|
|
401
|
+
onNavigate={onNavigate}
|
|
402
|
+
renderFolderActions={renderFolderActions}
|
|
403
|
+
/>
|
|
404
|
+
</TD>
|
|
405
|
+
</TR>
|
|
406
|
+
))}
|
|
407
|
+
{filtered.map((item) => (
|
|
408
|
+
<TR key={`item:${getItemKey(item)}`} {...openProps(item)}>
|
|
409
|
+
{renderRow(item)}
|
|
410
|
+
</TR>
|
|
411
|
+
))}
|
|
412
|
+
</TBody>
|
|
413
|
+
</Table>
|
|
414
|
+
</ScrollRegion>
|
|
375
415
|
);
|
|
376
416
|
}
|
|
377
417
|
|