@dxos/react-ui-mosaic 0.9.1-staging.ee54ba693a → 0.11.0

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