@adecore/ui 0.21.1 → 0.21.2

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 (66) hide show
  1. package/README.md +4 -4
  2. package/dist/DisabledReason.js +4 -0
  3. package/dist/Field.js +3 -2
  4. package/dist/Input.js +3 -8
  5. package/dist/SegmentBar.js +2 -1
  6. package/dist/Separator.js +2 -3
  7. package/dist/SlidingColumn.js +1 -1
  8. package/dist/ZoomControls.js +4 -1
  9. package/dist/field-context.d.ts +5 -0
  10. package/dist/field-context.js +6 -0
  11. package/dist/file-icon.js +8 -10
  12. package/dist/file-tree/parts.js +8 -15
  13. package/dist/file-tree/use-file-tree-shift.js +4 -5
  14. package/dist/file-tree/use-slots.js +31 -31
  15. package/dist/format/datetime.js +6 -5
  16. package/dist/format/locale.js +6 -1
  17. package/dist/format/number.js +15 -18
  18. package/dist/menu/parts.d.ts +3 -2
  19. package/dist/menu/parts.js +4 -2
  20. package/dist/modality.js +4 -5
  21. package/dist/placement.d.ts +4 -0
  22. package/dist/placement.js +23 -0
  23. package/dist/popover/parts.d.ts +4 -3
  24. package/dist/popover/parts.js +7 -4
  25. package/dist/shortcut.js +9 -4
  26. package/dist/tabs/parts.js +3 -2
  27. package/dist/tree/parts.js +10 -20
  28. package/dist/tree/use-tree-shift.js +1 -1
  29. package/dist/workspace/SplitView.js +20 -14
  30. package/dist/workspace/TabStrip.js +19 -11
  31. package/dist/workspace/Workspace.js +4 -3
  32. package/dist/workspace/model.js +123 -122
  33. package/package.json +1 -1
  34. package/src/DisabledReason.tsx +4 -5
  35. package/src/Field.tsx +4 -2
  36. package/src/IconButton.tsx +0 -1
  37. package/src/Input.tsx +3 -10
  38. package/src/Pill.tsx +8 -1
  39. package/src/SegmentBar.tsx +3 -10
  40. package/src/Separator.tsx +2 -3
  41. package/src/SlidingColumn.tsx +1 -1
  42. package/src/ZoomControls.tsx +11 -7
  43. package/src/field-context.ts +7 -0
  44. package/src/file-icon.ts +8 -10
  45. package/src/file-tree/parts.tsx +17 -22
  46. package/src/file-tree/use-file-tree-shift.tsx +4 -7
  47. package/src/file-tree/use-slots.ts +31 -31
  48. package/src/format/datetime.ts +7 -5
  49. package/src/format/locale.ts +7 -7
  50. package/src/format/number.ts +17 -20
  51. package/src/menu/parts.tsx +10 -29
  52. package/src/modality.ts +4 -5
  53. package/src/placement.ts +26 -0
  54. package/src/popover/parts.tsx +10 -63
  55. package/src/settings/SettingsDialog.tsx +1 -1
  56. package/src/shortcut.ts +9 -4
  57. package/src/tabs/parts.tsx +8 -8
  58. package/src/tree/parts.tsx +14 -21
  59. package/src/tree/use-tree-shift.tsx +1 -1
  60. package/src/workspace/SplitView.tsx +23 -19
  61. package/src/workspace/TabStrip.tsx +20 -12
  62. package/src/workspace/Workspace.tsx +5 -3
  63. package/src/workspace/model.ts +141 -138
  64. /package/dist/{file-tree → tree}/shift.d.ts +0 -0
  65. /package/dist/{file-tree → tree}/shift.js +0 -0
  66. /package/src/{file-tree → tree}/shift.ts +0 -0
@@ -238,6 +238,139 @@ function equalizeAxis(root: SplitNode, axis: SplitAxis, length: number, gap: num
238
238
  return distribute(root, length);
239
239
  }
240
240
 
