@tai42/studio-sdk 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/components.css +30 -0
- package/dist/components/explorer-view.d.ts +109 -0
- package/dist/components/explorer-view.d.ts.map +1 -0
- package/dist/components/explorer-view.js +165 -0
- package/dist/components/explorer-view.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/components.css +30 -0
- package/src/components/explorer-view.tsx +455 -0
- package/src/index.ts +15 -0
|
@@ -2031,6 +2031,36 @@
|
|
|
2031
2031
|
min-width: 0;
|
|
2032
2032
|
}
|
|
2033
2033
|
|
|
2034
|
+
/* -- Explorer ---------------------------------------------------------------------
|
|
2035
|
+
The shared current-directory explorer: controls row, breadcrumb, tag chips,
|
|
2036
|
+
then the folder/item body. Vertical rhythm only — the body carries its own
|
|
2037
|
+
table/grid. */
|
|
2038
|
+
.tai-explorer {
|
|
2039
|
+
display: flex;
|
|
2040
|
+
flex-direction: column;
|
|
2041
|
+
gap: var(--tai-space-4);
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
/* Search on the leading edge, the view toggle on the trailing edge; wraps under
|
|
2045
|
+
its own width on a narrow surface. */
|
|
2046
|
+
.tai-explorer-controls {
|
|
2047
|
+
display: flex;
|
|
2048
|
+
align-items: center;
|
|
2049
|
+
justify-content: space-between;
|
|
2050
|
+
gap: var(--tai-space-3);
|
|
2051
|
+
flex-wrap: wrap;
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
/* A first-class folder entry (row cell or card): the folder affordance beside
|
|
2055
|
+
its optional actions, the actions pushed to the trailing edge. */
|
|
2056
|
+
.tai-explorer-folder {
|
|
2057
|
+
display: flex;
|
|
2058
|
+
align-items: center;
|
|
2059
|
+
justify-content: space-between;
|
|
2060
|
+
gap: var(--tai-space-2);
|
|
2061
|
+
flex-wrap: wrap;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2034
2064
|
/* -- Card grids ------------------------------------------------------------------- */
|
|
2035
2065
|
.tai-grid-cards {
|
|
2036
2066
|
display: grid;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ExplorerView<T>` — the shared current-directory explorer every entity screen
|
|
3
|
+
* composes: a breadcrumb over a flat {@link Folder} tree, optional search + tag
|
|
4
|
+
* chips, a list/card toggle, and a body in which FOLDERS are first-class entries
|
|
5
|
+
* sorted above the items (folder rows inside the same table, folder cards inside
|
|
6
|
+
* the same grid). Fully controlled and data-agnostic — the caller owns the item
|
|
7
|
+
* shape via `getItemKey`/`getFolderId`/`renderRow`/`renderCard`, and keeps folder
|
|
8
|
+
* dir / tags / search in the URL or in local state; only the view mode persists
|
|
9
|
+
* internally (per `viewSurface`).
|
|
10
|
+
*
|
|
11
|
+
* The tag glue lives here as exported helpers ({@link buildTagVocabulary},
|
|
12
|
+
* {@link matchesSelectedTags}, {@link UNTAGGED_TOKEN}) so every consuming screen
|
|
13
|
+
* shares one vocabulary/untagged-sentinel/OR-match rule rather than copying it.
|
|
14
|
+
*/
|
|
15
|
+
import type { ReactNode } from 'react';
|
|
16
|
+
import { type Folder } from './folder-nav';
|
|
17
|
+
/** Reserved filter token for items carrying NO tag; namespaced so it never
|
|
18
|
+
* collides with a real tag. */
|
|
19
|
+
export declare const UNTAGGED_TOKEN = "__untagged__";
|
|
20
|
+
export interface TagVocabularyEntry {
|
|
21
|
+
readonly token: string;
|
|
22
|
+
readonly label: string;
|
|
23
|
+
readonly count: number;
|
|
24
|
+
}
|
|
25
|
+
/** The tag vocabulary over `items`, name-sorted, plus an untagged pseudo-tag
|
|
26
|
+
* (labelled `untaggedLabel`) when any item is untagged; a selected token whose
|
|
27
|
+
* items vanished still appears (count 0) so it can be cleared. */
|
|
28
|
+
export declare function buildTagVocabulary<T>(items: readonly T[], getTags: (item: T) => readonly string[], selectedTags: readonly string[], untaggedLabel: string): TagVocabularyEntry[];
|
|
29
|
+
/** OR semantics: an empty selection matches everything; otherwise an item
|
|
30
|
+
* matches when it carries any selected tag, or is untagged and UNTAGGED_TOKEN
|
|
31
|
+
* is selected. */
|
|
32
|
+
export declare function matchesSelectedTags(itemTags: readonly string[], selected: ReadonlySet<string>): boolean;
|
|
33
|
+
/** One header cell of the table view. `renderRow` must emit exactly this many
|
|
34
|
+
* `<TD>`s per item; folder rows span all of them. */
|
|
35
|
+
export interface ExplorerColumn {
|
|
36
|
+
readonly key: string;
|
|
37
|
+
readonly header: ReactNode;
|
|
38
|
+
readonly numeric?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** Enables the tag vocabulary, filter chips, and OR filter. Fully controlled. */
|
|
41
|
+
export interface ExplorerTags<T> {
|
|
42
|
+
readonly getTags: (item: T) => readonly string[];
|
|
43
|
+
readonly selected: readonly string[];
|
|
44
|
+
readonly onChange: (selected: readonly string[]) => void;
|
|
45
|
+
/** The untagged pseudo-tag's visible label (e.g. "Untagged"). */
|
|
46
|
+
readonly untaggedLabel: string;
|
|
47
|
+
/** The chip group's accessible name (e.g. "Filter tools by tag"). */
|
|
48
|
+
readonly filterLabel: string;
|
|
49
|
+
/** Collapse unselected chips beyond this count into a static "+N more"; unset
|
|
50
|
+
* shows every chip. Selected chips always show. */
|
|
51
|
+
readonly maxVisibleTags?: number;
|
|
52
|
+
}
|
|
53
|
+
/** Controlled free-text search. `matches` owns the item shape and casing; it is
|
|
54
|
+
* called only with a non-empty, already-trimmed query. */
|
|
55
|
+
export interface ExplorerSearch<T> {
|
|
56
|
+
readonly value: string;
|
|
57
|
+
readonly onChange: (value: string) => void;
|
|
58
|
+
readonly matches: (item: T, query: string) => boolean;
|
|
59
|
+
/** The input's accessible name. */
|
|
60
|
+
readonly label: string;
|
|
61
|
+
readonly placeholder?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface ExplorerEmptyState {
|
|
64
|
+
readonly title: string;
|
|
65
|
+
readonly description?: string;
|
|
66
|
+
readonly action?: ReactNode;
|
|
67
|
+
}
|
|
68
|
+
/** The folder-aware empty-state ladder — every label caller-supplied. */
|
|
69
|
+
export interface ExplorerEmptyStates {
|
|
70
|
+
/** No items and no folders exist at all. */
|
|
71
|
+
readonly empty: ExplorerEmptyState;
|
|
72
|
+
/** The current folder holds nothing — no items, no subfolders — yet the
|
|
73
|
+
* entity set is not globally empty. */
|
|
74
|
+
readonly emptyFolder: ExplorerEmptyState;
|
|
75
|
+
/** The current folder has items but the active tag/search filter excludes
|
|
76
|
+
* every one, and it has no subfolders to show. */
|
|
77
|
+
readonly noMatch: ExplorerEmptyState;
|
|
78
|
+
}
|
|
79
|
+
export interface ExplorerViewProps<T> {
|
|
80
|
+
readonly items: readonly T[];
|
|
81
|
+
readonly getItemKey: (item: T) => string;
|
|
82
|
+
/** The folder an item is filed in (`null` = the root directory). */
|
|
83
|
+
readonly getFolderId: (item: T) => string | null;
|
|
84
|
+
readonly folders: readonly Folder[];
|
|
85
|
+
readonly currentFolderId: string | null;
|
|
86
|
+
readonly onNavigate: (folderId: string | null) => void;
|
|
87
|
+
readonly rootLabel: string;
|
|
88
|
+
/** Persist + drive the list/card toggle under this surface key. */
|
|
89
|
+
readonly viewSurface: string;
|
|
90
|
+
/** The card grid's accessible name; the toggle's is "<label> view". */
|
|
91
|
+
readonly label: string;
|
|
92
|
+
readonly columns: readonly ExplorerColumn[];
|
|
93
|
+
/** The item's table cells (`<TD>`s) — wrapped in a keyed `<TR>` by the explorer. */
|
|
94
|
+
readonly renderRow: (item: T) => ReactNode;
|
|
95
|
+
/** The item's `<Card>` — wrapped in a keyed `listitem` by the explorer. */
|
|
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;
|
|
102
|
+
readonly tags?: ExplorerTags<T>;
|
|
103
|
+
readonly search?: ExplorerSearch<T>;
|
|
104
|
+
/** Per-folder actions rendered on the folder's row/card (e.g. a kebab). */
|
|
105
|
+
readonly renderFolderActions?: (folder: Folder) => ReactNode;
|
|
106
|
+
readonly emptyStates: ExplorerEmptyStates;
|
|
107
|
+
}
|
|
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;
|
|
109
|
+
//# sourceMappingURL=explorer-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explorer-view.d.ts","sourceRoot":"","sources":["../../src/components/explorer-view.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { EntityCardGrid } from './entity-card-grid';
|
|
3
|
+
import { childFolders, FolderBreadcrumb, FolderRow } from './folder-nav';
|
|
4
|
+
import { SearchIcon } from './icons';
|
|
5
|
+
import { TextInput } from './inputs';
|
|
6
|
+
import { Card, EmptyState } from './primitives';
|
|
7
|
+
import { Table, TBody, TD, TH, THead, TR } from './table';
|
|
8
|
+
import { useViewMode, ViewToggle } from './view-toggle';
|
|
9
|
+
/** Reserved filter token for items carrying NO tag; namespaced so it never
|
|
10
|
+
* collides with a real tag. */
|
|
11
|
+
export const UNTAGGED_TOKEN = '__untagged__';
|
|
12
|
+
/** The tag vocabulary over `items`, name-sorted, plus an untagged pseudo-tag
|
|
13
|
+
* (labelled `untaggedLabel`) when any item is untagged; a selected token whose
|
|
14
|
+
* items vanished still appears (count 0) so it can be cleared. */
|
|
15
|
+
export function buildTagVocabulary(items, getTags, selectedTags, untaggedLabel) {
|
|
16
|
+
const counts = new Map();
|
|
17
|
+
let untagged = 0;
|
|
18
|
+
for (const item of items) {
|
|
19
|
+
const tags = getTags(item);
|
|
20
|
+
if (tags.length === 0) {
|
|
21
|
+
untagged += 1;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
for (const tag of tags)
|
|
25
|
+
counts.set(tag, (counts.get(tag) ?? 0) + 1);
|
|
26
|
+
}
|
|
27
|
+
const vocabulary = [...counts.entries()]
|
|
28
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
29
|
+
.map(([label, count]) => ({ token: label, label, count }));
|
|
30
|
+
if (untagged > 0) {
|
|
31
|
+
vocabulary.push({ token: UNTAGGED_TOKEN, label: untaggedLabel, count: untagged });
|
|
32
|
+
}
|
|
33
|
+
for (const token of selectedTags) {
|
|
34
|
+
if (!vocabulary.some((entry) => entry.token === token)) {
|
|
35
|
+
vocabulary.push({
|
|
36
|
+
token,
|
|
37
|
+
label: token === UNTAGGED_TOKEN ? untaggedLabel : token,
|
|
38
|
+
count: 0,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return vocabulary;
|
|
43
|
+
}
|
|
44
|
+
/** OR semantics: an empty selection matches everything; otherwise an item
|
|
45
|
+
* matches when it carries any selected tag, or is untagged and UNTAGGED_TOKEN
|
|
46
|
+
* is selected. */
|
|
47
|
+
export function matchesSelectedTags(itemTags, selected) {
|
|
48
|
+
if (selected.size === 0)
|
|
49
|
+
return true;
|
|
50
|
+
if (itemTags.length === 0)
|
|
51
|
+
return selected.has(UNTAGGED_TOKEN);
|
|
52
|
+
return itemTags.some((tag) => selected.has(tag));
|
|
53
|
+
}
|
|
54
|
+
/** A togglable tag chip; `aria-pressed` reflects whether the tag filters the list. */
|
|
55
|
+
function TagChip({ entry, active, onToggle, }) {
|
|
56
|
+
return (_jsxs("button", { type: "button", className: "tai-chip", "aria-pressed": active, "aria-label": `${entry.label} (${String(entry.count)})`, onClick: onToggle, children: [_jsx("span", { children: entry.label }), _jsx("span", { children: entry.count })] }));
|
|
57
|
+
}
|
|
58
|
+
/** The filter row: every selected chip plus as many unselected chips as fit under
|
|
59
|
+
* the cap, with the remainder collapsed into a STATIC "+N more" count. An unset
|
|
60
|
+
* cap shows every chip. */
|
|
61
|
+
function TagFilterRow({ vocabulary, selectedSet, onToggle, filterLabel, maxVisibleTags, }) {
|
|
62
|
+
const visible = [];
|
|
63
|
+
let hidden = 0;
|
|
64
|
+
let unselectedShown = 0;
|
|
65
|
+
for (const entry of vocabulary) {
|
|
66
|
+
if (selectedSet.has(entry.token)) {
|
|
67
|
+
visible.push(entry);
|
|
68
|
+
}
|
|
69
|
+
else if (maxVisibleTags === undefined || unselectedShown < maxVisibleTags) {
|
|
70
|
+
visible.push(entry);
|
|
71
|
+
unselectedShown += 1;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
hidden += 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return (_jsxs("div", { role: "group", "aria-label": filterLabel, className: "tai-row", children: [visible.map((entry) => (_jsx(TagChip, { entry: entry, active: selectedSet.has(entry.token), onToggle: () => {
|
|
78
|
+
onToggle(entry.token);
|
|
79
|
+
} }, entry.token))), hidden > 0 ? (_jsx("span", { className: "tai-chip tai-chip-static", children: `+${String(hidden)} more` })) : null] }));
|
|
80
|
+
}
|
|
81
|
+
/** A first-class folder entry — a `FolderRow` (icon + name, navigates inward)
|
|
82
|
+
* beside its optional actions, in the layout shared by the row cell and the card. */
|
|
83
|
+
function FolderEntry({ folder, onNavigate, renderFolderActions, }) {
|
|
84
|
+
return (_jsxs("div", { className: "tai-explorer-folder", children: [_jsx(FolderRow, { folder: folder, onOpen: onNavigate }), renderFolderActions ? renderFolderActions(folder) : null] }));
|
|
85
|
+
}
|
|
86
|
+
export function ExplorerView({ items, getItemKey, getFolderId, folders, currentFolderId, onNavigate, rootLabel, viewSurface, label, columns, renderRow, renderCard, onOpenItem, tags, search, renderFolderActions, emptyStates, }) {
|
|
87
|
+
const [viewMode, setViewMode] = useViewMode(viewSurface);
|
|
88
|
+
if (viewSurface === '')
|
|
89
|
+
throw new Error('ExplorerView requires a non-empty viewSurface key.');
|
|
90
|
+
if (columns.length === 0)
|
|
91
|
+
throw new Error('ExplorerView requires at least one column.');
|
|
92
|
+
// Nothing anywhere: no items and no folders. A bare empty state, no controls.
|
|
93
|
+
if (items.length === 0 && folders.length === 0) {
|
|
94
|
+
return _jsx(EmptyState, { ...emptyStates.empty });
|
|
95
|
+
}
|
|
96
|
+
const subfolders = childFolders(folders, currentFolderId);
|
|
97
|
+
const inFolder = items.filter((item) => getFolderId(item) === currentFolderId);
|
|
98
|
+
const selectedSet = tags !== undefined ? new Set(tags.selected) : undefined;
|
|
99
|
+
const query = search ? search.value.trim() : '';
|
|
100
|
+
const filtered = inFolder.filter((item) => {
|
|
101
|
+
if (tags !== undefined && selectedSet !== undefined && selectedSet.size > 0) {
|
|
102
|
+
if (!matchesSelectedTags(tags.getTags(item), selectedSet))
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (search !== undefined && query !== '') {
|
|
106
|
+
if (!search.matches(item, query))
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
});
|
|
111
|
+
const vocabulary = tags !== undefined
|
|
112
|
+
? buildTagVocabulary(inFolder, tags.getTags, tags.selected, tags.untaggedLabel)
|
|
113
|
+
: [];
|
|
114
|
+
const toggleTag = (token) => {
|
|
115
|
+
if (tags === undefined || selectedSet === undefined)
|
|
116
|
+
return;
|
|
117
|
+
const next = selectedSet.has(token)
|
|
118
|
+
? tags.selected.filter((t) => t !== token)
|
|
119
|
+
: [...tags.selected, token];
|
|
120
|
+
tags.onChange(next);
|
|
121
|
+
};
|
|
122
|
+
// The pointer-open props for one item's row/card, present only when `onOpenItem`
|
|
123
|
+
// is set. The handler yields to any nested interactive element the click landed
|
|
124
|
+
// on (a name link, an actions kebab) so it never hijacks its activation; a
|
|
125
|
+
// portalled menu (Radix) never bubbles here, so the role selectors are defensive
|
|
126
|
+
// for an inline menu only.
|
|
127
|
+
const openProps = (item) => {
|
|
128
|
+
if (onOpenItem === undefined)
|
|
129
|
+
return {};
|
|
130
|
+
return {
|
|
131
|
+
onClick: (event) => {
|
|
132
|
+
// A press-drag that selects the name text also fires a click; that is a
|
|
133
|
+
// selection, not an open intent.
|
|
134
|
+
if (window.getSelection()?.isCollapsed === false)
|
|
135
|
+
return;
|
|
136
|
+
const target = event.target;
|
|
137
|
+
if (target instanceof Element &&
|
|
138
|
+
target.closest('button, a, [role="menu"], [role="menuitem"]') !== null) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
onOpenItem(item);
|
|
142
|
+
},
|
|
143
|
+
style: { cursor: 'pointer' },
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
const hasEntries = subfolders.length > 0 || filtered.length > 0;
|
|
147
|
+
let body;
|
|
148
|
+
if (!hasEntries) {
|
|
149
|
+
// The current folder renders nothing. A filter emptied it (`inFolder` non-empty)
|
|
150
|
+
// → "no match"; otherwise the folder is genuinely empty.
|
|
151
|
+
body = (_jsx(EmptyState, { ...(inFolder.length > 0 ? emptyStates.noMatch : emptyStates.emptyFolder) }));
|
|
152
|
+
}
|
|
153
|
+
else if (viewMode === 'cards') {
|
|
154
|
+
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)}`)))] }));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Folder rows share the item table, spanning every column, sorted above items —
|
|
158
|
+
// so a folder-with-only-subfolders is folder ROWS, never a header-only table.
|
|
159
|
+
body = (_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)}`)))] })] }));
|
|
160
|
+
}
|
|
161
|
+
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) => {
|
|
162
|
+
search.onChange(event.target.value);
|
|
163
|
+
} })] })) : (_jsx("span", {})), _jsx(ViewToggle, { value: viewMode, onValueChange: setViewMode, "aria-label": `${label} view` })] }), _jsx(FolderBreadcrumb, { folders: folders, currentFolderId: currentFolderId, onNavigate: onNavigate, rootLabel: rootLabel }), tags !== undefined && selectedSet !== undefined && vocabulary.length > 0 ? (_jsx(TagFilterRow, { vocabulary: vocabulary, selectedSet: selectedSet, onToggle: toggleTag, filterLabel: tags.filterLabel, maxVisibleTags: tags.maxVisibleTags })) : null, body] }));
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=explorer-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explorer-view.js","sourceRoot":"","sources":["../../src/components/explorer-view.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ export { ViewToggle, useViewMode } from './components/view-toggle';
|
|
|
86
86
|
export type { ViewMode, ViewToggleProps } from './components/view-toggle';
|
|
87
87
|
export { EntityCardGrid } from './components/entity-card-grid';
|
|
88
88
|
export type { EntityCardGridProps } from './components/entity-card-grid';
|
|
89
|
+
export { ExplorerView, buildTagVocabulary, matchesSelectedTags, UNTAGGED_TOKEN, } from './components/explorer-view';
|
|
90
|
+
export type { ExplorerViewProps, ExplorerColumn, ExplorerTags, ExplorerSearch, ExplorerEmptyState, ExplorerEmptyStates, TagVocabularyEntry, } from './components/explorer-view';
|
|
89
91
|
export { FolderBreadcrumb, FolderRow, FolderPicker, childFolders, folderPathTo, } from './components/folder-nav';
|
|
90
92
|
export type { Folder, FolderBreadcrumbProps, FolderRowProps, FolderPickerProps, } from './components/folder-nav';
|
|
91
93
|
export { CodeBlock } from './components/code-block';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,7 @@ export { TagChips, TagsInput } from './components/tags';
|
|
|
69
69
|
export { OverlayDetailsFields, overlayDetailsPatch } from './components/overlay-details-fields';
|
|
70
70
|
export { ViewToggle, useViewMode } from './components/view-toggle';
|
|
71
71
|
export { EntityCardGrid } from './components/entity-card-grid';
|
|
72
|
+
export { ExplorerView, buildTagVocabulary, matchesSelectedTags, UNTAGGED_TOKEN, } from './components/explorer-view';
|
|
72
73
|
export { FolderBreadcrumb, FolderRow, FolderPicker, childFolders, folderPathTo, } from './components/folder-nav';
|
|
73
74
|
export { CodeBlock } from './components/code-block';
|
|
74
75
|
export { FleetReport } from './components/fleet-report';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"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.8.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.8.0"
|
|
93
93
|
},
|
|
94
94
|
"scripts": {
|
|
95
95
|
"build": "tsc -b tsconfig.build.json && node scripts/copy-assets.mjs",
|
|
@@ -2031,6 +2031,36 @@
|
|
|
2031
2031
|
min-width: 0;
|
|
2032
2032
|
}
|
|
2033
2033
|
|
|
2034
|
+
/* -- Explorer ---------------------------------------------------------------------
|
|
2035
|
+
The shared current-directory explorer: controls row, breadcrumb, tag chips,
|
|
2036
|
+
then the folder/item body. Vertical rhythm only — the body carries its own
|
|
2037
|
+
table/grid. */
|
|
2038
|
+
.tai-explorer {
|
|
2039
|
+
display: flex;
|
|
2040
|
+
flex-direction: column;
|
|
2041
|
+
gap: var(--tai-space-4);
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
/* Search on the leading edge, the view toggle on the trailing edge; wraps under
|
|
2045
|
+
its own width on a narrow surface. */
|
|
2046
|
+
.tai-explorer-controls {
|
|
2047
|
+
display: flex;
|
|
2048
|
+
align-items: center;
|
|
2049
|
+
justify-content: space-between;
|
|
2050
|
+
gap: var(--tai-space-3);
|
|
2051
|
+
flex-wrap: wrap;
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
/* A first-class folder entry (row cell or card): the folder affordance beside
|
|
2055
|
+
its optional actions, the actions pushed to the trailing edge. */
|
|
2056
|
+
.tai-explorer-folder {
|
|
2057
|
+
display: flex;
|
|
2058
|
+
align-items: center;
|
|
2059
|
+
justify-content: space-between;
|
|
2060
|
+
gap: var(--tai-space-2);
|
|
2061
|
+
flex-wrap: wrap;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2034
2064
|
/* -- Card grids ------------------------------------------------------------------- */
|
|
2035
2065
|
.tai-grid-cards {
|
|
2036
2066
|
display: grid;
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ExplorerView<T>` — the shared current-directory explorer every entity screen
|
|
3
|
+
* composes: a breadcrumb over a flat {@link Folder} tree, optional search + tag
|
|
4
|
+
* chips, a list/card toggle, and a body in which FOLDERS are first-class entries
|
|
5
|
+
* sorted above the items (folder rows inside the same table, folder cards inside
|
|
6
|
+
* the same grid). Fully controlled and data-agnostic — the caller owns the item
|
|
7
|
+
* shape via `getItemKey`/`getFolderId`/`renderRow`/`renderCard`, and keeps folder
|
|
8
|
+
* dir / tags / search in the URL or in local state; only the view mode persists
|
|
9
|
+
* internally (per `viewSurface`).
|
|
10
|
+
*
|
|
11
|
+
* The tag glue lives here as exported helpers ({@link buildTagVocabulary},
|
|
12
|
+
* {@link matchesSelectedTags}, {@link UNTAGGED_TOKEN}) so every consuming screen
|
|
13
|
+
* shares one vocabulary/untagged-sentinel/OR-match rule rather than copying it.
|
|
14
|
+
*/
|
|
15
|
+
import type { MouseEvent, ReactNode } from 'react';
|
|
16
|
+
|
|
17
|
+
import { EntityCardGrid } from './entity-card-grid';
|
|
18
|
+
import { childFolders, FolderBreadcrumb, FolderRow, type Folder } from './folder-nav';
|
|
19
|
+
import { SearchIcon } from './icons';
|
|
20
|
+
import { TextInput } from './inputs';
|
|
21
|
+
import { Card, EmptyState } from './primitives';
|
|
22
|
+
import { Table, TBody, TD, TH, THead, TR } from './table';
|
|
23
|
+
import { useViewMode, ViewToggle } from './view-toggle';
|
|
24
|
+
|
|
25
|
+
/** Reserved filter token for items carrying NO tag; namespaced so it never
|
|
26
|
+
* collides with a real tag. */
|
|
27
|
+
export const UNTAGGED_TOKEN = '__untagged__';
|
|
28
|
+
|
|
29
|
+
export interface TagVocabularyEntry {
|
|
30
|
+
readonly token: string;
|
|
31
|
+
readonly label: string;
|
|
32
|
+
readonly count: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The tag vocabulary over `items`, name-sorted, plus an untagged pseudo-tag
|
|
36
|
+
* (labelled `untaggedLabel`) when any item is untagged; a selected token whose
|
|
37
|
+
* items vanished still appears (count 0) so it can be cleared. */
|
|
38
|
+
export function buildTagVocabulary<T>(
|
|
39
|
+
items: readonly T[],
|
|
40
|
+
getTags: (item: T) => readonly string[],
|
|
41
|
+
selectedTags: readonly string[],
|
|
42
|
+
untaggedLabel: string,
|
|
43
|
+
): TagVocabularyEntry[] {
|
|
44
|
+
const counts = new Map<string, number>();
|
|
45
|
+
let untagged = 0;
|
|
46
|
+
for (const item of items) {
|
|
47
|
+
const tags = getTags(item);
|
|
48
|
+
if (tags.length === 0) {
|
|
49
|
+
untagged += 1;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
for (const tag of tags) counts.set(tag, (counts.get(tag) ?? 0) + 1);
|
|
53
|
+
}
|
|
54
|
+
const vocabulary: TagVocabularyEntry[] = [...counts.entries()]
|
|
55
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
56
|
+
.map(([label, count]) => ({ token: label, label, count }));
|
|
57
|
+
if (untagged > 0) {
|
|
58
|
+
vocabulary.push({ token: UNTAGGED_TOKEN, label: untaggedLabel, count: untagged });
|
|
59
|
+
}
|
|
60
|
+
for (const token of selectedTags) {
|
|
61
|
+
if (!vocabulary.some((entry) => entry.token === token)) {
|
|
62
|
+
vocabulary.push({
|
|
63
|
+
token,
|
|
64
|
+
label: token === UNTAGGED_TOKEN ? untaggedLabel : token,
|
|
65
|
+
count: 0,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return vocabulary;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** OR semantics: an empty selection matches everything; otherwise an item
|
|
73
|
+
* matches when it carries any selected tag, or is untagged and UNTAGGED_TOKEN
|
|
74
|
+
* is selected. */
|
|
75
|
+
export function matchesSelectedTags(
|
|
76
|
+
itemTags: readonly string[],
|
|
77
|
+
selected: ReadonlySet<string>,
|
|
78
|
+
): boolean {
|
|
79
|
+
if (selected.size === 0) return true;
|
|
80
|
+
if (itemTags.length === 0) return selected.has(UNTAGGED_TOKEN);
|
|
81
|
+
return itemTags.some((tag) => selected.has(tag));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** One header cell of the table view. `renderRow` must emit exactly this many
|
|
85
|
+
* `<TD>`s per item; folder rows span all of them. */
|
|
86
|
+
export interface ExplorerColumn {
|
|
87
|
+
readonly key: string;
|
|
88
|
+
readonly header: ReactNode;
|
|
89
|
+
readonly numeric?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Enables the tag vocabulary, filter chips, and OR filter. Fully controlled. */
|
|
93
|
+
export interface ExplorerTags<T> {
|
|
94
|
+
readonly getTags: (item: T) => readonly string[];
|
|
95
|
+
readonly selected: readonly string[];
|
|
96
|
+
readonly onChange: (selected: readonly string[]) => void;
|
|
97
|
+
/** The untagged pseudo-tag's visible label (e.g. "Untagged"). */
|
|
98
|
+
readonly untaggedLabel: string;
|
|
99
|
+
/** The chip group's accessible name (e.g. "Filter tools by tag"). */
|
|
100
|
+
readonly filterLabel: string;
|
|
101
|
+
/** Collapse unselected chips beyond this count into a static "+N more"; unset
|
|
102
|
+
* shows every chip. Selected chips always show. */
|
|
103
|
+
readonly maxVisibleTags?: number;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Controlled free-text search. `matches` owns the item shape and casing; it is
|
|
107
|
+
* called only with a non-empty, already-trimmed query. */
|
|
108
|
+
export interface ExplorerSearch<T> {
|
|
109
|
+
readonly value: string;
|
|
110
|
+
readonly onChange: (value: string) => void;
|
|
111
|
+
readonly matches: (item: T, query: string) => boolean;
|
|
112
|
+
/** The input's accessible name. */
|
|
113
|
+
readonly label: string;
|
|
114
|
+
readonly placeholder?: string;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface ExplorerEmptyState {
|
|
118
|
+
readonly title: string;
|
|
119
|
+
readonly description?: string;
|
|
120
|
+
readonly action?: ReactNode;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The folder-aware empty-state ladder — every label caller-supplied. */
|
|
124
|
+
export interface ExplorerEmptyStates {
|
|
125
|
+
/** No items and no folders exist at all. */
|
|
126
|
+
readonly empty: ExplorerEmptyState;
|
|
127
|
+
/** The current folder holds nothing — no items, no subfolders — yet the
|
|
128
|
+
* entity set is not globally empty. */
|
|
129
|
+
readonly emptyFolder: ExplorerEmptyState;
|
|
130
|
+
/** The current folder has items but the active tag/search filter excludes
|
|
131
|
+
* every one, and it has no subfolders to show. */
|
|
132
|
+
readonly noMatch: ExplorerEmptyState;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface ExplorerViewProps<T> {
|
|
136
|
+
readonly items: readonly T[];
|
|
137
|
+
readonly getItemKey: (item: T) => string;
|
|
138
|
+
/** The folder an item is filed in (`null` = the root directory). */
|
|
139
|
+
readonly getFolderId: (item: T) => string | null;
|
|
140
|
+
|
|
141
|
+
readonly folders: readonly Folder[];
|
|
142
|
+
readonly currentFolderId: string | null;
|
|
143
|
+
readonly onNavigate: (folderId: string | null) => void;
|
|
144
|
+
readonly rootLabel: string;
|
|
145
|
+
|
|
146
|
+
/** Persist + drive the list/card toggle under this surface key. */
|
|
147
|
+
readonly viewSurface: string;
|
|
148
|
+
/** The card grid's accessible name; the toggle's is "<label> view". */
|
|
149
|
+
readonly label: string;
|
|
150
|
+
|
|
151
|
+
readonly columns: readonly ExplorerColumn[];
|
|
152
|
+
/** The item's table cells (`<TD>`s) — wrapped in a keyed `<TR>` by the explorer. */
|
|
153
|
+
readonly renderRow: (item: T) => ReactNode;
|
|
154
|
+
/** The item's `<Card>` — wrapped in a keyed `listitem` by the explorer. */
|
|
155
|
+
readonly renderCard: (item: T) => ReactNode;
|
|
156
|
+
|
|
157
|
+
/** Open an item on a pointer click anywhere on its row/card — a convenience
|
|
158
|
+
* ONLY. The accessible activation path stays the interactive element inside
|
|
159
|
+
* the cell (the name link), so the row is never a focusable button; a click
|
|
160
|
+
* originating on a nested control is left to that control. */
|
|
161
|
+
readonly onOpenItem?: (item: T) => void;
|
|
162
|
+
|
|
163
|
+
readonly tags?: ExplorerTags<T>;
|
|
164
|
+
readonly search?: ExplorerSearch<T>;
|
|
165
|
+
|
|
166
|
+
/** Per-folder actions rendered on the folder's row/card (e.g. a kebab). */
|
|
167
|
+
readonly renderFolderActions?: (folder: Folder) => ReactNode;
|
|
168
|
+
|
|
169
|
+
readonly emptyStates: ExplorerEmptyStates;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** A togglable tag chip; `aria-pressed` reflects whether the tag filters the list. */
|
|
173
|
+
function TagChip({
|
|
174
|
+
entry,
|
|
175
|
+
active,
|
|
176
|
+
onToggle,
|
|
177
|
+
}: {
|
|
178
|
+
readonly entry: TagVocabularyEntry;
|
|
179
|
+
readonly active: boolean;
|
|
180
|
+
readonly onToggle: () => void;
|
|
181
|
+
}): ReactNode {
|
|
182
|
+
return (
|
|
183
|
+
<button
|
|
184
|
+
type="button"
|
|
185
|
+
className="tai-chip"
|
|
186
|
+
aria-pressed={active}
|
|
187
|
+
aria-label={`${entry.label} (${String(entry.count)})`}
|
|
188
|
+
onClick={onToggle}
|
|
189
|
+
>
|
|
190
|
+
<span>{entry.label}</span>
|
|
191
|
+
<span>{entry.count}</span>
|
|
192
|
+
</button>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** The filter row: every selected chip plus as many unselected chips as fit under
|
|
197
|
+
* the cap, with the remainder collapsed into a STATIC "+N more" count. An unset
|
|
198
|
+
* cap shows every chip. */
|
|
199
|
+
function TagFilterRow({
|
|
200
|
+
vocabulary,
|
|
201
|
+
selectedSet,
|
|
202
|
+
onToggle,
|
|
203
|
+
filterLabel,
|
|
204
|
+
maxVisibleTags,
|
|
205
|
+
}: {
|
|
206
|
+
readonly vocabulary: readonly TagVocabularyEntry[];
|
|
207
|
+
readonly selectedSet: ReadonlySet<string>;
|
|
208
|
+
readonly onToggle: (token: string) => void;
|
|
209
|
+
readonly filterLabel: string;
|
|
210
|
+
readonly maxVisibleTags: number | undefined;
|
|
211
|
+
}): ReactNode {
|
|
212
|
+
const visible: TagVocabularyEntry[] = [];
|
|
213
|
+
let hidden = 0;
|
|
214
|
+
let unselectedShown = 0;
|
|
215
|
+
for (const entry of vocabulary) {
|
|
216
|
+
if (selectedSet.has(entry.token)) {
|
|
217
|
+
visible.push(entry);
|
|
218
|
+
} else if (maxVisibleTags === undefined || unselectedShown < maxVisibleTags) {
|
|
219
|
+
visible.push(entry);
|
|
220
|
+
unselectedShown += 1;
|
|
221
|
+
} else {
|
|
222
|
+
hidden += 1;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return (
|
|
227
|
+
<div role="group" aria-label={filterLabel} className="tai-row">
|
|
228
|
+
{visible.map((entry) => (
|
|
229
|
+
<TagChip
|
|
230
|
+
key={entry.token}
|
|
231
|
+
entry={entry}
|
|
232
|
+
active={selectedSet.has(entry.token)}
|
|
233
|
+
onToggle={() => {
|
|
234
|
+
onToggle(entry.token);
|
|
235
|
+
}}
|
|
236
|
+
/>
|
|
237
|
+
))}
|
|
238
|
+
{hidden > 0 ? (
|
|
239
|
+
<span className="tai-chip tai-chip-static">{`+${String(hidden)} more`}</span>
|
|
240
|
+
) : null}
|
|
241
|
+
</div>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** A first-class folder entry — a `FolderRow` (icon + name, navigates inward)
|
|
246
|
+
* beside its optional actions, in the layout shared by the row cell and the card. */
|
|
247
|
+
function FolderEntry({
|
|
248
|
+
folder,
|
|
249
|
+
onNavigate,
|
|
250
|
+
renderFolderActions,
|
|
251
|
+
}: {
|
|
252
|
+
readonly folder: Folder;
|
|
253
|
+
readonly onNavigate: (folderId: string | null) => void;
|
|
254
|
+
readonly renderFolderActions: ((folder: Folder) => ReactNode) | undefined;
|
|
255
|
+
}): ReactNode {
|
|
256
|
+
return (
|
|
257
|
+
<div className="tai-explorer-folder">
|
|
258
|
+
<FolderRow folder={folder} onOpen={onNavigate} />
|
|
259
|
+
{renderFolderActions ? renderFolderActions(folder) : null}
|
|
260
|
+
</div>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function ExplorerView<T>({
|
|
265
|
+
items,
|
|
266
|
+
getItemKey,
|
|
267
|
+
getFolderId,
|
|
268
|
+
folders,
|
|
269
|
+
currentFolderId,
|
|
270
|
+
onNavigate,
|
|
271
|
+
rootLabel,
|
|
272
|
+
viewSurface,
|
|
273
|
+
label,
|
|
274
|
+
columns,
|
|
275
|
+
renderRow,
|
|
276
|
+
renderCard,
|
|
277
|
+
onOpenItem,
|
|
278
|
+
tags,
|
|
279
|
+
search,
|
|
280
|
+
renderFolderActions,
|
|
281
|
+
emptyStates,
|
|
282
|
+
}: ExplorerViewProps<T>): ReactNode {
|
|
283
|
+
const [viewMode, setViewMode] = useViewMode(viewSurface);
|
|
284
|
+
|
|
285
|
+
if (viewSurface === '') throw new Error('ExplorerView requires a non-empty viewSurface key.');
|
|
286
|
+
if (columns.length === 0) throw new Error('ExplorerView requires at least one column.');
|
|
287
|
+
|
|
288
|
+
// Nothing anywhere: no items and no folders. A bare empty state, no controls.
|
|
289
|
+
if (items.length === 0 && folders.length === 0) {
|
|
290
|
+
return <EmptyState {...emptyStates.empty} />;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const subfolders = childFolders(folders, currentFolderId);
|
|
294
|
+
const inFolder = items.filter((item) => getFolderId(item) === currentFolderId);
|
|
295
|
+
|
|
296
|
+
const selectedSet = tags !== undefined ? new Set(tags.selected) : undefined;
|
|
297
|
+
const query = search ? search.value.trim() : '';
|
|
298
|
+
const filtered = inFolder.filter((item) => {
|
|
299
|
+
if (tags !== undefined && selectedSet !== undefined && selectedSet.size > 0) {
|
|
300
|
+
if (!matchesSelectedTags(tags.getTags(item), selectedSet)) return false;
|
|
301
|
+
}
|
|
302
|
+
if (search !== undefined && query !== '') {
|
|
303
|
+
if (!search.matches(item, query)) return false;
|
|
304
|
+
}
|
|
305
|
+
return true;
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const vocabulary =
|
|
309
|
+
tags !== undefined
|
|
310
|
+
? buildTagVocabulary(inFolder, tags.getTags, tags.selected, tags.untaggedLabel)
|
|
311
|
+
: [];
|
|
312
|
+
|
|
313
|
+
const toggleTag = (token: string): void => {
|
|
314
|
+
if (tags === undefined || selectedSet === undefined) return;
|
|
315
|
+
const next = selectedSet.has(token)
|
|
316
|
+
? tags.selected.filter((t) => t !== token)
|
|
317
|
+
: [...tags.selected, token];
|
|
318
|
+
tags.onChange(next);
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// The pointer-open props for one item's row/card, present only when `onOpenItem`
|
|
322
|
+
// is set. The handler yields to any nested interactive element the click landed
|
|
323
|
+
// on (a name link, an actions kebab) so it never hijacks its activation; a
|
|
324
|
+
// portalled menu (Radix) never bubbles here, so the role selectors are defensive
|
|
325
|
+
// for an inline menu only.
|
|
326
|
+
const openProps = (
|
|
327
|
+
item: T,
|
|
328
|
+
): { onClick?: (event: MouseEvent<HTMLElement>) => void; style?: { cursor: 'pointer' } } => {
|
|
329
|
+
if (onOpenItem === undefined) return {};
|
|
330
|
+
return {
|
|
331
|
+
onClick: (event) => {
|
|
332
|
+
// A press-drag that selects the name text also fires a click; that is a
|
|
333
|
+
// selection, not an open intent.
|
|
334
|
+
if (window.getSelection()?.isCollapsed === false) return;
|
|
335
|
+
const target = event.target;
|
|
336
|
+
if (
|
|
337
|
+
target instanceof Element &&
|
|
338
|
+
target.closest('button, a, [role="menu"], [role="menuitem"]') !== null
|
|
339
|
+
) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
onOpenItem(item);
|
|
343
|
+
},
|
|
344
|
+
style: { cursor: 'pointer' },
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
const hasEntries = subfolders.length > 0 || filtered.length > 0;
|
|
349
|
+
|
|
350
|
+
let body: ReactNode;
|
|
351
|
+
if (!hasEntries) {
|
|
352
|
+
// The current folder renders nothing. A filter emptied it (`inFolder` non-empty)
|
|
353
|
+
// → "no match"; otherwise the folder is genuinely empty.
|
|
354
|
+
body = (
|
|
355
|
+
<EmptyState {...(inFolder.length > 0 ? emptyStates.noMatch : emptyStates.emptyFolder)} />
|
|
356
|
+
);
|
|
357
|
+
} else if (viewMode === 'cards') {
|
|
358
|
+
body = (
|
|
359
|
+
<EntityCardGrid aria-label={label}>
|
|
360
|
+
{subfolders.map((folder) => (
|
|
361
|
+
<div role="listitem" key={`folder:${folder.id}`}>
|
|
362
|
+
<Card interactive>
|
|
363
|
+
<FolderEntry
|
|
364
|
+
folder={folder}
|
|
365
|
+
onNavigate={onNavigate}
|
|
366
|
+
renderFolderActions={renderFolderActions}
|
|
367
|
+
/>
|
|
368
|
+
</Card>
|
|
369
|
+
</div>
|
|
370
|
+
))}
|
|
371
|
+
{filtered.map((item) => (
|
|
372
|
+
<div role="listitem" key={`item:${getItemKey(item)}`} {...openProps(item)}>
|
|
373
|
+
{renderCard(item)}
|
|
374
|
+
</div>
|
|
375
|
+
))}
|
|
376
|
+
</EntityCardGrid>
|
|
377
|
+
);
|
|
378
|
+
} else {
|
|
379
|
+
// Folder rows share the item table, spanning every column, sorted above items —
|
|
380
|
+
// so a folder-with-only-subfolders is folder ROWS, never a header-only table.
|
|
381
|
+
body = (
|
|
382
|
+
<Table>
|
|
383
|
+
<THead>
|
|
384
|
+
<TR>
|
|
385
|
+
{columns.map((column) => (
|
|
386
|
+
<TH key={column.key} numeric={column.numeric}>
|
|
387
|
+
{column.header}
|
|
388
|
+
</TH>
|
|
389
|
+
))}
|
|
390
|
+
</TR>
|
|
391
|
+
</THead>
|
|
392
|
+
<TBody>
|
|
393
|
+
{subfolders.map((folder) => (
|
|
394
|
+
<TR key={`folder:${folder.id}`}>
|
|
395
|
+
<TD colSpan={columns.length}>
|
|
396
|
+
<FolderEntry
|
|
397
|
+
folder={folder}
|
|
398
|
+
onNavigate={onNavigate}
|
|
399
|
+
renderFolderActions={renderFolderActions}
|
|
400
|
+
/>
|
|
401
|
+
</TD>
|
|
402
|
+
</TR>
|
|
403
|
+
))}
|
|
404
|
+
{filtered.map((item) => (
|
|
405
|
+
<TR key={`item:${getItemKey(item)}`} {...openProps(item)}>
|
|
406
|
+
{renderRow(item)}
|
|
407
|
+
</TR>
|
|
408
|
+
))}
|
|
409
|
+
</TBody>
|
|
410
|
+
</Table>
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return (
|
|
415
|
+
<div className="tai-explorer">
|
|
416
|
+
<div className="tai-explorer-controls">
|
|
417
|
+
{search !== undefined ? (
|
|
418
|
+
<span className="tai-row">
|
|
419
|
+
<SearchIcon />
|
|
420
|
+
<TextInput
|
|
421
|
+
value={search.value}
|
|
422
|
+
aria-label={search.label}
|
|
423
|
+
placeholder={search.placeholder}
|
|
424
|
+
onChange={(event) => {
|
|
425
|
+
search.onChange(event.target.value);
|
|
426
|
+
}}
|
|
427
|
+
/>
|
|
428
|
+
</span>
|
|
429
|
+
) : (
|
|
430
|
+
<span />
|
|
431
|
+
)}
|
|
432
|
+
<ViewToggle value={viewMode} onValueChange={setViewMode} aria-label={`${label} view`} />
|
|
433
|
+
</div>
|
|
434
|
+
|
|
435
|
+
<FolderBreadcrumb
|
|
436
|
+
folders={folders}
|
|
437
|
+
currentFolderId={currentFolderId}
|
|
438
|
+
onNavigate={onNavigate}
|
|
439
|
+
rootLabel={rootLabel}
|
|
440
|
+
/>
|
|
441
|
+
|
|
442
|
+
{tags !== undefined && selectedSet !== undefined && vocabulary.length > 0 ? (
|
|
443
|
+
<TagFilterRow
|
|
444
|
+
vocabulary={vocabulary}
|
|
445
|
+
selectedSet={selectedSet}
|
|
446
|
+
onToggle={toggleTag}
|
|
447
|
+
filterLabel={tags.filterLabel}
|
|
448
|
+
maxVisibleTags={tags.maxVisibleTags}
|
|
449
|
+
/>
|
|
450
|
+
) : null}
|
|
451
|
+
|
|
452
|
+
{body}
|
|
453
|
+
</div>
|
|
454
|
+
);
|
|
455
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -176,6 +176,21 @@ export { ViewToggle, useViewMode } from './components/view-toggle';
|
|
|
176
176
|
export type { ViewMode, ViewToggleProps } from './components/view-toggle';
|
|
177
177
|
export { EntityCardGrid } from './components/entity-card-grid';
|
|
178
178
|
export type { EntityCardGridProps } from './components/entity-card-grid';
|
|
179
|
+
export {
|
|
180
|
+
ExplorerView,
|
|
181
|
+
buildTagVocabulary,
|
|
182
|
+
matchesSelectedTags,
|
|
183
|
+
UNTAGGED_TOKEN,
|
|
184
|
+
} from './components/explorer-view';
|
|
185
|
+
export type {
|
|
186
|
+
ExplorerViewProps,
|
|
187
|
+
ExplorerColumn,
|
|
188
|
+
ExplorerTags,
|
|
189
|
+
ExplorerSearch,
|
|
190
|
+
ExplorerEmptyState,
|
|
191
|
+
ExplorerEmptyStates,
|
|
192
|
+
TagVocabularyEntry,
|
|
193
|
+
} from './components/explorer-view';
|
|
179
194
|
export {
|
|
180
195
|
FolderBreadcrumb,
|
|
181
196
|
FolderRow,
|