@dxos/react-ui-table 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8

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 (90) hide show
  1. package/dist/lib/browser/{chunk-OZBLY7XM.mjs → chunk-BF54SSNL.mjs} +12 -18
  2. package/dist/lib/browser/chunk-BF54SSNL.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-I5IFW7UF.mjs → chunk-PTHMYAAM.mjs} +33 -28
  4. package/dist/lib/browser/chunk-PTHMYAAM.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +178 -176
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/testing/index.mjs +3 -3
  9. package/dist/lib/browser/testing/index.mjs.map +2 -2
  10. package/dist/lib/browser/types/index.mjs +1 -1
  11. package/dist/lib/node-esm/{chunk-DDJKYJFY.mjs → chunk-GI72MQSG.mjs} +33 -28
  12. package/dist/lib/node-esm/chunk-GI72MQSG.mjs.map +7 -0
  13. package/dist/lib/node-esm/{chunk-WNZSKIRF.mjs → chunk-SIRDIPHZ.mjs} +12 -18
  14. package/dist/lib/node-esm/chunk-SIRDIPHZ.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +178 -176
  16. package/dist/lib/node-esm/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/meta.json +1 -1
  18. package/dist/lib/node-esm/testing/index.mjs +3 -3
  19. package/dist/lib/node-esm/testing/index.mjs.map +2 -2
  20. package/dist/lib/node-esm/types/index.mjs +1 -1
  21. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  22. package/dist/types/src/components/Table/DynamicTable.d.ts +5 -4
  23. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  24. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +1 -1
  25. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  26. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/Table.d.ts +6 -6
  28. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  30. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +3 -3
  31. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  32. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +2 -2
  33. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  34. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  35. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +1 -1
  36. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  37. package/dist/types/src/hooks/useAddRow.d.ts +1 -1
  38. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  39. package/dist/types/src/hooks/useProjectionModel.d.ts +1 -1
  40. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
  41. package/dist/types/src/hooks/useTableModel.d.ts +1 -1
  42. package/dist/types/src/model/table-model.d.ts +5 -4
  43. package/dist/types/src/model/table-model.d.ts.map +1 -1
  44. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  45. package/dist/types/src/playwright/TableManager.d.ts +2 -1
  46. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  47. package/dist/types/src/testing/useTestTableModel.d.ts +2 -2
  48. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  49. package/dist/types/src/types/Table.d.ts +1 -6
  50. package/dist/types/src/types/Table.d.ts.map +1 -1
  51. package/dist/types/src/util/dynamic-table.d.ts +6 -5
  52. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  53. package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
  54. package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
  55. package/dist/types/src/util/query-ast.d.ts.map +1 -1
  56. package/dist/types/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +42 -42
  58. package/src/components/Table/ColumnSettings.tsx +3 -4
  59. package/src/components/Table/DynamicTable.stories.tsx +6 -5
  60. package/src/components/Table/DynamicTable.tsx +11 -10
  61. package/src/components/Table/Relations.stories.tsx +13 -10
  62. package/src/components/Table/Table.stories.tsx +54 -32
  63. package/src/components/Table/Table.tsx +51 -56
  64. package/src/components/TableCellEditor/CellValidationMessage.tsx +4 -4
  65. package/src/components/TableCellEditor/FormCellEditor.tsx +11 -5
  66. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +4 -3
  67. package/src/components/TableCellEditor/TableCellEditor.tsx +3 -3
  68. package/src/components/TableToolbar/TableToolbar.tsx +6 -6
  69. package/src/components/testing.ts +1 -1
  70. package/src/hooks/useAddRow.ts +1 -1
  71. package/src/hooks/useProjectionModel.ts +3 -3
  72. package/src/hooks/useTableModel.ts +1 -1
  73. package/src/model/table-model.test.ts +5 -5
  74. package/src/model/table-model.ts +9 -8
  75. package/src/model/table-presentation.test.ts +5 -5
  76. package/src/model/table-presentation.ts +12 -11
  77. package/src/playwright/TableManager.ts +10 -3
  78. package/src/playwright/playwright.config.ts +1 -1
  79. package/src/playwright/smoke.spec.ts +45 -2
  80. package/src/testing/useTestTableModel.ts +3 -3
  81. package/src/types/Table.ts +11 -22
  82. package/src/util/dynamic-table.test.ts +70 -0
  83. package/src/util/dynamic-table.ts +13 -12
  84. package/src/util/query-ast.ts +3 -0
  85. package/src/util/table-buttons.ts +1 -1
  86. package/src/util/table-controls.ts +2 -2
  87. package/dist/lib/browser/chunk-I5IFW7UF.mjs.map +0 -7
  88. package/dist/lib/browser/chunk-OZBLY7XM.mjs.map +0 -7
  89. package/dist/lib/node-esm/chunk-DDJKYJFY.mjs.map +0 -7
  90. package/dist/lib/node-esm/chunk-WNZSKIRF.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-table",
