@netless/telebox-insider 1.0.0-alpha.20 → 1.0.0-alpha.21

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.20",
3
+ "version": "1.0.0-alpha.21",
4
4
  "private": false,
5
5
  "description": "Window widget for Whiteboard",
6
6
  "license": "MIT",
@@ -54,7 +54,7 @@
54
54
  "sass": "^1.36.0",
55
55
  "sass-loader": "^10.1.1",
56
56
  "typescript": "^4.1.2",
57
- "vite": "^2.4.4"
57
+ "vite": "^2.9.13"
58
58
  },
59
59
  "dependencies": {
60
60
  "@juggle/resize-observer": "^3.3.1",
@@ -1,4 +1,5 @@
1
1
  import "./style.scss";
2
+ import shadowStyles from "./style.shadow.scss?inline";
2
3
 
3
4
  import Emittery from "emittery";
4
5
  import styler from "stylefire";
@@ -19,14 +20,7 @@ import {
19
20
  import type { TeleTitleBar } from "../TeleTitleBar";
20
21
  import { DefaultTitleBar } from "../TeleTitleBar";
21
22
  import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
22
- import {
23
- clamp,
24
- flattenEvent,
25
- getBoxDefaultName,
26
- isFalsy,
27
- isTruthy,
28
- preventEvent,
29
- } from "../utils";
23
+ import { clamp, flattenEvent, getBoxDefaultName, preventEvent } from "../utils";
30
24
  import {
31
25
  TELE_BOX_EVENT,
32
26
  TELE_BOX_STATE,
@@ -116,6 +110,7 @@ export class TeleBox {
116
110
  focus = false,
117
111
  zIndex = 100,
118
112
  stageRatio = null,
113
+ enableShadowDOM = true,
119
114
  titleBar,
120
115
  content,
121
116
  stage,
@@ -141,6 +136,7 @@ export class TeleBox {
141
136
 
142
137
  this.id = id;
143
138
  this.namespace = namespace;
139
+ this.enableShadowDOM = enableShadowDOM;
144
140
 
145
141
  const valManager = new ValManager();
146
142
  this._sideEffect.addDisposer(() => valManager.destroy());
@@ -368,6 +364,9 @@ export class TeleBox {
368
364
  /** ClassName Prefix. For CSS styling. Default "telebox" */
369
365
  public readonly namespace: string;
370
366
 
367
+ /** Enable shadow DOM for box content. Default true. */
368
+ public readonly enableShadowDOM: boolean;
369
+
371
370
  public readonly events = new Emittery<
372
371
  TeleBoxEventConfig,
373
372
  TeleBoxEventConfig
@@ -640,35 +639,48 @@ export class TeleBox {
640
639
  return this.$box;
641
640
  }
642
641
 
643
- this.$box = document.createElement("div");
644
-
645
- this.$box.classList.add(this.wrapClassName("box"));
646
-
647
- const bindClassName = <TValue>(
648
- el: Element,
649
- val: ReadonlyVal<TValue, boolean>,
650
- className: string,
651
- predicate: (value: TValue) => boolean = isTruthy
652
- ): string => {
653
- return this._sideEffect.add(() => {
654
- const wrappedClassName = this.wrapClassName(className);
655
- return val.subscribe((value) => {
656
- el.classList.toggle(wrappedClassName, predicate(value));
657
- });
658
- });
642
+ const bindBoxStates = (el: Element, disposerID?: string): string => {
643
+ return this._sideEffect.addDisposer(
644
+ [
645
+ this._readonly$.subscribe((readonly) =>
646
+ el.classList.toggle(
647
+ this.wrapClassName("readonly"),
648
+ readonly
649
+ )
650
+ ),
651
+ this._draggable$.subscribe((draggable) =>
652
+ el.classList.toggle(
653
+ this.wrapClassName("no-drag"),
654
+ !draggable
655
+ )
656
+ ),
657
+ this._resizable$.subscribe((resizable) =>
658
+ el.classList.toggle(
659
+ this.wrapClassName("no-resize"),
660
+ !resizable
661
+ )
662
+ ),
663
+ this._focus$.subscribe((focus) =>
664
+ el.classList.toggle(this.wrapClassName("blur"), !focus)
665
+ ),
666
+ this._darkMode$.subscribe((darkMode) => {
667
+ el.classList.toggle(
668
+ this.wrapClassName("color-scheme-dark"),
669
+ darkMode
670
+ );
671
+ el.classList.toggle(
672
+ this.wrapClassName("color-scheme-light"),
673
+ !darkMode
674
+ );
675
+ }),
676
+ ],
677
+ disposerID
678
+ );
659
679
  };
660
680
 
661
- bindClassName(this.$box, this._readonly$, "readonly");
662
- bindClassName(this.$box, this._draggable$, "no-drag", isFalsy);
663
- bindClassName(this.$box, this._resizable$, "no-resize", isFalsy);
664
- bindClassName(this.$box, this._focus$, "blur", isFalsy);
665
- bindClassName(this.$box, this._darkMode$, "color-scheme-dark");
666
- bindClassName(
667
- this.$box,
668
- this._darkMode$,
669
- "color-scheme-light",
670
- isFalsy
671
- );
681
+ this.$box = document.createElement("div");
682
+ this.$box.classList.add(this.wrapClassName("box"));
683
+ bindBoxStates(this.$box, "bind-box-state");
672
684
 
673
685
  this._sideEffect.add(() => {
674
686
  const minimizedClassName = this.wrapClassName("minimized");
@@ -806,7 +818,7 @@ export class TeleBox {
806
818
  this.$titleBar = $titleBar;
807
819
 
808
820
  const $body = document.createElement("div");
809
- $body.className = this.wrapClassName("content-wrap");
821
+ $body.className = this.wrapClassName("body-wrap");
810
822
  this.$body = $body;
811
823
 
812
824
  const $styles = document.createElement("style");
@@ -836,8 +848,29 @@ export class TeleBox {
836
848
  this.$footer = $footer;
837
849
 
838
850
  $boxMain.appendChild($titleBar);
839
- $boxMain.appendChild($body);
840
- $boxMain.appendChild($footer);
851
+
852
+ if (this.enableShadowDOM) {
853
+ const $quarantineWrap = document.createElement("div");
854
+ $quarantineWrap.className = this.wrapClassName("quarantine-wrap");
855
+ $boxMain.appendChild($quarantineWrap);
856
+
857
+ const $quarantine = document.createElement("div");
858
+ $quarantine.className = this.wrapClassName("quarantine");
859
+ bindBoxStates($quarantine, "bind-quarantine-state");
860
+
861
+ const $shadowStyle = document.createElement("style");
862
+ $shadowStyle.textContent = shadowStyles;
863
+
864
+ $quarantine.appendChild($shadowStyle);
865
+ $quarantine.appendChild($body);
866
+ $quarantine.appendChild($footer);
867
+
868
+ const shadow = $quarantineWrap.attachShadow({ mode: "open" });
869
+ shadow.appendChild($quarantine);
870
+ } else {
871
+ $boxMain.appendChild($body);
872
+ $boxMain.appendChild($footer);
873
+ }
841
874
 
842
875
  this._renderResizeHandlers();
843
876
 
@@ -878,7 +911,7 @@ export class TeleBox {
878
911
  private _renderStage(): HTMLDivElement {
879
912
  const $stage = document.createElement("div");
880
913
 
881
- $stage.className = this.wrapClassName("content-stage");
914
+ $stage.className = this.wrapClassName("box-stage");
882
915
  const updateStageRect = (stageRect: TeleBoxRect): void => {
883
916
  $stage.style.top = stageRect.y + "px";
884
917
  $stage.style.left = stageRect.x + "px";
@@ -897,7 +930,7 @@ export class TeleBox {
897
930
  }),
898
931
  this._stageRect$.subscribe(updateStageRect),
899
932
  ],
900
- "content-stage-styles"
933
+ "box-stage-styles"
901
934
  );
902
935
  return $stage;
903
936
  }
@@ -1,6 +1,8 @@
1
1
  @import "../scss/variables.scss";
2
2
  @import "../scss/mixins.scss";
3
3
 
4
+ @import "./style.shadow.scss";
5
+
4
6
  .#{$namespace}-box {
5
7
  position: absolute;
6
8
  top: 0;
@@ -12,15 +14,16 @@
12
14
  }
13
15
 
14
16
  .#{$namespace}-box-main {
17
+ @include v(border, box-border, $box-border);
18
+ @include v(box-shadow, box-shadow, $box-shadow);
19
+
15
20
  position: relative;
16
21
  width: 100%;
17
22
  height: 100%;
18
23
  display: flex;
19
24
  flex-direction: column;
20
25
  overflow: hidden;
21
- box-shadow: 0px 4px 10px 0px rgba(47, 65, 146, 0.15);
22
26
  border-radius: 6px;
23
- border: 1px solid #e3e3ec;
24
27
  }
25
28
 
26
29
  .#{$namespace}-titlebar-wrap {
@@ -29,41 +32,11 @@
29
32
  z-index: 1;
30
33
  }
31
34
 
32
- .#{$namespace}-content-wrap {
35
+ .#{$namespace}-quarantine-wrap {
36
+ all: initial;
33
37
  flex: 1;
34
38
  width: 100%;
35
39
  overflow: hidden;
36
- display: flex;
37
- justify-content: center;
38
- align-items: center;
39
- position: relative;
40
- }
41
-
42
- .#{$namespace}-content {
43
- width: 100%;
44
- height: 100%;
45
- position: relative;
46
- background: $color-container-background;
47
- }
48
-
49
- .#{$namespace}-content-stage {
50
- position: absolute;
51
- z-index: 1;
52
- overflow: hidden;
53
- background: $color-stage-background;
54
- box-shadow: $color-stage-shadow;
55
- }
56
-
57
- .#{$namespace}-footer-wrap {
58
- flex-shrink: 0;
59
- display: flex;
60
- flex-direction: column;
61
-
62
- &::before {
63
- content: "";
64
- display: block;
65
- flex: 1;
66
- }
67
40
  }
68
41
 
69
42
  .#{$namespace}-resize-handle {
@@ -219,16 +192,7 @@
219
192
  color-scheme: dark;
220
193
 
221
194
  .#{$namespace}-box-main {
222
- color: #e9e9e9;
223
- border-color: #43434d;
224
- }
225
-
226
- .#{$namespace}-content {
227
- background: $color-container-background-dark;
228
- }
229
-
230
- .#{$namespace}-content-stage {
231
- background: $color-stage-background-dark;
232
- box-shadow: $color-stage-shadow-dark;
195
+ @include v(border, box-border-dark, $box-border-dark);
196
+ @include v(box-shadow, box-shadow-dark, $box-shadow-dark);
233
197
  }
234
198
  }
@@ -0,0 +1,87 @@
1
+ @import "../scss/variables.scss";
2
+ @import "../scss/mixins.scss";
3
+
4
+ .#{$namespace}-quarantine {
5
+ position: relative;
6
+ width: 100%;
7
+ height: 100%;
8
+ display: flex;
9
+ flex-direction: column;
10
+ }
11
+
12
+ .#{$namespace}-body-wrap {
13
+ @include v(color, box-color, $box-color);
14
+
15
+ flex: 1;
16
+ width: 100%;
17
+ overflow: hidden;
18
+ display: flex;
19
+ justify-content: center;
20
+ align-items: center;
21
+ position: relative;
22
+ }
23
+
24
+ .#{$namespace}-content {
25
+ width: 100%;
26
+ height: 100%;
27
+ position: relative;
28
+ @include v(
29
+ background-color,
30
+ manager-container-background,
31
+ $manager-container-background
32
+ );
33
+ }
34
+
35
+ .#{$namespace}-box-stage {
36
+ position: absolute;
37
+ z-index: 1;
38
+ overflow: hidden;
39
+
40
+ @include v(
41
+ background-color,
42
+ manager-stage-background,
43
+ $manager-stage-background
44
+ );
45
+ @include v(box-shadow, manager-stage-shadow, $manager-stage-shadow);
46
+ }
47
+
48
+ .#{$namespace}-footer-wrap {
49
+ flex-shrink: 0;
50
+ display: flex;
51
+ flex-direction: column;
52
+
53
+ &::before {
54
+ content: "";
55
+ display: block;
56
+ flex: 1;
57
+ }
58
+ }
59
+
60
+ .#{$namespace}-color-scheme-dark {
61
+ color-scheme: dark;
62
+
63
+ .#{$namespace}-body-wrap {
64
+ @include v(color, box-color-dark, $box-color-dark);
65
+ }
66
+
67
+ .#{$namespace}-content {
68
+ @include v(
69
+ background-color,
70
+ manager-container-background-dark,
71
+ $manager-container-background-dark
72
+ );
73
+ }
74
+
75
+ .#{$namespace}-box-stage {
76
+ @include v(
77
+ background-color,
78
+ manager-stage-background-dark,
79
+ $manager-stage-background-dark
80
+ );
81
+ @include v(
82
+ box-shadow,
83
+ manager-stage-shadow-dark,
84
+ $manager-stage-shadow-dark
85
+ );
86
+ }
87
+ }
@@ -60,6 +60,8 @@ export interface TeleBoxConfig {
60
60
  readonly stageRatio?: number | null;
61
61
  /** Classname Prefix. For CSS styling. Default "telebox". */
62
62
  readonly namespace?: string;
63
+ /** Enable shadow DOM for box content. Default true. */
64
+ readonly enableShadowDOM?: boolean;
63
65
  /** TeleTitleBar Instance. */
64
66
  readonly titleBar?: TeleTitleBar;
65
67
  /** Box content element. */
@@ -16,8 +16,6 @@
16
16
  outline: none;
17
17
  font-size: 0;
18
18
  border-radius: 50%;
19
- background: #fff;
20
- box-shadow: 0px 2px 6px 0px rgba(47, 65, 146, 0.15);
21
19
  cursor: pointer;
22
20
  user-select: none;
23
21
  pointer-events: none;
@@ -25,6 +23,9 @@
25
23
  background-size: 18px 16px;
26
24
  background-position: center;
27
25
  -webkit-tap-highlight-color: transparent;
26
+
27
+ @include v(background-color, collector-background, $collector-background);
28
+ @include v(box-shadow, collector-shadow, $collector-shadow);
28
29
  }
