@difizen/libro-core 0.2.0 → 0.2.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 (78) hide show
  1. package/es/add-cell/libro-add-cell-view.js +1 -1
  2. package/es/cell/libro-cell-model.d.ts +2 -0
  3. package/es/cell/libro-cell-model.d.ts.map +1 -1
  4. package/es/cell/libro-cell-model.js +8 -1
  5. package/es/cell/libro-cell-view.d.ts +6 -1
  6. package/es/cell/libro-cell-view.d.ts.map +1 -1
  7. package/es/cell/libro-cell-view.js +17 -1
  8. package/es/command/document-commands.d.ts.map +1 -1
  9. package/es/command/document-commands.js +5 -3
  10. package/es/command/libro-command-contribution.d.ts +2 -2
  11. package/es/command/libro-command-contribution.d.ts.map +1 -1
  12. package/es/command/libro-command-contribution.js +71 -59
  13. package/es/components/dnd-cell-item-render.js +1 -1
  14. package/es/components/dnd-component/default-dnd-content.js +1 -1
  15. package/es/index.d.ts +2 -0
  16. package/es/index.d.ts.map +1 -1
  17. package/es/index.js +3 -1
  18. package/es/index.less +5 -3
  19. package/es/libro-context-key.d.ts +5 -1
  20. package/es/libro-context-key.d.ts.map +1 -1
  21. package/es/libro-context-key.js +12 -8
  22. package/es/libro-model.d.ts +8 -2
  23. package/es/libro-model.d.ts.map +1 -1
  24. package/es/libro-model.js +81 -47
  25. package/es/libro-protocol.d.ts +15 -4
  26. package/es/libro-protocol.d.ts.map +1 -1
  27. package/es/libro-service.d.ts +1 -0
  28. package/es/libro-service.d.ts.map +1 -1
  29. package/es/libro-service.js +17 -9
  30. package/es/libro-setting.d.ts +1 -0
  31. package/es/libro-setting.d.ts.map +1 -1
  32. package/es/libro-setting.js +10 -0
  33. package/es/libro-view.d.ts +3 -3
  34. package/es/libro-view.d.ts.map +1 -1
  35. package/es/libro-view.js +7 -5
  36. package/es/libro-workspace-service.d.ts +17 -0
  37. package/es/libro-workspace-service.d.ts.map +1 -0
  38. package/es/libro-workspace-service.js +36 -0
  39. package/es/material-from-designer.d.ts +1 -0
  40. package/es/material-from-designer.d.ts.map +1 -1
  41. package/es/material-from-designer.js +38 -2
  42. package/es/module.d.ts.map +1 -1
  43. package/es/module.js +3 -2
  44. package/es/output/output-area.d.ts +1 -0
  45. package/es/output/output-area.d.ts.map +1 -1
  46. package/es/output/output-area.js +70 -24
  47. package/es/output/output-model.d.ts +1 -0
  48. package/es/output/output-model.d.ts.map +1 -1
  49. package/es/output/output-model.js +17 -7
  50. package/es/output/output-protocol.d.ts +4 -0
  51. package/es/output/output-protocol.d.ts.map +1 -1
  52. package/es/theme/libro-color-registry.js +1 -1
  53. package/es/toolbar/change-cell-to-selector.d.ts.map +1 -1
  54. package/es/toolbar/change-cell-to-selector.js +7 -4
  55. package/package.json +6 -6
  56. package/src/add-cell/libro-add-cell-view.tsx +1 -1
  57. package/src/cell/libro-cell-model.ts +10 -1
  58. package/src/cell/libro-cell-view.tsx +17 -1
  59. package/src/command/document-commands.ts +5 -2
  60. package/src/command/libro-command-contribution.ts +86 -59
  61. package/src/components/dnd-cell-item-render.tsx +1 -1
  62. package/src/components/dnd-component/default-dnd-content.tsx +1 -1
  63. package/src/index.less +5 -3
  64. package/src/index.tsx +2 -1
  65. package/src/libro-context-key.ts +5 -1
  66. package/src/libro-model.ts +24 -5
  67. package/src/libro-protocol.ts +18 -5
  68. package/src/libro-service.ts +5 -1
  69. package/src/libro-setting.ts +11 -0
  70. package/src/libro-view.tsx +16 -7
  71. package/src/libro-workspace-service.ts +28 -0
  72. package/src/material-from-designer.tsx +32 -2
  73. package/src/module.ts +4 -2
  74. package/src/output/output-area.tsx +34 -9
  75. package/src/output/output-model.tsx +5 -1
  76. package/src/output/output-protocol.ts +5 -0
  77. package/src/theme/libro-color-registry.ts +1 -1
  78. package/src/toolbar/change-cell-to-selector.tsx +12 -3
