@tutti-os/workspace-file-reference 0.0.48 → 0.0.50

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.
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { WorkspaceFileReferenceCopy, WorkspaceFileReferenceAdapter, WorkspaceFileReference, ReferenceHandle, ReferenceLocateTarget, ReferenceNode } from '../contracts/index.js';
2
+ import { WorkspaceFileReferenceCopy, WorkspaceFileReferenceAdapter, WorkspaceFileReference, ReferenceHandle, NodeRef, ReferenceLocateTarget, ReferenceNode } from '../contracts/index.js';
3
3
  import { JSX } from 'react';
4
- import { WorkspaceFileManagerI18nRuntime, WorkspaceFileOpenWithApplication, WorkspaceFileEntry } from '@tutti-os/workspace-file-manager';
4
+ import { WorkspaceFileManagerI18nRuntime, WorkspaceFileEntry, WorkspaceFileOpenWithApplication } from '@tutti-os/workspace-file-manager';
5
5
  import { R as ReferenceSourceAggregator } from '../referenceSourceAggregator-DjtFsLnF.js';
6
6
  import '@tutti-os/workspace-file-manager/services';
7
7
 
@@ -63,5 +63,18 @@ interface ReferenceSourcePickerProps {
63
63
  workspaceId: string;
64
64
  }
65
65
  declare function ReferenceSourcePicker({ aggregator, copy, fileManagerCopy, hostOs, initialTarget, isNodeSelectable, onClose, onConfirm, onConfirmBundles, open, resolveEntryIconUrl, resolveOpenWithApplicationIcon, workspaceId }: ReferenceSourcePickerProps): JSX.Element | null;
66
+ interface ReferenceSourceContentPaneProps {
67
+ aggregator: ReferenceSourceAggregator;
68
+ className?: string;
69
+ copy: WorkspaceFileReferenceCopy;
70
+ fileManagerCopy?: WorkspaceFileManagerI18nRuntime;
71
+ hostOs?: NodeJS.Platform;
72
+ initialNodeRef?: NodeRef | null;
73
+ initialTarget?: ReferenceLocateTarget | null;
74
+ resolveEntryIconUrl?: (entry: WorkspaceFileEntry) => Promise<string | null | undefined>;
75
+ resolveOpenWithApplicationIcon?: (application: WorkspaceFileOpenWithApplication) => JSX.Element | null;
76
+ workspaceId: string;
77
+ }
78
+ declare function ReferenceSourceContentPane({ aggregator, className, copy, fileManagerCopy, hostOs, initialNodeRef, initialTarget, resolveEntryIconUrl, resolveOpenWithApplicationIcon, workspaceId }: ReferenceSourceContentPaneProps): JSX.Element;
66
79
 
67
- export { type ReferenceBundleSelection, type ReferenceGroupedSelection, ReferenceSourcePicker, type ReferenceSourcePickerProps, WorkspaceFileReferencePicker, type WorkspaceFileReferencePickerProps };
80
+ export { type ReferenceBundleSelection, type ReferenceGroupedSelection, ReferenceSourceContentPane, type ReferenceSourceContentPaneProps, ReferenceSourcePicker, type ReferenceSourcePickerProps, WorkspaceFileReferencePicker, type WorkspaceFileReferencePickerProps };
package/dist/ui/index.js CHANGED
@@ -1968,6 +1968,355 @@ function ReferenceSourcePicker({
1968
1968
  }
1969
1969
  return createPortal(dialog, document.body);
1970
1970
  }
