@netless/fastboard-react 0.1.0
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/LICENSE.txt +21 -0
- package/dist/behaviors/style.d.ts +1 -0
- package/dist/components/Fastboard.d.ts +15 -0
- package/dist/components/PageControl/PageControl.d.ts +5 -0
- package/dist/components/PageControl/hooks.d.ts +9 -0
- package/dist/components/PageControl/index.d.ts +2 -0
- package/dist/components/PlayerControl/PlayerControl.d.ts +9 -0
- package/dist/components/PlayerControl/hooks.d.ts +11 -0
- package/dist/components/PlayerControl/icons/Loading.d.ts +3 -0
- package/dist/components/PlayerControl/icons/Pause.d.ts +3 -0
- package/dist/components/PlayerControl/icons/Play.d.ts +3 -0
- package/dist/components/PlayerControl/icons/index.d.ts +6 -0
- package/dist/components/PlayerControl/index.d.ts +2 -0
- package/dist/components/RedoUndo/RedoUndo.d.ts +5 -0
- package/dist/components/RedoUndo/hooks.d.ts +6 -0
- package/dist/components/RedoUndo/index.d.ts +2 -0
- package/dist/components/Toolbar/Content.d.ts +2 -0
- package/dist/components/Toolbar/Toolbar.d.ts +14 -0
- package/dist/components/Toolbar/components/ApplianceButtons.d.ts +7 -0
- package/dist/components/Toolbar/components/AppsButton.d.ts +6 -0
- package/dist/components/Toolbar/components/ColorBox.d.ts +2 -0
- package/dist/components/Toolbar/components/CutLine.d.ts +2 -0
- package/dist/components/Toolbar/components/Mask.d.ts +7 -0
- package/dist/components/Toolbar/components/PencilButton.d.ts +2 -0
- package/dist/components/Toolbar/components/ShapesButton.d.ts +3 -0
- package/dist/components/Toolbar/components/Slider.d.ts +2 -0
- package/dist/components/Toolbar/components/TextButton.d.ts +2 -0
- package/dist/components/Toolbar/components/UpDownButtons.d.ts +7 -0
- package/dist/components/Toolbar/const.d.ts +18 -0
- package/dist/components/Toolbar/hooks.d.ts +12 -0
- package/dist/components/Toolbar/icons/Apps.d.ts +3 -0
- package/dist/components/Toolbar/icons/Arrow.d.ts +3 -0
- package/dist/components/Toolbar/icons/Circle.d.ts +3 -0
- package/dist/components/Toolbar/icons/Clean.d.ts +3 -0
- package/dist/components/Toolbar/icons/Clicker.d.ts +3 -0
- package/dist/components/Toolbar/icons/Collapse.d.ts +3 -0
- package/dist/components/Toolbar/icons/Diamond.d.ts +3 -0
- package/dist/components/Toolbar/icons/Down.d.ts +3 -0
- package/dist/components/Toolbar/icons/Eraser.d.ts +3 -0
- package/dist/components/Toolbar/icons/Expand.d.ts +3 -0
- package/dist/components/Toolbar/icons/Line.d.ts +3 -0
- package/dist/components/Toolbar/icons/Pencil.d.ts +3 -0
- package/dist/components/Toolbar/icons/Rectangle.d.ts +3 -0
- package/dist/components/Toolbar/icons/Selector.d.ts +3 -0
- package/dist/components/Toolbar/icons/SpeechBalloon.d.ts +3 -0
- package/dist/components/Toolbar/icons/Star.d.ts +3 -0
- package/dist/components/Toolbar/icons/Text.d.ts +3 -0
- package/dist/components/Toolbar/icons/Triangle.d.ts +3 -0
- package/dist/components/Toolbar/icons/Up.d.ts +3 -0
- package/dist/components/Toolbar/icons/index.d.ts +22 -0
- package/dist/components/Toolbar/index.d.ts +2 -0
- package/dist/components/ZoomControl/ZoomControl.d.ts +5 -0
- package/dist/components/ZoomControl/hooks.d.ts +7 -0
- package/dist/components/ZoomControl/index.d.ts +2 -0
- package/dist/components/hooks.d.ts +13 -0
- package/dist/i18n/index.d.ts +12 -0
- package/dist/icons/ChevronLeft.d.ts +3 -0
- package/dist/icons/ChevronRight.d.ts +3 -0
- package/dist/icons/FilePlus.d.ts +3 -0
- package/dist/icons/Minus.d.ts +3 -0
- package/dist/icons/Plus.d.ts +3 -0
- package/dist/icons/Redo.d.ts +3 -0
- package/dist/icons/Reset.d.ts +3 -0
- package/dist/icons/Undo.d.ts +3 -0
- package/dist/icons/index.d.ts +7 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +2116 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2083 -0
- package/dist/index.mjs.map +1 -0
- package/dist/internal/helpers.d.ts +16 -0
- package/dist/internal/hooks.d.ts +3 -0
- package/dist/internal/index.d.ts +2 -0
- package/dist/theme.d.ts +16 -0
- package/dist/typings.d.ts +10 -0
- package/package.json +41 -0
- package/src/behaviors/style.ts +4 -0
- package/src/components/Fastboard.scss +41 -0
- package/src/components/Fastboard.tsx +97 -0
- package/src/components/PageControl/PageControl.scss +80 -0
- package/src/components/PageControl/PageControl.tsx +105 -0
- package/src/components/PageControl/hooks.ts +67 -0
- package/src/components/PageControl/index.ts +2 -0
- package/src/components/PlayerControl/PlayerControl.scss +145 -0
- package/src/components/PlayerControl/PlayerControl.tsx +131 -0
- package/src/components/PlayerControl/components/Button.tsx +45 -0
- package/src/components/PlayerControl/hooks.ts +88 -0
- package/src/components/PlayerControl/icons/Loading.tsx +13 -0
- package/src/components/PlayerControl/icons/Pause.tsx +13 -0
- package/src/components/PlayerControl/icons/Play.tsx +13 -0
- package/src/components/PlayerControl/icons/index.ts +10 -0
- package/src/components/PlayerControl/index.ts +2 -0
- package/src/components/RedoUndo/RedoUndo.scss +56 -0
- package/src/components/RedoUndo/RedoUndo.tsx +76 -0
- package/src/components/RedoUndo/hooks.ts +18 -0
- package/src/components/RedoUndo/index.ts +2 -0
- package/src/components/Toolbar/Content.tsx +74 -0
- package/src/components/Toolbar/Toolbar.scss +281 -0
- package/src/components/Toolbar/Toolbar.tsx +116 -0
- package/src/components/Toolbar/components/ApplianceButtons.tsx +108 -0
- package/src/components/Toolbar/components/AppsButton.tsx +101 -0
- package/src/components/Toolbar/components/Button.tsx +46 -0
- package/src/components/Toolbar/components/ColorBox.tsx +55 -0
- package/src/components/Toolbar/components/CutLine.tsx +8 -0
- package/src/components/Toolbar/components/Mask.tsx +44 -0
- package/src/components/Toolbar/components/PencilButton.tsx +66 -0
- package/src/components/Toolbar/components/ShapesButton.tsx +128 -0
- package/src/components/Toolbar/components/Slider.tsx +26 -0
- package/src/components/Toolbar/components/TextButton.tsx +62 -0
- package/src/components/Toolbar/components/UpDownButtons.tsx +49 -0
- package/src/components/Toolbar/components/assets/cocos.png +0 -0
- package/src/components/Toolbar/components/assets/collapsed.png +0 -0
- package/src/components/Toolbar/components/assets/countdown.png +0 -0
- package/src/components/Toolbar/components/assets/expanded.png +0 -0
- package/src/components/Toolbar/components/assets/geogebra.png +0 -0
- package/src/components/Toolbar/components/assets/vscode.png +0 -0
- package/src/components/Toolbar/const.ts +32 -0
- package/src/components/Toolbar/hooks.ts +68 -0
- package/src/components/Toolbar/icons/Apps.tsx +16 -0
- package/src/components/Toolbar/icons/Arrow.tsx +13 -0
- package/src/components/Toolbar/icons/Circle.tsx +13 -0
- package/src/components/Toolbar/icons/Clean.tsx +16 -0
- package/src/components/Toolbar/icons/Clicker.tsx +19 -0
- package/src/components/Toolbar/icons/Collapse.tsx +13 -0
- package/src/components/Toolbar/icons/Diamond.tsx +13 -0
- package/src/components/Toolbar/icons/Down.tsx +13 -0
- package/src/components/Toolbar/icons/Eraser.tsx +16 -0
- package/src/components/Toolbar/icons/Expand.tsx +13 -0
- package/src/components/Toolbar/icons/Line.tsx +13 -0
- package/src/components/Toolbar/icons/Pencil.tsx +16 -0
- package/src/components/Toolbar/icons/Rectangle.tsx +13 -0
- package/src/components/Toolbar/icons/Selector.tsx +13 -0
- package/src/components/Toolbar/icons/SpeechBalloon.tsx +17 -0
- package/src/components/Toolbar/icons/Star.tsx +17 -0
- package/src/components/Toolbar/icons/Text.tsx +13 -0
- package/src/components/Toolbar/icons/Triangle.tsx +13 -0
- package/src/components/Toolbar/icons/Up.tsx +13 -0
- package/src/components/Toolbar/icons/index.ts +42 -0
- package/src/components/Toolbar/index.ts +2 -0
- package/src/components/ZoomControl/ZoomControl.scss +80 -0
- package/src/components/ZoomControl/ZoomControl.tsx +94 -0
- package/src/components/ZoomControl/hooks.ts +52 -0
- package/src/components/ZoomControl/index.ts +2 -0
- package/src/components/hooks.ts +59 -0
- package/src/i18n/en.json +31 -0
- package/src/i18n/index.ts +29 -0
- package/src/i18n/zh-CN.json +32 -0
- package/src/icons/ChevronLeft.tsx +21 -0
- package/src/icons/ChevronRight.tsx +21 -0
- package/src/icons/FilePlus.tsx +18 -0
- package/src/icons/Minus.tsx +15 -0
- package/src/icons/Plus.tsx +15 -0
- package/src/icons/Redo.tsx +18 -0
- package/src/icons/Reset.tsx +19 -0
- package/src/icons/Undo.tsx +18 -0
- package/src/icons/index.tsx +11 -0
- package/src/index.ts +10 -0
- package/src/internal/helpers.ts +31 -0
- package/src/internal/hooks.ts +23 -0
- package/src/internal/index.ts +2 -0
- package/src/style.scss +29 -0
- package/src/theme.ts +36 -0
- package/src/typings.ts +15 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { FastboardApp, FastboardReadable } from "@netless/fastboard";
|
|
2
|
+
import type { Theme } from "../typings";
|
|
3
|
+
|
|
4
|
+
import { BuiltinApps } from "@netless/window-manager";
|
|
5
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
6
|
+
|
|
7
|
+
export const FastboardAppContext = /* @__PURE__ */ createContext<FastboardApp | null>(null);
|
|
8
|
+
|
|
9
|
+
export const ThemeContext = /* @__PURE__ */ createContext<Theme>("light");
|
|
10
|
+
|
|
11
|
+
export function useTheme(userTheme?: Theme | null) {
|
|
12
|
+
const themeFromContext = useContext(ThemeContext);
|
|
13
|
+
return userTheme || themeFromContext;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function useFastboardApp() {
|
|
17
|
+
const app = useContext(FastboardAppContext);
|
|
18
|
+
if (!app) {
|
|
19
|
+
throw new Error("useFastboardApp() can only be called inside of <Fastboard>");
|
|
20
|
+
}
|
|
21
|
+
return app;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function useFastboardValue<T>(val: FastboardReadable<T>) {
|
|
25
|
+
const [value, setValue] = useState(val.value);
|
|
26
|
+
useEffect(() => val.subscribe(setValue), [val]);
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function useWritable() {
|
|
31
|
+
return useFastboardValue(useFastboardApp().writable);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function useBoxState() {
|
|
35
|
+
return useFastboardValue(useFastboardApp().boxState);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function useFocusedApp() {
|
|
39
|
+
return useFastboardValue(useFastboardApp().focusedApp);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function useMaximized() {
|
|
43
|
+
return useBoxState() === "maximized";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function useHideControls() {
|
|
47
|
+
const maximized = useMaximized();
|
|
48
|
+
const focusedApp = useFocusedApp();
|
|
49
|
+
|
|
50
|
+
if (maximized) {
|
|
51
|
+
if (Object.values(BuiltinApps).some(kind => focusedApp?.includes(kind))) {
|
|
52
|
+
return "toolbar-only";
|
|
53
|
+
} else {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return false;
|
|
59
|
+
}
|
package/src/i18n/en.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"translation": {
|
|
3
|
+
"clicker": "clicker",
|
|
4
|
+
"selector": "selector",
|
|
5
|
+
"text": "text",
|
|
6
|
+
"pencil": "pencil",
|
|
7
|
+
"arrow": "arrow",
|
|
8
|
+
"hand": "hand",
|
|
9
|
+
"eraser": "eraser",
|
|
10
|
+
"laser": "laser",
|
|
11
|
+
"collapse": "Collapse",
|
|
12
|
+
"expand": "Expand",
|
|
13
|
+
"zoomIn": "Zoom In",
|
|
14
|
+
"zoomOut": "Zoom Out",
|
|
15
|
+
"reset": "Reset",
|
|
16
|
+
"prevPage": "Prev Page",
|
|
17
|
+
"nextPage": "Next Page",
|
|
18
|
+
"addPage": "Add Page",
|
|
19
|
+
"redo": "Redo",
|
|
20
|
+
"undo": "Undo",
|
|
21
|
+
"shape": "Shape",
|
|
22
|
+
"triangle": "Triangle",
|
|
23
|
+
"rhombus": "Rhombus",
|
|
24
|
+
"pentagram": "Pentagram",
|
|
25
|
+
"speechBalloon": "Speech Balloon",
|
|
26
|
+
"rectangle": "Rectangle",
|
|
27
|
+
"ellipse": "Ellipse",
|
|
28
|
+
"straight": "Straight",
|
|
29
|
+
"speed": "Speed"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { i18n } from "i18next";
|
|
2
|
+
import type { Language } from "../typings";
|
|
3
|
+
|
|
4
|
+
import { createContext, useContext, useMemo } from "react";
|
|
5
|
+
import i18next from "i18next";
|
|
6
|
+
import en from "./en.json";
|
|
7
|
+
import zhCN from "./zh-CN.json";
|
|
8
|
+
|
|
9
|
+
export interface CreateI18nParams {
|
|
10
|
+
language?: Language;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const createI18n = async ({
|
|
14
|
+
language = (navigator.language as Language) || "zh-CN",
|
|
15
|
+
}: CreateI18nParams = {}) => {
|
|
16
|
+
await i18next.init({
|
|
17
|
+
lng: language,
|
|
18
|
+
resources: { en, "zh-CN": zhCN },
|
|
19
|
+
});
|
|
20
|
+
return i18next;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const I18nContext = /* @__PURE__ */ createContext<i18n | null>(null);
|
|
24
|
+
|
|
25
|
+
export function useTranslation() {
|
|
26
|
+
const i18n = useContext(I18nContext);
|
|
27
|
+
const t = useMemo(() => (i18n ? i18n.getFixedT(null, ["translation"]) : (id: string) => id), [i18n]);
|
|
28
|
+
return { t, i18n };
|
|
29
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"translation": {
|
|
3
|
+
"clicker": "点击",
|
|
4
|
+
"selector": "选择",
|
|
5
|
+
"text": "文字",
|
|
6
|
+
"pencil": "铅笔",
|
|
7
|
+
"arrow": "箭头",
|
|
8
|
+
"hand": "抓手",
|
|
9
|
+
"eraser": "橡皮",
|
|
10
|
+
"laser": "激光笔",
|
|
11
|
+
"zoomIn": "放大",
|
|
12
|
+
"zoomOut": "缩小",
|
|
13
|
+
"reset": "重置",
|
|
14
|
+
"prevPage": "上一页",
|
|
15
|
+
"nextPage": "下一页",
|
|
16
|
+
"addPage": "添加页面",
|
|
17
|
+
"redo": "重做",
|
|
18
|
+
"undo": "撤销",
|
|
19
|
+
"collapse": "收起",
|
|
20
|
+
"expand": "展开",
|
|
21
|
+
"clean": "清屏",
|
|
22
|
+
"shape": "形状",
|
|
23
|
+
"triangle": "三角形",
|
|
24
|
+
"rhombus": "菱形",
|
|
25
|
+
"pentagram": "五角星",
|
|
26
|
+
"speechBalloon": "气球",
|
|
27
|
+
"rectangle": "矩形",
|
|
28
|
+
"ellipse": "椭圆",
|
|
29
|
+
"straight": "直线",
|
|
30
|
+
"speed": "速度"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function ChevronLeft({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<path
|
|
13
|
+
fill="none"
|
|
14
|
+
stroke={stroke}
|
|
15
|
+
strokeLinecap="round"
|
|
16
|
+
strokeLinejoin="round"
|
|
17
|
+
d="m14 16-2-2-2-2 2-2 2-2"
|
|
18
|
+
/>
|
|
19
|
+
</svg>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function ChevronRight({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<path
|
|
13
|
+
fill="none"
|
|
14
|
+
stroke={stroke}
|
|
15
|
+
strokeLinecap="round"
|
|
16
|
+
strokeLinejoin="round"
|
|
17
|
+
d="m10 16 2-2 2-2-2-2-2-2"
|
|
18
|
+
/>
|
|
19
|
+
</svg>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function FilePlus({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<path
|
|
13
|
+
fill={stroke}
|
|
14
|
+
d="M12 7.5a.5.5 0 0 1 .09.992L12 8.5H8a1.5 1.5 0 0 0-1.493 1.356L6.5 10v6a1.5 1.5 0 0 0 1.356 1.493L8 17.5h6a1.5 1.5 0 0 0 1.493-1.356L15.5 16v-4a.5.5 0 0 1 .992-.09l.008.09v4a2.5 2.5 0 0 1-2.336 2.495L14 18.5H8a2.5 2.5 0 0 1-2.495-2.336L5.5 16v-6a2.5 2.5 0 0 1 2.336-2.495L8 7.5h4Zm4-2a.5.5 0 0 1 .492.41L16.5 6v1.5H18a.5.5 0 0 1 .09.992L18 8.5h-1.5V10a.5.5 0 0 1-.992.09L15.5 10V8.5H14a.5.5 0 0 1-.09-.992L14 7.5h1.5V6a.5.5 0 0 1 .5-.5Z"
|
|
15
|
+
/>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function Minus({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<path fill="none" stroke={stroke} strokeLinecap="round" strokeLinejoin="round" d="M7 12h10" />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function Plus({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<path fill="none" stroke={stroke} strokeLinecap="round" strokeLinejoin="round" d="M12 7v10m-5-5h10" />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function Redo({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<g fill="none" fillRule="evenodd" stroke={stroke} strokeLinecap="round" strokeLinejoin="round">
|
|
13
|
+
<path d="M14 14h4v-4" />
|
|
14
|
+
<path d="m18 14-.788-.9A7.005 7.005 0 0 0 6 14h0" />
|
|
15
|
+
</g>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function Reset({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<g fill="none" fillRule="evenodd" transform="translate(-176 -684)">
|
|
13
|
+
<path stroke={stroke} strokeLinejoin="round" d="M188 688v4m0 8v4m8-8h-4m-8 0h-4" />
|
|
14
|
+
<circle cx="188" cy="696" r="6" stroke={stroke} />
|
|
15
|
+
<circle cx="188" cy="696" r="1" fill={stroke} />
|
|
16
|
+
</g>
|
|
17
|
+
</svg>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IconProps } from "../typings";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { themes } from "../theme";
|
|
5
|
+
|
|
6
|
+
export function Undo({ theme = "light", active }: IconProps) {
|
|
7
|
+
const config = themes[theme];
|
|
8
|
+
const stroke = active ? config.activeColor : config.color;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 24 24">
|
|
12
|
+
<g fill="none" fillRule="evenodd" stroke={stroke} strokeLinecap="round" strokeLinejoin="round">
|
|
13
|
+
<path d="M10 14H6v-4" />
|
|
14
|
+
<path d="m6 14 .788-.9A7.005 7.005 0 0 1 18 14h0" />
|
|
15
|
+
</g>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export interface IconPropsWithFallback {
|
|
4
|
+
fallback: React.ReactElement;
|
|
5
|
+
src?: string;
|
|
6
|
+
alt?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function Icon({ fallback, src, alt = "[icon]" }: IconPropsWithFallback) {
|
|
10
|
+
return src ? <img src={src} alt={alt} title={alt} /> : fallback;
|
|
11
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "./behaviors/style";
|
|
2
|
+
|
|
3
|
+
export * from "./typings";
|
|
4
|
+
export * from "./components/hooks";
|
|
5
|
+
export * from "./components/RedoUndo";
|
|
6
|
+
export * from "./components/ZoomControl";
|
|
7
|
+
export * from "./components/PageControl";
|
|
8
|
+
export * from "./components/Toolbar";
|
|
9
|
+
export * from "./components/PlayerControl";
|
|
10
|
+
export * from "./components/Fastboard";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function noop() {
|
|
2
|
+
return;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function applyStyles(css: string) {
|
|
6
|
+
const el = document.createElement("style");
|
|
7
|
+
el.appendChild(document.createTextNode(css));
|
|
8
|
+
document.head.appendChild(el);
|
|
9
|
+
return el;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function clamp(value: number, min: number, max: number) {
|
|
13
|
+
return value < min ? min : value > max ? max : value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function isEqualArray<T>(a: T[], b: T[]) {
|
|
17
|
+
return a.length === b.length && a.every((e, i) => e === b[i]);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const defaultHotKeys = {
|
|
21
|
+
changeToSelector: "s",
|
|
22
|
+
changeToLaserPointer: "z",
|
|
23
|
+
changeToPencil: "p",
|
|
24
|
+
changeToRectangle: "r",
|
|
25
|
+
changeToEllipse: "c",
|
|
26
|
+
changeToEraser: "e",
|
|
27
|
+
changeToText: "t",
|
|
28
|
+
changeToStraight: "l",
|
|
29
|
+
changeToArrow: "a",
|
|
30
|
+
changeToHand: "h",
|
|
31
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
|
|
3
|
+
export function useLastValue<T>(value: T) {
|
|
4
|
+
const ref = useRef<T>(value);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
ref.current = value;
|
|
7
|
+
}, [value]);
|
|
8
|
+
return ref.current;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function useAsyncValue<T>(fn: () => Promise<T>) {
|
|
12
|
+
const [value, setValue] = useState<T | null>(null);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
fn().then(setValue);
|
|
15
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
16
|
+
}, []);
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function useForceUpdate() {
|
|
21
|
+
const [, forceUpdate] = useState({});
|
|
22
|
+
return useCallback(() => forceUpdate({}), []);
|
|
23
|
+
}
|
package/src/style.scss
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
@import "@netless/window-manager/dist/style.css";
|
|
2
|
+
@import "tippy.js/dist/tippy.css";
|
|
3
|
+
@import "tippy.js/themes/light.css";
|
|
4
|
+
@import "rc-slider/assets/index.css";
|
|
5
|
+
@import "./components/Fastboard.scss";
|
|
6
|
+
@import "./components/RedoUndo/RedoUndo.scss";
|
|
7
|
+
@import "./components/PageControl/PageControl.scss";
|
|
8
|
+
@import "./components/ZoomControl/ZoomControl.scss";
|
|
9
|
+
@import "./components/Toolbar/Toolbar.scss";
|
|
10
|
+
@import "./components/PlayerControl/PlayerControl.scss";
|
|
11
|
+
|
|
12
|
+
.tippy-box.fastboard-tip {
|
|
13
|
+
color: #eee;
|
|
14
|
+
background-color: rgba($color: #000000, $alpha: 0.95);
|
|
15
|
+
backdrop-filter: blur(2px);
|
|
16
|
+
-webkit-backdrop-filter: blur(2px);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.tippy-box.fastboard-tip[data-placement^="right"] > .tippy-arrow::before {
|
|
20
|
+
top: 4px;
|
|
21
|
+
border-width: 4px;
|
|
22
|
+
border-right-color: #000;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.tippy-box.fastboard-tip[data-placement^="top"] > .tippy-arrow::before {
|
|
26
|
+
left: 4px;
|
|
27
|
+
border-width: 4px;
|
|
28
|
+
border-top-color: #000;
|
|
29
|
+
}
|
package/src/theme.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IconProps } from "./typings";
|
|
2
|
+
|
|
3
|
+
export interface ThemeConfig {
|
|
4
|
+
color: string;
|
|
5
|
+
activeColor: string;
|
|
6
|
+
backgroundColor: string;
|
|
7
|
+
hoverBackgroundColor: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const light: ThemeConfig = {
|
|
11
|
+
color: "#5D5D5D",
|
|
12
|
+
activeColor: "#3381FF",
|
|
13
|
+
backgroundColor: "#fff",
|
|
14
|
+
hoverBackgroundColor: "rgba(51, 129, 255, 0.1)",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const dark: ThemeConfig = {
|
|
18
|
+
...light,
|
|
19
|
+
color: "#eee",
|
|
20
|
+
backgroundColor: "#111",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const themes = { light, dark };
|
|
24
|
+
|
|
25
|
+
export const getStroke = (props: IconProps) => {
|
|
26
|
+
let config;
|
|
27
|
+
if (props.theme) {
|
|
28
|
+
config = themes[props.theme];
|
|
29
|
+
} else {
|
|
30
|
+
config = themes.light;
|
|
31
|
+
}
|
|
32
|
+
return props.active ? config.activeColor : config.color;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const TopOffset = [0, 11] as [number, number];
|
|
36
|
+
export const RightOffset = [0, 11] as [number, number];
|
package/src/typings.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type Theme = "light" | "dark";
|
|
2
|
+
export type Language = "en" | "zh-CN";
|
|
3
|
+
|
|
4
|
+
export interface IconProps {
|
|
5
|
+
theme?: Theme;
|
|
6
|
+
active?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CommonProps {
|
|
10
|
+
theme?: Theme;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type GenericIcon<K extends string, E extends string = "disable"> = Partial<
|
|
14
|
+
Record<`${K}Icon${Capitalize<E | "">}`, string>
|
|
15
|
+
>;
|