3
- "version": "0.8.4-main.bc674ce",
3
+ "version": "0.8.4-main.c351d160a8",
4
4
  "description": "A table component.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -60,7 +60,7 @@
60
60
  "@codemirror/autocomplete": "^6.19.0",
61
61
  "@codemirror/state": "^6.5.2",
62
62
  "@codemirror/view": "^6.38.4",
63
- "@effect-atom/atom-react": "^0.4.6",
63
+ "@effect-atom/atom-react": "^0.5.0",
64
64
  "@fluentui/react-tabster": "9.26.11",
65
65
  "@radix-ui/react-context": "1.1.1",
66
66
  "@radix-ui/react-primitive": "2.0.2",
@@ -68,58 +68,58 @@
68
68
  "@radix-ui/react-use-controllable-state": "1.1.0",
69
69
  "date-fns": "^3.3.1",
70
70
  "lodash.orderby": "^4.6.0",
71
- "@dxos/async": "0.8.4-main.bc674ce",
72
- "@dxos/context": "0.8.4-main.bc674ce",
73
- "@dxos/debug": "0.8.4-main.bc674ce",
74
- "@dxos/echo": "0.8.4-main.bc674ce",
75
- "@dxos/echo-atom": "0.8.4-main.bc674ce",
76
- "@dxos/effect": "0.8.4-main.bc674ce",
77
- "@dxos/invariant": "0.8.4-main.bc674ce",
78
- "@dxos/keys": "0.8.4-main.bc674ce",
79
- "@dxos/lit-grid": "0.8.4-main.bc674ce",
80
- "@dxos/log": "0.8.4-main.bc674ce",
81
- "@dxos/react-client": "0.8.4-main.bc674ce",
82
- "@dxos/random": "0.8.4-main.bc674ce",
83
- "@dxos/react-ui-components": "0.8.4-main.bc674ce",
84
- "@dxos/react-ui-attention": "0.8.4-main.bc674ce",
85
- "@dxos/react-ui-form": "0.8.4-main.bc674ce",
86
- "@dxos/react-ui-editor": "0.8.4-main.bc674ce",
87
- "@dxos/react-ui-grid": "0.8.4-main.bc674ce",
88
- "@dxos/react-ui-searchlist": "0.8.4-main.bc674ce",
89
- "@dxos/react-ui-menu": "0.8.4-main.bc674ce",
90
- "@dxos/react-ui-stack": "0.8.4-main.bc674ce",
91
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.bc674ce",
92
- "@dxos/types": "0.8.4-main.bc674ce",
93
- "@dxos/ui-types": "0.8.4-main.bc674ce",
94
- "@dxos/schema": "0.8.4-main.bc674ce",
95
- "@dxos/util": "0.8.4-main.bc674ce"
71
+ "@dxos/async": "0.8.4-main.c351d160a8",
72
+ "@dxos/context": "0.8.4-main.c351d160a8",
73
+ "@dxos/debug": "0.8.4-main.c351d160a8",
74
+ "@dxos/echo": "0.8.4-main.c351d160a8",
75
+ "@dxos/echo-atom": "0.8.4-main.c351d160a8",
76
+ "@dxos/effect": "0.8.4-main.c351d160a8",
77
+ "@dxos/invariant": "0.8.4-main.c351d160a8",
78
+ "@dxos/lit-grid": "0.8.4-main.c351d160a8",
79
+ "@dxos/keys": "0.8.4-main.c351d160a8",
80
+ "@dxos/log": "0.8.4-main.c351d160a8",
81
+ "@dxos/random": "0.8.4-main.c351d160a8",
82
+ "@dxos/react-ui-attention": "0.8.4-main.c351d160a8",
83
+ "@dxos/react-ui-components": "0.8.4-main.c351d160a8",
84
+ "@dxos/react-ui-form": "0.8.4-main.c351d160a8",
85
+ "@dxos/react-ui-editor": "0.8.4-main.c351d160a8",
86
+ "@dxos/react-ui-grid": "0.8.4-main.c351d160a8",
87
+ "@dxos/react-ui-menu": "0.8.4-main.c351d160a8",
88
+ "@dxos/react-client": "0.8.4-main.c351d160a8",
89
+ "@dxos/react-ui-searchlist": "0.8.4-main.c351d160a8",
90
+ "@dxos/react-ui-stack": "0.8.4-main.c351d160a8",
91
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.c351d160a8",
92
+ "@dxos/schema": "0.8.4-main.c351d160a8",
93
+ "@dxos/types": "0.8.4-main.c351d160a8",
94
+ "@dxos/ui-types": "0.8.4-main.c351d160a8",
95
+ "@dxos/util": "0.8.4-main.c351d160a8"
96
96
  },