1971
+ function ReferenceSourceContentPane({
1972
+ aggregator,
1973
+ className,
1974
+ copy,
1975
+ fileManagerCopy,
1976
+ hostOs = "darwin",
1977
+ initialNodeRef = null,
1978
+ initialTarget = null,
1979
+ resolveEntryIconUrl,
1980
+ resolveOpenWithApplicationIcon,
1981
+ workspaceId
1982
+ }) {
1983
+ const view = useReferenceSourcePickerView({
1984
+ aggregator,
1985
+ workspaceId,
1986
+ open: true,
1987
+ workspaceRootGroupLabel: copy.t("referencePicker.workspaceRootGroup"),
1988
+ initialTarget,
1989
+ isNodeSelectable: () => false,
1990
+ onClose: noopVoid,
1991
+ onConfirm: noopVoid
1992
+ });
1993
+ useEffect3(() => {
1994
+ if (!initialNodeRef) {
1995
+ return;
1996
+ }
1997
+ if (view.selectedGroupKey === nodeRefKey(initialNodeRef)) {
1998
+ return;
1999
+ }
2000
+ const group = view.sidebarGroupsBySource[initialNodeRef.sourceId]?.find(
2001
+ (item) => item.ref.nodeId === initialNodeRef.nodeId
2002
+ );
2003
+ if (!group) {
2004
+ return;
2005
+ }
2006
+ view.selectGroup(group);
2007
+ }, [
2008
+ initialNodeRef,
2009
+ view.selectedGroupKey,
2010
+ view.sidebarGroupsBySource,
2011
+ view.selectGroup
2012
+ ]);
2013
+ const activeFilterSet = new Set(view.activeFilters);
2014
+ const toggleFilter = (id) => {
2015
+ const next = new Set(activeFilterSet);
2016
+ if (next.has(id)) {
2017
+ next.delete(id);
2018
+ } else {
2019
+ next.add(id);
2020
+ }
2021
+ view.setFilters([...next]);
2022
+ };
2023
+ const clearFilters = () => view.setFilters([]);
2024
+ const searchInput = useComposedInputValue2({
2025
+ onCommit: view.setSearchQuery,
2026
+ value: view.searchQuery
2027
+ });
2028
+ const contextMenuRef = useRef2(null);
2029
+ const [contextMenu, setContextMenu] = useState4(null);
2030
+ const [openWithApplications, setOpenWithApplications] = useState4([]);
2031
+ const [openWithLoading, setOpenWithLoading] = useState4(false);
2032
+ const retainedIconEntries = useMemo2(
2033
+ () => collectReferenceNodeIconEntries({
2034
+ childrenByKey: view.childrenByKey,
2035
+ currentEntries: view.currentEntries,
2036
+ expandedKeys: view.expandedKeys,
2037
+ focusedNode: view.focusedNode,
2038
+ searchResults: view.searchResults,
2039
+ selection: view.selection,
2040
+ sidebarGroupsBySource: view.sidebarGroupsBySource
2041
+ }),
2042
+ [
2043
+ view.childrenByKey,
2044
+ view.currentEntries,
2045
+ view.expandedKeys,
2046
+ view.focusedNode,
2047
+ view.searchResults,
2048
+ view.selection,
2049
+ view.sidebarGroupsBySource
2050
+ ]
2051
+ );
2052
+ const iconUrls = useWorkspaceFileEntryIconUrls({
2053
+ entries: retainedIconEntries,
2054
+ includeImageThumbnails: resolveEntryIconUrl !== void 0,
2055
+ resolveEntryIconUrl
2056
+ });
2057
+ useEffect3(() => {
2058
+ if (!contextMenu || !fileManagerCopy) {
2059
+ setOpenWithApplications([]);
2060
+ setOpenWithLoading(false);
2061
+ return;
2062
+ }
2063
+ let cancelled = false;
2064
+ const cachedApplications = view.getCachedOpenWithApplications(
2065
+ contextMenu.node
2066
+ );
2067
+ if (cachedApplications) {
2068
+ setOpenWithApplications(cachedApplications);
2069
+ setOpenWithLoading(false);
2070
+ return;
2071
+ }
2072
+ setOpenWithApplications([]);
2073
+ setOpenWithLoading(true);
2074
+ void view.listOpenWithApplications(contextMenu.node).then((applications) => {
2075
+ if (cancelled) {
2076
+ return;
2077
+ }
2078
+ setOpenWithApplications(applications);
2079
+ setOpenWithLoading(false);
2080
+ }).catch(() => {
2081
+ if (cancelled) {
2082
+ return;
2083
+ }
2084
+ setOpenWithApplications([]);
2085
+ setOpenWithLoading(false);
2086
+ });
2087
+ return () => {
2088
+ cancelled = true;
2089
+ };
2090
+ }, [contextMenu?.node, fileManagerCopy]);
2091
+ useEffect3(() => {
2092
+ if (!contextMenu) {
2093
+ return;
2094
+ }
2095
+ function handlePointerDown(event) {
2096
+ const target = event.target;
2097
+ if (target instanceof Node && contextMenuRef.current?.contains(target)) {
2098
+ return;
2099
+ }
2100
+ if (target instanceof Element && target.closest("[data-workspace-file-manager-submenu]")) {
2101
+ return;
2102
+ }
2103
+ setContextMenu(null);
2104
+ }
2105
+ function handleKeyDown(event) {
2106
+ if (event.key === "Escape") {
2107
+ setContextMenu(null);
2108
+ }
2109
+ }
2110
+ window.addEventListener("pointerdown", handlePointerDown);
2111
+ window.addEventListener("keydown", handleKeyDown);
2112
+ return () => {
2113
+ window.removeEventListener("pointerdown", handlePointerDown);
2114
+ window.removeEventListener("keydown", handleKeyDown);
2115
+ };
2116
+ }, [contextMenu]);
2117
+ const openReferenceContextMenu = (event, node) => {
2118
+ if (!fileManagerCopy || node.kind !== "file") {
2119
+ return;
2120
+ }
2121
+ event.preventDefault();
2122
+ event.stopPropagation();
2123
+ view.setFocusedNode(node);
2124
+ setContextMenu({
2125
+ node,
2126
+ x: event.clientX,
2127
+ y: event.clientY
2128
+ });
2129
+ };
2130
+ const hasSelectedGroup = view.selectedGroupKey != null;
2131
+ return /* @__PURE__ */ jsxs4(
2132
+ "div",
2133
+ {
2134
+ className: cn3(
2135
+ "relative flex min-h-0 min-w-0 flex-1 overflow-hidden bg-[var(--background-fronted)]",
2136
+ className
2137
+ ),
2138
+ "data-slot": "viewport-menu-boundary",
2139
+ "data-workspace-file-menu-boundary": "",
2140
+ style: {
2141
+ "--workspace-file-manager-dialog-overlay-z-index": "20"
2142
+ },
2143
+ children: [
2144
+ /* @__PURE__ */ jsxs4("div", { className: "flex min-h-0 min-w-0 flex-[1.7] flex-col border-r border-[var(--line-1)]", children: [
2145
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 border-b border-[var(--line-1)] p-3", children: [
2146
+ /* @__PURE__ */ jsxs4("div", { className: "relative flex-1", children: [
2147
+ /* @__PURE__ */ jsx4(SearchIcon2, { className: "pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-[var(--text-tertiary)]" }),
2148
+ /* @__PURE__ */ jsx4(
2149
+ Input2,
2150
+ {
2151
+ className: "pl-9",
2152
+ placeholder: copy.t("referencePicker.searchPlaceholder"),
2153
+ value: searchInput.value,
2154
+ onBlur: searchInput.onBlur,
2155
+ onChange: searchInput.onChange,
2156
+ onCompositionEnd: searchInput.onCompositionEnd,
2157
+ onCompositionStart: searchInput.onCompositionStart
2158
+ }
2159
+ )
2160
+ ] }),
2161
+ view.capabilities?.filterable && view.filterCategories.length > 0 ? /* @__PURE__ */ jsx4(
2162
+ FilterCategoryFilter,
2163
+ {
2164
+ categories: view.filterCategories,
2165
+ copy,
2166
+ selected: activeFilterSet,
2167
+ onClear: clearFilters,
2168
+ onToggle: toggleFilter
2169
+ }
2170
+ ) : null
2171
+ ] }),
2172
+ /* @__PURE__ */ jsx4(
2173
+ ScrollArea2,
2174
+ {
2175
+ className: "min-h-0 flex-1",
2176
+ viewportProps: {
2177
+ onScroll: (event) => {
2178
+ const el = event.currentTarget;
2179
+ if (view.hasMore && !view.isLoading && !view.isLoadingMore && el.scrollHeight - el.scrollTop - el.clientHeight < 120) {
2180
+ view.loadMore();
2181
+ }
2182
+ }
2183
+ },
2184
+ children: /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-[2px] p-3", children: [
2185
+ view.isLoading ? /* @__PURE__ */ jsx4(Feedback, { children: /* @__PURE__ */ jsx4(Spinner2, { size: 16 }) }) : view.isQuery ? view.searchResults.length === 0 ? /* @__PURE__ */ jsx4(Feedback, { children: copy.t("referencePicker.emptySearch") }) : view.searchResults.map((node) => /* @__PURE__ */ jsx4(
2186
+ SearchResultRow,
2187
+ {
2188
+ focused: isFocused(view.focusedNode, node),
2189
+ iconUrls,
2190
+ node,
2191
+ selected: view.isSelected(node),
2192
+ onFocus: view.setFocusedNode,
2193
+ onContextMenu: openReferenceContextMenu,
2194
+ onOpen: view.openNode,
2195
+ selectable: view.isSelectable(node),
2196
+ onSingleSelect: view.toggleSingleSelectionAndExpand,
2197
+ onToggle: view.toggleSelection
2198
+ },
2199
+ nodeRefKey(node.ref)
2200
+ )) : view.currentEntries.length === 0 ? /* @__PURE__ */ jsx4(Feedback, { children: copy.t(
2201
+ hasSelectedGroup ? "referencePicker.emptyDirectory" : "referencePicker.selectGroupHint"
2202
+ ) }) : view.currentEntries.map((node) => /* @__PURE__ */ jsx4(
2203
+ TreeNodeRow,
2204
+ {
2205
+ copy,
2206
+ depth: 0,
2207
+ iconUrls,
2208
+ node,
2209
+ onContextMenu: openReferenceContextMenu,
2210
+ view
2211
+ },
2212
+ nodeRefKey(node.ref)
2213
+ )),
2214
+ view.hasMore && (view.isQuery || hasSelectedGroup) ? /* @__PURE__ */ jsxs4(
2215
+ Button3,
2216
+ {
2217
+ className: "mt-1 w-full",
2218
+ disabled: view.isLoadingMore,
2219
+ size: "sm",
2220
+ type: "button",
2221
+ variant: "ghost",
2222
+ onClick: view.loadMore,
2223
+ children: [
2224
+ view.isLoadingMore ? /* @__PURE__ */ jsx4(Spinner2, { className: "text-current", size: 14 }) : null,
2225
+ copy.t("referencePicker.loadMore")
2226
+ ]
2227
+ }
2228
+ ) : null
2229
+ ] })
2230
+ }
2231
+ ),
2232
+ fileManagerCopy ? /* @__PURE__ */ jsx4(
2233
+ WorkspaceFileManagerContextMenu,
2234
+ {
2235
+ busy: view.isOpeningReference,
2236
+ contextMenu: contextMenu ? {
2237
+ entry: referenceNodeToWorkspaceFileEntry(contextMenu.node),
2238
+ x: contextMenu.x,
2239
+ y: contextMenu.y
2240
+ } : null,
2241
+ contextMenuRef,
2242
+ copy: fileManagerCopy,
2243
+ openWithApplications,
2244
+ openWithLoading,
2245
+ positionMode: "viewport",
2246
+ revealInFolderLabel: resolveRevealInFolderLabel(
2247
+ fileManagerCopy,
2248
+ hostOs
2249
+ ),
2250
+ resolveOpenWithApplicationIcon,
2251
+ showCopyAction: false,
2252
+ showCopyPathAction: false,
2253
+ showCreateAction: false,
2254
+ showDeleteAction: false,
2255
+ showExportAction: false,
2256
+ showImportAction: false,
2257
+ showOpenInAppBrowserAction: false,
2258
+ showOpenInDefaultBrowserAction: false,
2259
+ showOpenInFileViewerAction: false,
2260
+ showOpenWithAction: true,
2261
+ showOpenWithOtherAction: true,
2262
+ showRevealInFolderAction: true,
2263
+ showRenameAction: false,
2264
+ onClose: () => setContextMenu(null),
2265
+ onCopy: noopAsync,
2266
+ onCopyPath: noopAsync,
2267
+ onCreateDirectory: noopVoid,
2268
+ onCreateFile: noopVoid,
2269
+ onDelete: noopVoid,
2270
+ onExport: noopAsync,
2271
+ onImport: noopAsync,
2272
+ onOpen: async () => {
2273
+ if (contextMenu) {
2274
+ await view.openNode(contextMenu.node);
2275
+ }
2276
+ },
2277
+ onOpenInAppBrowser: noopAsync,
2278
+ onOpenInDefaultBrowser: noopAsync,
2279
+ onOpenInFileViewer: noopAsync,
2280
+ onOpenWithApplication: async (applicationPath) => {
2281
+ if (contextMenu) {
2282
+ await view.openWithApplication(
2283
+ contextMenu.node,
2284
+ applicationPath
2285
+ );
2286
+ }
2287
+ },
2288
+ onOpenWithOtherApplication: async () => {
2289
+ if (contextMenu) {
2290
+ await view.openWithOtherApplication(
2291
+ contextMenu.node,
2292
+ fileManagerCopy.t("openWithOtherPickerPrompt")
2293
+ );
2294
+ }
2295
+ },
2296
+ onRevealInFolder: async () => {
2297
+ if (contextMenu) {
2298
+ await view.revealNode(contextMenu.node);
2299
+ }
2300
+ },
2301
+ onRename: noopVoid
2302
+ }
2303
+ ) : null
2304
+ ] }),
2305
+ /* @__PURE__ */ jsx4("div", { className: "@max-[760px]/workspace-file-manager:hidden min-h-0 min-w-[220px] flex-1", children: /* @__PURE__ */ jsx4(
2306
+ PreviewInfoPane,
2307
+ {
2308
+ copy,
2309
+ hierarchy: view.breadcrumb,
2310
+ iconUrls,
2311
+ node: view.focusedNode,
2312
+ previewState: view.previewState,
2313
+ sourceLabel: view.activeTabLabel
2314
+ }
2315
+ ) })
2316
+ ]
2317
+ }
2318
+ );
2319
+ }
1971
2320
  function GroupFallbackIcon({
1972
2321
  icon,
1973
2322
  className
@@ -2805,6 +3154,7 @@ function noopVoid() {
2805
3154
  async function noopAsync() {
2806
3155
  }
2807
3156
  export {
3157
+ ReferenceSourceContentPane,
2808
3158
  ReferenceSourcePicker,
2809
3159
  WorkspaceFileReferencePicker
2810
3160
  };