@netless/fastboard 0.0.10 → 0.0.11

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 (43) hide show
  1. package/README.md +11 -1
  2. package/dist/index.cjs.js +4 -4
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +527 -365
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/svelte.cjs.js +1 -1
  7. package/dist/svelte.cjs.js.map +1 -1
  8. package/dist/svelte.es.js +1 -0
  9. package/dist/svelte.es.js.map +1 -1
  10. package/dist/vue.cjs.js +1 -1
  11. package/dist/vue.cjs.js.map +1 -1
  12. package/dist/vue.es.js +1 -0
  13. package/dist/vue.es.js.map +1 -1
  14. package/package.json +3 -2
  15. package/src/components/{PageControl.scss → PageControl/PageControl.scss} +0 -0
  16. package/src/components/PageControl/PageControl.tsx +110 -0
  17. package/src/components/PageControl/hooks.ts +70 -0
  18. package/src/components/PageControl/index.ts +2 -0
  19. package/src/components/PlayerControl/PlayerControl.tsx +7 -8
  20. package/src/components/PlayerControl/hooks.ts +1 -1
  21. package/src/components/PlayerControl/index.ts +1 -0
  22. package/src/components/{RedoUndo.scss → RedoUndo/RedoUndo.scss} +0 -0
  23. package/src/components/{RedoUndo.tsx → RedoUndo/RedoUndo.tsx} +13 -29
  24. package/src/components/RedoUndo/hooks.ts +50 -0
  25. package/src/components/RedoUndo/index.ts +2 -0
  26. package/src/components/Root.tsx +10 -6
  27. package/src/components/Toolbar/Content.tsx +4 -3
  28. package/src/components/Toolbar/Toolbar.scss +35 -1
  29. package/src/components/Toolbar/Toolbar.tsx +78 -28
  30. package/src/components/Toolbar/components/Mask.tsx +44 -0
  31. package/src/components/Toolbar/components/assets/collapsed.png +0 -0
  32. package/src/components/Toolbar/components/assets/expanded.png +0 -0
  33. package/src/components/Toolbar/hooks.ts +28 -29
  34. package/src/components/Toolbar/index.ts +1 -0
  35. package/src/components/{ZoomControl.scss → ZoomControl/ZoomControl.scss} +0 -0
  36. package/src/components/ZoomControl/ZoomControl.tsx +109 -0
  37. package/src/components/ZoomControl/hooks.ts +111 -0
  38. package/src/components/ZoomControl/index.ts +2 -0
  39. package/src/components/hooks.ts +80 -0
  40. package/src/index.ts +19 -4
  41. package/src/style.scss +3 -3
  42. package/src/components/PageControl.tsx +0 -181
  43. package/src/components/ZoomControl.tsx +0 -221
@@ -1,16 +1,19 @@
1
- import type { CommonProps, GenericIcon, Theme } from "../../types";
2
1
  import type { i18n } from "i18next";
2
+ import type { CommonProps, GenericIcon, Theme } from "../../types";
3
+ import { AnimatePresence, motion } from "framer-motion";
3
4
 
4
- import clsx from "clsx";
5
5
  import React, { createContext, useCallback, useState } from "react";
6
6
 
7
7
  import { Icon } from "../../icons";
8
- import { Icons } from "./icons";
9
- import { Button } from "./components/Button";
10
- import { CutLine } from "./components/CutLine";
11
8
  import { EmptyToolbarHook, useToolbar, type ToolbarHook } from "./hooks";
12
9
  import { Content } from "./Content";
13
10
 
