@dxos/react-ui-table 0.8.4-main.7ace549 → 0.8.4-main.8360d9e660

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 (123) hide show
  1. package/dist/lib/browser/{chunk-5XWSB3JP.mjs → chunk-BF54SSNL.mjs} +27 -28
  2. package/dist/lib/browser/chunk-BF54SSNL.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-KNC7XYT6.mjs → chunk-PTHMYAAM.mjs} +620 -652
  4. package/dist/lib/browser/chunk-PTHMYAAM.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +1154 -1036
  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 +20 -19
  9. package/dist/lib/browser/testing/index.mjs.map +3 -3
  10. package/dist/lib/browser/types/index.mjs +1 -1
  11. package/dist/lib/node-esm/{chunk-CWSGS3Y2.mjs → chunk-GI72MQSG.mjs} +620 -651
  12. package/dist/lib/node-esm/chunk-GI72MQSG.mjs.map +7 -0
  13. package/dist/lib/node-esm/{chunk-MKTMOY46.mjs → chunk-SIRDIPHZ.mjs} +27 -28
  14. package/dist/lib/node-esm/chunk-SIRDIPHZ.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +1154 -1036
  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 +20 -19
  19. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/types/index.mjs +1 -1
  21. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -2
  22. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -2
  24. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/DynamicTable.d.ts +7 -7
  26. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +2 -16
  28. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/Relations.stories.d.ts +6 -3
  30. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  32. package/dist/types/src/components/Table/Table.d.ts +11 -11
  33. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  34. package/dist/types/src/components/Table/Table.stories.d.ts +6 -3
  35. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +1 -1
  37. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +10 -12
  38. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  39. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +5 -7
  40. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  41. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +2 -2
  42. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  43. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +3 -3
  44. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  45. package/dist/types/src/components/testing.d.ts +22 -13
  46. package/dist/types/src/components/testing.d.ts.map +1 -1
  47. package/dist/types/src/hooks/useAddRow.d.ts +5 -6
  48. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  49. package/dist/types/src/hooks/useProjectionModel.d.ts +2 -1
  50. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
  51. package/dist/types/src/hooks/useTableModel.d.ts +6 -5
  52. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  53. package/dist/types/src/model/modal-controller.d.ts +5 -1
  54. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  55. package/dist/types/src/model/selection-model.d.ts +17 -8
  56. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  57. package/dist/types/src/model/table-model.d.ts +100 -18
  58. package/dist/types/src/model/table-model.d.ts.map +1 -1
  59. package/dist/types/src/model/table-presentation.d.ts +3 -1
  60. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  61. package/dist/types/src/playwright/TableManager.d.ts +2 -1
  62. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  63. package/dist/types/src/testing/useTestTableModel.d.ts +5 -8
  64. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  65. package/dist/types/src/translations.d.ts +2 -2
  66. package/dist/types/src/translations.d.ts.map +1 -1
  67. package/dist/types/src/types/Table.d.ts +13 -15
  68. package/dist/types/src/types/Table.d.ts.map +1 -1
  69. package/dist/types/src/util/dynamic-table.d.ts +12 -10
  70. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  71. package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
  72. package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
  73. package/dist/types/src/util/index.d.ts +2 -0
  74. package/dist/types/src/util/index.d.ts.map +1 -1
  75. package/dist/types/src/util/query-ast.d.ts +7 -0
  76. package/dist/types/src/util/query-ast.d.ts.map +1 -0
  77. package/dist/types/src/util/sort.d.ts +12 -0
  78. package/dist/types/src/util/sort.d.ts.map +1 -0
  79. package/dist/types/tsconfig.tsbuildinfo +1 -1
  80. package/package.json +54 -55
  81. package/src/components/Table/ColumnActionsMenu.tsx +10 -6
  82. package/src/components/Table/ColumnSettings.tsx +8 -9
  83. package/src/components/Table/DynamicTable.stories.tsx +11 -11
  84. package/src/components/Table/DynamicTable.tsx +30 -30
  85. package/src/components/Table/Relations.stories.tsx +34 -31
  86. package/src/components/Table/RowActionsMenu.tsx +3 -2
  87. package/src/components/Table/Table.stories.tsx +80 -67
  88. package/src/components/Table/Table.tsx +324 -299
  89. package/src/components/TableCellEditor/CellValidationMessage.tsx +5 -5
  90. package/src/components/TableCellEditor/FormCellEditor.tsx +118 -135
  91. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +10 -7
  92. package/src/components/TableCellEditor/TableCellEditor.tsx +27 -27
  93. package/src/components/TableToolbar/TableToolbar.tsx +24 -18
  94. package/src/components/testing.ts +37 -11
  95. package/src/hooks/useAddRow.ts +8 -10
  96. package/src/hooks/useProjectionModel.ts +29 -9
  97. package/src/hooks/useTableModel.ts +27 -23
  98. package/src/model/modal-controller.ts +23 -12
  99. package/src/model/selection-model.ts +75 -44
  100. package/src/model/table-model.test.ts +81 -53
  101. package/src/model/table-model.ts +410 -138
  102. package/src/model/table-presentation.test.ts +58 -48
  103. package/src/model/table-presentation.ts +34 -28
  104. package/src/playwright/TableManager.ts +12 -5
  105. package/src/playwright/playwright.config.ts +1 -1
  106. package/src/playwright/smoke.spec.ts +48 -4
  107. package/src/testing/useTestTableModel.ts +24 -25
  108. package/src/translations.ts +1 -1
  109. package/src/types/Table.ts +28 -38
  110. package/src/util/dynamic-table.test.ts +70 -0
  111. package/src/util/dynamic-table.ts +36 -19
  112. package/src/util/index.ts +2 -0
  113. package/src/util/query-ast.ts +22 -0
  114. package/src/util/sort.ts +90 -0
  115. package/src/util/table-buttons.ts +1 -1
  116. package/src/util/table-controls.ts +2 -2
  117. package/dist/lib/browser/chunk-5XWSB3JP.mjs.map +0 -7
  118. package/dist/lib/browser/chunk-KNC7XYT6.mjs.map +0 -7
  119. package/dist/lib/node-esm/chunk-CWSGS3Y2.mjs.map +0 -7
  120. package/dist/lib/node-esm/chunk-MKTMOY46.mjs.map +0 -7
  121. package/dist/types/src/model/table-sorting.d.ts +0 -56
  122. package/dist/types/src/model/table-sorting.d.ts.map +0 -1
  123. package/src/model/table-sorting.ts +0 -234
@@ -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, Format, Obj, type QueryAST, Type } from '@dxos/echo';
10
- import { PropertyMetaAnnotationId } from '@dxos/echo/internal';
9
+ import { Annotation, type Database, Format, Obj, type QueryAST, Ref, Type } from '@dxos/echo';
10
+ import { View } from '@dxos/echo';
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
- import { type Space } from '@dxos/react-client/echo';
15
15
  import { withClientProvider } from '@dxos/react-client/testing';
16
- import { withTheme } from '@dxos/react-ui/testing';
16
+ import { Panel, ScrollArea } from '@dxos/react-ui';
17
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
17
18
  import { ViewEditor, translations as formTranslations } from '@dxos/react-ui-form';
18
19
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
19
- import { View, getSchemaFromPropertyDefinitions, getTypenameFromQuery } from '@dxos/schema';
20
+ import { ViewModel, getSchemaFromPropertyDefinitions, getTypenameFromQuery } from '@dxos/schema';
20
21
  import { TestSchema, createObjectFactory } from '@dxos/schema/testing';
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.Obj({ 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> {}
@@ -59,12 +60,12 @@ interface Example extends Schema.Schema.Type<typeof Example> {}
59
60
  const StoryViewEditor = ({
60
61
  view,
61
62
  schema,
62
- space,
63
+ db,
63
64
  handleDeleteColumn,
64
65
  }: {
65
66
  view?: View.View;
66
67
  schema?: Schema.Schema.AnyNoContext;
67
- space?: Space;
68
+ db?: Database.Database;
68
69
  handleDeleteColumn: (fieldId: string) => void;
69
70
  }) => {
70
71
  const handleQueryChanged = useCallback(
@@ -73,7 +74,9 @@ const StoryViewEditor = ({
73
74
  invariant(Type.isMutable(schema));
74
75
  schema.updateTypename(getTypenameFromQuery(newQuery));
75
76
  invariant(view);
76
- view.query.ast = newQuery;
77
+ Obj.change(view, (v) => {
78
+ v.query.ast = newQuery as Mutable<typeof newQuery>;
79
+ });
77
80
  },
78
81
  [schema, view],
79
82
  );
@@ -84,7 +87,7 @@ const StoryViewEditor = ({
84
87
 
85
88
  return (
86
89
  <ViewEditor
87
- registry={space?.db.schemaRegistry}
90
+ registry={db?.schemaRegistry}
88
91
  schema={schema}
89
92
  view={view}
90
93
  onQueryChanged={handleQueryChanged}
@@ -98,18 +101,17 @@ const StoryViewEditor = ({
98
101
  //
99
102
 
100
103
  const DefaultStory = () => {
101
- const {
102
- space,
103
- schema,
104
- table,
105
- tableRef,
106
- model,
107
- presentation,
108
- client,
109
- handleInsertRow,
110
- handleSaveView,
111
- handleDeleteColumn,
112
- } = useTestTableModel();
104
+ const { db, schema, table, tableRef, model, presentation, handleInsertRow, handleSaveView, handleDeleteColumn } =
105
+ useTestTableModel();
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
+ );
113
115
 
114
116
  if (!schema || !table?.view.target) {
115
117
  return <div />;
@@ -117,30 +119,35 @@ const DefaultStory = () => {
117
119
 
118
120
  return (
119
121
  <div className='grow grid grid-cols-[1fr_350px]'>
120
- <div className='grid grid-rows-[min-content_1fr] min-bs-0 overflow-hidden'>
121
- <TableToolbar classNames='border-be border-subduedSeparator' onAdd={handleInsertRow} onSave={handleSaveView} />
122
- <TableComponent.Root>
123
- <TableComponent.Main
124
- ref={tableRef}
125
- model={model}
126
- presentation={presentation}
127
- schema={schema}
128
- client={client}
129
- ignoreAttention
130
- />
131
- </TableComponent.Root>
132
- </div>
133
- <div className='flex flex-col bs-full border-l border-separator overflow-y-auto'>
134
- <StoryViewEditor
135
- view={table.view.target}
136
- schema={schema}
137
- space={space}
138
- handleDeleteColumn={handleDeleteColumn}
139
- />
140
- <SyntaxHighlighter language='json' className='text-xs'>
141
- {JSON.stringify({ view: table.view.target, schema }, null, 2)}
142
- </SyntaxHighlighter>
143
- </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>
144
151
  </div>
145
152
  );
146
153
  };
@@ -151,25 +158,29 @@ type StoryProps = { rows?: number };
151
158
  // Story definitions.
152
159
  //
153
160
 
154
- // TODO(burdon): Need super simple story.
161
+ // TODO(burdon): Need simpler story.
155
162
 
156
163
  const meta = {
157
164
  title: 'ui/react-ui-table/Table',
158
165
  render: DefaultStory,
159
166
  decorators: [
160
- withTheme,
167
+ withTheme(),
168
+ withLayout({ layout: 'fullscreen' }),
169
+ withRegistry,
161
170
  withClientProvider({
162
171
  types: [View.View, Table.Table],
163
172
  createIdentity: true,
164
173
  createSpace: true,
165
- onCreateSpace: async ({ client, space }) => {
174
+ onCreateSpace: async ({ space }) => {
166
175
  const [schema] = await space.db.schemaRegistry.register([Example]);
167
- const { view, jsonSchema } = await View.makeFromSpace({ client, space, typename: schema.typename });
176
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename: schema.typename });
168
177
  const table = Table.make({ view, jsonSchema });
169
- view.projection.fields = [
170
- view.projection.fields.find((field: any) => field.path === 'name')!,
171
- ...view.projection.fields.filter((field: any) => field.path !== 'name'),
172
- ];
178
+ Obj.change(view, (v) => {
179
+ v.projection.fields = [
180
+ v.projection.fields.find((field) => field.path === 'name')!,
181
+ ...v.projection.fields.filter((field) => field.path !== 'name'),
182
+ ];
183
+ });
173
184
 
174
185
  space.db.add(table);
175
186
 
@@ -207,8 +218,11 @@ export const StaticSchema: StoryObj = {
207
218
  types: [View.View, Table.Table],
208
219
  createIdentity: true,
209
220
  createSpace: true,
210
- onCreateSpace: async ({ client, space }) => {
211
- const { view, jsonSchema } = await View.makeFromSpace({ client, space, typename: TestSchema.Person.typename });
221
+ onCreateSpace: async ({ space }) => {
222
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({
223
+ db: space.db,
224
+ typename: TestSchema.Person.typename,
225
+ });
212
226
  const table = Table.make({ view, jsonSchema });
213
227
  space.db.add(table);
214
228
 
@@ -237,8 +251,8 @@ const ContactWithArrayOfEmails = Schema.Struct({
237
251
  ),
238
252
  ),
239
253
  }).pipe(
240
- Type.Obj({
241
- typename: 'dxos.org/type/ContactWithArrayOfEmails',
254
+ Type.object({
255
+ typename: 'org.dxos.type.contact-with-array-of-emails',
242
256
  version: '0.1.0',
243
257
  }),
244
258
  );
@@ -250,10 +264,9 @@ export const ArrayOfObjects: StoryObj = {
250
264
  types: [View.View, Table.Table, TestSchema.Person, TestSchema.Organization, ContactWithArrayOfEmails],
251
265
  createIdentity: true,
252
266
  createSpace: true,
253
- onCreateSpace: async ({ client, space }) => {
254
- const { view, jsonSchema } = await View.makeFromSpace({
255
- client,
256
- space,
267
+ onCreateSpace: async ({ space }) => {
268
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({
269
+ db: space.db,
257
270
  typename: ContactWithArrayOfEmails.typename,
258
271
  });
259
272
  const table = Table.make({ view, jsonSchema });
@@ -282,9 +295,9 @@ export const Tags: Meta<StoryProps> = {
282
295
  types: [View.View, Table.Table],
283
296
  createIdentity: true,
284
297
  createSpace: true,
285
- onCreateSpace: async ({ client, space }) => {
298
+ onCreateSpace: async ({ space }) => {
286
299
  // Configure schema.
287
- const typename = 'example.com/SingleSelect';
300
+ const typename = 'com.example.type.single-select';
288
301
  const selectOptions = [
289
302
  { id: 'one', title: 'One', color: 'emerald' },
290
303
  { id: 'two', title: 'Two', color: 'blue' },
@@ -310,7 +323,7 @@ export const Tags: Meta<StoryProps> = {
310
323
  const [storedSchema] = await space.db.schemaRegistry.register([schema]);
311
324
 
312
325
  // Initialize table.
313
- const { view, jsonSchema } = await View.makeFromSpace({ client, space, typename });
326
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename });
314
327
  const table = Table.make({ view, jsonSchema });
315
328
  space.db.add(table);
316
329