@parallelworks/ui 0.52.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -8
- package/dist/access/AccessDrawer.d.ts +55 -0
- package/dist/access/AccessDrawer.js +445 -0
- package/dist/access/AccessList.d.ts +58 -0
- package/dist/access/AccessList.js +382 -0
- package/dist/access/GrantView.d.ts +35 -0
- package/dist/access/GrantView.js +188 -0
- package/dist/access/GroupPicker.d.ts +35 -0
- package/dist/access/GroupPicker.js +336 -0
- package/dist/access/focus.d.ts +10 -0
- package/dist/access/focus.js +27 -0
- package/dist/access/index.d.ts +3 -0
- package/dist/access/index.js +3 -0
- package/dist/access/model.d.ts +49 -0
- package/dist/access/model.js +129 -0
- package/dist/access/strings.d.ts +122 -0
- package/dist/access/strings.js +151 -0
- package/dist/access/types.d.ts +56 -0
- package/dist/ai/ai.css +5 -3
- package/dist/ai/components/SlashMenu.js +1 -1
- package/dist/ai/components/agent/AgentMessageParts.js +1 -1
- package/dist/ai/strings.js +0 -1
- package/dist/ai/ui/sidebar.js +1 -1
- package/dist/components/Combobox.d.ts +19 -0
- package/dist/components/Combobox.js +101 -50
- package/dist/components/Drawer.d.ts +6 -1
- package/dist/components/Drawer.js +25 -16
- package/dist/components/Field.d.ts +5 -4
- package/dist/components/Field.js +27 -4
- package/dist/components/InfoTip.d.ts +12 -4
- package/dist/components/InfoTip.js +13 -3
- package/dist/components/MarkdownImpl.d.ts +1 -0
- package/dist/components/MarkdownImpl.js +1 -0
- package/dist/components/Menu.js +4 -4
- package/dist/components/MenuEntries.js +1 -1
- package/dist/components/OptionDescription.d.ts +7 -0
- package/dist/components/OptionDescription.js +19 -0
- package/dist/components/Popover.d.ts +4 -1
- package/dist/components/Popover.js +2 -1
- package/dist/components/Provider.d.ts +9 -0
- package/dist/components/Provider.js +4 -0
- package/dist/components/Select.js +13 -11
- package/dist/components/comboboxItems.d.ts +10 -0
- package/dist/components/comboboxItems.js +8 -1
- package/dist/components/floating.d.ts +5 -2
- package/dist/components/floating.js +2 -2
- package/dist/components/focus.d.ts +5 -0
- package/dist/components/focus.js +21 -1
- package/dist/editor/Editor.js +13 -3
- package/dist/editor/Monaco.d.ts +8 -1
- package/dist/editor/Monaco.js +16 -3
- package/dist/editor/editorModel.d.ts +1 -1
- package/dist/editor/editorModel.js +1 -1
- package/dist/editor/index.d.ts +1 -0
- package/dist/editor/index.js +2 -1
- package/dist/editor/languages.d.ts +24 -0
- package/dist/editor/languages.js +31 -0
- package/dist/editor/monacoFeatures.d.ts +7 -0
- package/dist/editor/monacoFeatures.js +19 -0
- package/dist/editor/themes.d.ts +5 -0
- package/dist/editor/themes.js +24 -4
- package/dist/editor/workers.d.ts +3 -3
- package/dist/editor/workers.js +8 -4
- package/dist/editor/yamlLanguage.js +55 -38
- package/dist/file-explorer/FileExplorer.d.ts +18 -4
- package/dist/file-explorer/FileExplorer.js +64 -20
- package/dist/file-explorer/FilePreview/Viewer.js +12 -8
- package/dist/file-explorer/FileRow.d.ts +6 -2
- package/dist/file-explorer/FileRow.js +35 -17
- package/dist/file-explorer/FileRowsWindow.d.ts +2 -1
- package/dist/file-explorer/FileRowsWindow.js +2 -1
- package/dist/file-explorer/FileTable.d.ts +3 -1
- package/dist/file-explorer/FileTable.js +3 -2
- package/dist/file-explorer/TreeView.d.ts +5 -1
- package/dist/file-explorer/TreeView.js +49 -25
- package/dist/file-explorer/helpers.js +3 -3
- package/dist/file-explorer/lib/paging.d.ts +1 -0
- package/dist/file-explorer/lib/paging.js +5 -1
- package/dist/file-explorer/lib/utils.d.ts +3 -0
- package/dist/file-explorer/lib/utils.js +6 -1
- package/dist/form/Wizard/utils.js +2 -1
- package/dist/list/ActionToolbar.js +3 -2
- package/dist/list/ListPage.js +1 -1
- package/dist/list/ListTable.d.ts +5 -0
- package/dist/list/ListTable.js +6 -2
- package/dist/styles/theme.css +82 -62
- package/dist/styles.css +1 -1
- package/dist/theme/derive.d.ts +5 -3
- package/dist/theme/derive.js +61 -3
- package/package.json +9 -2
- package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +0 -6
- package/dist/file-explorer/FilePreview/CodePreviewEditor.js +0 -64
|
@@ -3,8 +3,9 @@ import { ChevronRightIcon, FolderIcon, FolderOpenIcon } from "../icons.js";
|
|
|
3
3
|
import { isDev } from "../dev.js";
|
|
4
4
|
import { positionKeys } from "../components/keys.js";
|
|
5
5
|
import { useStrings } from "../components/Provider.js";
|
|
6
|
+
import { AppLink, isPlainClick } from "../components/AppLink.js";
|
|
6
7
|
import { Skeleton } from "../components/Skeleton.js";
|
|
7
|
-
import { getParentPath } from "./lib/utils.js";
|
|
8
|
+
import { carriesFiles, getParentPath } from "./lib/utils.js";
|
|
8
9
|
import { canPreview } from "./FilePreview/previewType.js";
|
|
9
10
|
import { getNodeIcon } from "./helpers.js";
|
|
10
11
|
import { edgeRow, findRowIndex, firstChildRow, flattenTreeRows, nextFileLimit, parentRow, stepRow } from "./treeRows.js";
|
|
@@ -23,7 +24,7 @@ function rowHeight(row) {
|
|
|
23
24
|
}
|
|
24
25
|
/** The sidebar tree, flattened and windowed. The flat array is the single source
|
|
25
26
|
* of truth for rendering, arrow keys and ARIA. */
|
|
26
|
-
function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath, loadingPaths, onToggleExpand, onSelect, onDropToFolder, onContextMenu, onPreviewFile, paging }) {
|
|
27
|
+
function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath, loadingPaths, onToggleExpand, onSelect, onDropToFolder, onContextMenu, onPreviewFile, pathHref, onFollowLink, paging }) {
|
|
27
28
|
const [scrollEl, setScrollEl] = useState(null);
|
|
28
29
|
const treeLabel = useStrings().fileExplorer.chrome.folders;
|
|
29
30
|
const [fileLimits, setFileLimits] = useState(() => /* @__PURE__ */ new Map());
|
|
@@ -151,6 +152,8 @@ function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath,
|
|
|
151
152
|
}) : /* @__PURE__ */ jsx(TreeRowItem, {
|
|
152
153
|
row,
|
|
153
154
|
isSelected: row.node.path === selectedPath,
|
|
155
|
+
href: pathHref?.(row.node.path),
|
|
156
|
+
onFollowLink,
|
|
154
157
|
onToggleExpand,
|
|
155
158
|
onSelect,
|
|
156
159
|
onDropToFolder,
|
|
@@ -269,6 +272,7 @@ function useSpringLoadedDrop({ node, dropPath, isDirectory, isExpanded, onToggle
|
|
|
269
272
|
dragHandlers: {
|
|
270
273
|
onDragEnter: (e) => {
|
|
271
274
|
e.preventDefault();
|
|
275
|
+
if (!carriesFiles(e.dataTransfer)) return;
|
|
272
276
|
e.stopPropagation();
|
|
273
277
|
hoverCount.current += 1;
|
|
274
278
|
setDragActive(true);
|
|
@@ -280,6 +284,7 @@ function useSpringLoadedDrop({ node, dropPath, isDirectory, isExpanded, onToggle
|
|
|
280
284
|
onDragOver: (e) => e.preventDefault(),
|
|
281
285
|
onDragLeave: (e) => {
|
|
282
286
|
e.preventDefault();
|
|
287
|
+
if (!carriesFiles(e.dataTransfer)) return;
|
|
283
288
|
e.stopPropagation();
|
|
284
289
|
hoverCount.current -= 1;
|
|
285
290
|
if (hoverCount.current > 0) return;
|
|
@@ -287,8 +292,9 @@ function useSpringLoadedDrop({ node, dropPath, isDirectory, isExpanded, onToggle
|
|
|
287
292
|
clear();
|
|
288
293
|
},
|
|
289
294
|
onDrop: (e) => {
|
|
290
|
-
e.stopPropagation();
|
|
291
295
|
e.preventDefault();
|
|
296
|
+
if (!carriesFiles(e.dataTransfer)) return;
|
|
297
|
+
e.stopPropagation();
|
|
292
298
|
hoverCount.current = 0;
|
|
293
299
|
setDragActive(false);
|
|
294
300
|
clear();
|
|
@@ -300,8 +306,9 @@ function useSpringLoadedDrop({ node, dropPath, isDirectory, isExpanded, onToggle
|
|
|
300
306
|
/** Keys a row handles itself: Enter, Space, and Right or Left on a folder that
|
|
301
307
|
* can open or close. The keys that move between rows delegate upward, where
|
|
302
308
|
* the flat array is. There is no typeahead. */
|
|
303
|
-
function dispatchRowKey(e, { node, isDirectory, isExpanded, onSelect, onToggleExpand, onDelegate }) {
|
|
309
|
+
function dispatchRowKey(e, { node, isDirectory, isExpanded, isLink, onSelect, onToggleExpand, onDelegate }) {
|
|
304
310
|
if (e.key === "Enter") {
|
|
311
|
+
if (isLink && (e.metaKey || e.ctrlKey || e.shiftKey)) return;
|
|
305
312
|
e.preventDefault();
|
|
306
313
|
onSelect(e);
|
|
307
314
|
return;
|
|
@@ -319,7 +326,7 @@ function dispatchRowKey(e, { node, isDirectory, isExpanded, onSelect, onToggleEx
|
|
|
319
326
|
}
|
|
320
327
|
onDelegate(e, node);
|
|
321
328
|
}
|
|
322
|
-
var TreeRowItem = memo(function TreeRowItem({ row, isSelected, onToggleExpand, onSelect, onDropToFolder, onContextMenu, onKeyDown }) {
|
|
329
|
+
var TreeRowItem = memo(function TreeRowItem({ row, isSelected, href, onFollowLink, onToggleExpand, onSelect, onDropToFolder, onContextMenu, onKeyDown }) {
|
|
323
330
|
const { node, depth, isExpanded } = row;
|
|
324
331
|
const isDirectory = node.type === "directory";
|
|
325
332
|
const { dragActive, dragHandlers } = useSpringLoadedDrop({
|
|
@@ -335,40 +342,57 @@ var TreeRowItem = memo(function TreeRowItem({ row, isSelected, onToggleExpand, o
|
|
|
335
342
|
onSelect(node.path, node);
|
|
336
343
|
if (isDirectory) onToggleExpand(node.path);
|
|
337
344
|
};
|
|
345
|
+
const handleLinkClick = (e) => {
|
|
346
|
+
if (!isPlainClick(e)) return;
|
|
347
|
+
onFollowLink?.(node);
|
|
348
|
+
if (isDirectory) onToggleExpand(node.path);
|
|
349
|
+
};
|
|
338
350
|
const handleKeyDown = (e) => dispatchRowKey(e, {
|
|
339
351
|
node,
|
|
340
352
|
isDirectory,
|
|
341
353
|
isExpanded,
|
|
354
|
+
isLink: !!href,
|
|
342
355
|
onSelect: handleSelect,
|
|
343
356
|
onToggleExpand,
|
|
344
357
|
onDelegate: onKeyDown
|
|
345
358
|
});
|
|
346
359
|
const customIcon = getNodeIcon(node);
|
|
347
360
|
const label = isDirectory && node.storageId && node.displayName ? node.displayName : node.name;
|
|
361
|
+
const tabIndex = isSelected ? 0 : -1;
|
|
362
|
+
const itemProps = {
|
|
363
|
+
className: cx("group relative flex items-center gap-1.5 pr-2 py-1 rounded-md cursor-pointer", "transition-colors duration-150", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-(--theme-link)", isSelected ? "bg-(--theme-accent)/15 font-medium" : dragActive ? "theme-hover" : "hover:theme-hover"),
|
|
364
|
+
style: indentStyle(depth, isDirectory),
|
|
365
|
+
onContextMenu: (e) => onContextMenu(e, node),
|
|
366
|
+
"aria-level": depth + 1,
|
|
367
|
+
"aria-posinset": row.posInSet,
|
|
368
|
+
"aria-setsize": row.setSize,
|
|
369
|
+
"aria-selected": isSelected,
|
|
370
|
+
...isDirectory && { "aria-expanded": isExpanded },
|
|
371
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(RowIcons, {
|
|
372
|
+
isDirectory,
|
|
373
|
+
isExpanded,
|
|
374
|
+
customIcon
|
|
375
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
376
|
+
className: "text-sm truncate",
|
|
377
|
+
children: label
|
|
378
|
+
})] })
|
|
379
|
+
};
|
|
348
380
|
return /* @__PURE__ */ jsxs("div", {
|
|
349
381
|
className: cx("relative h-full rounded-md transition-[box-shadow,background-color] duration-150", dragActive && "ring-1 ring-(--theme-link)/60"),
|
|
350
382
|
...dragHandlers,
|
|
351
|
-
children: [/* @__PURE__ */ jsx(IndentGuides, { depth }), /* @__PURE__ */
|
|
352
|
-
|
|
353
|
-
style: indentStyle(depth, isDirectory),
|
|
354
|
-
onClick: handleSelect,
|
|
355
|
-
onKeyDown: handleKeyDown,
|
|
356
|
-
onContextMenu: (e) => onContextMenu(e, node),
|
|
383
|
+
children: [/* @__PURE__ */ jsx(IndentGuides, { depth }), href ? /* @__PURE__ */ jsx(AppLink, {
|
|
384
|
+
...itemProps,
|
|
357
385
|
role: "treeitem",
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
369
|
-
className: "text-sm truncate",
|
|
370
|
-
children: label
|
|
371
|
-
})]
|
|
386
|
+
tabIndex,
|
|
387
|
+
href,
|
|
388
|
+
onClick: handleLinkClick,
|
|
389
|
+
onKeyDown: handleKeyDown
|
|
390
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
391
|
+
...itemProps,
|
|
392
|
+
role: "treeitem",
|
|
393
|
+
tabIndex,
|
|
394
|
+
onClick: handleSelect,
|
|
395
|
+
onKeyDown: handleKeyDown
|
|
372
396
|
})]
|
|
373
397
|
});
|
|
374
398
|
});
|
|
@@ -9,7 +9,7 @@ import { Skeleton } from "../components/Skeleton.js";
|
|
|
9
9
|
import { formatBytes } from "../format.js";
|
|
10
10
|
import { useElapsed } from "../components/relativeTime.js";
|
|
11
11
|
import { ListSkeleton } from "../list/ListTable.js";
|
|
12
|
-
import { getFileExtension } from "./lib/utils.js";
|
|
12
|
+
import { carriesFiles, getFileExtension } from "./lib/utils.js";
|
|
13
13
|
import { CorsError } from "./lib/errors.js";
|
|
14
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
15
|
import { useState, useTransition } from "react";
|
|
@@ -467,13 +467,13 @@ function DragDropZone({ onDropFiles, children, className = "" }) {
|
|
|
467
467
|
className: cx("transition-[box-shadow,background-color] duration-150", className, isDragging && "ring-1 ring-(--theme-link) ring-inset bg-(--theme-link)/5"),
|
|
468
468
|
onDragOver: (e) => {
|
|
469
469
|
e.preventDefault();
|
|
470
|
-
if (onDropFiles) setIsDragging(true);
|
|
470
|
+
if (onDropFiles && carriesFiles(e.dataTransfer)) setIsDragging(true);
|
|
471
471
|
},
|
|
472
472
|
onDragLeave: () => setIsDragging(false),
|
|
473
473
|
onDrop: (e) => {
|
|
474
474
|
e.preventDefault();
|
|
475
475
|
setIsDragging(false);
|
|
476
|
-
if (!onDropFiles) return;
|
|
476
|
+
if (!onDropFiles || !carriesFiles(e.dataTransfer)) return;
|
|
477
477
|
onDropFiles(e.dataTransfer.items.length ? e.dataTransfer.items : e.dataTransfer.files);
|
|
478
478
|
},
|
|
479
479
|
children
|
|
@@ -47,6 +47,7 @@ export declare function recordListingError(listings: TListings, path: string, er
|
|
|
47
47
|
/** Keeps the cursor and pages, so a retry resumes paging instead of starting over. */
|
|
48
48
|
export declare function clearListingError(listings: TListings, path: string): TListings;
|
|
49
49
|
export declare function clearListingsUnder(listings: TListings, path: string): TListings;
|
|
50
|
+
export declare function retainListings(listings: TListings, paths: ReadonlySet<string>): TListings;
|
|
50
51
|
/** Tree paths whose children should keep arrival order, since sorting them would
|
|
51
52
|
* reshuffle rows under the user mid-scroll. */
|
|
52
53
|
export declare function incompletePaths(listings: TListings): Set<string>;
|
|
@@ -83,6 +83,10 @@ function clearListingsUnder(listings, path) {
|
|
|
83
83
|
for (const key of listings.keys()) if (key === path || key.startsWith(prefix)) next.delete(key);
|
|
84
84
|
return next;
|
|
85
85
|
}
|
|
86
|
+
function retainListings(listings, paths) {
|
|
87
|
+
if ([...listings.keys()].every((path) => paths.has(path))) return listings;
|
|
88
|
+
return new Map([...listings].filter(([path]) => paths.has(path)));
|
|
89
|
+
}
|
|
86
90
|
/** Tree paths whose children should keep arrival order, since sorting them would
|
|
87
91
|
* reshuffle rows under the user mid-scroll. */
|
|
88
92
|
function incompletePaths(listings) {
|
|
@@ -121,4 +125,4 @@ function nextHydrationStep({ targetResolved, ancestors, isListableDir, listings,
|
|
|
121
125
|
};
|
|
122
126
|
}
|
|
123
127
|
//#endregion
|
|
124
|
-
export { LIST_PAGE_SIZE, advanceListing, beginLoadingMore, canAutoLoadMore, clearListingError, clearListingsUnder, hasMore, incompletePaths, isListed, isLoadingMore, loadMoreError, nextHydrationStep, recordListingError, replaceListing };
|
|
128
|
+
export { LIST_PAGE_SIZE, advanceListing, beginLoadingMore, canAutoLoadMore, clearListingError, clearListingsUnder, hasMore, incompletePaths, isListed, isLoadingMore, loadMoreError, nextHydrationStep, recordListingError, replaceListing, retainListings };
|
|
@@ -32,6 +32,9 @@ export declare function attachmentDisposition(filename: string): string;
|
|
|
32
32
|
export declare function getDirectoryPrefixFromNode(node: TreeNode): string;
|
|
33
33
|
export declare function pruneNodesInsideSelectedDirectories(nodes: TreeNode[]): TreeNode[];
|
|
34
34
|
export declare function collectObjectKeysToDelete(nodes: TreeNode[], listKeysUnderPrefix: (prefix: string) => Promise<string[]>): Promise<string[]>;
|
|
35
|
+
/** True when a drag carries files or folders, not a link or text, such as a
|
|
36
|
+
* row's own link dragged across the explorer. */
|
|
37
|
+
export declare function carriesFiles(dataTransfer: DataTransfer): boolean;
|
|
35
38
|
export declare function getUriScheme(uri: string): string;
|
|
36
39
|
export declare function removeLeadingSlash(path: string): string;
|
|
37
40
|
export declare function removeLeadingAndTrailingSlashes(path: string): string;
|
|
@@ -229,6 +229,11 @@ async function collectObjectKeysToDelete(nodes, listKeysUnderPrefix) {
|
|
|
229
229
|
}
|
|
230
230
|
return Array.from(keys);
|
|
231
231
|
}
|
|
232
|
+
/** True when a drag carries files or folders, not a link or text, such as a
|
|
233
|
+
* row's own link dragged across the explorer. */
|
|
234
|
+
function carriesFiles(dataTransfer) {
|
|
235
|
+
return Array.from(dataTransfer.types).includes("Files");
|
|
236
|
+
}
|
|
232
237
|
function getUriScheme(uri) {
|
|
233
238
|
return uri.match(/^([a-z0-9+.-]+):\/\//i)?.[1] ?? "";
|
|
234
239
|
}
|
|
@@ -290,4 +295,4 @@ function getUploadSessionETA(totalLoadedBytes, totalSizeBytes, lastProgressTime,
|
|
|
290
295
|
};
|
|
291
296
|
}
|
|
292
297
|
//#endregion
|
|
293
|
-
export { attachmentDisposition, calculateUploadNodesTotalSize, collectObjectKeysToDelete, createTreeBuilder, ensureTrailingSlash, getDirectoryNameError, getDirectoryObjectPath, getDirectoryPrefixFromNode, getFileExtension, getNodeChildren, getNodeName, getObjectKeyFromNode, getParentPath, getUploadNodesFromDataTransferItems, getUploadSessionETA, getUriScheme, isClientValid, pruneNodesInsideSelectedDirectories, removeLeadingAndTrailingSlashes, removeLeadingSlash };
|
|
298
|
+
export { attachmentDisposition, calculateUploadNodesTotalSize, carriesFiles, collectObjectKeysToDelete, createTreeBuilder, ensureTrailingSlash, getDirectoryNameError, getDirectoryObjectPath, getDirectoryPrefixFromNode, getFileExtension, getNodeChildren, getNodeName, getObjectKeyFromNode, getParentPath, getUploadNodesFromDataTransferItems, getUploadSessionETA, getUriScheme, isClientValid, pruneNodesInsideSelectedDirectories, removeLeadingAndTrailingSlashes, removeLeadingSlash };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isDev } from "../../dev.js";
|
|
1
2
|
//#region src/form/Wizard/utils.ts
|
|
2
3
|
function isWizardMeta(value) {
|
|
3
4
|
return typeof value === "object" && value !== null && "wizard" in value;
|
|
@@ -16,7 +17,7 @@ function parseWizardConfig(options) {
|
|
|
16
17
|
stepOrder.push(key);
|
|
17
18
|
}
|
|
18
19
|
if (stepOrder.length === 0) {
|
|
19
|
-
if (
|
|
20
|
+
if (isDev()) console.warn("Wizard mode enabled but no steps found");
|
|
20
21
|
return null;
|
|
21
22
|
}
|
|
22
23
|
return {
|
|
@@ -2,6 +2,7 @@ import { cx } from "../cx.js";
|
|
|
2
2
|
import { buttonClasses } from "../components/buttonClasses.js";
|
|
3
3
|
import { MoreIcon } from "../icons.js";
|
|
4
4
|
import { MenuPopup, MenuSeparator } from "../components/Menu.js";
|
|
5
|
+
import { isDev } from "../dev.js";
|
|
5
6
|
import { Tooltip } from "../components/Tooltip.js";
|
|
6
7
|
import { useStrings } from "../components/Provider.js";
|
|
7
8
|
import { AppLink } from "../components/AppLink.js";
|
|
@@ -321,7 +322,7 @@ var warnedPrimary = /* @__PURE__ */ new Set();
|
|
|
321
322
|
/** Warns in development when more than one action is primary: the fill marks
|
|
322
323
|
* the one next step, so two of them mark none. */
|
|
323
324
|
function warnIfManyPrimary(items) {
|
|
324
|
-
if (
|
|
325
|
+
if (!isDev()) return;
|
|
325
326
|
const labels = items.flatMap((item) => "label" in item && item.primary ? [item.label] : []);
|
|
326
327
|
const names = labels.map((label) => `"${label}"`).join(", ");
|
|
327
328
|
if (labels.length < 2 || warnedPrimary.has(names)) return;
|
|
@@ -332,7 +333,7 @@ var warnedIcons = /* @__PURE__ */ new Set();
|
|
|
332
333
|
/** Warns in development when two actions share an icon: folded to their icons
|
|
333
334
|
* in a narrow toolbar, they would look the same. */
|
|
334
335
|
function warnIfIconsRepeat(items) {
|
|
335
|
-
if (
|
|
336
|
+
if (!isDev()) return;
|
|
336
337
|
const byIcon = /* @__PURE__ */ new Map();
|
|
337
338
|
for (const item of items) {
|
|
338
339
|
if ("element" in item || !isValidElement(item.icon) || typeof item.icon.type === "string") continue;
|
package/dist/list/ListPage.js
CHANGED
|
@@ -89,7 +89,7 @@ function ListRow({ href, onActivate, items, goTo, openMenu, pinnedActions, selec
|
|
|
89
89
|
const pinnedLabels = new Set((pinnedActions ?? []).map((a) => a.label));
|
|
90
90
|
const hasOverflowItems = items.some((item) => !isMenuDivider(item) && (isMenuSubmenu(item) || !pinnedLabels.has(item.label)));
|
|
91
91
|
return /* @__PURE__ */ jsxs("tr", {
|
|
92
|
-
className: cx("group", selected ? "bg-(--theme-accent-subtle)/60" : menuActive ? "theme-hover" : "hover:theme-hover", (href || onActivate || selectionActive) && "cursor-pointer", stretch && "relative [&_:is(a,button,input,label):not([data-row-link])]:relative [&_:is(a,button,input,label):not([data-row-link])]:z-[1]", className),
|
|
92
|
+
className: cx("group", selected ? "bg-(--theme-accent-subtle)/60" : menuActive ? "theme-hover" : "hover:theme-hover", (href || onActivate || selectionActive) && "cursor-pointer", stretch && "relative [&_:is(a,button,input,label,[role=checkbox]):not([data-row-link])]:relative [&_:is(a,button,input,label,[role=checkbox]):not([data-row-link])]:z-[1]", className),
|
|
93
93
|
onClick: handleRowClick,
|
|
94
94
|
...rowContextMenuProps(openRowMenu, items),
|
|
95
95
|
children: [
|
package/dist/list/ListTable.d.ts
CHANGED
|
@@ -28,6 +28,11 @@ export declare const listTableFixedProps: {
|
|
|
28
28
|
/** True inside a `ListRow` whose name link should take the whole row's
|
|
29
29
|
* clicks: it navigates, and no selection claims plain clicks. */
|
|
30
30
|
export declare const StretchRowLinkContext: import("react").Context<boolean>;
|
|
31
|
+
export declare const STRETCHED_LINK = "after:absolute after:inset-0 after:content-[''] focus-visible:outline-none focus-visible:after:outline-2 focus-visible:after:-outline-offset-2 focus-visible:after:outline-(--theme-link)";
|
|
32
|
+
/** The row a `STRETCHED_LINK` covers: its box, with the row's other controls
|
|
33
|
+
* raised above the link so they keep their own clicks. A checkbox is a
|
|
34
|
+
* `role="checkbox"` span, not an input, so the role names it. */
|
|
35
|
+
export declare const STRETCHED_LINK_ROW = "relative [&_:is(a,button,input,label,[role=checkbox]):not([data-row-link])]:relative [&_:is(a,button,input,label,[role=checkbox]):not([data-row-link])]:z-[1]";
|
|
31
36
|
export declare function NameCell({ icon, name, subtitle, href, badge, title, children, }: {
|
|
32
37
|
icon: ReactNode;
|
|
33
38
|
name: string;
|
package/dist/list/ListTable.js
CHANGED
|
@@ -37,6 +37,10 @@ var listTableFixedProps = {
|
|
|
37
37
|
* clicks: it navigates, and no selection claims plain clicks. */
|
|
38
38
|
var StretchRowLinkContext = createContext(false);
|
|
39
39
|
var STRETCHED_LINK = "after:absolute after:inset-0 after:content-[''] focus-visible:outline-none focus-visible:after:outline-2 focus-visible:after:-outline-offset-2 focus-visible:after:outline-(--theme-link)";
|
|
40
|
+
/** The row a `STRETCHED_LINK` covers: its box, with the row's other controls
|
|
41
|
+
* raised above the link so they keep their own clicks. A checkbox is a
|
|
42
|
+
* `role="checkbox"` span, not an input, so the role names it. */
|
|
43
|
+
var STRETCHED_LINK_ROW = "relative [&_:is(a,button,input,label,[role=checkbox]):not([data-row-link])]:relative [&_:is(a,button,input,label,[role=checkbox]):not([data-row-link])]:z-[1]";
|
|
40
44
|
function NameCell({ icon, name, subtitle, href, badge, title, children }) {
|
|
41
45
|
const stretch = useContext(StretchRowLinkContext);
|
|
42
46
|
const inner = /* @__PURE__ */ jsxs(Fragment, { children: [icon, /* @__PURE__ */ jsxs("div", {
|
|
@@ -58,7 +62,7 @@ function NameCell({ icon, name, subtitle, href, badge, title, children }) {
|
|
|
58
62
|
children: [href ? /* @__PURE__ */ jsx(AppLink, {
|
|
59
63
|
href,
|
|
60
64
|
"data-row-link": stretch || void 0,
|
|
61
|
-
className: cx("group/namecell flex items-center gap-2.5 min-w-0 cursor-pointer", stretch &&
|
|
65
|
+
className: cx("group/namecell flex items-center gap-2.5 min-w-0 cursor-pointer", stretch && "after:absolute after:inset-0 after:content-[''] focus-visible:outline-none focus-visible:after:outline-2 focus-visible:after:-outline-offset-2 focus-visible:after:outline-(--theme-link)"),
|
|
62
66
|
children: inner
|
|
63
67
|
}) : /* @__PURE__ */ jsx("div", {
|
|
64
68
|
className: "flex items-center gap-2.5 min-w-0",
|
|
@@ -203,4 +207,4 @@ function ListActionsHeader({ view, actionCount = 0, className }) {
|
|
|
203
207
|
}
|
|
204
208
|
ListActionsHeader.isTableHeader = true;
|
|
205
209
|
//#endregion
|
|
206
|
-
export { GroupRow, HEADERS_OFF, ListActionsHeader, ListError, ListSelectAllHeader, ListSkeleton, NAME_MIN_WIDTH_PX, NameCell, RowSelectCheckbox, StretchRowLinkContext, actionsColumnWidth, listTableFixedProps, listTableProps };
|
|
210
|
+
export { GroupRow, HEADERS_OFF, ListActionsHeader, ListError, ListSelectAllHeader, ListSkeleton, NAME_MIN_WIDTH_PX, NameCell, RowSelectCheckbox, STRETCHED_LINK, STRETCHED_LINK_ROW, StretchRowLinkContext, actionsColumnWidth, listTableFixedProps, listTableProps };
|
package/dist/styles/theme.css
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* The theme contract: `theme-*` utilities over the `--theme-*` tokens, which
|
|
2
2
|
* src/theme generates from a scheme of three choices (base, accent, contrast).
|
|
3
3
|
* Hosts set the tokens at runtime with applyTheme; the defaults below are the
|
|
4
|
-
* default theme's light
|
|
5
|
-
* wide-gamut screens.
|
|
4
|
+
* default theme's light and dark schemes, for standalone use and for any token
|
|
5
|
+
* a host leaves unset, with display-p3 values for wide-gamut screens. Each pairs
|
|
6
|
+
* its modes with light-dark(), so it follows the CSS color-scheme a host sets.
|
|
6
7
|
*
|
|
7
8
|
* Sidebar tokens (--theme-sidebar-*) are part of the contract but have no
|
|
8
9
|
* defaults here: hosts supply per-site fallbacks at the use sites, and a global
|
|
@@ -10,75 +11,94 @@
|
|
|
10
11
|
|
|
11
12
|
/* generated:start (src/theme/derive.test.ts checks this; UPDATE_THEME_CSS=1 rewrites it) */
|
|
12
13
|
:root {
|
|
13
|
-
--theme-app-bg: #f3f4f6;
|
|
14
|
-
--theme-panel-bg: #fcfeff;
|
|
15
|
-
--theme-panel-hover: #f2f5f9;
|
|
16
|
-
--theme-muted-panel-bg: #e7eaee;
|
|
17
|
-
--theme-hover: #e3e5e9;
|
|
18
|
-
--theme-input-bg: #fafcfe;
|
|
19
|
-
--theme-input-disabled-bg: #ebeef1;
|
|
20
|
-
--theme-app: #0a101b;
|
|
21
|
-
--theme-muted-text-color: #4e5664;
|
|
22
|
-
--theme-placeholder: #7e8796;
|
|
23
|
-
--theme-link: #06354f;
|
|
24
|
-
--theme-border: #cacdd0;
|
|
25
|
-
--theme-border-strong: #a3a6a9;
|
|
26
|
-
--theme-accent: #06354f;
|
|
27
|
-
--theme-accent-text: #ffffff;
|
|
28
|
-
--theme-accent-hover: #002841;
|
|
29
|
-
--theme-accent-subtle: #d3ebfc;
|
|
30
|
-
--theme-focus: #06354f;
|
|
31
|
-
--theme-focus-ring: rgba(6, 53, 79, 0.25);
|
|
32
|
-
--theme-success: #00973d;
|
|
33
|
-
--theme-success-text: #006226;
|
|
14
|
+
--theme-app-bg: light-dark(#f3f4f6, #111418);
|
|
15
|
+
--theme-panel-bg: light-dark(#fcfeff, #151c25);
|
|
16
|
+
--theme-panel-hover: light-dark(#f2f5f9, #1e262e);
|
|
17
|
+
--theme-muted-panel-bg: light-dark(#e7eaee, #1c242c);
|
|
18
|
+
--theme-hover: light-dark(#e3e5e9, #1f2730);
|
|
19
|
+
--theme-input-bg: light-dark(#fafcfe, #182028);
|
|
20
|
+
--theme-input-disabled-bg: light-dark(#ebeef1, #131a22);
|
|
21
|
+
--theme-app: light-dark(#0a101b, #e2eaf3);
|
|
22
|
+
--theme-muted-text-color: light-dark(#4e5664, #c1c9d2);
|
|
23
|
+
--theme-placeholder: light-dark(#7e8796, #9da5ad);
|
|
24
|
+
--theme-link: light-dark(#06354f, #8dcfff);
|
|
25
|
+
--theme-border: light-dark(#cacdd0, #30363d);
|
|
26
|
+
--theme-border-strong: light-dark(#a3a6a9, #4f565d);
|
|
27
|
+
--theme-accent: light-dark(#06354f, #5b9ccf);
|
|
28
|
+
--theme-accent-text: light-dark(#ffffff, #000000);
|
|
29
|
+
--theme-accent-hover: light-dark(#002841, #6aace0);
|
|
30
|
+
--theme-accent-subtle: light-dark(#d3ebfc, #0f2638);
|
|
31
|
+
--theme-focus: light-dark(#06354f, #5b9ccf);
|
|
32
|
+
--theme-focus-ring: light-dark(rgba(6, 53, 79, 0.25), rgba(91, 156, 207, 0.35));
|
|
33
|
+
--theme-success: light-dark(#00973d, #00bf54);
|
|
34
|
+
--theme-success-text: light-dark(#006226, #65e387);
|
|
34
35
|
--theme-success-solid: #00873c;
|
|
35
|
-
--theme-success-muted: rgba(0, 151, 61, 0.1);
|
|
36
|
-
--theme-error: #ea4841;
|
|
37
|
-
--theme-error-text: #a11a1b;
|
|
36
|
+
--theme-success-muted: light-dark(rgba(0, 151, 61, 0.1), rgba(0, 191, 84, 0.15));
|
|
37
|
+
--theme-error: light-dark(#ea4841, #ff6056);
|
|
38
|
+
--theme-error-text: light-dark(#a11a1b, #ffb8af);
|
|
38
39
|
--theme-error-solid: #db3934;
|
|
39
|
-
--theme-error-muted: rgba(234, 72, 65, 0.1);
|
|
40
|
-
--theme-warning: #bd7100;
|
|
41
|
-
--theme-warning-text: #7b4a00;
|
|
40
|
+
--theme-error-muted: light-dark(rgba(234, 72, 65, 0.1), rgba(255, 96, 86, 0.15));
|
|
41
|
+
--theme-warning: light-dark(#bd7100, #dd8900);
|
|
42
|
+
--theme-warning-text: light-dark(#7b4a00, #ffbe6a);
|
|
42
43
|
--theme-warning-solid: #a76900;
|
|
43
|
-
--theme-warning-muted: rgba(189, 113, 0, 0.1);
|
|
44
|
-
--theme-info: #0681f8;
|
|
45
|
-
--theme-info-text: #0050af;
|
|
46
|
-
--theme-info-solid: #0073e8;
|
|
47
|
-
--theme-info-muted: rgba(6, 129, 248, 0.1);
|
|
48
|
-
--theme-favorite: #e7457a;
|
|
49
|
-
--theme-favorite-text: #9e174b;
|
|
44
|
+
--theme-warning-muted: light-dark(rgba(189, 113, 0, 0.1), rgba(221, 137, 0, 0.15));
|
|
45
|
+
--theme-info: light-dark(#0681f8, #499fff);
|
|
46
|
+
--theme-info-text: light-dark(#0050af, #a6cfff);
|
|
47
|
+
--theme-info-solid: light-dark(#0073e8, #0073e9);
|
|
48
|
+
--theme-info-muted: light-dark(rgba(6, 129, 248, 0.1), rgba(73, 159, 255, 0.15));
|
|
49
|
+
--theme-favorite: light-dark(#e7457a, #fe5c8e);
|
|
50
|
+
--theme-favorite-text: light-dark(#9e174b, #ffb7c7);
|
|
50
51
|
--theme-favorite-solid: #d7366e;
|
|
51
|
-
--theme-favorite-muted: rgba(231, 69, 122, 0.1);
|
|
52
|
-
--theme-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.07);
|
|
53
|
-
--theme-shadow:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
--theme-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
--theme-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
--theme-code-
|
|
63
|
-
--theme-code-
|
|
64
|
-
--theme-code-
|
|
65
|
-
--theme-
|
|
66
|
-
--theme-
|
|
67
|
-
--theme-
|
|
68
|
-
--theme-
|
|
69
|
-
--theme-
|
|
70
|
-
--theme-
|
|
71
|
-
--theme-ansi-
|
|
72
|
-
--theme-ansi-
|
|
52
|
+
--theme-favorite-muted: light-dark(rgba(231, 69, 122, 0.1), rgba(254, 92, 142, 0.15));
|
|
53
|
+
--theme-shadow-sm: 0 1px 2px light-dark(rgba(0, 0, 0, 0.07), rgba(0, 0, 0, 0.35));
|
|
54
|
+
--theme-shadow:
|
|
55
|
+
0 4px 6px -1px light-dark(rgba(0, 0, 0, 0.07), rgba(0, 0, 0, 0.35)),
|
|
56
|
+
0 2px 4px -2px light-dark(rgba(0, 0, 0, 0.07), rgba(0, 0, 0, 0.35));
|
|
57
|
+
--theme-shadow-lg:
|
|
58
|
+
0 10px 15px -3px light-dark(rgba(0, 0, 0, 0.07), rgba(0, 0, 0, 0.35)),
|
|
59
|
+
0 4px 6px -4px light-dark(rgba(0, 0, 0, 0.07), rgba(0, 0, 0, 0.35));
|
|
60
|
+
--theme-shadow-xl:
|
|
61
|
+
0 25px 80px -20px light-dark(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.6)),
|
|
62
|
+
0 10px 30px -10px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.4));
|
|
63
|
+
--theme-code-bg: light-dark(#e7eaee, #1c242c);
|
|
64
|
+
--theme-code-text: light-dark(#1c2330, #e1e9f2);
|
|
65
|
+
--theme-code-comment: light-dark(#555d6c, #c0c8d1);
|
|
66
|
+
--theme-code-keyword: light-dark(#36617d, #8cceff);
|
|
67
|
+
--theme-code-string: light-dark(#196a24, #8bd98d);
|
|
68
|
+
--theme-code-number: light-dark(#944500, #ffb882);
|
|
69
|
+
--theme-code-function: light-dark(#6c4b9e, #d3bcff);
|
|
70
|
+
--theme-code-type: light-dark(#006565, #31dbdb);
|
|
71
|
+
--theme-code-property: light-dark(#5a51a5, #31dbdb);
|
|
72
|
+
--theme-ansi-black: light-dark(#1c2330, #c0c8d1);
|
|
73
|
+
--theme-ansi-red: light-dark(#a3322d, #ffb5ab);
|
|
74
|
+
--theme-ansi-green: light-dark(#006a12, #7fdb83);
|
|
75
|
+
--theme-ansi-yellow: light-dark(#755800, #edc23e);
|
|
76
|
+
--theme-ansi-blue: light-dark(#0b5aae, #9ecbff);
|
|
77
|
+
--theme-ansi-magenta: light-dark(#8d3a88, #ffaafe);
|
|
78
|
+
--theme-ansi-cyan: light-dark(#00666c, #00dbe5);
|
|
79
|
+
--theme-ansi-white: light-dark(#555d6c, #e1e9f2);
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
@media (color-gamut: p3) {
|
|
76
83
|
:root {
|
|
77
|
-
--theme-success: color(display-p3 0.1559 0.5942 0.2459);
|
|
84
|
+
--theme-success: light-dark(color(display-p3 0.1559 0.5942 0.2459), #00bf54);
|
|
78
85
|
--theme-success-solid: color(display-p3 0.0738 0.5422 0.1959);
|
|
79
|
-
--theme-success-muted:
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
--theme-success-muted: light-dark(
|
|
87
|
+
color(display-p3 0.1559 0.5942 0.2459 / 0.1),
|
|
88
|
+
rgba(0, 191, 84, 0.15)
|
|
89
|
+
);
|
|
90
|
+
--theme-warning: light-dark(#bd7100, color(display-p3 0.8343 0.5429 0));
|
|
91
|
+
--theme-warning-solid: light-dark(
|
|
92
|
+
color(display-p3 0.6474 0.4089 0),
|
|
93
|
+
color(display-p3 0.6478 0.4092 0)
|
|
94
|
+
);
|
|
95
|
+
--theme-warning-muted: light-dark(
|
|
96
|
+
rgba(189, 113, 0, 0.1),
|
|
97
|
+
color(display-p3 0.8343 0.5429 0 / 0.15)
|
|
98
|
+
);
|
|
99
|
+
--theme-code-number: light-dark(#944500, color(display-p3 1 0.7209 0.5024));
|
|
100
|
+
--theme-ansi-red: light-dark(#a3322d, color(display-p3 1 0.7032 0.6565));
|
|
101
|
+
--theme-ansi-cyan: light-dark(color(display-p3 0 0.4024 0.4329), #00dbe5);
|
|
82
102
|
}
|
|
83
103
|
}
|
|
84
104
|
/* generated:end */
|