241
+ type CommandOf<Type extends SplitCommand['type']> = Extract<SplitCommand, { type: Type }>;
242
+
243
+ function addPane(layout: SplitLayout, panes: SplitPane[], pane: SplitPane | undefined, command: CommandOf<'split'>): SplitLayout {
244
+ if (!pane || findSplitNode(layout.root, command.newPane.id) || findSplitNode(layout.root, command.splitId) || command.newPane.id === command.splitId) {
245
+ return layout;
246
+ }
247
+ const allViews = new Set(panes.flatMap((item) => item.views));
248
+ if (command.newPane.views.some((view) => allViews.has(view)) || new Set(command.newPane.views).size !== command.newPane.views.length) {
249
+ return layout;
250
+ }
251
+ const added = {
252
+ ...command.newPane,
253
+ active: command.newPane.views.includes(command.newPane.active ?? '') ? command.newPane.active : (command.newPane.views[0] ?? null)
254
+ };
255
+ return finish(
256
+ { ...layout, maximized: null },
257
+ replace(layout.root, pane.id, () => beside(pane, added, command.side, command.splitId)),
258
+ added.id
259
+ );
260
+ }
261
+
262
+ function swapPanes(layout: SplitLayout, panes: SplitPane[], command: CommandOf<'swap'>): SplitLayout {
263
+ const source = panes.find((item) => item.id === command.sourceId);
264
+ const target = panes.find((item) => item.id === command.targetId);
265
+ if (!source || !target || source === target || source.views.length === 0 || (command.viewId !== undefined && !source.views.includes(command.viewId))) {
266
+ return layout;
267
+ }
268
+ if (command.viewId === undefined || source.views.length === 1) {
269
+ const exchange = (node: SplitNode): SplitNode => {
270
+ if (node.id === source.id) {
271
+ return target;
272
+ }
273
+ if (node.id === target.id) {
274
+ return source;
275
+ }
276
+ return node.type === 'pane' ? node : { ...node, children: node.children.map(exchange) };
277
+ };
278
+ return finish({ ...layout, maximized: null }, exchange(layout.root), source.id);
279
+ }
280
+ const moving = command.viewId;
281
+ const displaced = target.active;
282
+ const sourceNext =
283
+ displaced === null
284
+ ? without(source, [moving])
285
+ : {
286
+ ...source,
287
+ views: source.views.map((view) => (view === moving ? displaced : view)),
288
+ active: source.active === moving ? displaced : source.active
289
+ };
290
+ const targetNext = {
291
+ ...target,
292
+ views: displaced === null ? [moving] : target.views.map((view) => (view === displaced ? moving : view)),
293
+ active: moving
294
+ };
295
+ const root = replace(layout.root, source.id, () => sourceNext)!;
296
+ return finish(
297
+ { ...layout, maximized: null },
298
+ replace(root, target.id, () => targetNext),
299
+ target.id
300
+ );
301
+ }
302
+
303
+ function moveViews(layout: SplitLayout, panes: SplitPane[], command: CommandOf<'move'>): SplitLayout {
304
+ const source = panes.find((item) => item.id === command.sourceId);
305
+ const target = panes.find((item) => item.id === command.targetId);
306
+ if (!source || !target || (command.viewId !== undefined && !source.views.includes(command.viewId))) {
307
+ return layout;
308
+ }
309
+ const moving = command.viewId === undefined ? source.views : [command.viewId];
310
+ if (!moving.length || (source === target && (command.viewId === undefined || (command.side !== undefined && source.views.length === 1)))) {
311
+ return layout;
312
+ }
313
+ let added: SplitPane | undefined;
314
+ if (command.side) {
315
+ const id = command.viewId === undefined ? source.id : command.newPaneId;
316
+ if (
317
+ !id ||
318
+ !command.splitId ||
319
+ id === command.splitId ||
320
+ findSplitNode(layout.root, command.splitId) ||
321
+ (findSplitNode(layout.root, id) && !(id === source.id && command.viewId === undefined))
322
+ ) {
323
+ return layout;
324
+ }
325
+ added = { type: 'pane', id, views: moving, active: command.viewId ?? source.active };
326
+ }
327
+ const remaining = without(source, moving);
328
+ const root = replace(layout.root, source.id, () => (remaining.views.length || source === target ? remaining : null));
329
+ if (!root) {
330
+ return layout;
331
+ }
332
+ const next = replace(root, target.id, (node) => {
333
+ if (node.type !== 'pane') {
334
+ return node;
335
+ }
336
+ if (added && command.side && command.splitId) {
337
+ return beside(node, added, command.side, command.splitId);
338
+ }
339
+ const gap = Math.max(0, Math.min(target.views.length, command.index ?? target.views.length));
340
+ const lifted = source === target ? target.views.slice(0, gap).filter((view) => moving.includes(view)).length : 0;
341
+ const views = [...node.views];
342
+ views.splice(gap - lifted, 0, ...moving);
343
+ return { ...node, views, active: command.viewId ?? source.active ?? views[0] ?? null };
344
+ });
345
+ return finish({ ...layout, maximized: null }, next, added?.id ?? target.id);
346
+ }
347
+
348
+ function resizeBranch(layout: SplitLayout, command: CommandOf<'resize' | 'equalize'>): SplitLayout {
349
+ const node = findSplitNode(layout.root, command.splitId);
350
+ if (!node || node.type !== 'split') {
351
+ return layout;
352
+ }
353
+ let sizes = [...node.sizes];
354
+ if (command.type === 'resize') {
355
+ if (command.sizes.length !== node.children.length || command.sizes.some((size) => !Number.isFinite(size) || size <= 0)) {
356
+ return layout;
357
+ }
358
+ sizes = shares(command.sizes, node.children.length);
359
+ } else if (command.index === undefined) {
360
+ sizes = node.children.map(() => 1 / node.children.length);
361
+ } else {
362
+ const index = command.index;
363
+ if (index < 0 || index >= sizes.length - 1) {
364
+ return layout;
365
+ }
366
+ sizes[index] = sizes[index + 1] = (sizes[index]! + sizes[index + 1]!) / 2;
367
+ }
368
+ return finish(
369
+ layout,
370
+ replace(layout.root, node.id, () => ({ ...node, sizes }))
371
+ );
372
+ }
373
+
241
374
  /** Invalid or stale commands are no-ops. IDs for new nodes come from the caller. */