97
97
  "devDependencies": {
98
- "@effect/platform": "0.93.6",
98
+ "@effect/platform": "0.94.4",
99
99
  "@types/lodash.orderby": "^4.6.9",
100
100
  "@types/react": "~19.2.7",
101
101
  "@types/react-dom": "~19.2.3",
102
- "effect": "3.19.11",
102
+ "effect": "3.19.16",
103
103
  "fast-check": "^3.19.0",
104
104
  "react": "~19.2.3",
105
105
  "react-dom": "~19.2.3",
106
- "vite": "7.1.9",
107
- "@dxos/random": "0.8.4-main.bc674ce",
108
- "@dxos/lit-ui": "0.8.4-main.bc674ce",
109
- "@dxos/react-client": "0.8.4-main.bc674ce",
110
- "@dxos/react-ui": "0.8.4-main.bc674ce",
111
- "@dxos/storybook-utils": "0.8.4-main.bc674ce",
112
- "@dxos/ui-theme": "0.8.4-main.bc674ce",
113
- "@dxos/test-utils": "0.8.4-main.bc674ce"
106
+ "vite": "^7.1.11",
107
+ "@dxos/lit-ui": "0.8.4-main.c351d160a8",
108
+ "@dxos/react-client": "0.8.4-main.c351d160a8",
109
+ "@dxos/react-ui": "0.8.4-main.c351d160a8",
110
+ "@dxos/random": "0.8.4-main.c351d160a8",
111
+ "@dxos/storybook-utils": "0.8.4-main.c351d160a8",
112
+ "@dxos/test-utils": "0.8.4-main.c351d160a8",
113
+ "@dxos/ui-theme": "0.8.4-main.c351d160a8"
114
114
  },
115
115
  "peerDependencies": {
116
- "@effect-atom/atom-react": "^0.4.6",
117
- "@effect/platform": "0.93.6",
118
- "effect": "3.19.11",
116
+ "@effect-atom/atom-react": "^0.5.0",
117
+ "@effect/platform": "0.94.4",
118
+ "effect": "3.19.16",
119
119
  "react": "~19.2.3",
120
120
  "react-dom": "~19.2.3",
121
- "@dxos/react-ui": "0.8.4-main.bc674ce",
122
- "@dxos/ui-theme": "0.8.4-main.bc674ce"
121
+ "@dxos/react-ui": "0.8.4-main.c351d160a8",
122
+ "@dxos/ui-theme": "0.8.4-main.c351d160a8"
123
123
  },
