@netless/fastboard-react 0.1.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.
- package/dist/index.js +426 -487
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +368 -425
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -13
- package/src/components/Fastboard.tsx +27 -17
- package/src/components/PageControl/PageControl.tsx +2 -4
- package/src/components/PageControl/hooks.ts +18 -61
- package/src/components/Toolbar/Content.tsx +19 -4
- package/src/components/Toolbar/Toolbar.scss +13 -3
- package/src/components/Toolbar/Toolbar.tsx +15 -47
- package/src/components/hooks.ts +1 -1
- package/src/index.ts +1 -0
- package/src/vanilla/index.tsx +18 -0
- package/dist/behaviors/style.d.ts +0 -1
- package/dist/components/Fastboard.d.ts +0 -15
- package/dist/components/PageControl/PageControl.d.ts +0 -5
- package/dist/components/PageControl/hooks.d.ts +0 -9
- package/dist/components/PageControl/index.d.ts +0 -2
- package/dist/components/PlayerControl/PlayerControl.d.ts +0 -9
- package/dist/components/PlayerControl/hooks.d.ts +0 -11
- package/dist/components/PlayerControl/icons/Loading.d.ts +0 -3
- package/dist/components/PlayerControl/icons/Pause.d.ts +0 -3
- package/dist/components/PlayerControl/icons/Play.d.ts +0 -3
- package/dist/components/PlayerControl/icons/index.d.ts +0 -6
- package/dist/components/PlayerControl/index.d.ts +0 -2
- package/dist/components/RedoUndo/RedoUndo.d.ts +0 -5
- package/dist/components/RedoUndo/hooks.d.ts +0 -6
- package/dist/components/RedoUndo/index.d.ts +0 -2
- package/dist/components/Toolbar/Content.d.ts +0 -2
- package/dist/components/Toolbar/Toolbar.d.ts +0 -14
- package/dist/components/Toolbar/components/ApplianceButtons.d.ts +0 -7
- package/dist/components/Toolbar/components/AppsButton.d.ts +0 -6
- package/dist/components/Toolbar/components/ColorBox.d.ts +0 -2
- package/dist/components/Toolbar/components/CutLine.d.ts +0 -2
- package/dist/components/Toolbar/components/Mask.d.ts +0 -7
- package/dist/components/Toolbar/components/PencilButton.d.ts +0 -2
- package/dist/components/Toolbar/components/ShapesButton.d.ts +0 -3
- package/dist/components/Toolbar/components/Slider.d.ts +0 -2
- package/dist/components/Toolbar/components/TextButton.d.ts +0 -2
- package/dist/components/Toolbar/components/UpDownButtons.d.ts +0 -7
- package/dist/components/Toolbar/const.d.ts +0 -18
- package/dist/components/Toolbar/hooks.d.ts +0 -12
- package/dist/components/Toolbar/icons/Apps.d.ts +0 -3
- package/dist/components/Toolbar/icons/Arrow.d.ts +0 -3
- package/dist/components/Toolbar/icons/Circle.d.ts +0 -3
- package/dist/components/Toolbar/icons/Clean.d.ts +0 -3
- package/dist/components/Toolbar/icons/Clicker.d.ts +0 -3
- package/dist/components/Toolbar/icons/Collapse.d.ts +0 -3
- package/dist/components/Toolbar/icons/Diamond.d.ts +0 -3
- package/dist/components/Toolbar/icons/Down.d.ts +0 -3
- package/dist/components/Toolbar/icons/Eraser.d.ts +0 -3
- package/dist/components/Toolbar/icons/Expand.d.ts +0 -3
- package/dist/components/Toolbar/icons/Line.d.ts +0 -3
- package/dist/components/Toolbar/icons/Pencil.d.ts +0 -3
- package/dist/components/Toolbar/icons/Rectangle.d.ts +0 -3
- package/dist/components/Toolbar/icons/Selector.d.ts +0 -3
- package/dist/components/Toolbar/icons/SpeechBalloon.d.ts +0 -3
- package/dist/components/Toolbar/icons/Star.d.ts +0 -3
- package/dist/components/Toolbar/icons/Text.d.ts +0 -3
- package/dist/components/Toolbar/icons/Triangle.d.ts +0 -3
- package/dist/components/Toolbar/icons/Up.d.ts +0 -3
- package/dist/components/Toolbar/icons/index.d.ts +0 -22
- package/dist/components/Toolbar/index.d.ts +0 -2
- package/dist/components/ZoomControl/ZoomControl.d.ts +0 -5
- package/dist/components/ZoomControl/hooks.d.ts +0 -7
- package/dist/components/ZoomControl/index.d.ts +0 -2
- package/dist/components/hooks.d.ts +0 -13
- package/dist/i18n/index.d.ts +0 -12
- package/dist/icons/ChevronLeft.d.ts +0 -3
- package/dist/icons/ChevronRight.d.ts +0 -3
- package/dist/icons/FilePlus.d.ts +0 -3
- package/dist/icons/Minus.d.ts +0 -3
- package/dist/icons/Plus.d.ts +0 -3
- package/dist/icons/Redo.d.ts +0 -3
- package/dist/icons/Reset.d.ts +0 -3
- package/dist/icons/Undo.d.ts +0 -3
- package/dist/icons/index.d.ts +0 -7
- package/dist/index.d.ts +0 -9
- package/dist/internal/helpers.d.ts +0 -16
- package/dist/internal/hooks.d.ts +0 -3
- package/dist/internal/index.d.ts +0 -2
- package/dist/theme.d.ts +0 -16
- package/dist/typings.d.ts +0 -10
- package/src/components/Toolbar/components/Mask.tsx +0 -44
package/package.json
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netless/fastboard-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "A UI kit built on top of @netless/fastboard.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.mjs",
|
|
7
|
-
"types": "src/index.ts",
|
|
8
|
-
"sideEffects": false,
|
|
9
6
|
"files": [
|
|
10
7
|
"src",
|
|
11
8
|
"dist"
|
|
@@ -13,29 +10,37 @@
|
|
|
13
10
|
"dependencies": {
|
|
14
11
|
"@tippyjs/react": "^4.2.6",
|
|
15
12
|
"clsx": "^1.1.1",
|
|
16
|
-
"framer-motion": "^
|
|
17
|
-
"i18next": "^21.6.
|
|
13
|
+
"framer-motion": "^6.2.3",
|
|
14
|
+
"i18next": "^21.6.9",
|
|
18
15
|
"rc-slider": "^9.7.5"
|
|
19
16
|
},
|
|
20
17
|
"peerDependencies": {
|
|
21
|
-
"@netless/fastboard": "*",
|
|
18
|
+
"@netless/fastboard-core": "*",
|
|
22
19
|
"@netless/window-manager": ">=0.4.0",
|
|
23
20
|
"react": "*",
|
|
24
21
|
"react-dom": "*",
|
|
25
22
|
"white-web-sdk": ">=2.16.0"
|
|
26
23
|
},
|
|
27
24
|
"devDependencies": {
|
|
28
|
-
"@netless/
|
|
29
|
-
"@netless/
|
|
30
|
-
"@netless/window-manager": "^0.4.0-canary.17",
|
|
25
|
+
"@netless/fastboard-core": "0.2.2",
|
|
26
|
+
"@netless/window-manager": "^0.4.0-canary.31",
|
|
31
27
|
"@types/react": "^17.0.38",
|
|
32
28
|
"@types/react-dom": "^17.0.11",
|
|
33
29
|
"sass": "^1.49.0",
|
|
34
30
|
"tippy.js": "^6.3.7",
|
|
35
31
|
"tsup": "^5.11.11",
|
|
36
|
-
"white-web-sdk": "^2.16.
|
|
32
|
+
"white-web-sdk": "^2.16.5"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"main": "dist/index.js",
|
|
36
|
+
"module": "dist/index.mjs",
|
|
37
|
+
"types": "src/index.ts"
|
|
37
38
|
},
|
|
38
39
|
"scripts": {
|
|
39
|
-
"build": "tsup"
|
|
40
|
-
|
|
40
|
+
"build": "tsup",
|
|
41
|
+
"cleanup": "rimraf dist",
|
|
42
|
+
"check": "tsc --noEmit"
|
|
43
|
+
},
|
|
44
|
+
"module": "dist/index.mjs",
|
|
45
|
+
"types": "src/index.ts"
|
|
41
46
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { FastboardApp } from "@netless/fastboard";
|
|
2
|
-
import type {
|
|
1
|
+
import type { FastboardApp } from "@netless/fastboard-core";
|
|
2
|
+
import type { ForwardedRef } from "react";
|
|
3
3
|
import type { Language, Theme } from "../typings";
|
|
4
4
|
|
|
5
|
-
import React, { useCallback, useEffect } from "react";
|
|
6
|
-
|
|
5
|
+
import React, { forwardRef, useCallback, useEffect } from "react";
|
|
7
6
|
import { createI18n, I18nContext } from "../i18n";
|
|
8
7
|
import { useAsyncValue, useForceUpdate } from "../internal";
|
|
9
8
|
import { FastboardAppContext, ThemeContext, useFastboardApp, useHideControls } from "./hooks";
|
|
@@ -19,24 +18,31 @@ export interface FastboardProps {
|
|
|
19
18
|
language?: Language;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
return <div className="fastboard-root" />;
|
|
25
|
-
}
|
|
21
|
+
export type DivProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
|
22
|
+
export type WithForwardedRef<T = HTMLDivElement> = { forwardedRef: ForwardedRef<T> };
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
export const Fastboard = /* @__PURE__ */ forwardRef<HTMLDivElement, FastboardProps & DivProps>(
|
|
25
|
+
function Fastboard({ app, theme, layout, language, ...restProps }, ref) {
|
|
26
|
+
if (!app) {
|
|
27
|
+
return <div className="fastboard-root" ref={ref} {...restProps} />;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<FastboardAppContext.Provider value={app}>
|
|
32
|
+
<FastboardInternal forwardedRef={ref} {...{ theme, layout, language }} {...restProps} />
|
|
33
|
+
</FastboardAppContext.Provider>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
);
|
|
33
37
|
|
|
34
38
|
function FastboardInternal({
|
|
39
|
+
forwardedRef,
|
|
35
40
|
language,
|
|
36
41
|
layout = {},
|
|
37
42
|
theme = "light",
|
|
38
43
|
children,
|
|
39
|
-
|
|
44
|
+
...restProps
|
|
45
|
+
}: Omit<FastboardProps, "app"> & DivProps & WithForwardedRef) {
|
|
40
46
|
const app = useFastboardApp();
|
|
41
47
|
const forceUpdate = useForceUpdate();
|
|
42
48
|
const i18n = useAsyncValue(() => createI18n({ language }));
|
|
@@ -46,9 +52,13 @@ function FastboardInternal({
|
|
|
46
52
|
forceUpdate();
|
|
47
53
|
}, [forceUpdate, i18n, language]);
|
|
48
54
|
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
app.manager.setPrefersColorScheme(theme);
|
|
57
|
+
}, [app, theme]);
|
|
58
|
+
|
|
49
59
|
const useWhiteboard = useCallback(
|
|
50
60
|
(container: HTMLDivElement | null) => {
|
|
51
|
-
container && app
|
|
61
|
+
if (container && app) app.manager.bindContainer(container);
|
|
52
62
|
},
|
|
53
63
|
[app]
|
|
54
64
|
);
|
|
@@ -66,7 +76,7 @@ function FastboardInternal({
|
|
|
66
76
|
return (
|
|
67
77
|
<ThemeContext.Provider value={theme}>
|
|
68
78
|
<I18nContext.Provider value={i18n}>
|
|
69
|
-
<div className="fastboard-root">
|
|
79
|
+
<div {...restProps} className="fastboard-root" ref={forwardedRef}>
|
|
70
80
|
<div className="fastboard-view" ref={useWhiteboard} />
|
|
71
81
|
{children ? (
|
|
72
82
|
children
|
|
@@ -10,7 +10,7 @@ import { ChevronLeft } from "../../icons/ChevronLeft";
|
|
|
10
10
|
import { ChevronRight } from "../../icons/ChevronRight";
|
|
11
11
|
import { FilePlus } from "../../icons/FilePlus";
|
|
12
12
|
import { TopOffset } from "../../theme";
|
|
13
|
-
import {
|
|
13
|
+
import { useTheme, useWritable } from "../hooks";
|
|
14
14
|
import { usePageControl } from "./hooks";
|
|
15
15
|
|
|
16
16
|
export const name = "fastboard-page-control";
|
|
@@ -26,13 +26,11 @@ export function PageControl({
|
|
|
26
26
|
nextIcon,
|
|
27
27
|
nextIconDisable,
|
|
28
28
|
}: PageControlProps) {
|
|
29
|
-
const app = useFastboardApp();
|
|
30
|
-
|
|
31
29
|
theme = useTheme(theme);
|
|
32
30
|
const { t } = useTranslation();
|
|
33
31
|
|
|
34
32
|
const writable = useWritable();
|
|
35
|
-
const { pageIndex, pageCount, ...actions } = usePageControl(
|
|
33
|
+
const { pageIndex, pageCount, ...actions } = usePageControl();
|
|
36
34
|
|
|
37
35
|
const disabled = !writable;
|
|
38
36
|
|
|
@@ -1,67 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { useCallback, useEffect, useState } from "react";
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useFastboardApp, useFastboardValue } from "../hooks";
|
|
4
3
|
|
|
5
|
-
export function usePageControl(
|
|
6
|
-
const
|
|
7
|
-
const
|
|
4
|
+
export function usePageControl() {
|
|
5
|
+
const app = useFastboardApp();
|
|
6
|
+
const pageIndex = useFastboardValue(app.sceneIndex);
|
|
7
|
+
const pageCount = useFastboardValue(app.sceneLength);
|
|
8
8
|
|
|
9
9
|
const addPage = useCallback(async () => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const prevPage = useCallback(() => {
|
|
23
|
-
if (manager) {
|
|
24
|
-
manager.setMainViewSceneIndex(pageIndex - 1);
|
|
25
|
-
} else if (room) {
|
|
26
|
-
room.pptPreviousStep();
|
|
27
|
-
}
|
|
28
|
-
}, [room, manager, pageIndex]);
|
|
29
|
-
|
|
30
|
-
const nextPage = useCallback(() => {
|
|
31
|
-
if (manager) {
|
|
32
|
-
manager.setMainViewSceneIndex(pageIndex + 1);
|
|
33
|
-
} else if (room) {
|
|
34
|
-
room.pptNextStep();
|
|
35
|
-
}
|
|
36
|
-
}, [room, manager, pageIndex]);
|
|
37
|
-
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (room) {
|
|
40
|
-
setPageIndex(room.state.sceneState.index);
|
|
41
|
-
setPageCount(room.state.sceneState.scenes.length);
|
|
42
|
-
|
|
43
|
-
if (manager) {
|
|
44
|
-
manager.emitter.on("mainViewSceneIndexChange", setPageIndex);
|
|
45
|
-
|
|
46
|
-
return () => {
|
|
47
|
-
manager.emitter.off("mainViewSceneIndexChange", setPageIndex);
|
|
48
|
-
};
|
|
49
|
-
} else {
|
|
50
|
-
const onRoomStateChanged = (modifyState: Partial<RoomState>) => {
|
|
51
|
-
if (modifyState.sceneState) {
|
|
52
|
-
setPageIndex(modifyState.sceneState.index);
|
|
53
|
-
setPageCount(modifyState.sceneState.scenes.length);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
room.callbacks.on("onRoomStateChanged", onRoomStateChanged);
|
|
58
|
-
|
|
59
|
-
return () => {
|
|
60
|
-
room.callbacks.off("onRoomStateChanged", onRoomStateChanged);
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}, [room, manager]);
|
|
10
|
+
await app.manager.switchMainViewToWriter();
|
|
11
|
+
app.room.putScenes(app.manager.mainViewSceneDir, [{}], pageIndex + 1);
|
|
12
|
+
await app.manager.setMainViewSceneIndex(pageIndex + 1);
|
|
13
|
+
}, [app, pageIndex]);
|
|
14
|
+
|
|
15
|
+
const prevPage = useCallback(async () => {
|
|
16
|
+
await app.manager.setMainViewSceneIndex(pageIndex - 1);
|
|
17
|
+
}, [app, pageIndex]);
|
|
18
|
+
|
|
19
|
+
const nextPage = useCallback(async () => {
|
|
20
|
+
await app.manager.setMainViewSceneIndex(pageIndex + 1);
|
|
21
|
+
}, [app, pageIndex]);
|
|
65
22
|
|
|
66
23
|
return { pageIndex, pageCount, prevPage, nextPage, addPage };
|
|
67
24
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import clsx from "clsx";
|
|
2
|
-
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { Icon } from "../../icons";
|
|
3
4
|
|
|
4
5
|
import { clamp } from "../../internal";
|
|
5
6
|
import { CleanButton, ClickerButton, EraserButton, SelectorButton } from "./components/ApplianceButtons";
|
|
@@ -9,12 +10,20 @@ import { ShapesButton } from "./components/ShapesButton";
|
|
|
9
10
|
import { TextButton } from "./components/TextButton";
|
|
10
11
|
import { DownButton, UpButton } from "./components/UpDownButtons";
|
|
11
12
|
import { ItemHeight, ItemsCount, MaxHeight, MinHeight } from "./const";
|
|
12
|
-
import { name } from "./Toolbar";
|
|
13
|
+
import { name, ToolbarContext } from "./Toolbar";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
import collapsePNG from "./components/assets/collapsed.png";
|
|
16
|
+
|
|
17
|
+
export interface ContextProps {
|
|
18
|
+
onCollapse: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function Content({ onCollapse }: ContextProps) {
|
|
22
|
+
const { theme, icons, writable } = useContext(ToolbarContext);
|
|
15
23
|
const ref = useRef<HTMLDivElement>(null);
|
|
16
24
|
const [scrollTop, setScrollTop] = useState(0);
|
|
17
25
|
const [parentHeight, setParentHeight] = useState(0);
|
|
26
|
+
const disabled = !writable;
|
|
18
27
|
|
|
19
28
|
const needScroll = parentHeight < ItemHeight * ItemsCount + 48;
|
|
20
29
|
const sectionHeight = clamp(parentHeight - 48 * (needScroll ? 3 : 1), MinHeight, MaxHeight);
|
|
@@ -69,6 +78,12 @@ export const Content = React.memo(() => {
|
|
|
69
78
|
<AppsButton />
|
|
70
79
|
</div>
|
|
71
80
|
{needScroll && <DownButton scrollTo={scrollTo} disabled={disableScrollDown} />}
|
|
81
|
+
<div className={clsx("fastboard-toolbar-mask", theme)} onClick={onCollapse}>
|
|
82
|
+
<Icon
|
|
83
|
+
fallback={<img draggable={false} className={clsx(`${name}-mask-btn`, theme)} src={collapsePNG} />}
|
|
84
|
+
src={disabled ? icons?.expandIconDisable : icons?.expandIcon}
|
|
85
|
+
/>
|
|
86
|
+
</div>
|
|
72
87
|
</>
|
|
73
88
|
);
|
|
74
|
-
}
|
|
89
|
+
}
|
|
@@ -98,8 +98,8 @@ $name: "fastboard-toolbar";
|
|
|
98
98
|
|
|
99
99
|
svg,
|
|
100
100
|
img {
|
|
101
|
-
width:
|
|
102
|
-
height:
|
|
101
|
+
width: 100%;
|
|
102
|
+
height: 100%;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
&:disabled {
|
|
@@ -191,7 +191,7 @@ $name: "fastboard-toolbar";
|
|
|
191
191
|
.#{$name}-btn {
|
|
192
192
|
width: 40px;
|
|
193
193
|
height: 40px;
|
|
194
|
-
font-size:
|
|
194
|
+
font-size: 0;
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
|
|
@@ -263,6 +263,16 @@ $name: "fastboard-toolbar";
|
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
&-mask {
|
|
267
|
+
position: absolute;
|
|
268
|
+
left: calc(100% + 1px);
|
|
269
|
+
top: 50%;
|
|
270
|
+
transform: translateY(-50%);
|
|
271
|
+
&.dark {
|
|
272
|
+
left: calc(100%);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
266
276
|
&-mask-btn {
|
|
267
277
|
width: 17px;
|
|
268
278
|
height: 62px;
|
|
@@ -3,14 +3,12 @@ import type { ToolbarHook } from "./hooks";
|
|
|
3
3
|
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import { AnimatePresence, motion } from "framer-motion";
|
|
6
|
-
import React, { createContext,
|
|
6
|
+
import React, { createContext, useState } from "react";
|
|
7
7
|
|
|
8
|
-
import collapsePNG from "./components/assets/collapsed.png";
|
|
9
8
|
import expandPNG from "./components/assets/expanded.png";
|
|
10
9
|
|
|
11
10
|
import { Icon } from "../../icons";
|
|
12
11
|
import { useTheme } from "../hooks";
|
|
13
|
-
import { Mask } from "./components/Mask";
|
|
14
12
|
import { Content } from "./Content";
|
|
15
13
|
import { EmptyToolbarHook, useToolbar } from "./hooks";
|
|
16
14
|
|
|
@@ -42,75 +40,45 @@ export const ToolbarContext = createContext<ToolbarContextType>({
|
|
|
42
40
|
|
|
43
41
|
export const name = "fastboard-toolbar";
|
|
44
42
|
|
|
45
|
-
export
|
|
43
|
+
export function Toolbar({ theme, icons }: ToolbarProps) {
|
|
46
44
|
theme = useTheme(theme);
|
|
47
45
|
|
|
48
46
|
const hook = useToolbar();
|
|
49
47
|
const [expanded, setExpanded] = useState(true);
|
|
50
|
-
const [
|
|
51
|
-
const [onHover, setOnHover] = useState(false);
|
|
52
|
-
const [delayedOnHover, setDelayedOnHover] = useState(false);
|
|
53
|
-
const [pointEvents, setPointEvents] = useState(true);
|
|
48
|
+
const [pointerEvents, setPointerEvents] = useState<"auto" | "none">("auto");
|
|
54
49
|
const disabled = !hook.writable;
|
|
55
50
|
|
|
56
|
-
const toggle = useCallback(() => {
|
|
57
|
-
setExpanded(e => !e);
|
|
58
|
-
}, []);
|
|
59
|
-
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
const timer = setTimeout(() => {
|
|
62
|
-
setDelayedOnHover(onHover);
|
|
63
|
-
}, 400);
|
|
64
|
-
return () => clearTimeout(timer);
|
|
65
|
-
}, [onHover]);
|
|
66
|
-
|
|
67
51
|
return (
|
|
68
52
|
<ToolbarContext.Provider value={{ theme, icons, ...hook }}>
|
|
69
53
|
<AnimatePresence>
|
|
70
54
|
{expanded ? (
|
|
71
55
|
<motion.div
|
|
72
|
-
initial={{ x: -100 }}
|
|
73
|
-
animate={{ x: 0, transition: { duration: 0.5 } }}
|
|
74
56
|
key="toolbar"
|
|
75
|
-
ref={toolbarRef}
|
|
76
57
|
className={clsx(name, theme)}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}}
|
|
80
|
-
onMouseLeave={() => setOnHover(false)}
|
|
58
|
+
initial={{ x: -100 }}
|
|
59
|
+
animate={{ x: 0, transition: { duration: 0.5 } }}
|
|
81
60
|
exit={{ x: -100, transition: { duration: 0.5 } }}
|
|
82
|
-
onAnimationStart={() =>
|
|
83
|
-
onAnimationComplete={() =>
|
|
84
|
-
style={{ pointerEvents
|
|
61
|
+
onAnimationStart={() => setPointerEvents("none")}
|
|
62
|
+
onAnimationComplete={() => setPointerEvents("auto")}
|
|
63
|
+
style={{ pointerEvents }}
|
|
85
64
|
>
|
|
86
|
-
<Content />
|
|
87
|
-
{expanded && (onHover || delayedOnHover) && (
|
|
88
|
-
<Mask toolbar={toolbar}>
|
|
89
|
-
<div onClick={toggle}>
|
|
90
|
-
<img draggable={false} className={clsx(`${name}-mask-btn`, theme)} src={collapsePNG} />
|
|
91
|
-
</div>
|
|
92
|
-
</Mask>
|
|
93
|
-
)}
|
|
65
|
+
<Content onCollapse={() => setExpanded(false)} />
|
|
94
66
|
</motion.div>
|
|
95
67
|
) : (
|
|
96
68
|
<motion.div
|
|
97
69
|
className={clsx(`${name}-expand-btn`, theme)}
|
|
98
70
|
key="expand"
|
|
99
|
-
onClick={
|
|
71
|
+
onClick={() => setExpanded(true)}
|
|
100
72
|
initial={{ x: -100 }}
|
|
101
73
|
animate={{ x: 0, transition: { duration: 0.5 } }}
|
|
102
74
|
>
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
src={disabled ? icons?.expandIconDisable : icons?.expandIcon}
|
|
109
|
-
/>
|
|
110
|
-
)}
|
|
75
|
+
<Icon
|
|
76
|
+
fallback={<img draggable={false} src={expandPNG} className={clsx(`${name}-mask-btn`, theme)} />}
|
|
77
|
+
src={disabled ? icons?.expandIconDisable : icons?.expandIcon}
|
|
78
|
+
/>
|
|
111
79
|
</motion.div>
|
|
112
80
|
)}
|
|
113
81
|
</AnimatePresence>
|
|
114
82
|
</ToolbarContext.Provider>
|
|
115
83
|
);
|
|
116
|
-
}
|
|
84
|
+
}
|
package/src/components/hooks.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FastboardApp } from "@netless/fastboard-core";
|
|
2
|
+
import type { DivProps, FastboardProps } from "../components/Fastboard";
|
|
3
|
+
|
|
4
|
+
import React from "react";
|
|
5
|
+
import ReactDOM from "react-dom";
|
|
6
|
+
import { Fastboard } from "../components/Fastboard";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Mount fastboard app to some dom, returns the disposer, which will unmount the app.
|
|
10
|
+
* @example
|
|
11
|
+
* let app = await createFastboard({ ...config })
|
|
12
|
+
* let disposer = mount(app, document.getElementById("whiteboard"))
|
|
13
|
+
* disposer()
|
|
14
|
+
*/
|
|
15
|
+
export function mount(app: FastboardApp, dom: HTMLElement, props: Omit<FastboardProps & DivProps, "ref">) {
|
|
16
|
+
ReactDOM.render(<Fastboard app={app} {...props} />, dom);
|
|
17
|
+
return () => ReactDOM.unmountComponentAtNode(dom);
|
|
18
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { FastboardApp } from "@netless/fastboard";
|
|
2
|
-
import type { PropsWithChildren } from "react";
|
|
3
|
-
import type { Language, Theme } from "../typings";
|
|
4
|
-
export interface FastboardProps {
|
|
5
|
-
app?: FastboardApp | null;
|
|
6
|
-
theme?: Theme;
|
|
7
|
-
layout?: {
|
|
8
|
-
Toolbar?: boolean;
|
|
9
|
-
RedoUndo?: boolean;
|
|
10
|
-
ZoomControl?: boolean;
|
|
11
|
-
PageControl?: boolean;
|
|
12
|
-
};
|
|
13
|
-
language?: Language;
|
|
14
|
-
}
|
|
15
|
-
export declare function Fastboard({ app, ...restProps }: PropsWithChildren<FastboardProps>): JSX.Element;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import type { CommonProps, GenericIcon } from "../../typings";
|
|
3
|
-
export declare const name = "fastboard-page-control";
|
|
4
|
-
export declare type PageControlProps = CommonProps & GenericIcon<"add" | "prev" | "next">;
|
|
5
|
-
export declare function PageControl({ theme, addIcon, addIconDisable, prevIcon, prevIconDisable, nextIcon, nextIconDisable, }: PageControlProps): JSX.Element;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Room } from "white-web-sdk";
|
|
2
|
-
import type { WindowManager } from "@netless/window-manager";
|
|
3
|
-
export declare function usePageControl(room?: Room | null, manager?: WindowManager | null): {
|
|
4
|
-
pageIndex: number;
|
|
5
|
-
pageCount: number;
|
|
6
|
-
prevPage: () => void;
|
|
7
|
-
nextPage: () => void;
|
|
8
|
-
addPage: () => Promise<void>;
|
|
9
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import type { Player } from "white-web-sdk";
|
|
3
|
-
import type { CommonProps, GenericIcon } from "../../typings";
|
|
4
|
-
export declare type PlayerControlProps = {
|
|
5
|
-
autoHide?: boolean;
|
|
6
|
-
player?: Player;
|
|
7
|
-
} & Omit<CommonProps, "room"> & GenericIcon<"play" | "pause" | "loading">;
|
|
8
|
-
export declare const name = "fastboard-player-control";
|
|
9
|
-
export declare function PlayerControl({ theme, autoHide, player: player_, ...icons }: PlayerControlProps): JSX.Element;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Player } from "white-web-sdk";
|
|
2
|
-
import { PlayerPhase } from "white-web-sdk";
|
|
3
|
-
export declare function usePlayerControl(player?: Player | null): {
|
|
4
|
-
phase: PlayerPhase;
|
|
5
|
-
currentTime: number;
|
|
6
|
-
totalTime: number;
|
|
7
|
-
speed: number;
|
|
8
|
-
setSpeed: (speed: number) => void;
|
|
9
|
-
togglePlay: () => void;
|
|
10
|
-
seekToProgressTime: (time: number) => void;
|
|
11
|
-
};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
export declare const Icons: {
|
|
3
|
-
Play: import("react").MemoExoticComponent<(props: import("../../..").IconProps) => JSX.Element>;
|
|
4
|
-
Pause: import("react").MemoExoticComponent<(props: import("../../..").IconProps) => JSX.Element>;
|
|
5
|
-
Loading: import("react").MemoExoticComponent<(props: import("../../..").IconProps) => JSX.Element>;
|
|
6
|
-
};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import type { CommonProps, GenericIcon } from "../../typings";
|
|
3
|
-
export declare const name = "fastboard-redo-undo";
|
|
4
|
-
export declare type RedoUndoProps = CommonProps & GenericIcon<"undo" | "redo">;
|
|
5
|
-
export declare function RedoUndo({ theme, undoIcon, undoIconDisable, redoIcon, redoIconDisable }: RedoUndoProps): JSX.Element;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { CommonProps, GenericIcon, Theme } from "../../typings";
|
|
2
|
-
import type { ToolbarHook } from "./hooks";
|
|
3
|
-
import React from "react";
|
|
4
|
-
export declare type ToolbarProps = CommonProps & {
|
|
5
|
-
icons?: GenericIcon<"clicker" | "selector" | "pencil" | "eraser" | "clean" | "expand" | "collapse" | "up" | "down" | "text" | "apps">;
|
|
6
|
-
};
|
|
7
|
-
declare type ToolbarContextType = ToolbarHook & {
|
|
8
|
-
theme: Theme;
|
|
9
|
-
icons?: ToolbarProps["icons"];
|
|
10
|
-
};
|
|
11
|
-
export declare const ToolbarContext: React.Context<ToolbarContextType>;
|
|
12
|
-
export declare const name = "fastboard-toolbar";
|
|
13
|
-
export declare const Toolbar: ({ theme, icons }: ToolbarProps) => JSX.Element;
|
|
14
|
-
export {};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import type { HotKey } from "white-web-sdk";
|
|
3
|
-
export declare function renderToolTip(text: string | undefined, hotkey?: HotKey): string | JSX.Element | undefined;
|
|
4
|
-
export declare function ClickerButton(): JSX.Element;
|
|
5
|
-
export declare function SelectorButton(): JSX.Element;
|
|
6
|
-
export declare function EraserButton(): JSX.Element;
|
|
7
|
-
export declare function CleanButton(): JSX.Element;
|