package/src/index.less CHANGED
@@ -56,13 +56,15 @@
56
56
  .libro-view-top {
57
57
  display: flex;
58
58
  align-items: center;
59
+ justify-content: space-between;
59
60
  width: 100%;
60
61
  height: 44px;
61
62
  // background-color: var(--mana-color-bg-elevated);
62
63
  border-bottom: 1px solid var(--mana-libro-toptoolbar-border-color);
63
64
 
64
65
  .libro-header-left {
65
- width: 265px;
66
+ width: 240px;
67
+ flex-shrink: 0;
66
68
 
67
69
  .mana-toolbar {
68
70
  justify-content: left;
@@ -71,13 +73,12 @@
71
73
 
72
74
  .libro-header-center {
73
75
  .mana-toolbar {
74
- justify-content: center;
76
+ justify-content: flex-start;
75
77
  }
76
78
  }
77
79
 
78
80
  .libro-header-center,
79
81
  .libro-header-right {
80
- flex: 1;
81
82
  overflow: hidden;
82
83
 
83
84
  .mana-toolbar {
@@ -122,6 +123,7 @@
122
123
 
123
124
  .libro-header-right {
124
125
  color: unset;
126
+ flex: 0 0 auto;
125
127
  }
126
128
 
127
129
  .libro-keybind-instructions-icon {
package/src/index.tsx CHANGED
@@ -19,6 +19,7 @@ export * from './collapse-service.js';
19
19
  export * from './formatter/index.js';
20
20
  export * from './libro-setting.js';
21
21
  export * from './settings/index.js';
22
-
23
22
  export * from './virtualized-manager.js';
24
23
  export * from './virtualized-manager-helper.js';
24
+ export * from './libro-workspace-service.js';
25
+ export * from './libro-context-key.js';
@@ -7,7 +7,7 @@ import { LibroContextKeys } from './libro-protocol.js';
7
7
  import { LibroService } from './libro-service.js';
8
8
 
9
9
  @singleton()
10
- export class LirboContextKey {
10
+ export class LibroContextKey {
11
11
  protected readonly contextKeyService: ContextKeyService;
12
12
  protected readonly libroService: LibroService;
13
13
  protected toDisposeOnActiveChanged?: Disposable;
@@ -78,3 +78,7 @@ export class LirboContextKey {
78
78
  }
79
79
  };
80
80
  }
81
+ /**
82
+ * @deprecated use LibroContextKey instead.
83
+ */
84
+ export const LirboContextKey = LibroContextKey;
@@ -78,6 +78,8 @@ export class LibroModel implements NotebookModel, DndListModel {
78
78
 
79
79
  id: string;
80
80
 
81
+ version = 0;
82
+
81
83
  /**
82
84
  * The shared notebook model.
83
85
  */
@@ -92,9 +94,28 @@ export class LibroModel implements NotebookModel, DndListModel {
92
94
  lastClipboardInteraction?: string;
93
95
 
94
96
  clipboard?: CellView | CellView[];
97
+ @prop()
98
+ inputEditable = true;
99
+
100
+ @prop()
101
+ outputEditable = true;
102
+
103
+ @prop()
104
+ cellsEditable = true;
105
+
106
+ get executable() {
107
+ return this.outputEditable && this.runnable;
108
+ }
109
+
110
+ set executable(value: boolean) {
111
+ this.runnable = value;
112
+ }
95
113
 
96
114
  @prop()
97
- quickEditMode = false;
115
+ savable = true;
116
+
117
+ @prop()
118
+ runnable = true;
98
119
 
99
120
  @prop()
100
121
  commandMode = true;
@@ -108,9 +129,6 @@ export class LibroModel implements NotebookModel, DndListModel {
108
129
  @prop()
109
130
  dirty = false;
110
131
 
111
- @prop()
112
- readOnly = false;
113
-
114
132
  @prop()
115
133
  cells: CellView[] = [];
116
134
 
@@ -234,7 +252,7 @@ export class LibroModel implements NotebookModel, DndListModel {
234
252
  currpos += delta.retain;
235
253
  }
236
254
  });
237
- if (this.readOnly && !this.isInitialized) {
255
+ if (!this.inputEditable && !this.isInitialized) {
238
256
  this.selectCell(undefined);
239
257
  return;
240
258
  }
@@ -298,6 +316,7 @@ export class LibroModel implements NotebookModel, DndListModel {
298
316
  }
299
317
 
300
318
  onChange() {
319
+ this.version++;
301
320
  this.dirty = true;
302
321
  this.onChangedEmitter.fire(true);
303
322
  }
@@ -71,6 +71,7 @@ export interface ICellContentChange {
71
71
  }
72
72
  export interface BaseNotebookModel {
73
73
  id: string;
74
+ version: number;
74
75
  /**
75
76
  * The dirty state of the model.
76
77
  * #### Notes
@@ -84,16 +85,26 @@ export interface BaseNotebookModel {
84
85
  active?: CellView | undefined;
85
86
  activeIndex: number;
86
87
  dndAreaNullEnable: boolean;
88
+
87
89
  /**
88
- * The read-only state of the model.
90
+ * Controlling whether the cell input is editable
89
91
  */
90
- readOnly: boolean;
92
+ inputEditable: boolean;
93
+
94
+ outputEditable: boolean;
91
95
 
92
96
  /**
93
- * The quick edit mode the model.
97
+ * Controlling whether the cells list is editable
94
98
  */
95
- quickEditMode: boolean;
96
-
99
+ cellsEditable: boolean;
100
+ /**
101
+ * Controlling whether the cells can execute
102
+ */
103
+ runnable: boolean;
104
+ /**
105
+ * Controlling whether the notebook can save
106
+ */
107
+ savable: boolean;
97
108
  /**
98
109
  * The command mode of the model.
99
110
  */
@@ -322,6 +333,8 @@ export interface CellModel extends IModel, Disposable {
322
333
  */
323
334
  id: string;
324
335
 
336
+ version: number;
337
+
325
338
  source: string;
326
339
 
327
340
  /**
@@ -41,6 +41,10 @@ export class LibroService implements NotebookService, Disposable {
41
41
  protected themeService: ThemeService;
42
42
  @prop()
43
43
  themeMode: string;
44
+
45
+ @prop()
46
+ hasFormatter = false;
47
+
44
48
  constructor(@inject(ThemeService) themeService: ThemeService) {
45
49
  this.themeService = themeService;
46
50
  this.themeMode = this.themeService.getCurrentTheme().type;
@@ -134,7 +138,7 @@ export class LibroService implements NotebookService, Disposable {
134
138
  }
135
139
  }
136
140
  const model = this.libroModelFactory(options);
137
- this.libroViewTracker.modelCache.set(model.id, model);
141
+ this.libroViewTracker.modelCache.set(options.modelId || model.id, model);
138
142
  return model;
139
143
  }
140
144
  async getOrCreateView(options: NotebookOption): Promise<NotebookView> {
@@ -97,3 +97,14 @@ export const OutputScrollBtnVisiable: ConfigurationNode<boolean> = {
97
97
  type: 'boolean',
98
98
  },
99
99
  };
100
+
101
+ export const SupportCodeFormat: ConfigurationNode<boolean> = {
102
+ id: 'libro.language.codeformat',
103
+ description: l10n.t('是否支持代码格式化'),
104
+ title: l10n.t('是否支持代码格式化'),
105
+ type: 'checkbox',
106
+ defaultValue: false,
107
+ schema: {
108
+ type: 'boolean',
109
+ },
110
+ };
@@ -49,7 +49,7 @@ import {
49
49
  DndList,
50
50
  } from './components/index.js';
51
51
  import { LibroViewHeader } from './components/libro-view-header.js';
52
- import { LirboContextKey } from './libro-context-key.js';
52
+ import { LibroContextKey } from './libro-context-key.js';
53
53
  import { LibroModel } from './libro-model.js';
54
54
  import { NotebookService, notebookViewFactoryId } from './libro-protocol.js';
55
55
  import type {
@@ -234,14 +234,23 @@ export const LibroRender = forwardRef<HTMLDivElement>(function LibroRender(props
234
234
  const dndDom = ref?.current?.getElementsByClassName(
235
235
  'libro-dnd-cells-container',
236
236
  )[0];
237
- if (!dndDom?.contains(e.relatedTarget) && instance.model.readOnly) {
237
+ if (
238
+ !dndDom?.contains(e.relatedTarget) &&
239
+ (!instance.model.inputEditable ||
240
+ !instance.model.outputEditable ||
241
+ !instance.model.cellsEditable)
242
+ ) {
238
243
  instance.selectCell(undefined);
239
244
  }
240
245
  } else {
241
246
  instance.enterCommandMode(false);
242
247
  libroService.focus = undefined;
243
248
  instance.onBlurEmitter.fire('');
244
- if (instance.model.readOnly) {
249
+ if (
250
+ !instance.model.inputEditable ||
251
+ !instance.model.outputEditable ||
252
+ !instance.model.cellsEditable
253
+ ) {
245
254
  instance.selectCell(undefined);
246
255
  }
247
256
  }
@@ -275,8 +284,8 @@ export class LibroView extends BaseView implements NotebookView {
275
284
  </div>
276
285
  );
277
286
  dndContentRender: FC<DndContentProps> = DndCellContainer;
278
- dndItemRender: ForwardRefExoticComponent<
279
- DndItemProps & RefAttributes<HTMLDivElement>
287
+ dndItemRender: React.MemoExoticComponent<
288
+ ForwardRefExoticComponent<DndItemProps & RefAttributes<HTMLDivElement>>
280
289
  > = DndCellItemRender;
281
290
  protected onCellCreateEmitter: Emitter<CellView> = new Emitter();
282
291
  get onCellCreate() {
@@ -295,7 +304,7 @@ export class LibroView extends BaseView implements NotebookView {
295
304
  @inject(CellService) cellService: CellService;
296
305
  @inject(LibroService) libroService: LibroService;
297
306
  @inject(LibroSlotManager) libroSlotManager: LibroSlotManager;
298
- @inject(LirboContextKey) contextKey: LirboContextKey;
307
+ @inject(LibroContextKey) contextKey: LibroContextKey;
299
308
 
300
309
  @inject(ViewManager) protected viewManager: ViewManager;
301
310
  @inject(ConfigurationService) protected configurationService: ConfigurationService;
@@ -586,7 +595,7 @@ export class LibroView extends BaseView implements NotebookView {
586
595
  }),
587
596
  )
588
597
  .then((resultList) => {
589
- return resultList.every((item) => !!item);
598
+ return resultList.filter((item) => item !== undefined).every((item) => !!item);
590
599
  })
591
600
  .catch((reason: any) => {
592
601
  if (reason.message.startsWith('KernelReplyNotOK')) {
@@ -0,0 +1,28 @@
1
+ import { Deferred, URI } from '@difizen/mana-app';
2
+ import { singleton } from '@difizen/mana-app';
3
+
4
+ import type { NotebookView } from './libro-protocol.js';
5
+
6
+ export const ILibroWorkspaceService = Symbol('ILibroWorkspaceService');
7
+ export interface ILibroWorkspaceService {
8
+ ready: Promise<void>;
9
+ get workspaceRoot(): URI;
10
+ get notebooks(): NotebookView[];
11
+ get files(): URI[];
12
+ }
13
+
14
+ @singleton({ contrib: ILibroWorkspaceService })
15
+ export class BaseWorkspaceService implements ILibroWorkspaceService {
16
+ protected deferred = new Deferred<void>();
17
+ ready = this.deferred.promise;
18
+
19
+ get workspaceRoot() {
20
+ return new URI('/');
21
+ }
22
+ get notebooks() {
23
+ return [];
24
+ }
25
+ get files() {
26
+ return [];
27
+ }
28
+ }
@@ -41,7 +41,7 @@ export const PauseCircleOutlined: React.FC = () => (
41
41
  xmlnsXlink="http://www.w3.org/1999/xlink"
42
42
  >
43
43
  <g id="原色" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
44
- <g id="time-out" fillRule="nonzero" fill="#7B7B7B">
44
+ <g id="time-out" fillRule="nonzero" fill="currentColor">
45
45
  <rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="20" height="20" />
46
46
  <path
47
47
  d="M10,1.25 C5.16796875,1.25 1.25,5.16796875 1.25,10 C1.25,14.8320312 5.16796875,18.75 10,18.75 C14.8320312,18.75 18.75,14.8320312 18.75,10 C18.75,5.16796875 14.8320312,1.25 10,1.25 Z M10,17.265625 C5.98828125,17.265625 2.734375,14.0117187 2.734375,10 C2.734375,5.98828125 5.98828125,2.734375 10,2.734375 C14.0117187,2.734375 17.265625,5.98828125 17.265625,10 C17.265625,14.0117187 14.0117187,17.265625 10,17.265625 Z M8.28125,6.875 L7.34375,6.875 C7.2578125,6.875 7.1875,6.9453125 7.1875,7.03125 L7.1875,12.96875 C7.1875,13.0546875 7.2578125,13.125 7.34375,13.125 L8.28125,13.125 C8.3671875,13.125 8.4375,13.0546875 8.4375,12.96875 L8.4375,7.03125 C8.4375,6.9453125 8.3671875,6.875 8.28125,6.875 Z M12.65625,6.875 L11.71875,6.875 C11.6328125,6.875 11.5625,6.9453125 11.5625,7.03125 L11.5625,12.96875 C11.5625,13.0546875 11.6328125,13.125 11.71875,13.125 L12.65625,13.125 C12.7421875,13.125 12.8125,13.0546875 12.8125,12.96875 L12.8125,7.03125 C12.8125,6.9453125 12.7421875,6.875 12.65625,6.875 Z"
@@ -65,7 +65,7 @@ export const Reload: React.FC = () => (
65
65
  <g
66
66
  id="2.1-kernel-状态展示"
67
67
  transform="translate(-776.000000, -80.000000)"
68
- fill="#7B7B7B"
68
+ fill="currentColor"
69
69
  fillRule="nonzero"
70
70
  >
71
71
  <g id="编组-24" transform="translate(637.000000, 80.000000)">
@@ -547,3 +547,33 @@ export const DisableOutputScroll: React.FC = () => (
547
547
  </g>
548
548
  </svg>
549
549
  );
550
+
551
+ export const FormatCellIcon: React.FC = () => {
552
+ return (
553
+ <svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
554
+ <g id="页面-1" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
555
+ <g id="file" fill="#000000">
556
+ <rect
557
+ id="矩形"
558
+ fillRule="nonzero"
559
+ opacity="0"
560
+ x="0"
561
+ y="0"
562
+ width="16"
563
+ height="16"
564
+ ></rect>
565
+ <path
566
+ d="M13.353125,4.509375 L9.990625,1.146875 C9.896875,1.053125 9.7703125,1 9.6375,1 L3,1 C2.7234375,1 2.5,1.2234375 2.5,1.5 L2.5,14.5 C2.5,14.7765625 2.7234375,15 3,15 L13,15 C13.2765625,15 13.5,14.7765625 13.5,14.5 L13.5,4.8640625 C13.5,4.73125 13.446875,4.603125 13.353125,4.509375 Z M12.346875,5.09375 L9.40625,5.09375 L9.40625,2.153125 L12.346875,5.09375 Z M12.375,13.875 L3.625,13.875 L3.625,2.125 L8.34375,2.125 L8.34375,5.5 C8.34375,5.8625 8.6375,6.15625 9,6.15625 L12.375,6.15625 L12.375,13.875 Z"
567
+ id="形状"
568
+ fillRule="nonzero"
569
+ ></path>
570
+ <path
571
+ d="M9.37349398,7 C9.47995851,7 9.56626506,7.08630655 9.56626506,7.19277108 L9.56626506,12.2048193 C9.56626506,12.3112838 9.47995851,12.3975904 9.37349398,12.3975904 L6.19277108,12.3975904 C6.08630655,12.3975904 6,12.3112838 6,12.2048193 L6,7.19277108 C6,7.08630655 6.08630655,7 6.19277108,7 L9.37349398,7 Z M8.81980094,7.74698795 L6.79570456,7.74698795 C6.68924003,7.74698795 6.60293347,7.83329451 6.60293347,7.93975904 L6.60293347,9.86746988 C6.60293347,9.97393441 6.68924003,10.060241 6.79570456,10.060241 L8.81980094,10.060241 C8.92626547,10.060241 9.01257203,9.97393441 9.01257203,9.86746988 L9.01257203,7.93975904 C9.01257203,7.83329451 8.92626547,7.74698795 8.81980094,7.74698795 Z"
572
+ id="形状结合"
573
+ transform="translate(7.783133, 9.698795) scale(1, -1) rotate(45.000000) translate(-7.783133, -9.698795) "
574
+ ></path>
575
+ </g>
576
+ </g>
577
+ </svg>
578
+ );
579
+ };
package/src/module.ts CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  } from './components/index.js';
23
23
  import { LibroContentModule } from './content/index.js';
24
24
  import { LibroFormatterModule } from './formatter/index.js';
25
- import { LirboContextKey } from './libro-context-key.js';
25
+ import { LibroContextKey } from './libro-context-key.js';
26
26
  import { LibroModel } from './libro-model.js';
27
27
  import {
28
28
  ModelFactory,
@@ -34,6 +34,7 @@ import { LibroService } from './libro-service.js';
34
34
  import { LibroSettingContribution } from './libro-setting-contribution.js';
35
35
  import { LibroViewTracker } from './libro-view-tracker.js';
36
36
  import { LibroView } from './libro-view.js';
37
+ import { BaseWorkspaceService } from './libro-workspace-service.js';
37
38
  import { OutputModule } from './output/index.js';
38
39
  import { LibroSlotModule } from './slot/index.js';
39
40
  import { LibroColorRegistry } from './theme/libro-color-registry.js';
@@ -42,9 +43,10 @@ import { VirtualizedManager } from './virtualized-manager.js';
42
43
 
43
44
  export const LibroModule = ManaModule.create()
44
45
  .register(
46
+ BaseWorkspaceService,
45
47
  VirtualizedManager,
46
48
  LibroService,
47
- LirboContextKey,
49
+ LibroContextKey,
48
50
  LibroModel,
49
51
  LibroView,
50
52
  LibroSettingContribution,
@@ -35,7 +35,15 @@ const LibroOutputAreaRender = forwardRef<HTMLDivElement>(
35
35
  useEffect(() => {
36
36
  outputArea.onUpdateEmitter.fire();
37
37
  }, [outputArea.onUpdateEmitter, outputArea.outputs]);
38
-
38
+ const childrenCannotClear = [];
39
+ const children = [];
40
+ for (const output of outputArea.outputs) {
41
+ if (output.allowClear === false) {
42
+ childrenCannotClear.push(output);
43
+ } else {
44
+ children.push(output);
45
+ }
46
+ }
39
47
  return (
40
48
  <div
41
49
  className="libro-output-area"
@@ -43,7 +51,10 @@ const LibroOutputAreaRender = forwardRef<HTMLDivElement>(
43
51
  //设置最小高度,用于优化长文本输出再次执行时的页面的滚动控制
44
52
  // style={{ minHeight: `${executing ? outputArea.lastOutputContainerHeight + 'px' : 'unset'}` }}
45
53
  >
46
- {outputArea.outputs.map((output) => {
54
+ {childrenCannotClear.map((output) => {
55
+ return <ViewRender view={output} key={output.id} />;
56
+ })}
57
+ {children.map((output) => {
47
58
  return <ViewRender view={output} key={output.id} />;
48
59
  })}
49
60
  </div>
@@ -103,10 +114,10 @@ export class LibroOutputArea extends BaseView implements BaseOutputArea {
103
114
  });
104
115
  }
105
116
  add = async (output: IOutput): Promise<number> => {
106
- // if (this.clearNext) {
107
- // this.clear();
108
- // this.clearNext = false;
109
- // }
117
+ if (this.clearNext) {
118
+ this.clear();
119
+ this.clearNext = false;
120
+ }
110
121
  // Consolidate outputs if they are stream outputs of the same kind.
111
122
  if (
112
123
  isStream(output) &&
@@ -141,13 +152,28 @@ export class LibroOutputArea extends BaseView implements BaseOutputArea {
141
152
  } else {
142
153
  this.lastStream = '';
143
154
  }
144
- return this.outputs.push(await outputModel);
155
+ const model = await outputModel;
156
+ model.onDisposed(() => {
157
+ this.remove(model);
158
+ });
159
+ return this.outputs.push(model);
145
160
  };
161
+
162
+ protected remove(model: BaseOutputView) {
163
+ let outputs = [...this.outputs];
164
+ outputs = outputs.filter((item) => item !== model);
165
+ this.outputs = outputs;
166
+ }
167
+
146
168
  set = async (index: number, output: IOutput) => {
147
169
  const outputModel = this.doCreateOutput(output);
148
170
  const current = this.outputs[index];
149
171
  current.dispose();
150
- this.outputs[index] = await outputModel;
172
+ const model = await outputModel;
173
+ model.onDisposed(() => {
174
+ this.remove(model);
175
+ });
176
+ this.outputs[index] = model;
151
177
  };
152
178
  clear(wait?: boolean | undefined) {
153
179
  this.lastStream = '';
@@ -158,7 +184,6 @@ export class LibroOutputArea extends BaseView implements BaseOutputArea {
158
184
  this.outputs.forEach((output) => {
159
185
  output.dispose();
160
186
  });
161
- this.outputs = [];
162
187
  }
163
188
  fromJSON = async (values: IOutput[]) => {
164
189
  if (!values) {
@@ -26,6 +26,10 @@ export class LibroOutputView extends BaseView implements BaseOutputView {
26
26
 
27
27
  @prop()
28
28
  raw: IOutput;
29
+
30
+ @prop()
31
+ allowClear = true;
32
+
29
33
  @prop()
30
34
  data: JSONObject;
31
35
  @prop()
@@ -45,7 +49,7 @@ export class LibroOutputView extends BaseView implements BaseOutputView {
45
49
  render: FC<{ output: BaseOutputView }> = LibroOutputModelRender;
46
50
 
47
51
  override dispose() {
48
- //
52
+ super.dispose();
49
53
  }
50
54
  toJSON() {
51
55
  return this.raw;
@@ -126,6 +126,11 @@ export interface BaseOutputView extends View {
126
126
  * Depending on the implementation of the mime model,
127
127
  */
128
128
  setData(options: ISetDataOptions): void;
129
+
130
+ /**
131
+ * undefined is considered allowed
132
+ */
133
+ allowClear?: boolean;
129
134
  }
130
135
 
131
136
  /**
@@ -343,7 +343,7 @@ export class LibroColorRegistry implements ColorContribution {
343
343
  },
344
344
  {
345
345
  id: 'libro.editor.gutter.number.color',
346
- defaults: { dark: '#A8EABF', light: '#A4AECB' },
346
+ defaults: { dark: '#A8AEBF', light: '#A4AECB' },
347
347
  description: '',
348
348
  },
349
349
  {
@@ -3,9 +3,10 @@ import {
3
3
  ToolbarInstance,
4
4
  getOrigin,
5
5
  CommandRegistry,
6
+ ThemeService,
6
7
  } from '@difizen/mana-app';
7
8
  import type { Toolbar } from '@difizen/mana-app';
8
- import { Select } from 'antd';
9
+ import { ConfigProvider, Select, theme } from 'antd';
9
10
  import { memo } from 'react';
10
11
 
11
12
  import type { CellMeta } from '../cell/index.js';
@@ -28,13 +29,21 @@ export const ToolItemSelectInner: React.FC = () => {
28
29
  const data = toolbar.currentArgs as LibroToolbarArags;
29
30
  const command = useInject(CommandRegistry);
30
31
  const curCell = data?.[0];
32
+ const themeService = useInject(ThemeService);
31
33
 
32
34
  const handleChange = (value: string) => {
33
35
  const args = getOrigin(data) || [];
34
36
  command.executeCommand(NotebookCommands['ChangeCellTo'].id, ...args, value);
35
37
  };
36
38
  return (
37
- <>
39
+ <ConfigProvider
40
+ theme={{
41
+ algorithm:
42
+ themeService.getCurrentTheme().type === 'dark'
43
+ ? theme.darkAlgorithm
44
+ : theme.defaultAlgorithm,
45
+ }}
46
+ >
38
47
  <Select
39
48
  value={curCell?.model?.type}
40
49
  size={'small'}
@@ -51,7 +60,7 @@ export const ToolItemSelectInner: React.FC = () => {
51
60
  );
52
61
  })}
53
62
  </Select>
54
- </>
63
+ </ConfigProvider>
55
64
  );
56
65
  };
57
66