@dxos/app-graph 0.8.3-staging.0fa589b → 0.8.4-main.28f8d3d

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.
@@ -5,38 +5,38 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Registry, RegistryContext, Rx, useRxValue } from '@effect-rx/rx-react';
8
- import { Pause, Play, Plus, Timer } from '@phosphor-icons/react';
8
+ import { type Meta } from '@storybook/react-vite';
9
9
  import { Option, pipe } from 'effect';
10
10
  import React, { type PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState } from 'react';
11
11
 
12
12
  import {
13
- live,
14
- isSpace,
13
+ Expando,
14
+ Filter,
15
+ type Live,
15
16
  Query,
16
17
  type QueryResult,
17
18
  type Space,
18
19
  SpaceState,
19
- Expando,
20
- type Live,
21
- Filter,
20
+ isSpace,
21
+ live,
22
22
  } from '@dxos/client/echo';
23
23
  import { Obj, Type } from '@dxos/echo';
24
24
  import { faker } from '@dxos/random';
25
25
  import { type Client, useClient } from '@dxos/react-client';
26
26
  import { withClientProvider } from '@dxos/react-client/testing';
27
- import { Button, Input, Select } from '@dxos/react-ui';
27
+ import { Icon, IconButton, Input, Select } from '@dxos/react-ui';
28
28
  import { Path, Tree } from '@dxos/react-ui-list';
29
- import { Tabs } from '@dxos/react-ui-tabs';
30
29
  import { getSize, mx } from '@dxos/react-ui-theme';
31
30
  import { withTheme } from '@dxos/storybook-utils';
32
31
  import { byPosition, isNonNullable, safeParseInt } from '@dxos/util';
33
32
 
34
- import { JsonTree } from './Tree';
35
33
  import { type ExpandableGraph, ROOT_ID } from '../graph';
36
34
  import { GraphBuilder, createExtension, rxFromObservable, rxFromSignal } from '../graph-builder';
37
35
  import { type Node } from '../node';
38
36
  import { rxFromQuery } from '../testing';
39
37
 
38
+ import { JsonTree } from './Tree';
39
+
40
40
  const DEFAULT_PERIOD = 500;
41
41
 