124
124
  "publishConfig": {
125
125
  "access": "public"
@@ -5,10 +5,9 @@
5
5
  import { useAtomValue } from '@effect-atom/atom-react';
6
6
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
7
7
 
8
- import { type SchemaRegistry } from '@dxos/echo';
8
+ import { type SchemaRegistry, type View } from '@dxos/echo';
9
9
  import { Popover } from '@dxos/react-ui';
10
10
  import { FieldEditor } from '@dxos/react-ui-form';
11
- import { type FieldType } from '@dxos/schema';
12
11
 
13
12
  import { type ModalController, type TableModel } from '../../model';
14
13
 
@@ -20,7 +19,7 @@ type ColumnSettingsProps = {
20
19
  };
21
20
 
22
21
  export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnSettingsProps) => {
23
- const [newField, setNewField] = useState<FieldType>();
22
+ const [newField, setNewField] = useState<View.FieldType>();
24
23
  const state = useAtomValue(modals.state);
25
24
 
26
25
  useEffect(() => {
@@ -64,7 +63,7 @@ export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnS
64
63
  <Popover.Root modal={false} open={state?.type === 'columnSettings'}>
65
64
  <Popover.VirtualTrigger virtualRef={modals.trigger} />
66
65
  <Popover.Portal>
67
- <Popover.Content classNames='md:is-64'>
66
+ <Popover.Content classNames='md:w-64'>
68
67
  <Popover.Viewport>
69
68
  <FieldEditor
70
69
  projection={model.projection}
@@ -3,14 +3,15 @@
3
3
  //
4
4
 
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import type * as Types from 'effect/Types';
6
7
  import React, { useMemo, useState } from 'react';
7
8
 
8
- import { Obj } from '@dxos/echo';
9
- import { Format, type JsonSchemaType } from '@dxos/echo/internal';
9
+ import { type JsonSchema, Obj } from '@dxos/echo';
10
+ import { Format } from '@dxos/echo/internal';
10
11
  import { faker } from '@dxos/random';
11
12
  import { Filter, useQuery, useSchema } from '@dxos/react-client/echo';
12
13
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
13
- import { withTheme } from '@dxos/react-ui/testing';
14
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
14
15
  import { type SchemaPropertyDefinition } from '@dxos/schema';
15
16
  import { TestSchema } from '@dxos/schema/testing';
16
17
  import { withRegistry } from '@dxos/storybook-utils';
@@ -58,7 +59,7 @@ const DynamicTableStory = () => {
58
59
  const meta = {
59
60
  title: 'ui/react-ui-table/DynamicTable',
60
61
  component: DynamicTable,
61
- decorators: [withTheme, withRegistry],
62
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' }), withRegistry],
62
63
  parameters: {
63
64
  layout: 'fullscreen',
64
65
  translations,
@@ -101,7 +102,7 @@ export const WithClickToSelect: StoryObj = {
101
102
 
102
103
  export const WithJsonSchema: StoryObj = {
103
104
  render: () => {
104
- const schema = useMemo<JsonSchemaType>(
105
+ const schema = useMemo<Types.DeepMutable<JsonSchema.JsonSchema>>(
105
106
  () => ({
106
107
  type: 'object',
107
108
  properties: {
@@ -3,10 +3,11 @@
3
3
  //
4
4
 
5
5
  import { RegistryContext } from '@effect-atom/atom-react';
6
+ import type * as Types from 'effect/Types';
6
7
  import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
7
8
 
8
9
  import { type Type } from '@dxos/echo';
9
- import { type JsonSchemaType } from '@dxos/echo/internal';
10
+ import { type JsonSchema } from '@dxos/echo';
10
11
  import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
11
12
  import { type ProjectionModel } from '@dxos/schema';
12
13
  import { mx } from '@dxos/ui-theme';
@@ -18,12 +19,12 @@ import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '.
18
19
 
19
20
  import { Table, type TableController } from './Table';
20
21
 
21
- export type DynamicTableProps<T extends Type.Entity.Any = Type.Entity.Any> = ThemedClassName<{
22
+ export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = ThemedClassName<{
22
23
  schema?: T;
23
24
  name?: string; // TODO(burdon): Remove?
24
25
  rows: any[];
25
26
  properties?: TablePropertyDefinition[];
26
- jsonSchema?: JsonSchemaType;
27
+ jsonSchema?: Types.DeepMutable<JsonSchema.JsonSchema>;
27
28
  features?: Partial<TableFeatures>;
28
29
  rowActions?: TableRowAction[];
29
30
  onRowClick?: (row: any) => void;
@@ -35,13 +36,13 @@ export type DynamicTableProps<T extends Type.Entity.Any = Type.Entity.Any> = The
35
36
  */
36
37
  // TODO(burdon): Instead of creating component variants, create helpers/hooks that normalize the props.
37
38
  // TODO(burdon): Warning: Cannot update a component (`DynamicTable`) while rendering a different component (`DynamicTable`).
38
- export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
39
+ export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
39
40
  classNames,
40
41
  schema,
41
- name = 'example.com/dynamic-table', // Rmove default or make random; this will lead to type collisions.
42
+ name = 'com.example.dynamic-table', // Remove default or make random; this will lead to type collisions.
42
43
  rows,
43
44
  properties,
44
- jsonSchema: _jsonSchema,
45
+ jsonSchema: jsonSchemaProp,
45
46
  rowActions,
46
47
  onRowClick,
47
48
  onRowAction,
@@ -52,8 +53,8 @@ export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
52
53
 
53
54
  // TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
54
55
  const { jsonSchema } = useMemo(
55
- () => getBaseSchema({ typename: name, properties, jsonSchema: _jsonSchema, schema }),
56
- [name, properties, _jsonSchema, schema],
56
+ () => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp, schema }),
57
+ [name, properties, jsonSchemaProp, schema],
57
58
  );
58
59
 
59
60
  useEffect(() => {
@@ -97,8 +98,8 @@ export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
97
98
 
98
99
  // TODO(burdon): Do we need the outer divs?
99
100
  return (
100
- <div role='none' className={mx('is-full bs-full grow grid', classNames)}>
101
- <div role='none' className='grid min-bs-0 overflow-hidden'>
101
+ <div role='none' className={mx('w-full h-full grow grid', classNames)}>
102
+ <div role='none' className='grid min-h-0 overflow-hidden'>
102
103
  <Table.Root>
103
104
  <Table.Main
104
105
  ref={tableRef}
@@ -8,6 +8,7 @@ import React, { useCallback, useContext, useEffect, useMemo, useState } from 're
8
8
  import { expect, userEvent, within } from 'storybook/test';
9
9
 
10
10
  import { Obj, Type } from '@dxos/echo';
11
+ import { View } from '@dxos/echo';
11
12
  import { invariant } from '@dxos/invariant';
12
13
  import { type DxGrid } from '@dxos/lit-grid';
13
14
  import '@dxos/lit-ui/dx-tag-picker.pcss';
@@ -16,7 +17,7 @@ import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
16
17
  import { useAsyncEffect } from '@dxos/react-ui';
17
18
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
18
19
  import { translations as formTranslations } from '@dxos/react-ui-form';
19
- import { View } from '@dxos/schema';
20
+ import { ViewModel } from '@dxos/schema';
20
21
  import { type ValueGenerator, createAsyncGenerator } from '@dxos/schema/testing';
21
22
  import { withRegistry } from '@dxos/storybook-utils';
22
23
  import { Organization, Person } from '@dxos/types';
@@ -35,7 +36,7 @@ const generator: ValueGenerator = faker as any;
35
36
  // TODO(burdon): Mutable and immutable views.
36
37
  // TODO(burdon): Reconcile schemas types and utils (see API PR).
37
38
  // TODO(burdon): Base type for T (with id); see ECHO API PR?
38
- const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
39
+ const useTestModel = <S extends Type.AnyObj>(schema: S, count: number) => {
39
40
  const registry = useContext(RegistryContext);
40
41
  const { space } = useClientStory();
41
42
  const [object, setObject] = useState<Table.Table>();
@@ -50,7 +51,7 @@ const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
50
51
  return;
51
52
  }
52
53
 
53
- const { view, jsonSchema } = await View.makeFromDatabase({ db: space.db, typename: Type.getTypename(schema) });
54
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename: Type.getTypename(schema) });
54
55
  const object = Table.make({ view, jsonSchema });
55
56
  setObject(object);
56
57
  space.db.add(object);
@@ -87,7 +88,7 @@ const DefaultStory = () => {
87
88
  const { space } = useClientStory();
88
89
 
89
90
  const handleCreate = useCallback(
90
- (schema: Type.Entity.Any, values: any) => {
91
+ (schema: Type.AnyEntity, values: any) => {
91
92
  invariant(Type.isObjectSchema(schema));
92
93
  invariant(space);
93
94
  return space.db.add(Obj.make(schema, values));
@@ -96,7 +97,7 @@ const DefaultStory = () => {
96
97
  );
97
98
 
98
99
  return (
99
- <div className='is-full bs-full grid grid-cols-2 divide-x divide-separator'>
100
+ <div className='w-full h-full grid grid-cols-2 divide-x divide-separator'>
100
101
  <TableComponent.Root>
101
102
  <TableComponent.Main
102
103
  model={orgModel}
@@ -125,7 +126,7 @@ const meta = {
125
126
  title: 'ui/react-ui-table/Relations',
126
127
  render: DefaultStory,
127
128
  decorators: [
128
- withTheme,
129
+ withTheme(),
129
130
  withRegistry,
130
131
  // TODO(thure): Shouldn't `layout: 'fullscreen'` below make this unnecessary?
131
132
  withLayout({ classNames: 'fixed inset-0' }),
@@ -195,8 +196,9 @@ export const Default: Story = {
195
196
  const saveButton = await body.findByTestId('save-button');
196
197
  await userEvent.click(saveButton);
197
198
 
198
- // Verify the relation was set (cell should now contain the org name)
199
- await expect(targetCell).toHaveTextContent(orgName.substring(0, 4));
199
+ // Verify the relation was set (cell should now contain the org name).
200
+ const updatedCell = within(secondGrid).getByTestId('grid.4.0');
201
+ await expect(updatedCell).toHaveTextContent(orgName.substring(0, 4));
200
202
 
201
203
  // Test object creation (new relations) - equivalent to "new relations work as expected" test
202
204
  // Find a different cell to test object creation (second row, relations column)
@@ -231,7 +233,8 @@ export const Default: Story = {
231
233
  const saveObjectButton = await within(createReferencedObjectForm).findByTestId('save-button');
232
234
  await userEvent.click(saveObjectButton);
233
235
 
234
- // Verify the new object was created and relation was set
235
- await expect(newTargetCell).toHaveTextContent(newOrgName);
236
+ // Verify the new object was created and relation was set.
237
+ const updatedNewCell = within(secondGrid).getByTestId('grid.4.1');
238
+ await expect(updatedNewCell).toHaveTextContent(newOrgName);
236
239
  },
237
240
  } as any;
@@ -6,23 +6,24 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import * as Schema from 'effect/Schema';
7
7
  import React, { useCallback } from 'react';
8
8
 
9
- import { Annotation, type Database, Format, Obj, type QueryAST, Type } from '@dxos/echo';
9
+ import { Annotation, type Database, Format, Obj, type QueryAST, Ref, Type } from '@dxos/echo';
10
+ import { View } from '@dxos/echo';
10
11
  import { type Mutable, PropertyMetaAnnotationId } from '@dxos/echo/internal';
11
12
  import { invariant } from '@dxos/invariant';
12
13
  import { faker } from '@dxos/random';
13
14
  import { PublicKey } from '@dxos/react-client';
14
15
  import { withClientProvider } from '@dxos/react-client/testing';
15
- import { withTheme } from '@dxos/react-ui/testing';
16
+ import { Panel, ScrollArea } from '@dxos/react-ui';
17
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
16
18
  import { ViewEditor, translations as formTranslations } from '@dxos/react-ui-form';
17
19
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
18
- import { View, getSchemaFromPropertyDefinitions, getTypenameFromQuery } from '@dxos/schema';
20
+ import { ViewModel, getSchemaFromPropertyDefinitions, getTypenameFromQuery } from '@dxos/schema';
19
21
  import { TestSchema, createObjectFactory } from '@dxos/schema/testing';
20
22
  import { withRegistry } from '@dxos/storybook-utils';
21
23
 
22
24
  import { useTestTableModel } from '../../testing';
23
25
  import { translations } from '../../translations';
24
26
  import { Table } from '../../types';
25
- import { TableToolbar } from '../TableToolbar';
26
27
 
27
28
  import { Table as TableComponent } from './Table';
28
29
 
@@ -47,11 +48,11 @@ const Example = Schema.Struct({
47
48
  }),
48
49
  ),
49
50
  description: Schema.optional(Schema.String).annotations({ title: 'Description' }),
50
- parent: Schema.optional(Schema.suspend((): Type.Ref<Example> => Type.Ref(Example))).annotations({
51
+ parent: Schema.optional(Schema.suspend((): Ref.RefSchema<Example> => Ref.Ref(Example))).annotations({
51
52
  title: 'Parent',
52
53
  }),
53
54
  }).pipe(
54
- Type.object({ typename: `example.com/type/${PublicKey.random().truncate()}`, version: '0.1.0' }),
55
+ Type.object({ typename: `com.example.type.${PublicKey.random().truncate()}`, version: '0.1.0' }),
55
56
  Annotation.LabelAnnotation.set(['name']),
56
57
  );
57
58
  interface Example extends Schema.Schema.Type<typeof Example> {}
@@ -103,30 +104,50 @@ const DefaultStory = () => {
103
104
  const { db, schema, table, tableRef, model, presentation, handleInsertRow, handleSaveView, handleDeleteColumn } =
104
105
  useTestTableModel();
105
106
 
107
+ const handleRowClick = useCallback(
108
+ (row: any) => {
109
+ if (model?.getDraftRowCount() === 0 && ['frozenRowsEnd', 'fixedEndStart', 'fixedEndEnd'].includes(row?.plane)) {
110
+ handleInsertRow();
111
+ }
112
+ },
113
+ [model, handleInsertRow],
114
+ );
115
+
106
116
  if (!schema || !table?.view.target) {
107
117
  return <div />;
108
118
  }
109
119
 
110
120
  return (
111
121
  <div className='grow grid grid-cols-[1fr_350px]'>
112
- <div className='grid grid-rows-[min-content_1fr] min-bs-0 overflow-hidden'>
113
- <TableToolbar classNames='border-be border-subduedSeparator' onAdd={handleInsertRow} onSave={handleSaveView} />
114
- <TableComponent.Root>
115
- <TableComponent.Main
116
- ref={tableRef}
117
- schema={schema}
118
- model={model}
119
- presentation={presentation}
120
- ignoreAttention
121
- />
122
- </TableComponent.Root>
123
- </div>
124
- <div className='flex flex-col bs-full border-l border-separator overflow-y-auto'>
125
- <StoryViewEditor view={table.view.target} schema={schema} db={db} handleDeleteColumn={handleDeleteColumn} />
126
- <SyntaxHighlighter language='json' className='text-xs'>
127
- {JSON.stringify({ view: table.view.target, schema }, null, 2)}
128
- </SyntaxHighlighter>
129
- </div>
122
+ <TableComponent.Root>
123
+ <Panel.Root>
124
+ <Panel.Toolbar asChild>
125
+ <TableComponent.Toolbar
126
+ classNames='border-b border-subdued-separator'
127
+ onAdd={handleInsertRow}
128
+ onSave={handleSaveView}
129
+ />
130
+ </Panel.Toolbar>
131
+ <Panel.Content asChild>
132
+ <TableComponent.Main
133
+ ref={tableRef}
134
+ schema={schema}
135
+ model={model}
136
+ presentation={presentation}
137
+ onRowClick={handleRowClick}
138
+ ignoreAttention
139
+ />
140
+ </Panel.Content>
141
+ </Panel.Root>
142
+ </TableComponent.Root>
143
+ <ScrollArea.Root orientation='vertical' classNames='border-l border-separator'>
144
+ <ScrollArea.Viewport>
145
+ <StoryViewEditor view={table.view.target} schema={schema} db={db} handleDeleteColumn={handleDeleteColumn} />
146
+ <SyntaxHighlighter language='json' className='text-xs'>
147
+ {JSON.stringify({ view: table.view.target, schema }, null, 2)}
148
+ </SyntaxHighlighter>
149
+ </ScrollArea.Viewport>
150
+ </ScrollArea.Root>
130
151
  </div>
131
152
  );
132
153
  };
@@ -137,13 +158,14 @@ type StoryProps = { rows?: number };
137
158
  // Story definitions.
138
159
  //
139
160
 
140
- // TODO(burdon): Need super simple story.
161
+ // TODO(burdon): Need simpler story.
141
162
 
142
163
  const meta = {
143
164
  title: 'ui/react-ui-table/Table',
144
165
  render: DefaultStory,
145
166
  decorators: [
146
- withTheme,
167
+ withTheme(),
168
+ withLayout({ layout: 'fullscreen' }),
147
169
  withRegistry,
148
170
  withClientProvider({
149
171
  types: [View.View, Table.Table],
@@ -151,7 +173,7 @@ const meta = {
151
173
  createSpace: true,
152
174
  onCreateSpace: async ({ space }) => {
153
175
  const [schema] = await space.db.schemaRegistry.register([Example]);
154
- const { view, jsonSchema } = await View.makeFromDatabase({ db: space.db, typename: schema.typename });
176
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename: schema.typename });
155
177
  const table = Table.make({ view, jsonSchema });
156
178
  Obj.change(view, (v) => {
157
179
  v.projection.fields = [
@@ -197,7 +219,7 @@ export const StaticSchema: StoryObj = {
197
219
  createIdentity: true,
198
220
  createSpace: true,
199
221
  onCreateSpace: async ({ space }) => {
200
- const { view, jsonSchema } = await View.makeFromDatabase({
222
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({
201
223
  db: space.db,
202
224
  typename: TestSchema.Person.typename,
203
225
  });
@@ -230,7 +252,7 @@ const ContactWithArrayOfEmails = Schema.Struct({
230
252
  ),
231
253
  }).pipe(
232
254
  Type.object({
233
- typename: 'dxos.org/type/ContactWithArrayOfEmails',
255
+ typename: 'org.dxos.type.contact-with-array-of-emails',
234
256
  version: '0.1.0',
235
257
  }),
236
258
  );
@@ -243,7 +265,7 @@ export const ArrayOfObjects: StoryObj = {
243
265
  createIdentity: true,
244
266
  createSpace: true,
245
267
  onCreateSpace: async ({ space }) => {
246
- const { view, jsonSchema } = await View.makeFromDatabase({
268
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({
247
269
  db: space.db,
248
270
  typename: ContactWithArrayOfEmails.typename,
249
271
  });
@@ -275,7 +297,7 @@ export const Tags: Meta<StoryProps> = {
275
297
  createSpace: true,
276
298
  onCreateSpace: async ({ space }) => {
277
299
  // Configure schema.
278
- const typename = 'example.com/SingleSelect';
300
+ const typename = 'com.example.type.single-select';
279
301
  const selectOptions = [
280
302
  { id: 'one', title: 'One', color: 'emerald' },
281
303
  { id: 'two', title: 'Two', color: 'blue' },
@@ -301,7 +323,7 @@ export const Tags: Meta<StoryProps> = {
301
323
  const [storedSchema] = await space.db.schemaRegistry.register([schema]);
302
324
 
303
325
  // Initialize table.
304
- const { view, jsonSchema } = await View.makeFromDatabase({ db: space.db, typename });
326
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename });
305
327
  const table = Table.make({ view, jsonSchema });
306
328
  space.db.add(table);
307
329