@dxos/react-ui-mosaic 0.10.0 → 0.11.1

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 (115) hide show
  1. package/dist/lib/chunk-Mosaic.mjs +1024 -0
  2. package/dist/lib/chunk-Mosaic.mjs.map +1 -0
  3. package/dist/lib/index.mjs +653 -0
  4. package/dist/lib/index.mjs.map +1 -0
  5. package/dist/lib/playwright.mjs +200 -0
  6. package/dist/lib/playwright.mjs.map +1 -0
  7. package/dist/lib/testing.mjs +127 -0
  8. package/dist/lib/testing.mjs.map +1 -0
  9. package/dist/lib/translations.mjs +11 -0
  10. package/dist/lib/translations.mjs.map +1 -0
  11. package/dist/types/src/components/Board/Board.d.ts +7 -27
  12. package/dist/types/src/components/Board/Board.d.ts.map +1 -1
  13. package/dist/types/src/components/Board/Board.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/Board/BoardColumnContext.d.ts +10 -0
  15. package/dist/types/src/components/Board/BoardColumnContext.d.ts.map +1 -0
  16. package/dist/types/src/components/Board/BoardContext.d.ts +26 -0
  17. package/dist/types/src/components/Board/BoardContext.d.ts.map +1 -0
  18. package/dist/types/src/components/Board/Column.d.ts +2 -7
  19. package/dist/types/src/components/Board/Column.d.ts.map +1 -1
  20. package/dist/types/src/components/Board/index.d.ts +2 -0
  21. package/dist/types/src/components/Board/index.d.ts.map +1 -1
  22. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
  23. package/dist/types/src/components/Mosaic/Container.d.ts +6 -34
  24. package/dist/types/src/components/Mosaic/Container.d.ts.map +1 -1
  25. package/dist/types/src/components/Mosaic/Mosaic.d.ts +10 -15
  26. package/dist/types/src/components/Mosaic/Mosaic.d.ts.map +1 -1
  27. package/dist/types/src/components/Mosaic/MosaicContainerContext.d.ts +34 -0
  28. package/dist/types/src/components/Mosaic/MosaicContainerContext.d.ts.map +1 -0
  29. package/dist/types/src/components/Mosaic/MosaicTileContext.d.ts +31 -0
  30. package/dist/types/src/components/Mosaic/MosaicTileContext.d.ts.map +1 -0
  31. package/dist/types/src/components/Mosaic/Placeholder.d.ts +3 -3
  32. package/dist/types/src/components/Mosaic/Placeholder.d.ts.map +1 -1
  33. package/dist/types/src/components/Mosaic/Stack.d.ts +8 -2
  34. package/dist/types/src/components/Mosaic/Stack.d.ts.map +1 -1
  35. package/dist/types/src/components/Mosaic/Stack.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/Mosaic/Tile.d.ts +6 -32
  37. package/dist/types/src/components/Mosaic/Tile.d.ts.map +1 -1
  38. package/dist/types/src/components/Mosaic/VirtualStackPagination.stories.d.ts +13 -0
  39. package/dist/types/src/components/Mosaic/VirtualStackPagination.stories.d.ts.map +1 -0
  40. package/dist/types/src/components/Mosaic/index.d.ts +0 -1
  41. package/dist/types/src/components/Mosaic/index.d.ts.map +1 -1
  42. package/dist/types/src/components/SearchStack/SearchStack.d.ts +1 -1
  43. package/dist/types/src/components/SearchStack/SearchStack.d.ts.map +1 -1
  44. package/dist/types/src/hooks/index.d.ts +1 -0
  45. package/dist/types/src/hooks/index.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useDefaultColumnEventHandler.d.ts +2 -2
  47. package/dist/types/src/hooks/useDefaultColumnEventHandler.d.ts.map +1 -1
  48. package/dist/types/src/hooks/useEventHandlerAdapter.d.ts +3 -3
  49. package/dist/types/src/hooks/useEventHandlerAdapter.d.ts.map +1 -1
  50. package/dist/types/src/hooks/useVirtualizerPagination.d.ts +60 -0
  51. package/dist/types/src/hooks/useVirtualizerPagination.d.ts.map +1 -0
  52. package/dist/types/src/hooks/useVirtualizerPagination.test.d.ts +2 -0
  53. package/dist/types/src/hooks/useVirtualizerPagination.test.d.ts.map +1 -0
  54. package/dist/types/src/hooks/useVisibleItems.d.ts +2 -2
  55. package/dist/types/src/hooks/useVisibleItems.d.ts.map +1 -1
  56. package/dist/types/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +35 -37
  58. package/src/components/Board/Board.stories.tsx +7 -6
  59. package/src/components/Board/Board.tsx +9 -54
  60. package/src/components/Board/BoardColumnContext.ts +25 -0
  61. package/src/components/Board/BoardContext.ts +43 -0
  62. package/src/components/Board/Column.tsx +13 -27
  63. package/src/components/Board/Item.tsx +2 -2
  64. package/src/components/Board/index.ts +3 -0
  65. package/src/components/Mosaic/Container.tsx +31 -53
  66. package/src/components/Mosaic/DragHandle.tsx +1 -1
  67. package/src/components/Mosaic/{Mosaic.tsx → Mosaic.ts} +5 -16
  68. package/src/components/Mosaic/MosaicContainerContext.ts +44 -0
  69. package/src/components/Mosaic/MosaicTileContext.ts +34 -0
  70. package/src/components/Mosaic/Placeholder.tsx +7 -8
  71. package/src/components/Mosaic/ResizeHandle.stories.tsx +4 -4
  72. package/src/components/Mosaic/ResizeHandle.tsx +2 -2
  73. package/src/components/Mosaic/Stack.stories.tsx +49 -13
  74. package/src/components/Mosaic/Stack.tsx +30 -9
  75. package/src/components/Mosaic/Tile.tsx +33 -33
  76. package/src/components/Mosaic/VirtualStackPagination.stories.tsx +423 -0
  77. package/src/components/Mosaic/index.ts +0 -1
  78. package/src/hooks/index.ts +1 -0
  79. package/src/hooks/useDefaultColumnEventHandler.ts +2 -2
  80. package/src/hooks/useEventHandlerAdapter.ts +4 -5
  81. package/src/hooks/useVirtualizerPagination.test.tsx +105 -0
  82. package/src/hooks/useVirtualizerPagination.ts +473 -0
  83. package/src/hooks/useVisibleItems.ts +2 -2
  84. package/src/playwright/smoke.spec.ts +4 -1
  85. package/src/testing/DefaultStackTile.tsx +1 -1
  86. package/src/testing/decorator.tsx +3 -3
  87. package/dist/lib/browser/chunk-OBVIYZLR.mjs +0 -1119
  88. package/dist/lib/browser/chunk-OBVIYZLR.mjs.map +0 -7
  89. package/dist/lib/browser/index.mjs +0 -701
  90. package/dist/lib/browser/index.mjs.map +0 -7
  91. package/dist/lib/browser/meta.json +0 -1
  92. package/dist/lib/browser/playwright/index.mjs +0 -256
  93. package/dist/lib/browser/playwright/index.mjs.map +0 -7
  94. package/dist/lib/browser/testing/index.mjs +0 -136
  95. package/dist/lib/browser/testing/index.mjs.map +0 -7
  96. package/dist/lib/browser/translations.mjs +0 -18
  97. package/dist/lib/browser/translations.mjs.map +0 -7
  98. package/dist/lib/node-esm/chunk-4IEMCMIV.mjs +0 -1121
  99. package/dist/lib/node-esm/chunk-4IEMCMIV.mjs.map +0 -7
  100. package/dist/lib/node-esm/index.mjs +0 -702
  101. package/dist/lib/node-esm/index.mjs.map +0 -7
  102. package/dist/lib/node-esm/meta.json +0 -1
  103. package/dist/lib/node-esm/playwright/index.mjs +0 -258
  104. package/dist/lib/node-esm/playwright/index.mjs.map +0 -7
  105. package/dist/lib/node-esm/testing/index.mjs +0 -137
  106. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  107. package/dist/lib/node-esm/translations.mjs +0 -20
  108. package/dist/lib/node-esm/translations.mjs.map +0 -7
  109. package/dist/types/src/components/Mosaic/Root.d.ts +0 -35
  110. package/dist/types/src/components/Mosaic/Root.d.ts.map +0 -1
  111. package/dist/types/src/components/Mosaic/types.d.ts +0 -86
  112. package/dist/types/src/components/Mosaic/types.d.ts.map +0 -1
  113. package/src/components/Mosaic/Root.tsx +0 -288
  114. package/src/components/Mosaic/types.ts +0 -94
  115. /package/src/components/Focus/{Focus.tsx → Focus.ts} +0 -0