42
42
  enum Action {
@@ -205,7 +205,11 @@ const Controls = ({ children }: PropsWithChildren) => {
205
205
  return (
206
206
  <>
207
207
  <div className='flex shrink-0 p-2 space-x-2'>
208
- <Button onClick={() => setGenerating((generating) => !generating)}>{generating ? <Pause /> : <Play />}</Button>
208
+ <IconButton
209
+ icon={generating ? 'ph--pause--regular' : 'ph--play--regular'}
210
+ label={generating ? 'Pause' : 'Play'}
211
+ onClick={() => setGenerating((generating) => !generating)}
212
+ />
209
213
  <div className='relative' title='mutation period'>
210
214
  <Input.Root>
211
215
  <Input.TextInput
@@ -217,11 +221,9 @@ const Controls = ({ children }: PropsWithChildren) => {
217
221
  onChange={({ target: { value } }) => setActionInterval(value)}
218
222
  />
219
223
  </Input.Root>
220
- <Timer className={mx('absolute inline-end-1 block-start-1 mt-[6px]', getSize(3))} />
224
+ <Icon icon='ph--timer--regular' classNames={mx('absolute inline-end-1 block-start-1 mt-[6px]', getSize(3))} />
221
225
  </div>
222
- <Button onClick={() => action && runAction(client, action)}>
223
- <Plus />
224
- </Button>
226
+ <IconButton icon='ph--plus--regular' label='Add' onClick={() => action && runAction(client, action)} />
225
227
  <Select.Root value={action?.toString()} onValueChange={(action) => setAction(action as unknown as Action)}>
226
228
  <Select.TriggerButton placeholder='Select value' />
227
229
  <Select.Portal>
@@ -245,10 +247,9 @@ const Controls = ({ children }: PropsWithChildren) => {
245
247
  );
246
248
  };
247
249
 
248
- export default {
250
+ const meta: Meta = {
249
251
  title: 'sdk/app-graph/EchoGraph',
250
252
  decorators: [
251
- withTheme,
252
253
  withClientProvider({
253
254
  createIdentity: true,
254
255
  onIdentityCreated: async ({ client }) => {
@@ -256,9 +257,12 @@ export default {
256
257
  await client.spaces.create();
257
258
  },
258
259
  }),
260
+ withTheme,
259
261
  ],
260
262
  };
261
263
 
264
+ export default meta;
265
+
262
266
  export const JsonView = {
263
267
  render: () => {
264
268
  const client = useClient();
@@ -372,122 +376,3 @@ export const TreeView = {
372
376
  );
373
377
  },
374
378
  };
375
-
376
- // TODO(wittjosiah): Remove.
377
- export const TabTreeView = {
378
- render: () => {
379
- const client = useClient();
380
- const registry = useContext(RegistryContext);
381
- const graph = useMemo(() => createGraph(client, registry), [client, registry]);
382
- const state = useMemo(() => new Map<string, Live<{ open: boolean; current: boolean }>>(), []);
383
-
384
- const useItems = useCallback(
385
- (node?: Node, options?: { disposition?: string; sort?: boolean }) => {
386
- const connections = useRxValue(graph.connections(node?.id ?? ROOT_ID));
387
- return options?.sort ? connections.toSorted((a, b) => byPosition(a.properties, b.properties)) : connections;
388
- },
389
- [graph],
390
- );
391
-
392
- const getProps = useCallback(
393
- (node: Node, path: string[]) => {
394
- const children = graph
395
- .getConnections(node.id, 'outbound')
396
- .map((n) => {
397
- // Break cycles.
398
- const nextPath = [...path, node.id];
399
- return nextPath.includes(n.id) ? undefined : (n as Node);
400
- })
401
- .filter(isNonNullable) as Node[];
402
- const parentOf =
403
- children.length > 0 ? children.map(({ id }) => id) : node.properties.role === 'branch' ? [] : undefined;
404
- return {
405
- id: node.id,
406
- label: node.id,
407
- icon: node.type === 'dxos.org/type/Space' ? 'ph--planet--regular' : 'ph--placeholder--regular',
408
- parentOf,
409
- };
410
- },
411
- [graph],
412
- );
413
-
414
- const isOpen = useCallback(
415
- (_path: string[]) => {
416
- const path = Path.create(..._path);
417
- const object = state.get(path) ?? live({ open: true, current: false });
418
- if (!state.has(path)) {
419
- state.set(path, object);
420
- }
421
-
422
- return object.open;
423
- },
424
- [state],
425
- );
426
-
427
- const isCurrent = useCallback(
428
- (_path: string[]) => {
429
- const path = Path.create(..._path);
430
- const object = state.get(path) ?? live({ open: false, current: false });
431
- if (!state.has(path)) {
432
- state.set(path, object);
433
- }
434
-
435
- return object.current;
436
- },
437
- [state],
438
- );
439
-
440
- const onOpenChange = useCallback(
441
- ({ path: _path, open }: { path: string[]; open: boolean }) => {
442
- const path = Path.create(..._path);
443
- const object = state.get(path);
444
- object!.open = open;
445
- },
446
- [state],
447
- );
448
-
449
- const onSelect = useCallback(
450
- ({ path: _path, current }: { path: string[]; current: boolean }) => {
451
- const path = Path.create(..._path);
452
- const object = state.get(path);
453
- object!.current = current;
454
- },
455
- [state],
456
- );
457
-
458
- const spaces = useItems(graph.root);
459
-
460
- return (
461
- <>
462
- <Controls />
463
- <Tabs.Root defaultValue={spaces[0].id}>
464
- <Tabs.Tablist>
465
- {spaces.map((space) => {
466
- return (
467
- <Tabs.Tab key={space.id} value={space.id}>
468
- {space.id}
469
- </Tabs.Tab>
470
- );
471
- })}
472
- </Tabs.Tablist>
473
- {spaces.map((space) => {
474
- return (
475
- <Tabs.Tabpanel key={space.id} value={space.id}>
476
- <Tree
477
- id={space.id}
478
- root={space}
479
- useItems={useItems}
480
- getProps={getProps}
481
- isOpen={isOpen}
482
- isCurrent={isCurrent}
483
- onOpenChange={onOpenChange}
484
- onSelect={onSelect}
485
- />
486
- </Tabs.Tabpanel>
487
- );
488
- })}
489
- </Tabs.Root>
490
- </>
491
- );
492
- },
493
- };