@netless/telebox-insider 0.2.7 → 0.2.8

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": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "private": false,
5
5
  "description": "Window widget for Whiteboard",
6
6
  "license": "MIT",
@@ -1,3 +1,9 @@
1
+ export enum TELE_BOX_COLOR_SCHEME {
2
+ Light = "light",
3
+ Dark = "dark",
4
+ Auto = "auto",
5
+ }
6
+
1
7
  export enum TELE_BOX_STATE {
2
8
  Normal = "normal",
3
9
  Minimized = "minimized",
@@ -5,6 +11,8 @@ export enum TELE_BOX_STATE {
5
11
  }
6
12
 
7
13
  export enum TELE_BOX_EVENT {
14
+ DarkMode = "dark_mode",
15
+ PrefersColorScheme = "prefers_color_scheme",
8
16
  Close = "close",
9
17
  Focus = "focus",
10
18
  Blur = "blur",
@@ -26,6 +26,7 @@ import {
26
26
  TELE_BOX_STATE,
27
27
  TELE_BOX_RESIZE_HANDLE,
28
28
  TELE_BOX_DELEGATE_EVENT,
29
+ TELE_BOX_COLOR_SCHEME,
29
30
  } from "./constants";
30
31
  import type {
31
32
  TeleBoxConfig,
@@ -36,12 +37,15 @@ import type {
36
37
  TeleBoxDelegateEvents,
37
38
  TeleBoxCoord,
38
39
  TeleBoxSize,
40
+ TeleBoxColorScheme,
39
41
  } from "./typings";
40
42
 
41
43
  export * from "./constants";
42
44
  export * from "./typings";
43
45
 
44
46
  type ValConfig = {
47
+ prefersColorScheme: Val<TeleBoxColorScheme, boolean>;
48
+ darkMode: Val<boolean, boolean>;
45
49
  containerRect: Val<TeleBoxRect, boolean>;
46
50
  collectorRect: Val<TeleBoxRect | undefined, boolean>;
47
51
  /** Box title. Default empty. */
@@ -74,6 +78,8 @@ export class TeleBox {
74
78
  public constructor({
75
79
  id = genUniqueKey(),
76
80
  title = getBoxDefaultName(),
81
+ prefersColorScheme = TELE_BOX_COLOR_SCHEME.Light,
82
+ darkMode,
77
83
  visible = true,
78
84
  width = 0.5,
79
85
  height = 0.5,
@@ -112,6 +118,58 @@ export class TeleBox {
112
118
  this.events = new EventEmitter();
113
119
  this._delegateEvents = new EventEmitter();
114
120
 
121
+ const prefersColorScheme$ = createVal<TeleBoxColorScheme, boolean>(
122
+ prefersColorScheme
123
+ );
124
+ prefersColorScheme$.reaction((prefersColorScheme, _, skipUpdate) => {
125
+ if (!skipUpdate) {
126
+ this.events.emit(
127
+ TELE_BOX_EVENT.PrefersColorScheme,
128
+ prefersColorScheme
129
+ );
130
+ }
131
+ });
132
+
133
+ const darkMode$ = createVal(Boolean(darkMode));
134
+
135
+ if (darkMode == null) {
136
+ prefersColorScheme$.subscribe(
137
+ (prefersColorScheme, _, skipUpdate) => {
138
+ this._sideEffect.add(() => {
139
+ if (prefersColorScheme === "auto") {
140
+ const prefersDark = window.matchMedia(
141
+ "(prefers-color-scheme: dark)"
142
+ );
143
+ darkMode$.setValue(prefersDark.matches, skipUpdate);
144
+ const handler = (
145
+ evt: MediaQueryListEvent
146
+ ): void => {
147
+ darkMode$.setValue(evt.matches, skipUpdate);
148
+ };
149
+ prefersDark.addEventListener("change", handler);
150
+ return () =>
151
+ prefersDark.removeEventListener(
152
+ "change",
153
+ handler
154
+ );
155
+ } else {
156
+ darkMode$.setValue(
157
+ prefersColorScheme === "dark",
158
+ skipUpdate
159
+ );
160
+ return () => {};
161
+ }
162
+ }, "prefers-color-scheme");
163
+ }
164
+ );
165
+ }
166
+
167
+ darkMode$.reaction((darkMode, _, skipUpdate) => {
168
+ if (!skipUpdate) {
169
+ this.events.emit(TELE_BOX_EVENT.DarkMode, darkMode);
170
+ }
171
+ });
172
+
115
173
  const containerRect$ = createVal(containerRect, shallowequal);
116
174
  const collectorRect$ = createVal(collectorRect, shallowequal);
117
175
 
@@ -354,6 +412,8 @@ export class TeleBox {
354
412
  const $userStyles$ = createVal(styles);
355
413
 
356
414
  const valConfig: ValConfig = {
415
+ prefersColorScheme: prefersColorScheme$,
416
+ darkMode: darkMode$,
357
417
  containerRect: containerRect$,
358
418
  collectorRect: collectorRect$,
359
419
  title: title$,
@@ -417,6 +477,10 @@ export class TeleBox {
417
477
  public _coord$: Val<TeleBoxCoord, boolean>;
418
478
  public _intrinsicCoord$: Val<TeleBoxCoord, boolean>;
419
479
 
480
+ public get darkMode(): boolean {
481
+ return this._darkMode$.value;
482
+ }
483
+
420
484
  public _state$: Val<TeleBoxState, boolean>;
421
485
 
422
486
  public get state(): TeleBoxState {
@@ -735,6 +799,13 @@ export class TeleBox {
735
799
  bindClassName(this.$box, this._draggable$, "no-drag", isFalsy);
736
800
  bindClassName(this.$box, this._resizable$, "no-resize", isFalsy);
737
801
  bindClassName(this.$box, this._focus$, "blur", isFalsy);
802
+ bindClassName(this.$box, this._darkMode$, "color-scheme-dark");
803
+ bindClassName(
804
+ this.$box,
805
+ this._darkMode$,
806
+ "color-scheme-light",
807
+ isFalsy
808
+ );
738
809
 
739
810
  this._renderSideEffect.add(() => {
740
811
  const minimizedClassName = this.wrapClassName("minimized");
@@ -202,3 +202,11 @@
202
202
  pointer-events: none !important;
203
203
  }
204
204
  }
205
+
206
+ .#{$namespace}-color-scheme-dark {
207
+ .#{$namespace}-box-main {
208
+ color: #e9e9e9;
209
+ background: #212126;
210
+ border-color: #43434d;
211
+ }
212
+ }
@@ -6,8 +6,11 @@ import type {
6
6
  TELE_BOX_DELEGATE_EVENT,
7
7
  TELE_BOX_RESIZE_HANDLE,
8
8
  TELE_BOX_STATE,
9
+ TELE_BOX_COLOR_SCHEME,
9
10
  } from "./constants";
10
11
 
12
+ export type TeleBoxColorScheme = `${TELE_BOX_COLOR_SCHEME}`;
13
+
11
14
  export type TeleBoxCoord = { x: number; y: number };
12
15
 
13
16
  export type TeleBoxSize = { width: number; height: number };
@@ -26,6 +29,10 @@ export interface TeleBoxConfig {
26
29
  readonly id?: string;
27
30
  /** Box title. Default empty. */
28
31
  readonly title?: string;
32
+ /** Prefers Box color scheme. Default light. */
33
+ readonly prefersColorScheme?: TeleBoxColorScheme;
34
+ /** Actual Box Dark Mode */
35
+ readonly darkMode?: boolean;
29
36
  /** Box visible. Default true. */
30
37
  readonly visible?: boolean;
31
38
  /** Box width relative to root element. 0~1. Default 0.5. */
@@ -79,6 +86,8 @@ export interface TeleBoxConfig {
79
86
  type CheckTeleBoxConfig<T extends Record<`${TELE_BOX_EVENT}`, any>> = T;
80
87
 
81
88
  export type TeleBoxEventConfig = CheckTeleBoxConfig<{
89
+ dark_mode: boolean;
90
+ prefers_color_scheme: TeleBoxColorScheme;
82
91
  close: void;
83
92
  focus: void;
84
93
  blur: void;
@@ -10,4 +10,6 @@ export enum TELE_BOX_MANAGER_EVENT {
10
10
  IntrinsicMove = "intrinsic_move",
11
11
  IntrinsicResize = "intrinsic_resize",
12
12
  VisualResize = "visual_resize",
13
+ PrefersColorScheme = "prefers_color_scheme",
14
+ DarkMode = "dark_mode",
13
15
  }
@@ -17,7 +17,11 @@ import type {
17
17
  TeleBoxManagerUpdateConfig,
18
18
  } from "./typings";
19
19
  import { MaxTitleBar } from "./MaxTitleBar";
20
- import { TELE_BOX_DELEGATE_EVENT } from "..";
20
+ import {
21
+ TeleBoxColorScheme,
22
+ TELE_BOX_COLOR_SCHEME,
23
+ TELE_BOX_DELEGATE_EVENT,
24
+ } from "..";
21
25
  import { SideEffectManager } from "side-effect-manager";
22
26
  import {
23
27
  createSideEffectBinder,
@@ -30,6 +34,7 @@ export * from "./typings";
30
34
  export * from "./constants";
31
35
 
32
36
  type ValConfig = {
37
+ prefersColorScheme: Val<TeleBoxColorScheme, boolean>;
33
38
  containerRect: Val<TeleBoxRect, boolean>;
34
39
  collector: Val<TeleBoxCollector | null>;
35
40
  readonly: Val<boolean, boolean>;
@@ -42,6 +47,7 @@ export interface TeleBoxManager extends ValEnhancedResult<ValConfig> {}
42
47
  export class TeleBoxManager {
43
48
  public constructor({
44
49
  root = document.body,
50
+ prefersColorScheme = TELE_BOX_COLOR_SCHEME.Light,
45
51
  minimized = false,
46
52
  maximized = false,
47
53
  fence = true,
@@ -63,6 +69,43 @@ export class TeleBoxManager {
63
69
  this.namespace = namespace;
64
70
  this.zIndex = zIndex;
65
71
 
72
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
73
+ const prefersDark$ = createVal(prefersDark.matches);
74
+ this._sideEffect.add(() => {
75
+ const handler = (evt: MediaQueryListEvent): void => {
76
+ prefersDark$.setValue(evt.matches);
77
+ };
78
+ prefersDark.addEventListener("change", handler);
79
+ return () => prefersDark.removeEventListener("change", handler);
80
+ });
81
+
82
+ const prefersColorScheme$ = createVal(prefersColorScheme);
83
+ prefersColorScheme$.reaction((prefersColorScheme, _, skipUpdate) => {
84
+ this.boxes.forEach((box) =>
85
+ box.setPrefersColorScheme(prefersColorScheme, skipUpdate)
86
+ );
87
+ if (!skipUpdate) {
88
+ this.events.emit(
89
+ TELE_BOX_MANAGER_EVENT.PrefersColorScheme,
90
+ prefersColorScheme
91
+ );
92
+ }
93
+ });
94
+
95
+ this._darkMode$ = combine(
96
+ [prefersDark$, prefersColorScheme$],
97
+ ([prefersDark, prefersColorScheme]) =>
98
+ prefersColorScheme === "auto"
99
+ ? prefersDark
100
+ : prefersColorScheme === "dark"
101
+ );
102
+ this._darkMode$.reaction((darkMode, _, skipUpdate) => {
103
+ this.boxes.forEach((box) => box.setDarkMode(darkMode, skipUpdate));
104
+ if (!skipUpdate) {
105
+ this.events.emit(TELE_BOX_MANAGER_EVENT.DarkMode, darkMode);
106
+ }
107
+ });
108
+
66
109
  const readonly$ = createVal(readonly);
67
110
  readonly$.reaction((readonly, _, skipUpdate) => {
68
111
  this.boxes.forEach((box) => box.setReadonly(readonly, skipUpdate));
@@ -246,6 +289,7 @@ export class TeleBoxManager {
246
289
  );
247
290
 
248
291
  const valConfig: ValConfig = {
292
+ prefersColorScheme: prefersColorScheme$,
249
293
  containerRect: containerRect$,
250
294
  collector: collector$,
251
295
  readonly: readonly$,
@@ -271,6 +315,12 @@ export class TeleBoxManager {
271
315
 
272
316
  public zIndex: number;
273
317
 
318
+ public _darkMode$: Val<boolean, boolean>;
319
+
320
+ public get darkMode(): boolean {
321
+ return this._darkMode$.value;
322
+ }
323
+
274
324
  public _state$: Val<TeleBoxState, boolean>;
275
325
 
276
326
  public get state(): TeleBoxState {
@@ -614,6 +664,8 @@ export class TeleBoxManager {
614
664
  y,
615
665
  width,
616
666
  height,
667
+ darkMode: this.darkMode,
668
+ prefersColorScheme: this.prefersColorScheme,
617
669
  maximized: this.maximized,
618
670
  minimized: this.minimized,
619
671
  fence: this.fence,
@@ -1,4 +1,5 @@
1
1
  import type EventEmitter from "eventemitter3";
2
+ import { TeleBoxColorScheme } from "..";
2
3
  import type { ReadonlyTeleBox, TeleBoxState } from "../TeleBox";
3
4
  import type { TeleBoxConfig } from "../TeleBox/typings";
4
5
  import type { TeleBoxCollector } from "../TeleBoxCollector";
@@ -7,6 +8,7 @@ import type { TELE_BOX_MANAGER_EVENT } from "./constants";
7
8
  export interface TeleBoxManagerConfig
8
9
  extends Pick<
9
10
  TeleBoxConfig,
11
+ | "prefersColorScheme"
10
12
  | "fence"
11
13
  | "containerRect"
12
14
  | "maximized"
@@ -67,6 +69,8 @@ export type TeleBoxManagerEventConfig = CheckTeleBoxManagerConfig<{
67
69
  intrinsic_move: [ReadonlyTeleBox];
68
70
  intrinsic_resize: [ReadonlyTeleBox];
69
71
  visual_resize: [ReadonlyTeleBox];
72
+ prefers_color_scheme: [TeleBoxColorScheme];
73
+ dark_mode: [boolean];
70
74
  }>;
71
75
 
72
76
  export type TeleBoxManagerEvent = keyof TeleBoxManagerEventConfig;
@@ -16,6 +16,12 @@ export type TeleBoxReactProps = TeleBoxConfig & {
16
16
  export const TeleBoxReact: FC<TeleBoxReactProps> = (props) => {
17
17
  const [teleBox] = useState(() => new TeleBox(props));
18
18
 
19
+ useUpdateEffect(() => {
20
+ if (props.prefersColorScheme != null) {
21
+ teleBox.setPrefersColorScheme(props.prefersColorScheme);
22
+ }
23
+ }, [teleBox, props.prefersColorScheme]);
24
+
19
25
  useUpdateEffect(() => {
20
26
  if (props.minWidth != null) {
21
27
  teleBox.setMinWidth(props.minWidth);
@@ -52,6 +58,18 @@ export const TeleBoxReact: FC<TeleBoxReactProps> = (props) => {
52
58
  }
53
59
  }, [teleBox, props.visible]);
54
60
 
61
+ useUpdateEffect(() => {
62
+ if (props.minimized != null) {
63
+ teleBox.setMinimized(props.minimized, true);
64
+ }
65
+ }, [teleBox, props.minimized]);
66
+
67
+ useUpdateEffect(() => {
68
+ if (props.maximized != null) {
69
+ teleBox.setMaximized(props.maximized, true);
70
+ }
71
+ }, [teleBox, props.maximized]);
72
+
55
73
  useUpdateEffect(() => {
56
74
  if (props.state != null) {
57
75
  teleBox.setState(props.state, true);
@@ -71,3 +71,15 @@
71
71
  .#{$namespace}-titlebar-icon-close {
72
72
  background: center / cover no-repeat url("./icons/close.svg");
73
73
  }
74
+
75
+ .#{$namespace}-color-scheme-dark {
76
+ .#{$namespace}-title {
77
+ color: #e9e9e9;
78
+ }
79
+
80
+ .#{$namespace}-titlebar {
81
+ color: #e9e9e9;
82
+ background: #43434d;
83
+ border-bottom: none;
84
+ }
85
+ }