29
30
 
30
31
  .#{$namespace}-collector-visible {
@@ -40,6 +41,11 @@
40
41
  color-scheme: dark;
41
42
 
42
43
  &.#{$namespace}-collector {
43
- background-color: #43434d;
44
+ @include v(
45
+ background-color,
46
+ collector-background-dark,
47
+ $collector-background-dark
48
+ );
49
+ @include v(box-shadow, collector-shadow-dark, $collector-shadow-dark);
44
50
  }
45
51
  }
@@ -14,7 +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
+ root: HTMLElement;
18
18
  }
19
19
 
20
20
  export class MaxTitleBar extends DefaultTitleBar {
@@ -25,15 +25,7 @@ export class MaxTitleBar extends DefaultTitleBar {
25
25
  this.rootRect$ = config.rootRect$;
26
26
  this.darkMode$ = config.darkMode$;
27
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
- );
28
+ config.root.appendChild(this.render());
37
29
  }
38
30
 
39
31
  public focusBox(box?: TeleBox): void {
@@ -87,16 +79,6 @@ export class MaxTitleBar extends DefaultTitleBar {
87
79
  readonly
88
80
  );
89
81
  }),
90
- this.darkMode$.subscribe((darkMode) => {
91
- $titleBar.classList.toggle(
92
- this.wrapClassName("color-scheme-dark"),
93
- darkMode
94
- );
95
- $titleBar.classList.toggle(
96
- this.wrapClassName("color-scheme-light"),
97
- !darkMode
98
- );
99
- }),
100
82
  combine([this.state$, this.boxes$]).subscribe(
101
83
  ([state, titles]) => {
102
84
  if (state === TELE_BOX_STATE.Maximized) {
@@ -1,7 +1,7 @@
1
1
  @import "../../scss/variables.scss";
2
2
  @import "../../scss/mixins.scss";
3
3
 
4
- $scrollbar-size: 8px;
4
+ $scrollbar-size: 4px;
5
5
  $scrollbar-ff-width: auto; // FF-only accepts auto, thin, none
6
6
  $scrollbar-minlength: 50px; // Minimum length of scrollbar thumb
7
7
  $scrollbar-track-color: transparent;
@@ -108,15 +108,26 @@ $scrollbar-color-active: rgba(238, 238, 247, 1);
108
108
  white-space: nowrap;
109
109
  word-break: keep-all;
110
110
  border: none;
111
- border-right: 1px solid #e5e5f0;
112
- color: #7b88a0;
113
- background: transparent;
111
+ border-right-width: 1px;
112
+ border-right-style: solid;
114
113
  cursor: pointer;
115
114
  user-select: none;
115
+
116
+ @include v(color, titlebar-tab-color, $titlebar-tab-color);
117
+ @include v(
118
+ background-color,
119
+ titlebar-tab-background,
120
+ $titlebar-tab-background
121
+ );
122
+ @include v(
123
+ border-right-color,
124
+ titlebar-tab-divider-color,
125
+ $titlebar-tab-divider-color
126
+ );
116
127
  }
117
128
 
118
129
  .#{$namespace}-titles-tab-focus {
119
- color: #357bf6;
130
+ @include v(color, titlebar-tab-focus-color, $titlebar-tab-focus-color);
120
131
  }
121
132
 
122
133
  .#{$namespace}-readonly {
@@ -128,17 +139,25 @@ $scrollbar-color-active: rgba(238, 238, 247, 1);
128
139
  .#{$namespace}-color-scheme-dark {
129
140
  color-scheme: dark;
130
141
 
131
- &.#{$namespace}-titlebar {
132
- color: #e9e9e9;
133
- background: #43434d;
134
- border-bottom: none;
135
- }
136
-
137
142
  .#{$namespace}-titles-tab {
138
- border-right-color: #7b88a0;
143
+ @include v(color, titlebar-tab-color-dark, $titlebar-tab-color-dark);
144
+ @include v(
145
+ background-color,
146
+ titlebar-tab-background-dark,
147
+ $titlebar-tab-background-dark
148
+ );
149
+ @include v(
150
+ border-right-color,
151
+ titlebar-tab-divider-color-dark,
152
+ $titlebar-tab-divider-color-dark
153
+ );
139
154
  }
140
155
 
141
- .#{$namespace}-title {
142
- color: #e9e9e9;
156
+ .#{$namespace}-titles-tab-focus {
157
+ @include v(
158
+ color,
159
+ titlebar-tab-focus-color-dark,
160
+ $titlebar-tab-focus-color-dark
161
+ );
143
162
  }
144
163
  }
@@ -282,6 +282,51 @@ export class TeleBoxManager {
282
282
  true
283
283
  );
284
284
 
285
+ this.$container = document.createElement("div");
286
+ this.$container.className = this.wrapClassName("manager-container");
287
+
288
+ this.$stage = document.createElement("div");
289
+ this.$stage.className = this.wrapClassName("manager-stage");
290
+ this.$container.appendChild(this.$stage);
291
+
292
+ this._sideEffect.addDisposer([
293
+ darkMode$.subscribe((darkMode) => {
294
+ this.$container.classList.toggle(
295
+ this.wrapClassName("color-scheme-dark"),
296
+ darkMode
297
+ );
298
+ this.$container.classList.toggle(
299
+ this.wrapClassName("color-scheme-light"),
300
+ !darkMode
301
+ );
302
+ }),
303
+ maximized$.subscribe((maximized) => {
304
+ this.$container.classList.toggle("is-maximized", maximized);
305
+ }),
306
+ minimized$.subscribe((minimized) => {
307
+ this.$container.classList.toggle("is-minimized", minimized);
308
+ }),
309
+ containerStyle$.subscribe((containerStyle) => {
310
+ this.$container.style.cssText = containerStyle;
311
+ }),
312
+ stageStyle$.subscribe((stageStyle) => {
313
+ this.$stage.style.cssText = stageStyle;
314
+ this.$stage.style.width = stageRect$.value.width + "px";
315
+ this.$stage.style.height = stageRect$.value.height + "px";
316
+ }),
317
+ stageRect$.subscribe((stageRect) => {
318
+ this.$stage.style.width = stageRect.width + "px";
319
+ this.$stage.style.height = stageRect.height + "px";
320
+ }),
321
+ root$.subscribe((root) => {
322
+ if (root) {
323
+ root.appendChild(this.$container);
324
+ } else if (this.$container.parentElement) {
325
+ this.$container.remove();
326
+ }
327
+ }),
328
+ ]);
329
+
285
330
  this.titleBar = new MaxTitleBar({
286
331
  namespace: this.namespace,
287
332
  title$: derive(this.topBox$, (topBox) => topBox?.title || ""),
@@ -289,8 +334,8 @@ export class TeleBoxManager {
289
334
  darkMode$: darkMode$,
290
335
  readonly$: readonly$,
291
336
  state$: state$,
292
- root$,
293
337
  rootRect$: rootRect$,
338
+ root: this.$container,
294
339
  onEvent: (event): void => {
295
340
  switch (event.type) {
296
341
  case TELE_BOX_DELEGATE_EVENT.Maximize: {
@@ -341,51 +386,6 @@ export class TeleBoxManager {
341
386
  }
342
387
  }),
343
388
  ]);
344
-
345
- this.$container = document.createElement("div");
346
- this.$container.className = this.wrapClassName("manager-container");
347
-
348
- this.$stage = document.createElement("div");
349
- this.$stage.className = this.wrapClassName("manager-stage");
350
- this.$container.appendChild(this.$stage);
351
-
352
- this._sideEffect.addDisposer([
353
- darkMode$.subscribe((darkMode) => {
354
- this.$container.classList.toggle(
355
- this.wrapClassName("color-scheme-dark"),
356
- darkMode
357
- );
358
- this.$container.classList.toggle(
359
- this.wrapClassName("color-scheme-light"),
360
- !darkMode
361
- );
362
- }),
363
- maximized$.subscribe((maximized) => {
364
- this.$container.classList.toggle("is-maximized", maximized);
365
- }),
366
- minimized$.subscribe((minimized) => {
367
- this.$container.classList.toggle("is-minimized", minimized);
368
- }),
369
- containerStyle$.subscribe((containerStyle) => {
370
- this.$container.style.cssText = containerStyle;
371
- }),
372
- stageStyle$.subscribe((stageStyle) => {
373
- this.$stage.style.cssText = stageStyle;
374
- this.$stage.style.width = stageRect$.value.width + "px";
375
- this.$stage.style.height = stageRect$.value.height + "px";
376
- }),
377
- stageRect$.subscribe((stageRect) => {
378
- this.$stage.style.width = stageRect.width + "px";
379
- this.$stage.style.height = stageRect.height + "px";
380
- }),
381
- root$.subscribe((root) => {
382
- if (root) {
383
- root.appendChild(this.$container);
384
- } else if (this.$container.parentElement) {
385
- this.$container.remove();
386
- }
387
- }),
388
- ]);
389
389
  }
390
390
 
391
391
  public readonly $container: HTMLDivElement;