@dxos/react-ui-table 0.7.4 → 0.7.5-main.937ce75

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 (93) hide show
  1. package/dist/lib/browser/{chunk-IYCSJDMB.mjs → chunk-AT7O4RAD.mjs} +4 -4
  2. package/dist/lib/browser/{chunk-IYCSJDMB.mjs.map → chunk-AT7O4RAD.mjs.map} +2 -2
  3. package/dist/lib/browser/index.mjs +1442 -1219
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/types/index.mjs +1 -1
  7. package/dist/lib/node/{chunk-MHBMVCFZ.cjs → chunk-YSBXNBDJ.cjs} +6 -6
  8. package/dist/lib/node/{chunk-MHBMVCFZ.cjs.map → chunk-YSBXNBDJ.cjs.map} +2 -2
  9. package/dist/lib/node/index.cjs +1351 -1111
  10. package/dist/lib/node/index.cjs.map +4 -4
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/types/index.cjs +3 -3
  13. package/dist/lib/node/types/index.cjs.map +1 -1
  14. package/dist/lib/node-esm/{chunk-BMWGPXPL.mjs → chunk-6OH2NHUX.mjs} +4 -4
  15. package/dist/lib/node-esm/{chunk-BMWGPXPL.mjs.map → chunk-6OH2NHUX.mjs.map} +2 -2
  16. package/dist/lib/node-esm/index.mjs +1442 -1219
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/types/index.mjs +1 -1
  20. package/dist/types/src/_deprecated/hooks/useColumnSorting.d.ts +1 -1
  21. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +4 -3
  22. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/ColumnSettings.d.ts +3 -2
  24. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/CreateRefPanel.d.ts +3 -2
  26. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/RefPanel.d.ts +4 -3
  28. package/dist/types/src/components/Table/RefPanel.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/RowActionsMenu.d.ts +3 -2
  30. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/Table.d.ts +2 -1
  32. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  33. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +3 -2
  35. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  36. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  37. package/dist/types/src/components/testing.d.ts +55 -71
  38. package/dist/types/src/components/testing.d.ts.map +1 -1
  39. package/dist/types/src/index.d.ts +1 -0
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/model/index.d.ts +1 -0
  42. package/dist/types/src/model/index.d.ts.map +1 -1
  43. package/dist/types/src/model/modal-controller.d.ts +6 -2
  44. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  45. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  46. package/dist/types/src/model/table-model.d.ts +14 -27
  47. package/dist/types/src/model/table-model.d.ts.map +1 -1
  48. package/dist/types/src/model/table-presentation.d.ts +22 -0
  49. package/dist/types/src/model/table-presentation.d.ts.map +1 -0
  50. package/dist/types/src/model/table-presentation.test.d.ts +2 -0
  51. package/dist/types/src/model/table-presentation.test.d.ts.map +1 -0
  52. package/dist/types/src/model/table-sorting.d.ts +48 -0
  53. package/dist/types/src/model/table-sorting.d.ts.map +1 -0
  54. package/dist/types/src/playwright/TableManager.d.ts +2 -1
  55. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  56. package/dist/types/src/types/table.d.ts +118 -154
  57. package/dist/types/src/types/table.d.ts.map +1 -1
  58. package/dist/types/src/util/index.d.ts +1 -0
  59. package/dist/types/src/util/index.d.ts.map +1 -1
  60. package/dist/types/src/util/table-buttons.d.ts +50 -20
  61. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  62. package/dist/types/src/util/table-controls.d.ts +32 -9
  63. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  64. package/dist/types/src/util/table.d.ts +2 -2
  65. package/dist/types/src/util/table.d.ts.map +1 -1
  66. package/dist/types/tsconfig.tsbuildinfo +1 -0
  67. package/package.json +29 -29
  68. package/src/components/Table/ColumnActionsMenu.tsx +8 -8
  69. package/src/components/Table/ColumnSettings.tsx +11 -11
  70. package/src/components/Table/CreateRefPanel.tsx +13 -14
  71. package/src/components/Table/RefPanel.tsx +9 -9
  72. package/src/components/Table/RowActionsMenu.tsx +6 -7
  73. package/src/components/Table/Table.stories.tsx +40 -23
  74. package/src/components/Table/Table.tsx +235 -148
  75. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +13 -12
  76. package/src/components/TableCellEditor/TableCellEditor.tsx +6 -4
  77. package/src/components/testing.ts +10 -8
  78. package/src/index.ts +2 -0
  79. package/src/model/index.ts +1 -0
  80. package/src/model/modal-controller.ts +15 -48
  81. package/src/model/selection-model.ts +12 -1
  82. package/src/model/table-model.test.ts +4 -71
  83. package/src/model/table-model.ts +61 -292
  84. package/src/model/table-presentation.test.ts +102 -0
  85. package/src/model/table-presentation.ts +217 -0
  86. package/src/model/table-sorting.ts +131 -0
  87. package/src/playwright/TableManager.ts +5 -1
  88. package/src/playwright/smoke.spec.ts +79 -1
  89. package/src/types/table.ts +3 -3
  90. package/src/util/index.ts +1 -0
  91. package/src/util/table-buttons.ts +97 -48
  92. package/src/util/table-controls.ts +71 -7
  93. package/src/util/table.ts +21 -13
