@dxos/plugin-search 0.7.4 → 0.7.5-labs.401163d

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.
Files changed (52) hide show
  1. package/dist/lib/browser/app-graph-builder-4C2ZPCED.mjs +41 -0
  2. package/dist/lib/browser/app-graph-builder-4C2ZPCED.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-4L4PWJYC.mjs → chunk-B532NWHM.mjs} +3 -3
  4. package/dist/lib/browser/chunk-B532NWHM.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-GGOOQO2C.mjs +133 -0
  6. package/dist/lib/browser/chunk-GGOOQO2C.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-Z745WIBH.mjs +21 -0
  8. package/dist/lib/browser/chunk-Z745WIBH.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +61 -577
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/intent-resolver-MKBD2LPH.mjs +22 -0
  12. package/dist/lib/browser/intent-resolver-MKBD2LPH.mjs.map +7 -0
  13. package/dist/lib/browser/meta.json +1 -1
  14. package/dist/lib/browser/react-surface-CSJGZ5JK.mjs +343 -0
  15. package/dist/lib/browser/react-surface-CSJGZ5JK.mjs.map +7 -0
  16. package/dist/types/src/SearchPlugin.d.ts +1 -3
  17. package/dist/types/src/SearchPlugin.d.ts.map +1 -1
  18. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  19. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  20. package/dist/types/src/capabilities/index.d.ts +180 -0
  21. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  22. package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
  23. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  24. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  25. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  26. package/dist/types/src/components/SearchDialog.d.ts +5 -8
  27. package/dist/types/src/components/SearchDialog.d.ts.map +1 -1
  28. package/dist/types/src/components/SearchResults/SearchResults.d.ts +3 -2
  29. package/dist/types/src/components/SearchResults/SearchResults.d.ts.map +1 -1
  30. package/dist/types/src/index.d.ts +1 -2
  31. package/dist/types/src/index.d.ts.map +1 -1
  32. package/dist/types/src/meta.d.ts +1 -2
  33. package/dist/types/src/meta.d.ts.map +1 -1
  34. package/dist/types/src/types.d.ts +11 -4
  35. package/dist/types/src/types.d.ts.map +1 -1
  36. package/dist/types/tsconfig.tsbuildinfo +1 -0
  37. package/package.json +19 -27
  38. package/src/SearchPlugin.tsx +35 -101
  39. package/src/capabilities/app-graph-builder.ts +36 -0
  40. package/src/capabilities/index.ts +9 -0
  41. package/src/capabilities/intent-resolver.ts +18 -0
  42. package/src/capabilities/react-surface.tsx +39 -0
  43. package/src/components/SearchDialog.tsx +28 -44
  44. package/src/components/SearchResults/SearchResults.tsx +30 -43
  45. package/src/index.ts +1 -4
  46. package/src/meta.ts +1 -1
  47. package/src/search-sync.ts +1 -1
  48. package/src/search.ts +1 -1
  49. package/src/types.tsx +7 -16
  50. package/dist/lib/browser/chunk-4L4PWJYC.mjs.map +0 -7
  51. package/dist/lib/browser/meta.mjs +0 -11
  52. package/dist/lib/browser/meta.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-search",
3
- "version": "0.7.4",
3
+ "version": "0.7.5-labs.401163d",
4
4
  "description": "Braneframe sketch plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -11,19 +11,11 @@
11
11
  ".": {
12
12
  "types": "./dist/types/src/index.d.ts",
13
13
  "browser": "./dist/lib/browser/index.mjs"
14
- },
15
- "./meta": {
16
- "types": "./dist/types/src/meta.d.ts",
17
- "browser": "./dist/lib/browser/meta.mjs"
18
14
  }
19
15
  },
20
16
  "types": "dist/types/src/index.d.ts",
21
17
  "typesVersions": {
22
- "*": {
23
- "meta": [
24
- "dist/types/src/meta.d.ts"
25
- ]
26
- }
18
+ "*": {}
27
19
  },