242
375
  export function updateSplitLayout(layout: SplitLayout, command: SplitCommand): SplitLayout {
243
376
  const panes = splitPanes(layout.root);
@@ -289,119 +422,12 @@ export function updateSplitLayout(layout: SplitLayout, command: SplitCommand): S
289
422
  pane.id
290
423
  );
291
424
  }
292
- case 'split': {
293
- if (
294
- !pane ||
295
- findSplitNode(layout.root, command.newPane.id) ||
296
- findSplitNode(layout.root, command.splitId) ||
297
- command.newPane.id === command.splitId
298
- ) {
299
- return layout;
300
- }
301
- const allViews = new Set(panes.flatMap((item) => item.views));
302
- if (command.newPane.views.some((view) => allViews.has(view)) || new Set(command.newPane.views).size !== command.newPane.views.length) {
303
- return layout;
304
- }
305
- const added = {
306
- ...command.newPane,
307
- active: command.newPane.views.includes(command.newPane.active ?? '') ? command.newPane.active : (command.newPane.views[0] ?? null)
308
- };
309
- return finish(
310
- { ...layout, maximized: null },
311
- replace(layout.root, pane.id, () => beside(pane, added, command.side, command.splitId)),
312
- added.id
313
- );
314
- }
315
- case 'swap': {
316
- const source = panes.find((item) => item.id === command.sourceId);
317
- const target = panes.find((item) => item.id === command.targetId);
318
- if (
319
- !source ||
320
- !target ||
321
- source === target ||
322
- source.views.length === 0 ||
323
- (command.viewId !== undefined && !source.views.includes(command.viewId))
324
- ) {
325
- return layout;
326
- }
327
- if (command.viewId === undefined || source.views.length === 1) {
328
- const exchange = (node: SplitNode): SplitNode => {
329
- if (node.id === source.id) {
330
- return target;
331
- }
332
- if (node.id === target.id) {
333
- return source;
334
- }
335
- return node.type === 'pane' ? node : { ...node, children: node.children.map(exchange) };
336
- };
337
- return finish({ ...layout, maximized: null }, exchange(layout.root), source.id);
338
- }
339
- const moving = command.viewId;
340
- const displaced = target.active;
341
- const sourceNext =
342
- displaced === null
343
- ? without(source, [moving])
344
- : {
345
- ...source,
346
- views: source.views.map((view) => (view === moving ? displaced : view)),
347
- active: source.active === moving ? displaced : source.active
348
- };
349
- const targetNext = {
350
- ...target,
351
- views: displaced === null ? [moving] : target.views.map((view) => (view === displaced ? moving : view)),
352
- active: moving
353
- };
354
- const root = replace(layout.root, source.id, () => sourceNext)!;
355
- return finish(
356
- { ...layout, maximized: null },
357
- replace(root, target.id, () => targetNext),
358
- target.id
359
- );
360
- }
361
- case 'move': {
362
- const source = panes.find((item) => item.id === command.sourceId);
363
- const target = panes.find((item) => item.id === command.targetId);
364
- if (!source || !target || (command.viewId !== undefined && !source.views.includes(command.viewId))) {
365
- return layout;
366
- }
367
- const moving = command.viewId === undefined ? source.views : [command.viewId];
368
- if (!moving.length || (source === target && (command.viewId === undefined || (command.side !== undefined && source.views.length === 1)))) {
369
- return layout;
370
- }
371
- let added: SplitPane | undefined;
372
- if (command.side) {
373
- const id = command.viewId === undefined ? source.id : command.newPaneId;
374
- if (
375
- !id ||
376
- !command.splitId ||
377
- id === command.splitId ||
378
- findSplitNode(layout.root, command.splitId) ||
379
- (findSplitNode(layout.root, id) && !(id === source.id && command.viewId === undefined))
380
- ) {
381
- return layout;
382
- }
383
- added = { type: 'pane', id, views: moving, active: command.viewId ?? source.active };
384
- }
385
- const remaining = without(source, moving);
386
- const root = replace(layout.root, source.id, () => (remaining.views.length || source === target ? remaining : null));
387
- if (!root) {
388
- return layout;
389
- }
390
- const next = replace(root, target.id, (node) => {
391
- if (node.type !== 'pane') {
392
- return node;
393
- }
394
- if (added && command.side && command.splitId) {
395
- return beside(node, added, command.side, command.splitId);
396
- }
397
- const gap = Math.max(0, Math.min(target.views.length, command.index ?? target.views.length));
398
- const lifted = source === target ? target.views.slice(0, gap).filter((view) => moving.includes(view)).length : 0;
399
- const views = [...node.views];
400
- views.splice(gap - lifted, 0, ...moving);
401
- return { ...node, views, active: command.viewId ?? source.active ?? views[0] ?? null };
402
- });
403
- return finish({ ...layout, maximized: null }, next, added?.id ?? target.id);
404
- }
425
+ case 'split':
426
+ return addPane(layout, panes, pane, command);
427
+ case 'swap':
428
+ return swapPanes(layout, panes, command);
429
+ case 'move':
430
+ return moveViews(layout, panes, command);
405
431
  case 'equalizeAxis': {
406
432
  const length = command.length ?? 1;
407
433
  const gap = command.gap ?? 0;
@@ -411,30 +437,7 @@ export function updateSplitLayout(layout: SplitLayout, command: SplitCommand): S
411
437
  return finish(layout, equalizeAxis(layout.root, command.axis, length, gap));
412
438
  }
413
439
  case 'resize':
414
- case 'equalize': {
415
- const node = findSplitNode(layout.root, command.splitId);
416
- if (!node || node.type !== 'split') {
417
- return layout;
418
- }
419
- let sizes = [...node.sizes];
420
- if (command.type === 'resize') {
421
- if (command.sizes.length !== node.children.length || command.sizes.some((size) => !Number.isFinite(size) || size <= 0)) {
422
- return layout;
423
- }
424
- sizes = shares(command.sizes, node.children.length);
425
- } else if (command.index === undefined) {
426
- sizes = node.children.map(() => 1 / node.children.length);
427
- } else {
428
- const index = command.index;
429
- if (index < 0 || index >= sizes.length - 1) {
430
- return layout;
431
- }
432
- sizes[index] = sizes[index + 1] = (sizes[index]! + sizes[index + 1]!) / 2;
433
- }
434
- return finish(
435
- layout,
436
- replace(layout.root, node.id, () => ({ ...node, sizes }))
437
- );
438
- }
440
+ case 'equalize':
441
+ return resizeBranch(layout, command);
439
442
  }
440
443
  }
File without changes
File without changes
File without changes