@@ -3,13 +3,11 @@
3
3
  //
4
4
 
5
5
  import { signal } from '@preact/signals-core';
6
- import { type RefObject, type MouseEvent, type MutableRefObject } from 'react';
6
+ import { type RefObject, type MutableRefObject } from 'react';
7
7
 
8
8
  import { type ReactiveObject } from '@dxos/live-object';
9
9
  import { log } from '@dxos/log';
10
10
 
11
- import { tableButtons } from '../util';
12
-
13
11
  export type ColumnSettingsMode = { type: 'create' } | { type: 'edit'; fieldId: string };
14
12
 
15
13
  export type ModalState =
@@ -37,55 +35,24 @@ export class ModalController {
37
35
  return this._triggerRef as RefObject<HTMLButtonElement>;
38
36
  }
39
37
 
40
- public handleClick = (event: MouseEvent): boolean => {
41
- const target = event.target as HTMLElement;
42
-
43
- // TODO(thure): why not just get the value of the closest recognized attribute and `switch` on that?
44
- // Repeated querying is more error-prone and less legible, I’d think.
45
-
46
- const rowButton = target.closest(`button[${tableButtons.rowMenu.attr}]`);
47
- if (rowButton) {
48
- this._triggerRef.current = rowButton as HTMLElement;
49
- this._state.value = {
50
- type: 'row',
51
- rowIndex: Number(rowButton.getAttribute(tableButtons.rowMenu.attr)),
52
- };
53
- return true;
54
- }
38
+ public setTrigger = (trigger: HTMLElement) => {
39
+ this._triggerRef.current = trigger;
40
+ };
55
41
 
56
- const columnButton = target.closest(`button[${tableButtons.columnSettings.attr}]`);
57
- if (columnButton) {
58
- const fieldId = columnButton.getAttribute(tableButtons.columnSettings.attr)!;
59
- this._triggerRef.current = columnButton as HTMLElement;
60
- this._state.value = {
61
- type: 'column',
62
- fieldId,
63
- };
64
- return true;
65
- }
42
+ public showRowMenu = (rowIndex: number) => {
43
+ this._state.value = { type: 'row', rowIndex };
44
+ };
66
45
 
67
- const addColumnButton = target.closest(`button[${tableButtons.addColumn.attr}]`);
68
- if (addColumnButton) {
69
- this._triggerRef.current = addColumnButton as HTMLElement;
70
- this._state.value = {
71
- type: 'columnSettings',
72
- mode: { type: 'create' },
73
- };
74
- return true;
75
- }
46
+ public showColumnMenu = (fieldId: string) => {
47
+ this._state.value = { type: 'column', fieldId };
48
+ };
76
49
 
77
- const refButton = target.closest(`button[${tableButtons.referencedCell.attr}]`);
78
- if (refButton) {
79
- this._triggerRef.current = refButton as HTMLElement;
80
- const [schemaId, targetId] = refButton.getAttribute(tableButtons.referencedCell.attr)!.split('#');
81
- this._state.value = {
82
- type: 'refPanel',
83
- targetId,
84
- typename: schemaId,
85
- };
86
- }
50
+ public showColumnCreator = () => {
51
+ this._state.value = { type: 'columnSettings', mode: { type: 'create' } };
52
+ };
87
53
 
88
- return false;
54
+ public showReferencePanel = (targetId: string, schemaId: string) => {
55
+ this._state.value = { type: 'refPanel', targetId, typename: schemaId };
89
56
  };
90
57
 
91
58
  public openColumnSettings = () => {
@@ -17,6 +17,7 @@ export class SelectionModel<T extends BaseTableRow> extends Resource {
17
17
  if (!rows) {
18
18
  return new Set<string>();
19
19
  }
20
+
20
21
  const validIds = new Set(rows.map((row) => row.id));
21
22
  return new Set([...this._selection.value].filter((id) => validIds.has(id)));
22
23
  });
@@ -28,6 +29,7 @@ export class SelectionModel<T extends BaseTableRow> extends Resource {
28
29
  if (rows.length === 0) {
29
30
  return false;
30
31
  }
32
+
31
33
  return rows.every((row) => this._selection.value.has(row.id));
32
34
  });
33
35
 
@@ -94,6 +96,15 @@ export class SelectionModel<T extends BaseTableRow> extends Resource {
94
96
  };
95
97
 
96
98
  public setSelection = (mode: 'all' | 'none'): void => {
97
- this._selection.value = mode === 'all' ? new Set(this._rows.value.map((row) => row.id)) : new Set();
99
+ switch (mode) {
100
+ case 'all': {
101
+ this._selection.value = new Set(this._rows.value.map((row) => row.id));
102
+ break;
103
+ }
104
+ case 'none': {
105
+ this._selection.value = new Set();
106
+ break;
107
+ }
108
+ }
98
109
  };
99
110
  }
@@ -8,8 +8,8 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
8
8
  import { S, TypedObject } from '@dxos/echo-schema';
9
9
  import { updateCounter } from '@dxos/echo-schema/testing';
10
10
  import { registerSignalsRuntime } from '@dxos/echo-signals';
11
- import { createMutableSchema } from '@dxos/live-object/testing';
12
- import { create } from '@dxos/react-client/echo';
11
+ import { createEchoSchema } from '@dxos/live-object/testing';
12
+ import { create, makeRef } from '@dxos/react-client/echo';
13
13
  import { createView, ViewProjection } from '@dxos/schema';
14
14
 
15
15
  import { TableModel, type TableModelProps } from './table-model';
@@ -100,73 +100,6 @@ describe('TableModel', () => {
100
100
  expect(outerCounter.count).toBe(1);
101
101
  expect(innerCounter.count).toBe(1);
102
102
  });
103
-
104
- describe('row reactivity', () => {
105
- let data: any[];
106
-
107
- beforeEach(async () => {
108
- // TODO(burdon): Use generator.
109
- ({ data } = create({
110
- data: [
111
- { col1: 'A', col2: 1, col3: true },
112
- { col1: 'B', col2: 2, col3: false },
113
- ],
114
- }));
115
-
116
- const model = createTableModel();
117
- model.setRows(data);
118
- await model.open();
119
- });
120
-
121
- it('should update with row-level reactivity', () => {
122
- // Set up visible range to include our test data
123
- model.getCells({ start: { row: 0, col: 0 }, end: { row: 1, col: 2 } }, 'grid');
124
-
125
- // Trigger a row update
126
- data[0].col1 = 'New Value';
127
- expect(updateCount).toBe(1);
128
-
129
- // Verify the new value through getCells
130
- const cells = model.getCells({ start: { row: 0, col: 0 }, end: { row: 0, col: 0 } }, 'grid');
131
- expect(cells['0,0']?.value).toBe('New Value');
132
- });
133
-
134
- it('should update reactively when adding a new row', () => {
135
- // Set up visible range to include our test data
136
- model.getCells({ start: { row: 0, col: 0 }, end: { row: 2, col: 2 } }, 'grid');
137
-
138
- data.push({ col1: 'C', col2: 3, col3: true });
139
- expect(updateCount).toBe(1);
140
-
141
- const cells = model.getCells({ start: { row: 0, col: 0 }, end: { row: 2, col: 2 } }, 'grid');
142
-
143
- // Verify the new row's data
144
- expect(cells['0,2']?.value).toBe('C');
145
- expect(cells['1,2']?.value).toBe('3');
146
- expect(cells['2,2']?.value).toBe('true');
147
- });
148
-
149
- it('should handle combined operations reactively', () => {
150
- // Set up visible range
151
- model.getCells({ start: { row: 0, col: 0 }, end: { row: 2, col: 2 } }, 'grid');
152
-
153
- // Multiple operations
154
- data[0].col1 = 'Updated A';
155
- data.push({ col1: 'C', col2: 3, col3: true });
156
- data.splice(1, 1);
157
-
158
- // We expect one update per operation affecting visible rows
159
- expect(updateCount).toBe(3);
160
-
161
- const cells = model.getCells({ start: { row: 0, col: 0 }, end: { row: 1, col: 2 } }, 'grid');
162
-
163
- // Verify final state
164
- expect(cells['0,0']?.value).toBe('Updated A');
165
- expect(cells['0,1']?.value).toBe('C');
166
- expect(cells['1,1']?.value).toBe('3');
167
- expect(cells['2,1']?.value).toBe('true');
168
- });
169
- });
170
103
  });
171
104
  });
172
105
 
@@ -176,9 +109,9 @@ class Test extends TypedObject({ typename: 'example.com/type/Test', version: '0.
176
109
  }) {}
177
110
 
178
111
  const createTableModel = (props: Partial<TableModelProps> = {}): TableModel => {
179
- const schema = createMutableSchema(Test);
112
+ const schema = createEchoSchema(Test);
180
113
  const view = createView({ name: 'Test', typename: schema.typename, jsonSchema: schema.jsonSchema });
181
114
  const projection = new ViewProjection(schema, view);
182
- const table = create(TableType, { view });
115
+ const table = create(TableType, { view: makeRef(view) });
183
116
  return new TableModel({ table, projection, ...props });
184
117
  };