28
20
  "files": [
29
21
  "dist",
@@ -32,17 +24,17 @@
32
24
  "dependencies": {
33
25
  "@effect/schema": "^0.75.5",
34
26
  "main-thread-scheduling": "^14.1.1",
35
- "@dxos/app-framework": "0.7.4",
36
- "@dxos/debug": "0.7.4",
37
- "@dxos/live-object": "0.7.4",
38
- "@dxos/echo-schema": "0.7.4",
39
- "@dxos/plugin-graph": "0.7.4",
40
- "@dxos/plugin-space": "0.7.4",
41
- "@dxos/react-client": "0.7.4",
42
- "@dxos/plugin-markdown": "0.7.4",
43
- "@dxos/react-ui-card": "0.7.4",
44
- "@dxos/react-ui-mosaic": "0.7.4",
45
- "@dxos/react-ui-searchlist": "0.7.4"
27
+ "@dxos/app-framework": "0.7.5-labs.401163d",
28
+ "@dxos/debug": "0.7.5-labs.401163d",
29
+ "@dxos/echo-schema": "0.7.5-labs.401163d",
30
+ "@dxos/live-object": "0.7.5-labs.401163d",
31
+ "@dxos/plugin-space": "0.7.5-labs.401163d",
32
+ "@dxos/react-client": "0.7.5-labs.401163d",
33
+ "@dxos/plugin-markdown": "0.7.5-labs.401163d",
34
+ "@dxos/plugin-graph": "0.7.5-labs.401163d",
35
+ "@dxos/react-ui-card": "0.7.5-labs.401163d",
36
+ "@dxos/react-ui-searchlist": "0.7.5-labs.401163d",
37
+ "@dxos/schema": "0.7.5-labs.401163d"
46
38
  },
47
39
  "devDependencies": {
48
40
  "@phosphor-icons/react": "^2.1.5",
@@ -51,17 +43,17 @@
51
43
  "react": "~18.2.0",
52
44
  "react-dom": "~18.2.0",
53
45
  "vite": "5.4.7",
54
- "@dxos/random": "0.7.4",
55
- "@dxos/react-ui": "0.7.4",
56
- "@dxos/react-ui-theme": "0.7.4",
57
- "@dxos/storybook-utils": "0.7.4"
46
+ "@dxos/random": "0.7.5-labs.401163d",
47
+ "@dxos/react-ui": "0.7.5-labs.401163d",
48
+ "@dxos/react-ui-theme": "0.7.5-labs.401163d",
49
+ "@dxos/storybook-utils": "0.7.5-labs.401163d"
58
50
  },
59
51
  "peerDependencies": {
60
52
  "@phosphor-icons/react": "^2.1.5",
61
53
  "react": "~18.2.0",
62
54
  "react-dom": "~18.2.0",
63
- "@dxos/react-ui": "0.7.4",
64
- "@dxos/react-ui-theme": "0.7.4"
55
+ "@dxos/react-ui-theme": "0.7.5-labs.401163d",
56
+ "@dxos/react-ui": "0.7.5-labs.401163d"
65
57
  },
66
58
  "publishConfig": {
67
59
  "access": "public"
@@ -2,45 +2,27 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React from 'react';
5
+ import { contributes, Events, defineModule, definePlugin, Capabilities } from '@dxos/app-framework';
6
6
 
7
- import {
8
- type PluginDefinition,
9
- type LocationProvides,
10
- type GraphProvides,
11
- type Plugin,
12
- resolvePlugin,
13
- parseIntentPlugin,
14
- parseGraphPlugin,
15
- parseNavigationPlugin,
16
- LayoutAction,
17
- firstIdInPart,
18
- } from '@dxos/app-framework';
19
- import { createExtension, type Node } from '@dxos/plugin-graph';
20
- import { getActiveSpace } from '@dxos/plugin-space';
21
-
22
- import { SearchDialog, SearchMain } from './components';
23
- import { SearchContextProvider } from './context';
24
- import meta, { SEARCH_PLUGIN, SEARCH_RESULT } from './meta';
7
+ import { AppGraphBuilder, IntentResolver, ReactSurface } from './capabilities';
8
+ import { meta, SEARCH_RESULT } from './meta';
25
9
  import type { SearchResult } from './search-sync';
26
10
  import translations from './translations';
27
- import { SearchAction, type SearchPluginProvides } from './types';
28
-
29
- export const SearchPlugin = (): PluginDefinition<SearchPluginProvides> => {
30
- let navigationPlugin: Plugin<LocationProvides> | undefined;
31
- let graphPlugin: Plugin<GraphProvides> | undefined;
32
11
 
33
- return {
34
- meta,
35
- ready: async (plugins) => {
36
- navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
37
- graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
38
- },
39
- provides: {
40
- translations,
41
- metadata: {
42
- records: {
43
- [SEARCH_RESULT]: {
12
+ export const SearchPlugin = () =>
13
+ definePlugin(meta, [
14
+ defineModule({
15
+ id: `${meta.id}/module/translations`,
16
+ activatesOn: Events.SetupTranslations,
17
+ activate: () => contributes(Capabilities.Translations, translations),
18
+ }),
19
+ defineModule({
20
+ id: `${meta.id}/module/metadata`,
21
+ activatesOn: Events.SetupMetadata,
22
+ activate: () =>
23
+ contributes(Capabilities.Metadata, {
24
+ id: SEARCH_RESULT,
25
+ metadata: {
44
26
  parse: (item: SearchResult, type: string) => {
45
27
  switch (type) {
46
28
  case 'node':
@@ -52,69 +34,21 @@ export const SearchPlugin = (): PluginDefinition<SearchPluginProvides> => {
52
34
  }
53
35
  },
54
36
  },
55
- },
56
- },
57
- graph: {
58
- builder: (plugins) => {
59
- const intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
60
- return createExtension({
61
- id: SEARCH_PLUGIN,
62
- filter: (node): node is Node<null> => node.id === 'root',
63
- actions: () => [
64
- {
65
- id: SearchAction.SEARCH,
66
- data: async () => {
67
- await intentPlugin?.provides.intent.dispatch({
68
- plugin: SEARCH_PLUGIN,
69
- action: SearchAction.SEARCH,
70
- });
71
- },
72
- properties: {
73
- label: ['search action label', { ns: SEARCH_PLUGIN }],
74
- icon: 'ph--magnifying-glass--regular',
75
- keyBinding: {
76
- macos: 'shift+meta+f',
77
- windows: 'shift+alt+f',
78
- },
79
- testId: 'searchPlugin.search',
80
- },
81
- },
82
- ],
83
- });
84
- },
85
- },
86
- context: ({ children }) => <SearchContextProvider>{children}</SearchContextProvider>,
87
- surface: {
88
- component: ({ data, role }) => {
89
- const location = navigationPlugin?.provides.location;
90
- const graph = graphPlugin?.provides.graph;
91
- const space = graph && location ? getActiveSpace(graph, firstIdInPart(location.active, 'main')) : undefined;
92
-
93
- switch (role) {
94
- case 'dialog':
95
- return data.component === `${SEARCH_PLUGIN}/Dialog` ? (
96
- <SearchDialog subject={data.subject as any} />
97
- ) : null;
98
- case 'search-input':
99
- return space ? <SearchMain space={space} /> : null;
100
- }
101
-
102
- return null;
103
- },
104
- },
105
- intent: {
106
- resolver: (intent, plugins) => {
107
- switch (intent.action) {
108
- case SearchAction.SEARCH: {
109
- const intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
110
- return intentPlugin?.provides.intent.dispatch({
111
- action: LayoutAction.SET_LAYOUT,
112
- data: { element: 'complementary', state: true },
113
- });
114
- }
115
- }
116
- },
117
- },
118
- },
119
- };
120
- };
37
+ }),
38
+ }),
39
+ defineModule({
40
+ id: `${meta.id}/module/react-surface`,
41
+ activatesOn: Events.SetupSurfaces,
42
+ activate: ReactSurface,
43
+ }),
44
+ defineModule({
45
+ id: `${meta.id}/module/intent-resolver`,
46
+ activatesOn: Events.SetupIntents,
47
+ activate: IntentResolver,
48
+ }),
49
+ defineModule({
50
+ id: `${meta.id}/module/app-graph-builder`,
51
+ activatesOn: Events.SetupAppGraph,
52
+ activate: AppGraphBuilder,
53
+ }),
54
+ ]);
@@ -0,0 +1,36 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capabilities, contributes, createIntent, type PluginsContext } from '@dxos/app-framework';
6
+ import { createExtension, type Node } from '@dxos/plugin-graph';
7
+
8
+ import { SEARCH_PLUGIN } from '../meta';
9
+ import { SearchAction } from '../types';
10
+
11
+ export default (context: PluginsContext) =>
12
+ contributes(
13
+ Capabilities.AppGraphBuilder,
14
+ createExtension({
15
+ id: SEARCH_PLUGIN,
16
+ filter: (node): node is Node<null> => node.id === 'root',
17
+ actions: () => [
18
+ {
19
+ id: SearchAction.OpenSearch._tag,
20
+ data: async () => {
21
+ const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
22
+ await dispatch(createIntent(SearchAction.OpenSearch));
23
+ },
24
+ properties: {
25
+ label: ['search action label', { ns: SEARCH_PLUGIN }],
26
+ icon: 'ph--magnifying-glass--regular',
27
+ keyBinding: {
28
+ macos: 'shift+meta+f',
29
+ windows: 'shift+alt+f',
30
+ },
31
+ testId: 'searchPlugin.search',
32
+ },
33
+ },
34
+ ],
35
+ }),
36
+ );
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { lazy } from '@dxos/app-framework';
6
+
7
+ export const AppGraphBuilder = lazy(() => import('./app-graph-builder'));
8
+ export const IntentResolver = lazy(() => import('./intent-resolver'));
9
+ export const ReactSurface = lazy(() => import('./react-surface'));
@@ -0,0 +1,18 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { contributes, Capabilities, createResolver, LayoutAction, createIntent } from '@dxos/app-framework';
6
+
7
+ import { SearchAction } from '../types';
8
+
9
+ export default () =>
10
+ contributes(
11
+ Capabilities.IntentResolver,
12
+ createResolver({
13
+ intent: SearchAction.OpenSearch,
14
+ resolve: () => ({
15
+ intents: [createIntent(LayoutAction.UpdateComplementary, { part: 'complementary', subject: 'search' })],
16
+ }),
17
+ }),
18
+ );
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { Capabilities, contributes, createSurface, useLayout, useAppGraph } from '@dxos/app-framework';
8
+ import { getActiveSpace } from '@dxos/plugin-space';
9
+
10
+ import { SEARCH_DIALOG, SearchDialog, type SearchDialogProps, SearchMain } from '../components';
11
+ import { SearchContextProvider } from '../context';
12
+
13
+ export default () =>
14
+ contributes(Capabilities.ReactSurface, [
15
+ createSurface({
16
+ id: SEARCH_DIALOG,
17
+ role: 'dialog',
18
+ filter: (data): data is { props: SearchDialogProps } => data.component === SEARCH_DIALOG,
19
+ component: ({ data }) => (
20
+ <SearchContextProvider>
21
+ <SearchDialog {...data.props} />
22
+ </SearchContextProvider>
23
+ ),
24
+ }),
25
+ createSurface({
26
+ id: 'search-input',
27
+ role: 'search-input',
28
+ component: () => {
29
+ const layout = useLayout();
30
+ const { graph } = useAppGraph();
31
+ const space = graph ? getActiveSpace(graph, layout.active[0]) : undefined;
32
+ return space ? (
33
+ <SearchContextProvider>
34
+ <SearchMain space={space} />
35
+ </SearchContextProvider>
36
+ ) : null;
37
+ },
38
+ }),
39
+ ]);
@@ -4,16 +4,7 @@
4
4
 
5
5
  import React, { forwardRef, useCallback, useState } from 'react';
6
6
 
7
- import {
8
- useResolvePlugin,
9
- parseNavigationPlugin,
10
- parseGraphPlugin,
11
- NavigationAction,
12
- LayoutAction,
13
- type LayoutCoordinate,
14
- isLayoutParts,
15
- useIntentDispatcher,
16
- } from '@dxos/app-framework';
7
+ import { LayoutAction, createIntent, useAppGraph, useIntentDispatcher, useLayout } from '@dxos/app-framework';
17
8
  import { type Node } from '@dxos/plugin-graph';
18
9
  import { useClient } from '@dxos/react-client';
19
10
  import { Filter, fullyQualifiedId, useQuery } from '@dxos/react-client/echo';
@@ -24,6 +15,8 @@ import { descriptionText, mx } from '@dxos/react-ui-theme';
24
15
  import { SEARCH_PLUGIN } from '../meta';
25
16
  import { useSearchResults } from '../search';
26
17
 
18
+ export const SEARCH_DIALOG = `${SEARCH_PLUGIN}/SearchDialog`;
19
+
27
20
  type SearchListResultProps = {
28
21
  node: Node;
29
22
  } & Pick<SearchListItemProps, 'onSelect'>;
@@ -45,55 +38,46 @@ const SearchListResult = forwardRef<HTMLDivElement, SearchListResultProps>(({ no
45
38
  );
46
39
  });
47
40
 
48
- export const SearchDialog = ({
49
- subject,
50
- }: {
51
- subject: { action: NavigationAction; layoutCoordinate: LayoutCoordinate; position: 'add-after' | 'add-before' };
52
- }) => {
41
+ export type SearchDialogProps = {
42
+ pivotId: string;
43
+ };
44
+
45
+ export const SearchDialog = ({ pivotId }: SearchDialogProps) => {
53
46
  const { t } = useTranslation(SEARCH_PLUGIN);
54
- const graphPlugin = useResolvePlugin(parseGraphPlugin);
55
- const graph = graphPlugin?.provides.graph;
56
- const navigationPlugin = useResolvePlugin(parseNavigationPlugin);
57
- const providedClosed = navigationPlugin?.provides.location.closed ?? [];
58
- const closed = (Array.isArray(providedClosed) ? providedClosed : [providedClosed])
47
+ const layout = useLayout();
48
+ const { graph } = useAppGraph();
49
+ const closed = (Array.isArray(layout.inactive) ? layout.inactive : [layout.inactive])
59
50
  .map((id) => graph?.findNode(id))
60
51
  .filter(Boolean);
61
- const active = navigationPlugin?.provides.location.active;
62
52
  const [queryString, setQueryString] = useState('');
63
53
  const client = useClient();
64
54
  const dangerouslyLoadAllObjects = useQuery(client.spaces, Filter.all());
65
55
  const [pending, results] = useSearchResults(queryString, dangerouslyLoadAllObjects);
66
56
  const resultObjects = Array.from(results.keys());
67
- const dispatch = useIntentDispatcher();
57
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
68
58
 
69
59
  const handleSelect = useCallback(
70
- (nodeId: string) => {
71
- if (active && isLayoutParts(active)) {
72
- // If node is already present in the active parts, scroll to it and close the dialog.
73
- const index = active?.main?.findIndex((entry) => entry.id === nodeId);
74
- if (index !== -1) {
75
- return dispatch([
76
- { action: LayoutAction.SET_LAYOUT, data: { element: 'dialog', state: false } },
77
- { action: LayoutAction.SCROLL_INTO_VIEW, data: { id: nodeId } },
78
- ]);
79
- }
60
+ async (nodeId: string) => {
61
+ await dispatch(createIntent(LayoutAction.UpdateDialog, { part: 'dialog', options: { state: false } }));
80
62
 
81
- return dispatch([
82
- {
83
- action: NavigationAction.ADD_TO_ACTIVE,
84
- data: {
85
- part: subject.layoutCoordinate.part,
86
- id: nodeId,
87
- pivotId: subject.layoutCoordinate.entryId,
63
+ // If node is already present in the active parts, scroll to it and close the dialog.
64
+ const index = layout.active.findIndex((id) => id === nodeId);
65
+ if (index !== -1) {
66
+ await dispatch(createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: nodeId }));
67
+ } else {
68
+ await dispatch(
69
+ createIntent(LayoutAction.Open, {
70
+ part: 'main',
71
+ subject: [nodeId],
72
+ options: {
73
+ pivotId,
88
74
  positioning: 'end',
89
75
  },
90
- },
91
- { action: LayoutAction.SET_LAYOUT, data: { element: 'dialog', state: false } },
92
- { action: LayoutAction.SCROLL_INTO_VIEW, data: { id: nodeId } },
93
- ]);
76
+ }),
77
+ );
94
78
  }
95
79
  },
96
- [subject, dispatch, active],
80
+ [pivotId, dispatch, layout],
97
81
  );
98
82
 
99
83
  return (
@@ -7,7 +7,6 @@ import React, { type FC, forwardRef } from 'react';
7
7
 
8
8
  import { ScrollArea } from '@dxos/react-ui';
9
9
  import { Card } from '@dxos/react-ui-card';
10
- import { type MosaicTileComponent, Mosaic } from '@dxos/react-ui-mosaic';
11
10
  import { ghostHover, mx } from '@dxos/react-ui-theme';
12
11
 
13
12
  import { SEARCH_RESULT } from '../../meta';
@@ -58,37 +57,28 @@ export const Snippet: FC<{ text: string; match?: RegExp }> = ({ text, match }) =
58
57
 
59
58
  export type SearchItemProps = SearchResult & { selected: boolean } & Pick<SearchResultsProps, 'onSelect'>;
60
59
 
61
- export const SearchItem: MosaicTileComponent<SearchItemProps> = forwardRef(
62
- ({ draggableStyle, draggableProps, item, debug = false }, forwardRef) => {
63
- const { id, type, label, snippet, match, selected, onSelect } = item;
64
- const Icon = type ? getIcon(type) : undefined;
60
+ export const SearchItem = forwardRef<HTMLDivElement, SearchItemProps>((item, forwardRef) => {
61
+ const { id, type, label, snippet, match, selected, onSelect } = item;
62
+ const Icon = type ? getIcon(type) : undefined;
65
63
 
66
- return (
67
- <Card.Root
68
- ref={forwardRef}
69
- style={draggableStyle}
70
- classNames={mx('mx-2 mt-2 cursor-pointer', ghostHover, selected && styles.selected)}
71
- onClick={() => onSelect?.(id)}
72
- >
73
- <Card.Header>
74
- <Card.DragHandle {...draggableProps} />
75
- <Card.Title title={label ?? 'Untitled'} />
76
- {Icon && <Card.Endcap Icon={Icon} />}
77
- </Card.Header>
78
- {snippet && (
79
- <Card.Body gutter>
80
- <Snippet text={snippet} match={match} />
81
- </Card.Body>
82
- )}
83
- {debug && (
84
- <Card.Body gutter>
85
- <pre className='text-xs whitespace-pre-line'>{JSON.stringify(item)}</pre>
86
- </Card.Body>
87
- )}
88
- </Card.Root>
89
- );
90
- },
91
- );
64
+ return (
65
+ <Card.Root
66
+ ref={forwardRef}
67
+ classNames={mx('mx-2 mt-2 cursor-pointer', ghostHover, selected && styles.selected)}
68
+ onClick={() => onSelect?.(id)}
69
+ >
70
+ <Card.Header>
71
+ <Card.Title title={label ?? 'Untitled'} />
72
+ {Icon && <Card.Endcap Icon={Icon} />}
73
+ </Card.Header>
74
+ {snippet && (
75
+ <Card.Body gutter>
76
+ <Snippet text={snippet} match={match} />
77
+ </Card.Body>
78
+ )}
79
+ </Card.Root>
80
+ );
81
+ });
92
82
 
93
83
  export type SearchResultsProps = {
94
84
  match?: RegExp;
@@ -99,21 +89,18 @@ export type SearchResultsProps = {
99
89
 
100
90
  // TODO(burdon): Key cursor up/down.
101
91
  export const SearchResults = ({ items, selected, onSelect }: SearchResultsProps) => {
102
- const path = 'search';
103
92
  return (
104
93
  <ScrollArea.Root classNames='grow'>
105
94
  <ScrollArea.Viewport>
106
- <Mosaic.Container id={path} Component={SearchItem}>
107
- {items.map((item) => (
108
- <Mosaic.DraggableTile
109
- key={item.id}
110
- path={path}
111
- type={SEARCH_RESULT}
112
- item={{ ...item, selected: selected === item.id, onSelect }}
113
- Component={SearchItem}
114
- />
115
- ))}
116
- </Mosaic.Container>
95
+ {items.map((item) => (
96
+ <SearchItem
97
+ key={item.id}
98
+ type={SEARCH_RESULT}
99
+ {...item}
100
+ onSelect={onSelect}
101
+ selected={selected === item.id}
102
+ />
103
+ ))}
117
104
  </ScrollArea.Viewport>
118
105
  <ScrollArea.Scrollbar orientation='vertical'>
119
106
  <ScrollArea.Thumb />
package/src/index.ts CHANGED
@@ -2,11 +2,8 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { SearchPlugin } from './SearchPlugin';
6
-
7
- export default SearchPlugin;
8
-
9
5
  export * from './context';
6
+ export * from './meta';
10
7
  export * from './search-sync';
11
8
 
12
9
  export * from './SearchPlugin';
package/src/meta.ts CHANGED
@@ -7,7 +7,7 @@ import { type PluginMeta } from '@dxos/app-framework';
7
7
  export const SEARCH_PLUGIN = 'dxos.org/plugin/search';
8
8
  export const SEARCH_RESULT = `${SEARCH_PLUGIN}/result`;
9
9
 
10
- export default {
10
+ export const meta = {
11
11
  id: SEARCH_PLUGIN,
12
12
  name: 'Search',
13
13
  description: 'Search ECHO spaces for content.',
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { AST, type S } from '@dxos/echo-schema';
6
6
  import { getSchema } from '@dxos/live-object';
7
- import { TextType } from '@dxos/plugin-markdown/types';
7
+ import { TextType } from '@dxos/schema';
8
8
 
9
9
  export const queryStringToMatch = (queryString?: string): RegExp | undefined => {
10
10
  const trimmed = queryString?.trim();
package/src/search.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  import { yieldOrContinue } from 'main-thread-scheduling';
6
6
  import { useEffect, useState } from 'react';
7
7
 
8
- import { TextType } from '@dxos/plugin-markdown/types';
8
+ import { TextType } from '@dxos/schema';
9
9
 
10
10
  // TODO(thure): Deprecate search-sync, move still-relevant utilities elsewhere (here, probably).
11
11
  import { mapObjectToTextFields, queryStringToMatch } from './search-sync';
package/src/types.tsx CHANGED
@@ -2,24 +2,15 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import type {
6
- GraphBuilderProvides,
7
- IntentResolverProvides,
8
- MetadataRecordsProvides,
9
- SurfaceProvides,
10
- TranslationsProvides,
11
- } from '@dxos/app-framework';
5
+ import { S } from '@dxos/echo-schema';
12
6
 
13
7
  import { SEARCH_PLUGIN } from './meta';
14
8
 
15
- const SEARCH_ACTION = `${SEARCH_PLUGIN}/action`;
9
+ export namespace SearchAction {
10
+ const SEARCH_ACTION = `${SEARCH_PLUGIN}/action`;
16
11
 
17
- export enum SearchAction {
18
- SEARCH = `${SEARCH_ACTION}/search`,
12
+ export class OpenSearch extends S.TaggedClass<OpenSearch>()(`${SEARCH_ACTION}/open-search`, {
13
+ input: S.Void,
14
+ output: S.Void,
15
+ }) {}
19
16
  }
20
-
21
- export type SearchPluginProvides = SurfaceProvides &
22
- IntentResolverProvides &
23
- GraphBuilderProvides &
24
- MetadataRecordsProvides &
25
- TranslationsProvides;
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/meta.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type PluginMeta } from '@dxos/app-framework';\n\nexport const SEARCH_PLUGIN = 'dxos.org/plugin/search';\nexport const SEARCH_RESULT = `${SEARCH_PLUGIN}/result`;\n\nexport default {\n id: SEARCH_PLUGIN,\n name: 'Search',\n description: 'Search ECHO spaces for content.',\n icon: 'ph--magnifying-glass--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/experimental/plugin-search',\n tags: ['experimental'],\n} satisfies PluginMeta;\n"],
5
- "mappings": ";AAMO,IAAMA,gBAAgB;AACtB,IAAMC,gBAAgB,GAAGD,aAAAA;AAEhC,IAAA,eAAe;EACbE,IAAIF;EACJG,MAAM;EACNC,aAAa;EACbC,MAAM;EACNC,QAAQ;EACRC,MAAM;IAAC;;AACT;",
6
- "names": ["SEARCH_PLUGIN", "SEARCH_RESULT", "id", "name", "description", "icon", "source", "tags"]
7
- }
@@ -1,11 +0,0 @@
1
- import {
2
- SEARCH_PLUGIN,
3
- SEARCH_RESULT,
4
- meta_default
5
- } from "./chunk-4L4PWJYC.mjs";
6
- export {
7
- SEARCH_PLUGIN,
8
- SEARCH_RESULT,
9
- meta_default as default
10
- };
11
- //# sourceMappingURL=meta.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }