@netless/telebox-insider 1.0.0-alpha.1 → 1.0.0-alpha.10

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/telebox-insider",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.10",
4
4
  "private": false,
5
5
  "description": "Window widget for Whiteboard",
6
6
  "license": "MIT",
@@ -50,6 +50,7 @@
50
50
  "minimist": "^1.2.5",
51
51
  "prettier": "^2.0.5",
52
52
  "rimraf": "^3.0.0",
53
+ "rollup-plugin-exclude-dependencies-from-bundle": "^1.1.22",
53
54
  "sass": "^1.36.0",
54
55
  "sass-loader": "^10.1.1",
55
56
  "typescript": "^4.1.2",
@@ -62,6 +63,6 @@
62
63
  "shallowequal": "^1.1.0",
63
64
  "side-effect-manager": "^1.1.0",
64
65
  "stylefire": "^7.0.3",
65
- "value-enhancer": "^1.1.1"
66
+ "value-enhancer": "^1.3.0"
66
67
  }
67
68
  }
@@ -9,8 +9,13 @@ import type {
9
9
  ReadonlyValEnhancedResult,
10
10
  ValEnhancedResult,
11
11
  } from "value-enhancer";
12
- import { withValueEnhancer } from "value-enhancer";
13
- import { combine, Val, withReadonlyValueEnhancer } from "value-enhancer";
12
+ import {
13
+ combine,
14
+ Val,
15
+ withReadonlyValueEnhancer,
16
+ withValueEnhancer,
17
+ ValManager,
18
+ } from "value-enhancer";
14
19
  import type { TeleTitleBar } from "../TeleTitleBar";
15
20
  import { DefaultTitleBar } from "../TeleTitleBar";
16
21
  import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
@@ -55,7 +60,7 @@ type ValConfig = {
55
60
  ratio: Val<RequiredTeleBoxConfig["ratio"], boolean>;
56
61
  };
57
62
 
58
- type ReadonlyValConfig = {
63
+ type PropsValConfig = {
59
64
  darkMode: RequiredTeleBoxConfig["darkMode$"];
60
65
  fence: RequiredTeleBoxConfig["fence$"];
61
66
  minimized: RequiredTeleBoxConfig["minimized$"];
@@ -64,7 +69,9 @@ type ReadonlyValConfig = {
64
69
  rootRect: RequiredTeleBoxConfig["rootRect$"];
65
70
  managerStageRect: RequiredTeleBoxConfig["managerStageRect$"];
66
71
  collectorRect: RequiredTeleBoxConfig["collectorRect$"];
72
+ };
67
73
 
74
+ type MyReadonlyValConfig = {
68
75
  zIndex: Val<RequiredTeleBoxConfig["zIndex"], boolean>;
69
76
  focus: Val<RequiredTeleBoxConfig["focus"], boolean>;
70
77
 
@@ -85,7 +92,9 @@ type ReadonlyValConfig = {
85
92
  contentStageRect: ReadonlyVal<TeleBoxRect | null>;
86
93
  };
87
94
 
88
- type CombinedValEnhancedResult = ReadonlyValEnhancedResult<ReadonlyValConfig> &
95
+ type CombinedValEnhancedResult = ReadonlyValEnhancedResult<
96
+ PropsValConfig & MyReadonlyValConfig
97
+ > &
89
98
  ValEnhancedResult<ValConfig>;
90
99
 
91
100
  export interface TeleBox extends CombinedValEnhancedResult {}
@@ -117,6 +126,7 @@ export class TeleBox {
117
126
  minimized$,
118
127
  maximized$,
119
128
  readonly$,
129
+ root$,
120
130
  rootRect$,
121
131
  managerStageRect$,
122
132
  stageRatio$,
@@ -128,6 +138,9 @@ export class TeleBox {
128
138
  this.id = id;
129
139
  this.namespace = namespace;
130
140
 
141
+ const valManager = new ValManager();
142
+ this._sideEffect.addDisposer(() => valManager.destroy());
143
+
131
144
  const title$ = new Val(title);
132
145
  const visible$ = new Val(visible);
133
146
  const resizable$ = new Val(resizable);
@@ -220,19 +233,22 @@ export class TeleBox {
220
233
  : boxHighlightStage
221
234
  );
222
235
 
236
+ const contentRoot$ = new Val<HTMLElement | null>(null);
237
+
223
238
  const contentRect$ = new Val<TeleBoxRect>(rootRect$.value, {
224
239
  compare: shallowequal,
225
240
  });
226
241
 
227
242
  const teleStage = new TeleStage({
228
243
  namespace,
244
+ root$: contentRoot$,
229
245
  rootRect$: contentRect$,
230
246
  ratio$: stageRatio$,
231
247
  highlightStage$,
232
248
  });
233
249
  this._sideEffect.addDisposer(() => teleStage.destroy());
234
250
 
235
- const readonlyValConfig: ReadonlyValConfig = {
251
+ const propsValConfig: PropsValConfig = {
236
252
  darkMode: darkMode$,
237
253
  fence: fence$,
238
254
  minimized: minimized$,
@@ -241,7 +257,11 @@ export class TeleBox {
241
257
  rootRect: rootRect$,
242
258
  managerStageRect: managerStageRect$,
243
259
  collectorRect: collectorRect$,
260
+ };
261
+
262
+ withReadonlyValueEnhancer(this, propsValConfig);
244
263
 
264
+ const myReadonlyValConfig: MyReadonlyValConfig = {
245
265
  zIndex: zIndex$,
246
266
  focus: focus$,
247
267
 
@@ -262,7 +282,7 @@ export class TeleBox {
262
282
  contentStageRect: teleStage.stageRect$,
263
283
  };
264
284
 
265
- withReadonlyValueEnhancer(this, readonlyValConfig);
285
+ withReadonlyValueEnhancer(this, myReadonlyValConfig, valManager);
266
286
 
267
287
  const valConfig: ValConfig = {
268
288
  title: title$,
@@ -272,14 +292,14 @@ export class TeleBox {
272
292
  ratio: ratio$,
273
293
  };
274
294
 
275
- withValueEnhancer(this, valConfig);
295
+ withValueEnhancer(this, valConfig, valManager);
276
296
 
277
297
  this.titleBar =
278
298
  titleBar ||
279
299
  new DefaultTitleBar({
280
300
  readonly$: readonly$,
281
301
  state$: state$,
282
- title: title$.value,
302
+ title$: title$,
283
303
  namespace: this.namespace,
284
304
  onDragStart: (event) => this._handleTrackStart?.(event),
285
305
  onEvent: (event) => this._delegateEvents.emit(event.type),
@@ -312,7 +332,7 @@ export class TeleBox {
312
332
  );
313
333
 
314
334
  this.$box = this.render();
315
- teleStage.root$.setValue(this.$content.parentElement);
335
+ contentRoot$.setValue(this.$content.parentElement);
316
336
 
317
337
  const watchValEvent = <E extends TeleBoxEvent>(
318
338
  val: ReadonlyVal<TeleBoxEventConfig[E], boolean>,
@@ -336,23 +356,27 @@ export class TeleBox {
336
356
  watchValEvent(intrinsicSize$, TELE_BOX_EVENT.IntrinsicResize);
337
357
  watchValEvent(intrinsicCoord$, TELE_BOX_EVENT.IntrinsicMove);
338
358
 
339
- this._sideEffect.addDisposer(
359
+ this._sideEffect.addDisposer([
340
360
  visible$.reaction((visible, skipUpdate) => {
341
361
  if (!skipUpdate && !visible) {
342
362
  this.events.emit(TELE_BOX_EVENT.Close);
343
363
  }
344
- })
345
- );
346
-
347
- this._sideEffect.addDisposer(
364
+ }),
348
365
  focus$.reaction((focus, skipUpdate) => {
349
366
  if (!skipUpdate) {
350
367
  this.events.emit(
351
368
  focus ? TELE_BOX_EVENT.Focus : TELE_BOX_EVENT.Blur
352
369
  );
353
370
  }
354
- })
355
- );
371
+ }),
372
+ root$.subscribe((root) => {
373
+ if (root) {
374
+ root.appendChild(this.$box);
375
+ } else if (this.$box.parentNode) {
376
+ this.$box.remove();
377
+ }
378
+ }),
379
+ ]);
356
380
  }
357
381
 
358
382
  public readonly id: string;
@@ -475,10 +499,10 @@ export class TeleBox {
475
499
  const rootRect = this.rootRect;
476
500
  safeX = clamp(
477
501
  x,
478
- rootRect.x - pxIntrinsicSize.width + 20,
479
- rootRect.x + rootRect.width - 20
502
+ 0 - pxIntrinsicSize.width + 20,
503
+ 0 + rootRect.width - 20
480
504
  );
481
- safeY = clamp(y, rootRect.y, rootRect.y + rootRect.height - 20);
505
+ safeY = clamp(y, 0, 0 + rootRect.height - 20);
482
506
  }
483
507
 
484
508
  this._intrinsicCoord$.setValue(
@@ -535,22 +559,6 @@ export class TeleBox {
535
559
  );
536
560
  }
537
561
 
538
- /**
539
- * Mount box to a container element.
540
- */
541
- public mount(container: HTMLElement): void {
542
- container.appendChild(this.$box);
543
- }
544
-
545
- /**
546
- * Unmount box from the container element.
547
- */
548
- public unmount(): void {
549
- if (this.$box.parentNode) {
550
- this.$box.remove();
551
- }
552
- }
553
-
554
562
  /**
555
563
  * Mount dom to box content.
556
564
  */
@@ -711,34 +719,39 @@ export class TeleBox {
711
719
  pxIntrinsicCoord,
712
720
  collectorRect,
713
721
  ]) => {
722
+ const styles = maximized
723
+ ? {
724
+ x: 0,
725
+ y: 0,
726
+ width: "100%",
727
+ height: "100%",
728
+ scaleX: 1,
729
+ scaleY: 1,
730
+ }
731
+ : {
732
+ x: pxIntrinsicCoord.x,
733
+ y: pxIntrinsicCoord.y,
734
+ width: pxIntrinsicSize.width + "px",
735
+ height: pxIntrinsicSize.height + "px",
736
+ scaleX: 1,
737
+ scaleY: 1,
738
+ };
714
739
  if (minimized && collectorRect) {
715
- return {
716
- x: collectorRect.x + collectorRect.width / 2,
717
- y: collectorRect.y + collectorRect.height / 2,
718
- width: pxIntrinsicSize.width + "px",
719
- height: pxIntrinsicSize.height + "px",
720
- scaleX: collectorRect.width / pxIntrinsicSize.width,
721
- scaleY: collectorRect.height / pxIntrinsicSize.height,
722
- };
723
- }
724
- if (maximized) {
725
- return {
726
- x: 0,
727
- y: 0,
728
- width: "100%",
729
- height: "100%",
730
- scaleX: 1,
731
- scaleY: 1,
732
- };
740
+ const { width: boxWidth, height: boxHeight } = maximized
741
+ ? this.rootRect
742
+ : pxIntrinsicSize;
743
+ styles.x =
744
+ collectorRect.x -
745
+ boxWidth / 2 +
746
+ collectorRect.width / 2;
747
+ styles.y =
748
+ collectorRect.y -
749
+ boxHeight / 2 +
750
+ collectorRect.height / 2;
751
+ styles.scaleX = collectorRect.width / boxWidth;
752
+ styles.scaleY = collectorRect.height / boxHeight;
733
753
  }
734
- return {
735
- x: pxIntrinsicCoord.x,
736
- y: pxIntrinsicCoord.y,
737
- width: pxIntrinsicSize.width + "px",
738
- height: pxIntrinsicSize.height + "px",
739
- scaleX: 1,
740
- scaleY: 1,
741
- };
754
+ return styles;
742
755
  },
743
756
  { compare: shallowequal }
744
757
  );
@@ -776,16 +789,14 @@ export class TeleBox {
776
789
  this.$content = $content;
777
790
 
778
791
  this._sideEffect.add(() => {
779
- const observer = new ResizeObserver((entries) => {
780
- const rect = entries[0]?.contentRect;
781
- if (rect) {
782
- this._contentRect$.setValue({
783
- x: rect.x,
784
- y: rect.y,
785
- width: rect.width,
786
- height: rect.height,
787
- });
788
- }
792
+ const observer = new ResizeObserver(() => {
793
+ const rect = $content.getBoundingClientRect();
794
+ this._contentRect$.setValue({
795
+ x: rect.x,
796
+ y: rect.y,
797
+ width: rect.width,
798
+ height: rect.height,
799
+ });
789
800
  });
790
801
  observer.observe($content);
791
802
  return () => observer.disconnect();
@@ -78,6 +78,8 @@ export interface TeleBoxConfig {
78
78
  readonly minimized$: ReadonlyVal<boolean, boolean>;
79
79
  /** Is box readonly */
80
80
  readonly readonly$: ReadonlyVal<boolean, boolean>;
81
+ /** Root element to mount boxes */
82
+ readonly root$: ReadonlyVal<HTMLElement | null>;
81
83
  /** Position and dimension of root element */
82
84
  readonly rootRect$: ReadonlyVal<TeleBoxRect>;
83
85
  /** Position and dimension of stage area */
@@ -6,17 +6,21 @@ import type {
6
6
  ReadonlyValEnhancedResult,
7
7
  ValEnhancedResult,
8
8
  } from "value-enhancer";
9
- import { withValueEnhancer } from "value-enhancer";
10
- import { combine } from "value-enhancer";
11
- import { Val } from "value-enhancer";
12
- import { withReadonlyValueEnhancer } from "value-enhancer";
9
+ import { derive } from "value-enhancer";
10
+ import {
11
+ withValueEnhancer,
12
+ combine,
13
+ Val,
14
+ withReadonlyValueEnhancer,
15
+ ValManager,
16
+ } from "value-enhancer";
13
17
  import { SideEffectManager } from "side-effect-manager";
14
18
  import type { TeleBoxRect } from "../TeleBox/typings";
15
19
 
16
20
  export interface TeleBoxCollectorConfig {
17
21
  namespace?: string;
18
22
  styles?: TeleStyles;
19
- root?: HTMLElement;
23
+ root$: ReadonlyVal<HTMLElement | null>;
20
24
  minimized$: Val<boolean>;
21
25
  readonly$: ReadonlyVal<boolean>;
22
26
  darkMode$: ReadonlyVal<boolean>;
@@ -25,17 +29,20 @@ export interface TeleBoxCollectorConfig {
25
29
 
26
30
  type ValConfig = {
27
31
  styles: Val<TeleStyles>;
28
- root: Val<HTMLElement | undefined>;
29
- el: Val<HTMLElement>;
32
+ $collector: Val<HTMLElement>;
33
+ };
34
+
35
+ type PropsValConfig = {
36
+ root: TeleBoxCollectorConfig["root$"];
30
37
  };
31
38
 
32
- type ReadonlyValConfig = {
39
+ type MyReadonlyValConfig = {
33
40
  rect: ReadonlyVal<TeleBoxRect | undefined>;
34
41
  visible: ReadonlyVal<boolean>;
35
42
  };
36
43
 
37
44
  type CombinedValEnhancedResult = ValEnhancedResult<ValConfig> &
38
- ReadonlyValEnhancedResult<ReadonlyValConfig>;
45
+ ReadonlyValEnhancedResult<PropsValConfig & MyReadonlyValConfig>;
39
46
 
40
47
  export interface TeleBoxCollector extends CombinedValEnhancedResult {}
41
48
 
@@ -47,30 +54,37 @@ export class TeleBoxCollector {
47
54
  rootRect$,
48
55
  namespace = "telebox",
49
56
  styles = {},
50
- root,
57
+ root$,
51
58
  }: TeleBoxCollectorConfig) {
52
59
  this.namespace = namespace;
53
60
 
61
+ const valManager = new ValManager();
62
+ this._sideEffect.addDisposer(() => valManager.destroy());
63
+
54
64
  const rect$ = new Val<TeleBoxRect | undefined>(void 0);
55
- const visible$ = minimized$;
65
+ const visible$ = derive(minimized$);
56
66
  const styles$ = new Val(styles);
57
- const root$ = new Val(root);
58
67
  const el$ = new Val<HTMLElement>(document.createElement("button"));
59
68
 
60
69
  const valConfig: ValConfig = {
61
70
  styles: styles$,
71
+ $collector: el$,
72
+ };
73
+
74
+ withValueEnhancer(this, valConfig, valManager);
75
+
76
+ const propsValConfig: PropsValConfig = {
62
77
  root: root$,
63
- el: el$,
64
78
  };
65
79
 
66
- withValueEnhancer(this, valConfig);
80
+ withReadonlyValueEnhancer(this, propsValConfig);
67
81
 
68
- const readonlyValConfig: ReadonlyValConfig = {
82
+ const myReadonlyValConfig: MyReadonlyValConfig = {
69
83
  rect: rect$,
70
84
  visible: visible$,
71
85
  };
72
86
 
73
- withReadonlyValueEnhancer(this, readonlyValConfig);
87
+ withReadonlyValueEnhancer(this, myReadonlyValConfig, valManager);
74
88
 
75
89
  el$.value.className = this.wrapClassName("collector");
76
90
  el$.value.style.backgroundImage = `url('${collectorSVG}')`;
@@ -7,7 +7,7 @@
7
7
  visibility: hidden;
8
8
  display: block;
9
9
  position: absolute;
10
- z-index: $base-z-index * 2;
10
+ z-index: $collector-z-index;
11
11
  width: 40px;
12
12
  height: 40px;
13
13
  margin: 0;
@@ -14,6 +14,7 @@ export interface MaxTitleBarConfig extends DefaultTitleBarConfig {
14
14
  darkMode$: ReadonlyVal<boolean>;
15
15
  boxes$: ReadonlyVal<TeleBox[]>;
16
16
  rootRect$: ReadonlyVal<TeleBoxRect>;
17
+ root$: ReadonlyVal<HTMLElement | null>;
17
18
  }
18
19
 
19
20
  export class MaxTitleBar extends DefaultTitleBar {
@@ -23,6 +24,16 @@ export class MaxTitleBar extends DefaultTitleBar {
23
24
  this.boxes$ = config.boxes$;
24
25
  this.rootRect$ = config.rootRect$;
25
26
  this.darkMode$ = config.darkMode$;
27
+
28
+ this.sideEffect.addDisposer(
29
+ config.root$.subscribe((root) => {
30
+ if (root) {
31
+ root.appendChild(this.render());
32
+ } else if (this.$titleBar?.parentNode) {
33
+ this.$titleBar.remove();
34
+ }
35
+ })
36
+ );
26
37
  }
27
38
 
28
39
  public focusBox(box?: TeleBox): void {
@@ -54,17 +65,16 @@ export class MaxTitleBar extends DefaultTitleBar {
54
65
  }
55
66
 
56
67
  public render(): HTMLElement {
68
+ if (this.$titleBar) {
69
+ return this.$titleBar;
70
+ }
71
+
57
72
  const $titleBar = super.render();
58
73
 
59
74
  $titleBar.classList.add(this.wrapClassName("max-titlebar"));
60
75
 
61
76
  this.sideEffect.addDisposer(
62
77
  [
63
- this.rootRect$.subscribe((rootRect) => {
64
- const { x, y, width } = rootRect;
65
- $titleBar.style.transform = `translate(${x}px, ${y}px)`;
66
- $titleBar.style.width = width + "px";
67
- }),
68
78
  this.state$.subscribe((state) => {
69
79
  $titleBar.classList.toggle(
70
80
  this.wrapClassName("max-titlebar-maximized"),
@@ -94,9 +104,7 @@ export class MaxTitleBar extends DefaultTitleBar {
94
104
  this.wrapClassName("max-titlebar-single-title"),
95
105
  titles.length === 1
96
106
  );
97
- if (titles.length === 1) {
98
- this.setTitle(titles[0].title);
99
- } else {
107
+ if (titles.length !== 1) {
100
108
  $titleBar.replaceChild(
101
109
  this.renderTitles(),
102
110
  $titleBar.firstElementChild as HTMLElement
@@ -16,7 +16,10 @@ $scrollbar-color-active: rgba(238, 238, 247, 1);
16
16
  position: absolute;
17
17
  top: 0;
18
18
  left: 0;
19
- z-index: $base-z-index * 500;
19
+ width: 100%;
20
+ z-index: $max-titlebar-z-index;
21
+ border-top-left-radius: 6px;
22
+ border-top-right-radius: 6px;
20
23
 
21
24
  .#{$namespace}-title {
22
25
  display: none;
@@ -95,7 +98,7 @@ $scrollbar-color-active: rgba(238, 238, 247, 1);
95
98
  height: 100%;
96
99
  overflow: hidden;
97
100
  max-width: 182px;
98
- min-width: 50px;
101
+ min-width: 150px;
99
102
  padding: 0 26px 0 16px;
100
103
  outline: none;
101
104
  font-size: 13px;