@@ -1,702 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import {
3
- Focus,
4
- Mosaic,
5
- getSourceData,
6
- styles,
7
- useFocus,
8
- useMosaicContainerContext,
9
- useMosaicRootContext,
10
- useMosaicTileContext,
11
- useVisibleItems
12
- } from "./chunk-4IEMCMIV.mjs";
13
-
14
- // src/components/Board/Board.tsx
15
- import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
16
- import { createContext as createContext2 } from "@radix-ui/react-context";
17
- import React4, { forwardRef as forwardRef4, useRef as useRef3, useState as useState3 } from "react";
18
- import { ScrollArea as ScrollArea2 } from "@dxos/react-ui";
19
- import { composable as composable2, composableProps as composableProps2 } from "@dxos/react-ui";
20
- import { JsonHighlighter as JsonHighlighter2 } from "@dxos/react-ui-syntax-highlighter";
21
- import { mx as mx3 } from "@dxos/ui-theme";
22
-
23
- // src/hooks/useContainerDebug.tsx
24
- import React, { forwardRef, useMemo, useRef } from "react";
25
- import { createPortal } from "react-dom";
26
- import { JsonHighlighter } from "@dxos/react-ui-syntax-highlighter";
27
- import { mx } from "@dxos/ui-theme";
28
- var useContainerDebug = (debug) => {
29
- const debugRef = useRef(null);
30
- return useMemo(() => {
31
- if (!debug) {
32
- return [
33
- () => null,
34
- void 0
35
- ];
36
- }
37
- return [
38
- ({ classNames }) => /* @__PURE__ */ React.createElement("div", {
39
- className: mx("overflow-hidden", classNames),
40
- ref: debugRef
41
- }),
42
- () => debugRef.current && /* @__PURE__ */ createPortal(/* @__PURE__ */ React.createElement(ContainerInfo, null), debugRef.current)
43
- ];
44
- }, [
45
- debug,
46
- debugRef
47
- ]);
48
- };
49
- var CONTAINER_INFO_NAME = "ContainerInfo";
50
- var ContainerInfo = /* @__PURE__ */ forwardRef(({ classNames }, forwardedRef) => {
51
- const { id, state, activeLocation, scrolling } = useMosaicContainerContext(CONTAINER_INFO_NAME);
52
- const counter = useRef(0);
53
- return /* @__PURE__ */ React.createElement(JsonHighlighter, {
54
- data: {
55
- id,
56
- activeLocation,
57
- scrolling,
58
- state,
59
- count: counter.current++
60
- },
61
- classNames: mx("text-xs", classNames),
62
- ref: forwardedRef
63
- });
64
- });
65
- ContainerInfo.displayName = CONTAINER_INFO_NAME;
66
-
67
- // src/hooks/useEventHandlerAdapter.ts
68
- import { useMemo as useMemo2 } from "react";
69
- import { log } from "@dxos/log";
70
- import { arrayMove } from "@dxos/util";
71
- var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/hooks/useEventHandlerAdapter.ts";
72
- var useEventHandlerAdapter = ({ items, getId, get, make, onChange, ...props }) => {
73
- return useMemo2(() => ({
74
- ...props,
75
- onTake: ({ source }, cb) => {
76
- log.info("onTake", {
77
- source
78
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 14, S: void 0 });
79
- const mutate = (items2) => {
80
- const from = items2.findIndex((item) => getId(item) === source.id);
81
- if (from !== -1) {
82
- items2.splice(from, 1);
83
- }
84
- };
85
- if (onChange) {
86
- onChange(mutate);
87
- } else {
88
- mutate(items);
89
- }
90
- void cb(source.data);
91
- },
92
- onDrop: ({ source, target }) => {
93
- log.info("onDrop", {
94
- source,
95
- target
96
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 31, S: void 0 });
97
- const mutate = (items2) => {
98
- const to = target?.type === "tile" || target?.type === "placeholder" ? target.location : target?.type === "container" ? items2.length : -1;
99
- const from = items2.findIndex((item) => getId(item) === source.id);
100
- const insertIndex = typeof to === "number" && to >= 0 ? Math.floor(to) : -1;
101
- if (insertIndex !== -1) {
102
- if (from !== -1) {
103
- arrayMove(items2, from, insertIndex);
104
- } else {
105
- items2.splice(insertIndex, 0, make(get(source.data)));
106
- }
107
- }
108
- };
109
- if (onChange) {
110
- onChange(mutate);
111
- } else {
112
- mutate(items);
113
- }
114
- }
115
- }), [
116
- items,
117
- onChange
118
- ]);
119
- };
120
-
121
- // src/hooks/useDefaultColumnEventHandler.ts
122
- var useDefaultColumnEventHandler = (id, model, items) => useEventHandlerAdapter({
123
- id,
124
- items,
125
- getId: model.getColumnId,
126
- get: (data) => data,
127
- make: (object) => object,
128
- canDrop: ({ source }) => model.isColumn(source.data)
129
- });
130
-
131
- // src/components/Mosaic/extension.ts
132
- import { StateEffect, StateField } from "@codemirror/state";
133
- import { Decoration, EditorView, ViewPlugin, WidgetType } from "@codemirror/view";
134
- var dropHandler = ({ onDrop = handleDrop } = {}) => {
135
- const views = /* @__PURE__ */ new Set();
136
- let state = null;
137
- const reset = () => {
138
- views.forEach((view) => view.dispatch({
139
- effects: setDrop.of(null)
140
- }));
141
- state = null;
142
- };
143
- const extension = [
144
- dropField,
145
- ViewPlugin.fromClass(class {
146
- _view;
147
- constructor(_view) {
148
- this._view = _view;
149
- views.add(_view);
150
- }
151
- destroy() {
152
- views.delete(this._view);
153
- }
154
- })
155
- ];
156
- return {
157
- extension,
158
- update: (position) => {
159
- if (!position) {
160
- reset();
161
- return;
162
- }
163
- views.forEach((view) => {
164
- const rect = view.dom.getBoundingClientRect();
165
- if (position.x >= rect.left && position.x <= rect.right && position.y >= rect.top && position.y <= rect.bottom) {
166
- let pos = view.posAtCoords(position);
167
- if (pos !== null) {
168
- const word = view.state.wordAt(pos);
169
- if (word) {
170
- const startDist = Math.abs(pos - word.from);
171
- const endDist = Math.abs(pos - word.to);
172
- pos = startDist < endDist ? word.from : word.to;
173
- }
174
- view.dispatch({
175
- effects: setDrop.of(pos)
176
- });
177
- state = {
178
- view,
179
- pos
180
- };
181
- return;
182
- }
183
- }
184
- view.dispatch({
185
- effects: setDrop.of(null)
186
- });
187
- });
188
- },
189
- cancel: () => {
190
- reset();
191
- },
192
- drop: ({ text, url }) => {
193
- if (state) {
194
- onDrop(state.view, state.pos, {
195
- text,
196
- url
197
- });
198
- }
199
- reset();
200
- }
201
- };
202
- };
203
- var handleDrop = (view, pos, event) => {
204
- const line = view.state.doc.lineAt(pos);
205
- if (line.text.trim() === "") {
206
- view.dispatch({
207
- changes: {
208
- from: pos,
209
- insert: `
210
- ![${event.text}](${event.url})
211
- `
212
- },
213
- effects: setDrop.of(null)
214
- });
215
- } else {
216
- view.dispatch({
217
- changes: {
218
- from: pos,
219
- insert: ` [${event.text}](${event.url})`
220
- },
221
- effects: setDrop.of(null)
222
- });
223
- }
224
- };
225
- var setDrop = StateEffect.define();
226
- var dropField = StateField.define({
227
- create: () => Decoration.none,
228
- update: (decorations, tr) => {
229
- for (const effect of tr.effects) {
230
- if (effect.is(setDrop)) {
231
- if (effect.value === null) {
232
- return Decoration.none;
233
- }
234
- return Decoration.set([
235
- Decoration.widget({
236
- widget: new class extends WidgetType {
237
- toDOM() {
238
- const dom = document.createElement("span");
239
- dom.className = "cm-drop-cursor";
240
- dom.style.borderLeft = "2px solid var(--color-accent-bg)";
241
- dom.style.display = "inline-block";
242
- dom.style.height = "1em";
243
- dom.style.verticalAlign = "middle";
244
- return dom;
245
- }
246
- }(),
247
- side: 0
248
- }).range(effect.value)
249
- ]);
250
- }
251
- }
252
- return decorations.map(tr.changes);
253
- },
254
- provide: (field) => EditorView.decorations.from(field)
255
- });
256
-
257
- // src/components/Board/Column.tsx
258
- import { useAtomValue } from "@effect-atom/atom-react";
259
- import { createContext } from "@radix-ui/react-context";
260
- import React3, { forwardRef as forwardRef3, useMemo as useMemo4, useState as useState2 } from "react";
261
- import { Obj as Obj2, Ref } from "@dxos/echo";
262
- import { useObject } from "@dxos/react-client/echo";
263
- import { IconButton as IconButton2, ScrollArea, Toolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
264
- import { composable, composableProps } from "@dxos/react-ui";
265
- import { Menu as Menu2, createMenuAction as createMenuAction2 } from "@dxos/react-ui-menu";
266
- import { mx as mx2 } from "@dxos/ui-theme";
267
- import { translationKey as translationKey2 } from "#translations";
268
-
269
- // src/components/Board/Item.tsx
270
- import { useComposedRefs } from "@radix-ui/react-compose-refs";
271
- import React2, { forwardRef as forwardRef2, useMemo as useMemo3, useRef as useRef2, useState } from "react";
272
- import { Obj } from "@dxos/echo";
273
- import { Card, Icon, IconButton, Tag, useTranslation } from "@dxos/react-ui";
274
- import { Menu, createMenuAction } from "@dxos/react-ui-menu";
275
- import { getHashStyles } from "@dxos/ui-theme";
276
- import { translationKey } from "#translations";
277
- var BOARD_ITEM_NAME = "Board.Item";
278
- var BoardItemInner = /* @__PURE__ */ forwardRef2(({ classNames, data, location, debug, draggable }, forwardedRef) => {
279
- const { t } = useTranslation(translationKey);
280
- const rootRef = useRef2(null);
281
- const composedRef = useComposedRefs(rootRef, forwardedRef);
282
- const [dragHandle, setDragHandle] = useState(null);
283
- const { model } = useBoard(BOARD_ITEM_NAME);
284
- const column = useBoardColumn();
285
- const items = useMemo3(() => column != null && model.onItemDelete ? [
286
- createMenuAction("delete-item", () => model.onItemDelete?.(column, data), {
287
- label: t("delete-menu.label"),
288
- icon: "ph--trash--regular"
289
- })
290
- ] : [], [
291
- column,
292
- data,
293
- model.onItemDelete,
294
- t
295
- ]);
296
- if (!data) {
297
- return null;
298
- }
299
- const label = Obj.getLabel(data);
300
- const description = Obj.getDescription(data);
301
- return /* @__PURE__ */ React2.createElement(Menu.Root, null, /* @__PURE__ */ React2.createElement(Mosaic.Tile, {
302
- ref: rootRef,
303
- asChild: true,
304
- draggable,
305
- dragHandle,
306
- id: data.id,
307
- data,
308
- location,
309
- debug
310
- }, /* @__PURE__ */ React2.createElement(Focus.Item, {
311
- asChild: true
312
- }, /* @__PURE__ */ React2.createElement(Card.Root, {
313
- classNames,
314
- "data-testid": "board-item",
315
- ref: composedRef,
316
- onClick: (event) => event.currentTarget.focus()
317
- }, /* @__PURE__ */ React2.createElement(Card.Header, null, /* @__PURE__ */ React2.createElement(Card.DragHandle, {
318
- ref: setDragHandle,
319
- testId: "mosaicBoard.cardDragHandle"
320
- }), /* @__PURE__ */ React2.createElement(Card.Title, {
321
- "data-testid": "mosaicBoard.cardTitle"
322
- }, label), /* @__PURE__ */ React2.createElement(Card.Block, {
323
- end: true
324
- }, /* @__PURE__ */ React2.createElement(Menu.Trigger, {
325
- asChild: true,
326
- disabled: !items?.length
327
- }, /* @__PURE__ */ React2.createElement(IconButton, {
328
- iconOnly: true,
329
- variant: "ghost",
330
- icon: "ph--dots-three-vertical--regular",
331
- label: t("action-menu.label")
332
- }))), /* @__PURE__ */ React2.createElement(Menu.Content, {
333
- items
334
- })), /* @__PURE__ */ React2.createElement(Card.Row, {
335
- classNames: "text-description"
336
- }, /* @__PURE__ */ React2.createElement(Card.Block, null, /* @__PURE__ */ React2.createElement(Icon, {
337
- icon: "ph--note--regular"
338
- })), /* @__PURE__ */ React2.createElement(Card.Text, null, description)), /* @__PURE__ */ React2.createElement(Card.Row, null, /* @__PURE__ */ React2.createElement(Card.Block, null, /* @__PURE__ */ React2.createElement(Icon, {
339
- icon: "ph--tag--regular"
340
- })), label && /* @__PURE__ */ React2.createElement("div", {
341
- className: "shrink-0 flex gap-1 items-center text-xs"
342
- }, /* @__PURE__ */ React2.createElement(Tag, {
343
- hue: getHashStyles(label).hue
344
- }, label)))))));
345
- });
346
- BoardItemInner.displayName = BOARD_ITEM_NAME;
347
- var BoardItem = BoardItemInner;
348
-
349
- // src/components/Board/Column.tsx
350
- var BOARD_COLUMN_CONTEXT_NAME = "Board.Column";
351
- var [BoardColumnProvider, useBoardColumnContext] = createContext(BOARD_COLUMN_CONTEXT_NAME, null);
352
- function useBoardColumn() {
353
- const value = useBoardColumnContext(BOARD_COLUMN_CONTEXT_NAME);
354
- return value?.column;
355
- }
356
- var BOARD_COLUMN_ROOT_NAME = "Board.Column.Root";
357
- var BoardColumnRootInner = composable(({ classNames, children, location, data, debug, draggable, dragHandle, ...rest }, forwardedRef) => {
358
- const { model } = useBoard(BOARD_COLUMN_ROOT_NAME);
359
- return /* @__PURE__ */ React3.createElement(Mosaic.Tile, {
360
- asChild: true,
361
- location,
362
- id: model.getColumnId(data),
363
- data,
364
- debug,
365
- draggable,
366
- dragHandle
367
- }, /* @__PURE__ */ React3.createElement(Focus.Group, {
368
- ...rest,
369
- "data-testid": "board-column",
370
- border: true,
371
- classNames: mx2("group/column", "h-full w-full md:w-card-default-width snap-center bg-deck-surface", "overflow-hidden", classNames),
372
- ref: forwardedRef
373
- }, /* @__PURE__ */ React3.createElement(BoardColumnProvider, {
374
- column: data
375
- }, children)));
376
- });
377
- BoardColumnRootInner.displayName = BOARD_COLUMN_ROOT_NAME;
378
- var BoardColumnRoot = BoardColumnRootInner;
379
- var BOARD_COLUMN_HEADER_NAME = "Board.Column.Header";
380
- var BoardColumnHeader = composable(({ label, dragHandleRef, ...props }, forwardedRef) => {
381
- const { t } = useTranslation2(translationKey2);
382
- const { model } = useBoard(BOARD_COLUMN_HEADER_NAME);
383
- const column = useBoardColumn();
384
- const columnMenuItems = useMemo4(() => column != null && model.onColumnDelete ? [
385
- createMenuAction2("delete-column", () => model.onColumnDelete?.(column), {
386
- label: t("delete-menu.label"),
387
- icon: "ph--trash--regular"
388
- })
389
- ] : [], [
390
- column,
391
- model.onColumnDelete,
392
- t
393
- ]);
394
- return /* @__PURE__ */ React3.createElement(Menu2.Root, null, /* @__PURE__ */ React3.createElement(Toolbar.Root, {
395
- ...composableProps(props),
396
- "data-testid": "board-column-header",
397
- ref: forwardedRef
398
- }, /* @__PURE__ */ React3.createElement(Toolbar.DragHandle, {
399
- ref: dragHandleRef,
400
- testId: "mosaicBoard.columnDragHandle"
401
- }), /* @__PURE__ */ React3.createElement(Toolbar.Text, {
402
- "data-testid": "mosaicBoard.columnTitle"
403
- }, label), /* @__PURE__ */ React3.createElement(Menu2.Trigger, {
404
- asChild: true,
405
- disabled: !columnMenuItems?.length
406
- }, /* @__PURE__ */ React3.createElement(Toolbar.IconButton, {
407
- iconOnly: true,
408
- variant: "ghost",
409
- icon: "ph--dots-three-vertical--regular",
410
- label: t("action-menu.label")
411
- })), /* @__PURE__ */ React3.createElement(Menu2.Content, {
412
- items: columnMenuItems
413
- })));
414
- });
415
- BoardColumnHeader.displayName = BOARD_COLUMN_HEADER_NAME;
416
- var BOARD_COLUMN_BODY_NAME = "Board.Column.Body";
417
- var BoardColumnBody = composable(({ data, eventHandler, Tile = BoardItem, debug, ...props }, forwardedRef) => {
418
- const { model } = useBoard(BOARD_COLUMN_BODY_NAME);
419
- const [viewport, setViewport] = useState2(null);
420
- const items = useAtomValue(model.items(data));
421
- return /* @__PURE__ */ React3.createElement(Mosaic.Container, {
422
- ...composableProps(props),
423
- asChild: true,
424
- withFocus: true,
425
- orientation: "vertical",
426
- autoScroll: viewport,
427
- eventHandler,
428
- debug,
429
- ref: forwardedRef
430
- }, /* @__PURE__ */ React3.createElement(ScrollArea.Root, {
431
- orientation: "vertical",
432
- thin: true,
433
- centered: true,
434
- padding: true
435
- }, /* @__PURE__ */ React3.createElement(ScrollArea.Viewport, {
436
- classNames: "snap-y md:snap-none",
437
- ref: setViewport
438
- }, /* @__PURE__ */ React3.createElement(Mosaic.Stack, {
439
- items,
440
- getId: model.getItemId,
441
- Tile
442
- }))));
443
- });
444
- BoardColumnBody.displayName = BOARD_COLUMN_BODY_NAME;
445
- var BOARD_COLUMN_FOOTER_NAME = "Board.Column.Footer";
446
- var BoardColumnFooter = /* @__PURE__ */ forwardRef3(({ classNames, data, onAdd }, forwardedRef) => {
447
- const { t } = useTranslation2(translationKey2);
448
- const { model } = useBoard(BOARD_COLUMN_FOOTER_NAME);
449
- const handleAdd = onAdd ?? (model.onItemCreate && data ? () => void model.onItemCreate?.(data) : void 0);
450
- return /* @__PURE__ */ React3.createElement(Toolbar.Root, {
451
- classNames: mx2("rounded-b-sm border-t border-separator", classNames),
452
- ref: forwardedRef
453
- }, handleAdd && /* @__PURE__ */ React3.createElement(IconButton2, {
454
- "data-testid": "board-column-add-item",
455
- classNames: "group-hover/column:opacity-100 md:opacity-0 transition transition-opacity duration-500",
456
- variant: "ghost",
457
- icon: "ph--plus--regular",
458
- iconOnly: true,
459
- label: t("add-item.label"),
460
- onClick: handleAdd
461
- }));
462
- });
463
- BoardColumnFooter.displayName = BOARD_COLUMN_FOOTER_NAME;
464
- var BOARD_DEFAULT_COLUMN_NAME = "Board.DefaultColumn";
465
- var DefaultBoardColumn = /* @__PURE__ */ forwardRef3(({ classNames, location, data, debug, draggable, Tile = BoardItem }, forwardedRef) => {
466
- const { model } = useBoard(BOARD_DEFAULT_COLUMN_NAME);
467
- const [DebugInfo, debugHandler] = useContainerDebug(debug);
468
- const [dragHandle, setDragHandle] = useState2(null);
469
- const [column, updateColumn] = useObject(data);
470
- const eventHandler = useEventHandlerAdapter({
471
- id: model.getColumnId(data),
472
- items: column?.items ?? [],
473
- getId: (ref) => ref.target?.id ?? ref.uri,
474
- get: (refOrObj) => Ref.isRef(refOrObj) ? refOrObj.target : refOrObj,
475
- make: (object) => Ref.make(object),
476
- canDrop: ({ source }) => {
477
- const item = Ref.isRef(source.data) ? source.data.target : source.data;
478
- return item != null && Obj2.isObject(item) && model.isItem(item);
479
- },
480
- onChange: (mutator) => updateColumn((col) => mutator(col.items))
481
- });
482
- return /* @__PURE__ */ React3.createElement(BoardColumnRootInner, {
483
- classNames: mx2("group/column grid", debug ? "grid-rows-[var(--dx-rail-action)_1fr_20rem]" : "grid-rows-[var(--dx-rail-action)_1fr_var(--dx-rail-action)]", classNames),
484
- location,
485
- data,
486
- draggable,
487
- dragHandle,
488
- ref: forwardedRef
489
- }, /* @__PURE__ */ React3.createElement(BoardColumnHeader, {
490
- label: Obj2.getLabel(data) ?? data.id,
491
- dragHandleRef: setDragHandle
492
- }), /* @__PURE__ */ React3.createElement(BoardColumnBody, {
493
- data,
494
- eventHandler,
495
- debug: debugHandler,
496
- Tile
497
- }), /* @__PURE__ */ React3.createElement("div", {
498
- className: "flex flex-col col-span-full"
499
- }, /* @__PURE__ */ React3.createElement(BoardColumnFooter, {
500
- data
501
- }), /* @__PURE__ */ React3.createElement(DebugInfo, null)));
502
- });
503
- DefaultBoardColumn.displayName = BOARD_DEFAULT_COLUMN_NAME;
504
- var BoardColumn = {
505
- Root: BoardColumnRoot,
506
- Header: BoardColumnHeader,
507
- Body: BoardColumnBody,
508
- Footer: BoardColumnFooter
509
- };
510
-
511
- // src/components/Board/Board.tsx
512
- var BOARD_NAME = "Board";
513
- var [BoardContextProvider, useBoardContext] = createContext2(BOARD_NAME);
514
- function useBoard(displayName) {
515
- return useBoardContext(displayName ?? BOARD_NAME);
516
- }
517
- var BOARD_ROOT_NAME = "Board.Root";
518
- var BoardRootInner = ({ model, children }) => {
519
- return /* @__PURE__ */ React4.createElement(BoardContextProvider, {
520
- model
521
- }, children);
522
- };
523
- BoardRootInner.displayName = BOARD_ROOT_NAME;
524
- var BoardRoot = BoardRootInner;
525
- var BOARD_CONTENT_NAME = "Board.Content";
526
- var BoardContentInner = composable2(({ id: _id, debug, eventHandler, Tile = DefaultBoardColumn, ...props }, forwardedRef) => {
527
- const { model } = useBoardContext(BOARD_CONTENT_NAME);
528
- const [DebugInfo, debugHandler] = useContainerDebug(debug);
529
- const [viewport, setViewport] = useState3(null);
530
- const items = useAtomValue2(model.columns);
531
- return /* @__PURE__ */ React4.createElement("div", {
532
- ...composableProps2(props, {
533
- classNames: "dx-container"
534
- }),
535
- ref: forwardedRef
536
- }, /* @__PURE__ */ React4.createElement(Focus.Group, {
537
- asChild: true,
538
- orientation: "horizontal"
539
- }, /* @__PURE__ */ React4.createElement(Mosaic.Container, {
540
- asChild: true,
541
- withFocus: true,
542
- orientation: "horizontal",
543
- autoScroll: viewport,
544
- eventHandler,
545
- debug: debugHandler
546
- }, /* @__PURE__ */ React4.createElement(ScrollArea2.Root, {
547
- orientation: "horizontal",
548
- centered: true,
549
- padding: true
550
- }, /* @__PURE__ */ React4.createElement(ScrollArea2.Viewport, {
551
- classNames: "snap-mandatory snap-x md:snap-none",
552
- ref: setViewport
553
- }, /* @__PURE__ */ React4.createElement(Mosaic.Stack, {
554
- items,
555
- getId: model.getColumnId,
556
- Tile,
557
- debug
558
- }))))), /* @__PURE__ */ React4.createElement(DebugInfo, null));
559
- });
560
- BoardContentInner.displayName = BOARD_CONTENT_NAME;
561
- var BoardContent = BoardContentInner;
562
- var BOARD_PLACEHOLDER_NAME = "Board.Placeholder";
563
- var BoardPlaceholder = (props) => {
564
- return /* @__PURE__ */ React4.createElement(Mosaic.Placeholder, {
565
- ...props,
566
- classNames: styles.placeholder.root
567
- }, /* @__PURE__ */ React4.createElement("div", {
568
- className: mx3("flex h-full border border-dashed border-separator rounded-xs", styles.placeholder.content)
569
- }));
570
- };
571
- BoardPlaceholder.displayName = BOARD_PLACEHOLDER_NAME;
572
- var BOARD_DEBUG_NAME = "Board.Debug";
573
- var BoardDebug = /* @__PURE__ */ forwardRef4(({ classNames }, forwardedRef) => {
574
- const { containers, dragging } = useMosaicRootContext(BOARD_DEBUG_NAME);
575
- const counter = useRef3(0);
576
- return /* @__PURE__ */ React4.createElement(JsonHighlighter2, {
577
- data: {
578
- containers,
579
- dragging,
580
- count: counter.current++
581
- },
582
- classNames: mx3("text-xs", classNames),
583
- ref: forwardedRef
584
- });
585
- });
586
- BoardDebug.displayName = BOARD_DEBUG_NAME;
587
- var Board = {
588
- Root: BoardRoot,
589
- Content: BoardContent,
590
- Column: BoardColumn,
591
- Item: BoardItem,
592
- Placeholder: BoardPlaceholder,
593
- Debug: BoardDebug
594
- };
595
-
596
- // src/components/SearchStack/SearchStack.tsx
597
- import React5, { forwardRef as forwardRef5, useCallback, useMemo as useMemo5, useState as useState4 } from "react";
598
- import { Card as Card2, ScrollArea as ScrollArea3 } from "@dxos/react-ui";
599
- import { composable as composable3, composableProps as composableProps3 } from "@dxos/react-ui";
600
- var SearchStack = composable3(({ results = [], currentId, onAction, ...props }, forwardedRef) => {
601
- const [viewport, setViewport] = useState4(null);
602
- const items = useMemo5(() => results.map((result) => ({
603
- result,
604
- onAction
605
- })), [
606
- results,
607
- onAction
608
- ]);
609
- const handleCurrentChange = useCallback((id) => {
610
- if (id) {
611
- onAction?.({
612
- type: "select",
613
- resultId: id
614
- });
615
- }
616
- }, [
617
- onAction
618
- ]);
619
- const handleKeyDown = useCallback((event) => {
620
- if (event.key === "Enter") {
621
- event.preventDefault();
622
- document.activeElement?.click();
623
- }
624
- }, []);
625
- return /* @__PURE__ */ React5.createElement(Focus.Group, {
626
- asChild: true,
627
- ...composableProps3(props),
628
- onKeyDown: handleKeyDown,
629
- ref: forwardedRef
630
- }, /* @__PURE__ */ React5.createElement(Mosaic.Container, {
631
- asChild: true,
632
- withFocus: true,
633
- currentId,
634
- onCurrentChange: handleCurrentChange
635
- }, /* @__PURE__ */ React5.createElement(ScrollArea3.Root, {
636
- orientation: "vertical",
637
- padding: true,
638
- centered: true,
639
- thin: true
640
- }, /* @__PURE__ */ React5.createElement(ScrollArea3.Viewport, {
641
- ref: setViewport
642
- }, /* @__PURE__ */ React5.createElement(Mosaic.VirtualStack, {
643
- Tile: SearchTile,
644
- classNames: "my-2",
645
- gap: 8,
646
- items,
647
- draggable: false,
648
- getId: (item) => item.result.id,
649
- getScrollElement: () => viewport,
650
- estimateSize: () => 100
651
- })))));
652
- });
653
- SearchStack.displayName = "SearchStack";
654
- var SearchTile = /* @__PURE__ */ forwardRef5(({ data, location, current }, forwardedRef) => {
655
- const { result } = data;
656
- const { setCurrentId } = useMosaicContainerContext("SearchTile");
657
- const handleCurrentChange = useCallback(() => {
658
- setCurrentId(result.id);
659
- }, [
660
- result.id,
661
- setCurrentId
662
- ]);
663
- return /* @__PURE__ */ React5.createElement(Mosaic.Tile, {
664
- asChild: true,
665
- classNames: "dx-hover dx-current",
666
- id: result.id,
667
- data,
668
- location,
669
- current
670
- }, /* @__PURE__ */ React5.createElement(Focus.Item, {
671
- asChild: true,
672
- current,
673
- onCurrentChange: handleCurrentChange
674
- }, /* @__PURE__ */ React5.createElement(Card2.Root, {
675
- fullWidth: true,
676
- ref: forwardedRef
677
- }, /* @__PURE__ */ React5.createElement(Card2.Header, null, /* @__PURE__ */ React5.createElement(Card2.Block, null), /* @__PURE__ */ React5.createElement(Card2.Title, null, result.label)), result.snippet && /* @__PURE__ */ React5.createElement(Card2.Body, null, /* @__PURE__ */ React5.createElement(Card2.Row, null, /* @__PURE__ */ React5.createElement(Card2.Text, {
678
- variant: "description"
679
- }, result.snippet))))));
680
- });
681
- SearchTile.displayName = "SearchTile";
682
- export {
683
- Board,
684
- BoardDebug,
685
- Focus,
686
- Mosaic,
687
- SearchStack,
688
- dropHandler,
689
- getSourceData,
690
- styles as mosaicStyles,
691
- useBoard,
692
- useBoardColumn,
693
- useContainerDebug,
694
- useDefaultColumnEventHandler,
695
- useEventHandlerAdapter,
696
- useFocus,
697
- useMosaicRootContext as useMosaic,
698
- useMosaicContainerContext as useMosaicContainer,
699
- useMosaicTileContext as useMosaicTile,
700
- useVisibleItems
701
- };
702
- //# sourceMappingURL=index.mjs.map