11
+ import collapsePNG from "./components/assets/collapsed.png";
12
+ import expandPNG from "./components/assets/expanded.png";
13
+
14
+ import clsx from "clsx";
15
+ import { Mask } from "./components/Mask";
16
+
14
17
  export type ToolbarProps = CommonProps & {
15
18
  icons?: GenericIcon<
16
19
  | "clicker"
@@ -44,39 +47,86 @@ export const Toolbar = ({
44
47
  theme = "light",
45
48
  icons,
46
49
  room,
50
+ manager,
47
51
  i18n,
48
52
  }: ToolbarProps) => {
49
53
  const [expanded, setExpanded] = useState(true);
50
- const hook = useToolbar(room);
51
- const toggle = useCallback(() => setExpanded(e => !e), []);
52
-
54
+ const hook = useToolbar(room, manager);
55
+ const [toolbar, toolbarRef] = useState<HTMLDivElement | null>(null);
56
+ const [onHover, setOnHover] = useState<boolean>(false);
57
+ const [pointEvents, setPointEvents] = useState(true);
53
58
  const disabled = !hook.writable;
54
59
 
60
+ const toggle = useCallback(() => {
61
+ setExpanded(e => !e);
62
+ }, []);
63
+
55
64
  return (
56
65
  <ToolbarContext.Provider value={{ theme, icons, ...hook, i18n }}>
57
- <div className={clsx(name, theme)}>
66
+ <AnimatePresence>
58
67
  {expanded ? (
59
- <Button content={i18n?.t("collapse")} onClick={toggle}>
60
- <Icon
61
- fallback={<Icons.Collapse theme={theme} />}
62
- src={disabled ? icons?.collapseIconDisable : icons?.collapseIcon}
63
- />
64
- </Button>
65
- ) : (
66
- <Button content={i18n?.t("expand")} onClick={toggle}>
67
- <Icon
68
- fallback={<Icons.Expand theme={theme} />}
69
- src={disabled ? icons?.expandIconDisable : icons?.expandIcon}
70
- />
71
- </Button>
72
- )}
73
- {expanded && (
74
- <>
75
- <CutLine />
68
+ <motion.div
69
+ initial={{ x: -100 }}
70
+ animate={{
71
+ x: 0,
72
+ transition: { duration: 0.5 },
73
+ }}
74
+ key="toolbar"
75
+ ref={toolbarRef}
76
+ className={clsx(name, theme)}
77
+ onPointerEnter={() => {
78
+ if (expanded) {
79
+ setOnHover(true);
80
+ }
81
+ }}
82
+ onMouseLeave={() => setOnHover(false)}
83
+ exit={{
84
+ x: -100,
85
+ transition: { duration: 0.5 },
86
+ }}
87
+ onAnimationStart={() => setPointEvents(false)}
88
+ onAnimationComplete={() => setPointEvents(true)}
89
+ style={{ pointerEvents: pointEvents ? "auto" : "none" }}
90
+ >
76
91
  <Content />
77
- </>
92
+ {expanded && onHover && (
93
+ <Mask toolbar={toolbar}>
94
+ <div onClick={toggle}>
95
+ <img
96
+ draggable={false}
97
+ className={clsx(`${name}-mask-btn`, theme)}
98
+ src={collapsePNG}
99
+ />
100
+ </div>
101
+ </Mask>
102
+ )}
103
+ </motion.div>
104
+ ) : (
105
+ <motion.div
106
+ className={clsx(`${name}-expand-btn`, theme)}
107
+ key="expand"
108
+ onClick={toggle}
109
+ initial={{ x: -100 }}
110
+ animate={{
111
+ x: 0,
112
+ transition: { duration: 0.5 },
113
+ }}
114
+ >
115
+ {!expanded && (
116
+ <Icon
117
+ fallback={
118
+ <img
119
+ draggable={false}
120
+ src={expandPNG}
121
+ className={clsx(`${name}-mask-btn`, theme)}
122
+ />
123
+ }
124
+ src={disabled ? icons?.expandIconDisable : icons?.expandIcon}
125
+ />
126
+ )}
127
+ </motion.div>
78
128
  )}
79
- </div>
129
+ </AnimatePresence>
80
130
  </ToolbarContext.Provider>
81
131
  );
82
132
  };
@@ -0,0 +1,44 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import ReactDOM from "react-dom";
3
+
4
+ type MaskProps = {
5
+ toolbar: HTMLDivElement | null;
6
+ children: React.ReactNode;
7
+ };
8
+
9
+ export const Mask = React.memo(({ toolbar, children }: MaskProps) => {
10
+ const [rootElement] = useState<HTMLDivElement | null>(() => {
11
+ const element = document.createElement("div");
12
+ element.style.position = "absolute";
13
+ return element;
14
+ });
15
+
16
+ useEffect(() => {
17
+ if (toolbar && rootElement) {
18
+ toolbar.appendChild(rootElement);
19
+ }
20
+ }, [rootElement, toolbar]);
21
+
22
+ useEffect(() => {
23
+ if (rootElement && toolbar) {
24
+ toolbar.appendChild(rootElement);
25
+
26
+ const toolbarRect = toolbar.getBoundingClientRect();
27
+ const halfHeight = toolbarRect.height / 2 - 31;
28
+ rootElement.style.top = halfHeight + "px";
29
+ rootElement.style.left = "41px";
30
+ rootElement.style.width = "17px";
31
+ rootElement.style.height = "62px";
32
+
33
+ return () => {
34
+ toolbar.removeChild(rootElement);
35
+ };
36
+ }
37
+ }, [rootElement, toolbar]);
38
+
39
+ if (rootElement) {
40
+ return ReactDOM.createPortal(children, rootElement);
41
+ } else {
42
+ return null;
43
+ }
44
+ });
@@ -6,24 +6,11 @@ import type {
6
6
  RoomState,
7
7
  ShapeType,
8
8
  } from "white-web-sdk";
9
-
9
+ import type { WindowManager } from "@netless/window-manager";
10
10
  import { useCallback, useEffect, useState } from "react";
11
- import { noop } from "../../internal";
12
-
13
- export function useWritable(room?: Room | null) {
14
- const [value, setValue] = useState(false);
15
-
16
- useEffect(() => {
17
- if (room) {
18
- const setWritable = () => setValue(room.isWritable);
19
- setWritable();
20
- room.callbacks.on("onEnableWriteNowChanged", setWritable);
21
- return () => room.callbacks.off("onEnableWriteNowChanged", setWritable);
22
- }
23
- }, [room]);
24
11
 
25
- return value;
26
- }
12
+ import { noop } from "../../internal";
13
+ import { useWritable } from "../hooks";
27
14
 
28
15
  export function useRoomState(room?: Room | null) {
29
16
  const [memberState, setMemberState] = useState<MemberState | undefined>(
@@ -53,44 +40,56 @@ export interface ToolbarHook {
53
40
  setStrokeColor(color: Color): void;
54
41
  }
55
42
 
56
- export function useToolbar(room?: Room | null): ToolbarHook {
43
+ export function useToolbar(
44
+ room?: Room | null,
45
+ manager?: WindowManager | null
46
+ ): ToolbarHook {
57
47
  const writable = useWritable(room);
58
48
  const { memberState } = useRoomState(room);
59
49
 
60
50
  const cleanCurrentScene = useCallback(() => {
61
- if (room?.isWritable) {
51
+ if (manager) {
52
+ manager.mainView.cleanCurrentScene();
53
+ } else if (room) {
62
54
  room.cleanCurrentScene();
63
55
  }
64
- }, [room]);
56
+ }, [manager, room]);
65
57
 
66
58
  const setAppliance = useCallback(
67
59
  (appliance: ApplianceNames, shape?: ShapeType) => {
68
- if (room?.isWritable) {
69
- room.setMemberState({
70
- currentApplianceName: appliance,
71
- shapeType: shape,
72
- });
60
+ const memberState = {
61
+ currentApplianceName: appliance,
62
+ shapeType: shape,
63
+ };
64
+ if (manager) {
65
+ manager.mainView.setMemberState(memberState);
66
+ } else if (room) {
67
+ room.setMemberState(memberState);
73
68
  }
74
69
  },
75
- [room]
70
+ [manager, room]
76
71
  );
77
72
 
78
73
  const setStrokeWidth = useCallback(
79
74
  (strokeWidth: number) => {
80
- if (room?.isWritable) {
75
+ if (manager) {
76
+ manager.mainView.setMemberState({ strokeWidth });
77
+ } else if (room) {
81
78
  room.setMemberState({ strokeWidth });
82
79
  }
83
80
  },
84
- [room]
81
+ [manager, room]
85
82
  );
86
83
 
87
84
  const setStrokeColor = useCallback(
88
85
  (strokeColor: Color) => {
89
- if (room?.isWritable) {
86
+ if (manager) {
87
+ manager.mainView.setMemberState({ strokeColor });
88
+ } else if (room) {
90
89
  room.setMemberState({ strokeColor });
91
90
  }
92
91
  },
93
- [room]
92
+ [manager, room]
94
93
  );
95
94
 
96
95
  return {
@@ -1 +1,2 @@
1
+ export * from "./hooks";
1
2
  export { name, Toolbar, type ToolbarProps } from "./Toolbar";
@@ -0,0 +1,109 @@
1
+ import type { CommonProps, GenericIcon } from "../../types";
2
+
3
+ import clsx from "clsx";
4
+ import React from "react";
5
+ import Tippy from "@tippyjs/react";
6
+
7
+ import { TopOffset } from "../../theme";
8
+ import { Icon } from "../../icons";
9
+ import { Minus } from "../../icons/Minus";
10
+ import { Plus } from "../../icons/Plus";
11
+ import { Reset } from "../../icons/Reset";
12
+ import { useWritable } from "../hooks";
13
+ import { useZoomControl } from "./hooks";
14
+
15
+ export const name = "fastboard-zoom-control";
16
+
17
+ export type ZoomControlProps = CommonProps &
18
+ GenericIcon<"reset" | "minus" | "plus">;
19
+
20
+ export function ZoomControl({
21
+ room,
22
+ manager,
23
+ theme = "light",
24
+ resetIcon,
25
+ resetIconDisable,
26
+ minusIcon,
27
+ minusIconDisable,
28
+ plusIcon,
29
+ plusIconDisable,
30
+ i18n,
31
+ }: ZoomControlProps) {
32
+ const writable = useWritable(room);
33
+ const { scale, resetCamera, zoomIn, zoomOut } = useZoomControl(room, manager);
34
+
35
+ const disabled = !writable;
36
+
37
+ return (
38
+ <div className={clsx(name, theme)}>
39
+ {/* <span className={clsx(`${name}-cut-line`, theme)} /> */}
40
+ <Tippy
41
+ className="fastboard-tip"
42
+ content={i18n?.t("zoomOut")}
43
+ theme={theme}
44
+ disabled={disabled}
45
+ placement="top"
46
+ duration={300}
47
+ offset={TopOffset}
48
+ >
49
+ <button
50
+ className={clsx(`${name}-btn`, "minus", theme)}
51
+ disabled={disabled}
52
+ onClick={zoomOut}
53
+ >
54
+ <Icon
55
+ fallback={<Minus theme={theme} />}
56
+ src={disabled ? minusIconDisable : minusIcon}
57
+ alt="[minus]"
58
+ />
59
+ </button>
60
+ </Tippy>
61
+ <span className={clsx(`${name}-scale`, theme)}>
62
+ {Math.ceil(scale * 100)}
63
+ </span>
64
+ <span className={clsx(`${name}-percent`, theme)}>%</span>
65
+ <Tippy
66
+ className="fastboard-tip"
67
+ content={i18n?.t("zoomIn")}
68
+ theme={theme}
69
+ disabled={disabled}
70
+ placement="top"
71
+ duration={300}
72
+ offset={TopOffset}
73
+ >
74
+ <button
75
+ className={clsx(`${name}-btn`, "plus", theme)}
76
+ disabled={disabled}
77
+ onClick={zoomIn}
78
+ >
79
+ <Icon
80
+ fallback={<Plus theme={theme} />}
81
+ src={disabled ? plusIconDisable : plusIcon}
82
+ alt="[plus]"
83
+ />
84
+ </button>
85
+ </Tippy>
86
+ <Tippy
87
+ className="fastboard-tip"
88
+ content={i18n?.t("reset")}
89
+ theme={theme}
90
+ disabled={disabled}
91
+ placement="top"
92
+ duration={300}
93
+ offset={TopOffset}
94
+ >
95
+ <button
96
+ className={clsx(`${name}-btn`, "reset", theme)}
97
+ disabled={disabled}
98
+ onClick={resetCamera}
99
+ >
100
+ <Icon
101
+ fallback={<Reset theme={theme} />}
102
+ src={disabled ? resetIconDisable : resetIcon}
103
+ alt="[reset]"
104
+ />
105
+ </button>
106
+ </Tippy>
107
+ </div>
108
+ );
109
+ }
@@ -0,0 +1,111 @@
1
+ import type { Room, RoomState } from "white-web-sdk";
2
+ import type { WindowManager } from "@netless/window-manager";
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import { clamp } from "../../internal";
5
+
6
+ export const ScalePoints: readonly number[] = [
7
+ 0.10737418240000011, 0.13421772800000012, 0.16777216000000014,
8
+ 0.20971520000000016, 0.26214400000000015, 0.3276800000000002,
9
+ 0.4096000000000002, 0.5120000000000001, 0.6400000000000001, 0.8, 1, 1.26,
10
+ 1.5876000000000001, 2.000376, 2.5204737600000002, 3.1757969376000004,
11
+ 4.001504141376, 5.041895218133761, 6.352787974848539, 8.00451284830916, 10,
12
+ ];
13
+
14
+ function nextScale(scale: number, delta: 1 | -1) {
15
+ const { length } = ScalePoints;
16
+ const last = length - 1;
17
+ if (scale < ScalePoints[0]) return ScalePoints[0];
18
+ if (scale > ScalePoints[last]) return ScalePoints[last];
19
+ for (let i = 0; i < length; ++i) {
20
+ const curr = ScalePoints[i];
21
+ const prev = i === 0 ? -Infinity : (ScalePoints[i - 1] + curr) / 2;
22
+ const next = i === last ? Infinity : (ScalePoints[i + 1] + curr) / 2;
23
+ if (prev <= scale && scale <= next)
24
+ return ScalePoints[clamp(i + delta, 0, last)];
25
+ }
26
+ return 1;
27
+ }
28
+
29
+ export function useZoomControl(
30
+ room?: Room | null,
31
+ manager?: WindowManager | null
32
+ ) {
33
+ const [scale, setScale] = useState(1);
34
+
35
+ const resetCamera = useCallback(() => {
36
+ if (manager) {
37
+ manager.mainView.moveCamera({ scale: 1, centerX: 0, centerY: 0 });
38
+ } else if (room) {
39
+ const { scenes, index } = room.state.sceneState;
40
+ if (scenes[index].ppt) {
41
+ room.scalePptToFit();
42
+ } else {
43
+ room.moveCamera({ scale: 1, centerX: 0, centerY: 0 });
44
+ }
45
+ }
46
+ }, [room, manager]);
47
+
48
+ const zoomIn = useCallback(() => {
49
+ if (manager) {
50
+ manager.mainView.moveCamera({
51
+ scale: nextScale(scale, 1),
52
+ centerX: 0,
53
+ centerY: 0,
54
+ });
55
+ } else if (room) {
56
+ room.moveCamera({
57
+ scale: nextScale(scale, 1),
58
+ centerX: 0,
59
+ centerY: 0,
60
+ });
61
+ }
62
+ }, [room, manager, scale]);
63
+
64
+ const zoomOut = useCallback(() => {
65
+ if (manager) {
66
+ manager.mainView.moveCamera({
67
+ scale: nextScale(scale, -1),
68
+ centerX: 0,
69
+ centerY: 0,
70
+ });
71
+ } else if (room) {
72
+ room.moveCamera({
73
+ scale: nextScale(scale, -1),
74
+ centerX: 0,
75
+ centerY: 0,
76
+ });
77
+ }
78
+ }, [room, manager, scale]);
79
+
80
+ useEffect(() => {
81
+ if (manager) {
82
+ setScale(manager.mainView.camera.scale);
83
+
84
+ const onCameraUpdated = ({ scale }: { scale: number }) => setScale(scale);
85
+
86
+ manager.mainView.callbacks.on("onCameraUpdated", onCameraUpdated);
87
+
88
+ return () => {
89
+ manager.mainView.callbacks.off("onCameraUpdated", onCameraUpdated);
90
+ };
91
+ }
92
+
93
+ if (room) {
94
+ setScale(room.state.cameraState.scale);
95
+
96
+ const onRoomStateChanged = (modifyState: Partial<RoomState>) => {
97
+ if (modifyState.cameraState) {
98
+ setScale(modifyState.cameraState.scale);
99
+ }
100
+ };
101
+
102
+ room.callbacks.on("onRoomStateChanged", onRoomStateChanged);
103
+
104
+ return () => {
105
+ room.callbacks.off("onRoomStateChanged", onRoomStateChanged);
106
+ };
107
+ }
108
+ }, [room, manager]);
109
+
110
+ return { scale, resetCamera, zoomIn, zoomOut };
111
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./hooks";
2
+ export { name, ZoomControl, type ZoomControlProps } from "./ZoomControl";
@@ -0,0 +1,80 @@
1
+ import type { Room, WindowManager } from "@netless/window-manager";
2
+ import { BuiltinApps } from "@netless/window-manager";
3
+ import { useEffect, useState } from "react";
4
+
5
+ export function useWritable(room?: Room | null) {
6
+ const [writable, setWritable] = useState(false);
7
+
8
+ useEffect(() => {
9
+ if (room) {
10
+ setWritable(room.isWritable);
11
+ room.isWritable && (room.disableSerialization = false);
12
+
13
+ const updateWritable = () => setWritable(room.isWritable);
14
+ room.callbacks.on("onEnableWriteNowChanged", updateWritable);
15
+
16
+ return () => {
17
+ room.callbacks.off("onEnableWriteNowChanged", updateWritable);
18
+ };
19
+ }
20
+ }, [room]);
21
+
22
+ return writable;
23
+ }
24
+
25
+ export type BoxState = "normal" | "minimized" | "maximized";
26
+
27
+ export function useBoxState(manager?: WindowManager | null) {
28
+ const [boxState, setBoxState] = useState<BoxState | undefined>();
29
+
30
+ useEffect(() => {
31
+ if (manager) {
32
+ setBoxState(manager.boxState);
33
+
34
+ manager.emitter.on("boxStateChange", setBoxState);
35
+
36
+ return () => {
37
+ manager.emitter.off("boxStateChange", setBoxState);
38
+ };
39
+ }
40
+ }, [manager]);
41
+
42
+ return boxState;
43
+ }
44
+
45
+ export function useFocusedApp(manager?: WindowManager | null) {
46
+ const [focused, setFocused] = useState<string | undefined>();
47
+
48
+ useEffect(() => {
49
+ if (manager) {
50
+ setFocused(manager.focused);
51
+
52
+ manager.emitter.on("focusedChange", setFocused);
53
+
54
+ return () => {
55
+ manager.emitter.off("focusedChange", setFocused);
56
+ };
57
+ }
58
+ }, [manager]);
59
+
60
+ return focused;
61
+ }
62
+
63
+ export function useMaximized(manager?: WindowManager | null) {
64
+ return useBoxState(manager) === "maximized";
65
+ }
66
+
67
+ export function useHideControls(manager?: WindowManager | null) {
68
+ const maximized = useMaximized(manager);
69
+ const focusedApp = useFocusedApp(manager);
70
+
71
+ if (maximized) {
72
+ if (Object.values(BuiltinApps).some(kind => focusedApp?.includes(kind))) {
73
+ return "toolbar-only";
74
+ } else {
75
+ return true;
76
+ }
77
+ }
78
+
79
+ return false;
80
+ }
package/src/index.ts CHANGED
@@ -6,14 +6,29 @@ import "./behaviors/style";
6
6
  import { WhiteboardApp, type WhiteboardAppConfig } from "./WhiteboardApp";
7
7
 
8
8
  export { version } from "../package.json";
9
- export { PageControl, type PageControlProps } from "./components/PageControl";
10
- export { RedoUndo, type RedoUndoProps } from "./components/RedoUndo";
11
- export { Toolbar, type ToolbarProps } from "./components/Toolbar";
12
- export { ZoomControl, type ZoomControlProps } from "./components/ZoomControl";
9
+ export {
10
+ PageControl,
11
+ usePageControl,
12
+ type PageControlProps,
13
+ } from "./components/PageControl";
14
+ export {
15
+ RedoUndo,
16
+ useRedoUndo,
17
+ type RedoUndoProps,
18
+ } from "./components/RedoUndo";
19
+ export { Toolbar, useToolbar, type ToolbarProps } from "./components/Toolbar";
20
+ export {
21
+ ZoomControl,
22
+ useZoomControl,
23
+ type ZoomControlProps,
24
+ } from "./components/ZoomControl";
13
25
  export {
14
26
  PlayerControl,
27
+ usePlayerControl,
15
28
  type PlayerControlProps,
16
29
  } from "./components/PlayerControl";
30
+ export {};
31
+
17
32
  export * from "./WhiteboardApp";
18
33
  export * from "./react";
19
34
 
package/src/style.scss CHANGED
@@ -3,9 +3,9 @@
3
3
  @import "tippy.js/themes/light.css";
4
4
  @import "rc-slider/assets/index.css";
5
5
  @import "./components/Root.scss";
6
- @import "./components/RedoUndo.scss";
7
- @import "./components/PageControl.scss";
8
- @import "./components/ZoomControl.scss";
6
+ @import "./components/RedoUndo/RedoUndo.scss";
7
+ @import "./components/PageControl/PageControl.scss";
8
+ @import "./components/ZoomControl/ZoomControl.scss";
9
9
  @import "./components/Toolbar/Toolbar.scss";
10
10
  @import "./components/PlayerControl/PlayerControl.scss";
11
11