@netless/fastboard-ui 0.3.0-canary.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.
Files changed (111) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +7 -0
  3. package/dist/index.d.ts +92 -0
  4. package/dist/index.js +10143 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +10114 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/index.svelte.mjs +10368 -0
  9. package/dist/index.svelte.mjs.map +1 -0
  10. package/package.json +31 -0
  11. package/src/actions/height.ts +43 -0
  12. package/src/actions/scroll.ts +31 -0
  13. package/src/actions/tippy.ts +70 -0
  14. package/src/behaviors/icons/countdown.svg +1 -0
  15. package/src/behaviors/icons/geogebra.svg +1 -0
  16. package/src/behaviors/icons/visual-studio-code.svg +1 -0
  17. package/src/behaviors/index.ts +68 -0
  18. package/src/components/Button/Button.svelte +51 -0
  19. package/src/components/Button/Button.svelte.d.ts +26 -0
  20. package/src/components/Button/index.ts +2 -0
  21. package/src/components/Fastboard/Fastboard.scss +49 -0
  22. package/src/components/Fastboard/Fastboard.svelte +32 -0
  23. package/src/components/Fastboard/Fastboard.svelte.ts +12 -0
  24. package/src/components/Fastboard/ReplayFastboard.svelte +22 -0
  25. package/src/components/Fastboard/ReplayFastboard.svelte.ts +12 -0
  26. package/src/components/Fastboard/index.ts +5 -0
  27. package/src/components/Icon/Icon.svelte +11 -0
  28. package/src/components/Icon/Icon.svelte.d.ts +10 -0
  29. package/src/components/Icon/index.ts +2 -0
  30. package/src/components/Icons/Apps.svelte +49 -0
  31. package/src/components/Icons/Arrow.svelte +16 -0
  32. package/src/components/Icons/ArrowBolded.svelte +17 -0
  33. package/src/components/Icons/Balloon.svelte +16 -0
  34. package/src/components/Icons/BalloonBolded.svelte +16 -0
  35. package/src/components/Icons/Circle.svelte +20 -0
  36. package/src/components/Icons/CircleBolded.svelte +20 -0
  37. package/src/components/Icons/Clean.svelte +14 -0
  38. package/src/components/Icons/Clear.svelte +16 -0
  39. package/src/components/Icons/Click.svelte +16 -0
  40. package/src/components/Icons/ClickFilled.svelte +10 -0
  41. package/src/components/Icons/Diamond.svelte +16 -0
  42. package/src/components/Icons/Down.svelte +16 -0
  43. package/src/components/Icons/Eraser.svelte +16 -0
  44. package/src/components/Icons/EraserFilled.svelte +16 -0
  45. package/src/components/Icons/Icons.scss +20 -0
  46. package/src/components/Icons/Left.svelte +16 -0
  47. package/src/components/Icons/Line.svelte +16 -0
  48. package/src/components/Icons/LineBolded.svelte +16 -0
  49. package/src/components/Icons/Loading.svelte +10 -0
  50. package/src/components/Icons/Minus.svelte +16 -0
  51. package/src/components/Icons/Pause.svelte +10 -0
  52. package/src/components/Icons/Pencil.svelte +29 -0
  53. package/src/components/Icons/PencilFilled.svelte +16 -0
  54. package/src/components/Icons/Play.svelte +10 -0
  55. package/src/components/Icons/Plus.svelte +16 -0
  56. package/src/components/Icons/Rectangle.svelte +16 -0
  57. package/src/components/Icons/RectangleBolded.svelte +16 -0
  58. package/src/components/Icons/Redo.svelte +15 -0
  59. package/src/components/Icons/Reset.svelte +26 -0
  60. package/src/components/Icons/Rhombus.svelte +16 -0
  61. package/src/components/Icons/RhombusBolded.svelte +16 -0
  62. package/src/components/Icons/Right.svelte +16 -0
  63. package/src/components/Icons/Selector.svelte +24 -0
  64. package/src/components/Icons/SelectorFilled.svelte +18 -0
  65. package/src/components/Icons/SpeechBalloon.svelte +16 -0
  66. package/src/components/Icons/Star.svelte +16 -0
  67. package/src/components/Icons/StarBolded.svelte +16 -0
  68. package/src/components/Icons/Text.svelte +16 -0
  69. package/src/components/Icons/TextFilled.svelte +17 -0
  70. package/src/components/Icons/Triangle.svelte +16 -0
  71. package/src/components/Icons/TriangleBolded.svelte +16 -0
  72. package/src/components/Icons/Undo.svelte +15 -0
  73. package/src/components/Icons/Up.svelte +16 -0
  74. package/src/components/Icons/WhiteboardAdd.svelte +34 -0
  75. package/src/components/Icons/index.ts +93 -0
  76. package/src/components/PageControl/PageControl.scss +15 -0
  77. package/src/components/PageControl/PageControl.svelte +78 -0
  78. package/src/components/PageControl/PageControl.svelte.d.ts +13 -0
  79. package/src/components/PageControl/index.ts +2 -0
  80. package/src/components/PlayerControl/PlayerControl.scss +57 -0
  81. package/src/components/PlayerControl/PlayerControl.svelte +153 -0
  82. package/src/components/PlayerControl/PlayerControl.svelte.d.ts +13 -0
  83. package/src/components/PlayerControl/index.ts +2 -0
  84. package/src/components/RedoUndo/RedoUndo.scss +11 -0
  85. package/src/components/RedoUndo/RedoUndo.svelte +60 -0
  86. package/src/components/RedoUndo/RedoUndo.svelte.d.ts +13 -0
  87. package/src/components/RedoUndo/index.ts +2 -0
  88. package/src/components/Toolbar/README.md +57 -0
  89. package/src/components/Toolbar/Toolbar.scss +69 -0
  90. package/src/components/Toolbar/Toolbar.svelte +50 -0
  91. package/src/components/Toolbar/Toolbar.svelte.d.ts +12 -0
  92. package/src/components/Toolbar/components/Contents.scss +166 -0
  93. package/src/components/Toolbar/components/Contents.svelte +191 -0
  94. package/src/components/Toolbar/components/Shapes.svelte +85 -0
  95. package/src/components/Toolbar/components/Slider.scss +119 -0
  96. package/src/components/Toolbar/components/Slider.svelte +54 -0
  97. package/src/components/Toolbar/components/StrokeColor.svelte +39 -0
  98. package/src/components/Toolbar/components/StrokeWidth.svelte +20 -0
  99. package/src/components/Toolbar/components/constants.ts +80 -0
  100. package/src/components/Toolbar/components/helper.ts +24 -0
  101. package/src/components/Toolbar/index.ts +2 -0
  102. package/src/components/ZoomControl/ZoomControl.scss +15 -0
  103. package/src/components/ZoomControl/ZoomControl.svelte +99 -0
  104. package/src/components/ZoomControl/ZoomControl.svelte.d.ts +13 -0
  105. package/src/components/ZoomControl/index.ts +2 -0
  106. package/src/components/helpers.ts +3 -0
  107. package/src/components/theme.scss +91 -0
  108. package/src/components/variables.scss +69 -0
  109. package/src/index.ts +13 -0
  110. package/src/style.scss +36 -0
  111. package/src/typings.ts +17 -0
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@netless/fastboard-ui",
3
+ "version": "0.3.0-canary.0",
4
+ "description": "The front-end of @netless/fastboard-core.",
5
+ "main": "dist/index.js",
6
+ "svelte": "dist/index.svelte.mjs",
7
+ "files": [
8
+ "src",
9
+ "dist"
10
+ ],
11
+ "peerDependencies": {
12
+ "@netless/fastboard-core": "0.3.0-canary.0"
13
+ },
14
+ "dependencies": {
15
+ "tippy.js": "^6.3.7"
16
+ },
17
+ "devDependencies": {
18
+ "@netless/esbuild-plugin-inline-sass": "0.1.0",
19
+ "@netless/fastboard-core": "0.3.0-canary.0"
20
+ },
21
+ "scripts": {
22
+ "cleanup": "rimraf dist",
23
+ "check": "tsc --noEmit",
24
+ "build": "tsup",
25
+ "dev": "vite",
26
+ "test:ssr": "esbuild-dev test/ssr.ts"
27
+ },
28
+ "module": "dist/index.mjs",
29
+ "types": "dist/index.d.ts",
30
+ "readme": "## @netless/fastboard-ui\n\nThe front-end of [@netless/fastboard-core](https://github.com/netless-io/fastboard/tree/main/packages/fastboard-core).\n\n### License\n\nMIT @ [netless](https://github.com/netless-io)\n"
31
+ }
@@ -0,0 +1,43 @@
1
+ import type { Writable } from "svelte/store";
2
+ import type { SvelteAction } from "../typings";
3
+
4
+ export const height: SvelteAction<Writable<number>> = function (node, height) {
5
+ const styles = getComputedStyle(node);
6
+ const paddings =
7
+ (parseInt(styles.paddingTop) || 0) +
8
+ (parseInt(styles.paddingBottom) || 0) +
9
+ (parseInt(styles.borderTopWidth) || 0) +
10
+ (parseInt(styles.borderBottomWidth) || 0);
11
+
12
+ const observer = new ResizeObserver(() => {
13
+ height.set(node.getBoundingClientRect().height - paddings);
14
+ });
15
+
16
+ observer.observe(node);
17
+
18
+ return {
19
+ update(new_height) {
20
+ height = new_height;
21
+ },
22
+ destroy() {
23
+ observer.disconnect();
24
+ },
25
+ };
26
+ };
27
+
28
+ export const scrollHeight: SvelteAction<Writable<number>> = function (node, height) {
29
+ const observer = new ResizeObserver(() => {
30
+ height.set(node.scrollHeight);
31
+ });
32
+
33
+ observer.observe(node);
34
+
35
+ return {
36
+ update(new_height) {
37
+ height = new_height;
38
+ },
39
+ destroy() {
40
+ observer.disconnect();
41
+ },
42
+ };
43
+ };
@@ -0,0 +1,31 @@
1
+ import type { Writable } from "svelte/store";
2
+ import type { SvelteAction } from "../typings";
3
+
4
+ export const scrollTop: SvelteAction<Writable<number>> = function (node, value) {
5
+ const listener = (top: number) => {
6
+ node.scrollTo({ top, behavior: "smooth" });
7
+ };
8
+
9
+ let timer = 0;
10
+
11
+ function on_scroll() {
12
+ clearTimeout(timer);
13
+ timer = setTimeout(() => value.set(node.scrollTop), 200);
14
+ }
15
+
16
+ node.addEventListener("scroll", on_scroll);
17
+
18
+ let unsubscribe = value.subscribe(listener);
19
+
20
+ return {
21
+ update(new_value) {
22
+ unsubscribe();
23
+ unsubscribe = (value = new_value).subscribe(listener);
24
+ },
25
+ destroy() {
26
+ clearTimeout(timer);
27
+ node.removeEventListener("scroll", on_scroll);
28
+ unsubscribe();
29
+ },
30
+ };
31
+ };
@@ -0,0 +1,70 @@
1
+ import type { Instance, Props } from "tippy.js";
2
+ import type { SvelteAction } from "../typings";
3
+ import { is_client } from "svelte/internal";
4
+
5
+ import Tippy from "tippy.js";
6
+
7
+ if (is_client) {
8
+ Tippy.setDefaultProps({
9
+ delay: [1000, 400],
10
+ duration: 300,
11
+ offset: [0, 11],
12
+ theme: "dark",
13
+ plugins: [
14
+ {
15
+ name: "className",
16
+ defaultValue: "",
17
+ fn(instance) {
18
+ function add() {
19
+ const el = instance.popper.firstElementChild;
20
+ if (el) {
21
+ el.classList.add("fastboard-tip");
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ const extra = ((instance.props as any).className || "").trim();
24
+ if (extra) {
25
+ el.classList.add(extra);
26
+ }
27
+ }
28
+ }
29
+
30
+ function remove() {
31
+ instance.popper.firstElementChild?.classList.remove("fastboard-tip");
32
+ }
33
+
34
+ return {
35
+ onCreate: add,
36
+ onBeforeUpdate: remove,
37
+ onAfterUpdate: add,
38
+ };
39
+ },
40
+ },
41
+ ],
42
+ });
43
+ }
44
+
45
+ export const tippy: SvelteAction<Partial<Props & { className: string }>> = function (node, props) {
46
+ const instance = Tippy(node, props);
47
+
48
+ return {
49
+ update(props: Partial<Props & { className: string }>) {
50
+ instance.setProps(props);
51
+ },
52
+ destroy() {
53
+ instance.destroy();
54
+ },
55
+ };
56
+ };
57
+
58
+ export function tippy_hide_all() {
59
+ document.querySelectorAll("[data-tippy-root]").forEach(el => {
60
+ const instance = (el as unknown as { _tippy: Instance })._tippy;
61
+ if (instance) instance.hide();
62
+ });
63
+ }
64
+
65
+ export const tippy_menu: Partial<Props> = {
66
+ delay: 0,
67
+ placement: "right-start",
68
+ interactive: true,
69
+ trigger: "click",
70
+ };
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--radix-icons" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 15 15"><path fill="grey" fill-rule="evenodd" d="M13.15 7.5c0-2.835-2.21-5.65-5.65-5.65c-2.778 0-4.151 2.056-4.737 3.15H4.5a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5v-3a.5.5 0 0 1 1 0v1.813C2.705 3.071 4.334.85 7.5.85c4.063 0 6.65 3.335 6.65 6.65c0 3.315-2.587 6.65-6.65 6.65c-1.944 0-3.562-.77-4.715-1.942a6.772 6.772 0 0 1-1.427-2.167a.5.5 0 1 1 .925-.38c.28.681.692 1.314 1.216 1.846c.972.99 2.336 1.643 4.001 1.643c3.44 0 5.65-2.815 5.65-5.65ZM7 10V5h1v5H7Z" clip-rule="evenodd"></path></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--arcticons" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 48 48"><path fill="none" stroke="#6557d2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M24 3a4.77 4.77 0 1 0 4.77 4.77A4.78 4.78 0 0 0 24 3ZM7.69 14.86a4.77 4.77 0 1 0 4.76 4.77a4.76 4.76 0 0 0-4.76-4.77Zm32.64 0a4.77 4.77 0 1 0 4.77 4.77a4.77 4.77 0 0 0-4.77-4.77ZM13.92 34.05a4.77 4.77 0 1 0 4.77 4.77a4.76 4.76 0 0 0-4.77-4.77Zm20.18 0a4.77 4.77 0 1 0 4.76 4.77a4.76 4.76 0 0 0-4.76-4.77Z"></path><path fill="none" stroke="#6557d2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M19.27 8.35a17.24 17.24 0 0 0-9.73 6.87m28.51.22a17.28 17.28 0 0 0-9.34-6.94m8.7 26.89A17.09 17.09 0 0 0 40.93 25v-.61M18 41.22a17.23 17.23 0 0 0 5.68 1a17 17 0 0 0 6.2-1.22M6.53 24.25v.72a17.16 17.16 0 0 0 3.77 10.76"></path></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1.01em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 254" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);"><defs><linearGradient id="IconifyId-17f872155be-cc766e-5439" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#FFF"/><stop offset="100%" stop-color="#FFF" stop-opacity="0"/></linearGradient><path id="IconifyId-17f872155be-cc766e-5440" d="M180.828 252.605a15.872 15.872 0 0 0 12.65-.486l52.501-25.262a15.94 15.94 0 0 0 9.025-14.364V41.197a15.939 15.939 0 0 0-9.025-14.363l-52.5-25.263a15.877 15.877 0 0 0-18.115 3.084L74.857 96.35l-43.78-33.232a10.614 10.614 0 0 0-13.56.603L3.476 76.494c-4.63 4.211-4.635 11.495-.012 15.713l37.967 34.638l-37.967 34.637c-4.623 4.219-4.618 11.502.012 15.714l14.041 12.772a10.614 10.614 0 0 0 13.56.604l43.78-33.233l100.507 91.695a15.853 15.853 0 0 0 5.464 3.571Zm10.464-183.649l-76.262 57.889l76.262 57.888V68.956Z"/></defs><mask id="IconifyId-17f872155be-cc766e-5441" fill="#fff"><use href="#IconifyId-17f872155be-cc766e-5440"/></mask><path fill="#0065A9" d="M246.135 26.873L193.593 1.575a15.885 15.885 0 0 0-18.123 3.08L3.466 161.482c-4.626 4.219-4.62 11.502.012 15.714l14.05 12.772a10.625 10.625 0 0 0 13.569.604L238.229 33.436c6.949-5.271 16.93-.315 16.93 8.407v-.61a15.938 15.938 0 0 0-9.024-14.36Z" mask="url(#IconifyId-17f872155be-cc766e-5441)"/><path fill="#007ACC" d="m246.135 226.816l-52.542 25.298a15.887 15.887 0 0 1-18.123-3.08L3.466 92.207c-4.626-4.218-4.62-11.502.012-15.713l14.05-12.773a10.625 10.625 0 0 1 13.569-.603l207.132 157.135c6.949 5.271 16.93.315 16.93-8.408v.611a15.939 15.939 0 0 1-9.024 14.36Z" mask="url(#IconifyId-17f872155be-cc766e-5441)"/><path fill="#1F9CF0" d="M193.428 252.134a15.892 15.892 0 0 1-18.125-3.083c5.881 5.88 15.938 1.715 15.938-6.603V11.273c0-8.318-10.057-12.483-15.938-6.602a15.892 15.892 0 0 1 18.125-3.084l52.533 25.263a15.937 15.937 0 0 1 9.03 14.363V212.51c0 6.125-3.51 11.709-9.03 14.363l-52.533 25.262Z" mask="url(#IconifyId-17f872155be-cc766e-5441)"/><path fill="url(#IconifyId-17f872155be-cc766e-5439)" fill-opacity=".25" d="M180.828 252.605a15.874 15.874 0 0 0 12.65-.486l52.5-25.263a15.938 15.938 0 0 0 9.026-14.363V41.197a15.939 15.939 0 0 0-9.025-14.363L193.477 1.57a15.877 15.877 0 0 0-18.114 3.084L74.857 96.35l-43.78-33.232a10.614 10.614 0 0 0-13.56.603L3.476 76.494c-4.63 4.211-4.635 11.495-.012 15.713l37.967 34.638l-37.967 34.637c-4.623 4.219-4.618 11.502.012 15.714l14.041 12.772a10.614 10.614 0 0 0 13.56.604l43.78-33.233l100.506 91.695a15.857 15.857 0 0 0 5.465 3.571Zm10.464-183.65l-76.262 57.89l76.262 57.888V68.956Z" mask="url(#IconifyId-17f872155be-cc766e-5441)"/></svg>
@@ -0,0 +1,68 @@
1
+ import type { FastboardApp } from "@netless/fastboard-core";
2
+ import code_editor_svg from "./icons/visual-studio-code.svg";
3
+ import geogebra_svg from "./icons/geogebra.svg";
4
+ import countdown_svg from "./icons/countdown.svg";
5
+
6
+ export interface AppInToolbar {
7
+ kind: string;
8
+ icon: string;
9
+ label: string;
10
+ onClick: (app: FastboardApp) => void;
11
+ }
12
+
13
+ class AppsInToolbar {
14
+ _listeners: Array<(data: AppInToolbar[]) => void> = [];
15
+ constructor(private _data: AppInToolbar[]) {}
16
+ get data() {
17
+ return this._data;
18
+ }
19
+ get length() {
20
+ return this._data.length;
21
+ }
22
+ subscribe(fn: (data: AppInToolbar[]) => void) {
23
+ this._listeners.push(fn);
24
+ fn(this._data);
25
+ return () => {
26
+ this._listeners = this._listeners.filter(item => item !== fn);
27
+ };
28
+ }
29
+ push(data: AppInToolbar) {
30
+ this._data.push(data);
31
+ this._listeners.forEach(fn => fn(this._data));
32
+ }
33
+ insert(data: AppInToolbar, index: number) {
34
+ this._data.splice(index, 0, data);
35
+ this._listeners.forEach(fn => fn(this._data));
36
+ }
37
+ delete(filter: (data: AppInToolbar) => boolean) {
38
+ this._data = this._data.filter(item => !filter(item));
39
+ this._listeners.forEach(fn => fn(this._data));
40
+ }
41
+ }
42
+
43
+ export const apps = new AppsInToolbar([
44
+ {
45
+ kind: "Monaco",
46
+ icon: code_editor_svg,
47
+ label: "Code Editor",
48
+ onClick(app) {
49
+ app.insertCodeEditor();
50
+ },
51
+ },
52
+ {
53
+ kind: "GeoGebra",
54
+ icon: geogebra_svg,
55
+ label: "GeoGebra",
56
+ onClick(app) {
57
+ app.insertGeoGebra();
58
+ },
59
+ },
60
+ {
61
+ kind: "Countdown",
62
+ icon: countdown_svg,
63
+ label: "Countdown",
64
+ onClick(app) {
65
+ app.insertCountdown();
66
+ },
67
+ },
68
+ ]);
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ import type { Content, Placement } from "tippy.js";
3
+ import type { Theme } from "../../typings";
4
+ import { tippy, tippy_menu } from "../../actions/tippy";
5
+
6
+ let className = "";
7
+ export { className as class };
8
+ export let name = "fastboard-ui";
9
+ export let theme: Theme = "light";
10
+ export let disabled = false;
11
+ export let content: Content = "";
12
+ export let placement: Placement = "top";
13
+ export let menu: Content = "";
14
+ export let menu_placement: Placement = "right-start";
15
+ </script>
16
+
17
+ {#if content}
18
+ {#if menu}
19
+ <span class="{name}-btn-interactive {theme}" use:tippy={{ content, placement, className }}>
20
+ <button
21
+ class="{name}-btn {className} {theme}"
22
+ {disabled}
23
+ on:click
24
+ use:tippy={{
25
+ content: menu,
26
+ ...tippy_menu,
27
+ placement: menu_placement,
28
+ appendTo: document.body,
29
+ theme,
30
+ className: "fastboard-panel",
31
+ }}
32
+ >
33
+ <slot />
34
+ </button>
35
+ <span class="{name}-triangle" />
36
+ </span>
37
+ {:else}
38
+ <button
39
+ class="{name}-btn {className} {theme}"
40
+ {disabled}
41
+ on:click
42
+ use:tippy={{ content, placement, className }}
43
+ >
44
+ <slot />
45
+ </button>
46
+ {/if}
47
+ {:else}
48
+ <button class="{name}-btn {className} {theme}" {disabled} on:click>
49
+ <slot />
50
+ </button>
51
+ {/if}
@@ -0,0 +1,26 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { Content, Placement } from "tippy.js";
3
+ import type { Theme } from "../../typings";
4
+
5
+ export declare interface ButtonProps {
6
+ class?: string;
7
+ name?: string;
8
+ theme?: Theme;
9
+ disabled?: boolean;
10
+ content?: Content;
11
+ placement?: Placement;
12
+ menu?: Content;
13
+ menu_placement?: Placement;
14
+ }
15
+
16
+ export declare interface ButtonEvents {
17
+ click: WindowEventMap["click"];
18
+ }
19
+
20
+ export declare interface ButtonSlots {
21
+ // eslint-disable-next-line @typescript-eslint/ban-types
22
+ default: {};
23
+ }
24
+
25
+ declare class Button extends SvelteComponentTyped<ButtonProps, ButtonEvents, ButtonSlots> {}
26
+ export default Button;
@@ -0,0 +1,2 @@
1
+ export { default } from "./Button.svelte";
2
+ export * from "./Button.svelte";
@@ -0,0 +1,49 @@
1
+ .fastboard-root {
2
+ position: relative;
3
+ width: 100%;
4
+ height: 100%;
5
+ overflow: hidden;
6
+ }
7
+
8
+ .fastboard-view {
9
+ position: absolute;
10
+ top: 0;
11
+ left: 0;
12
+ width: 100%;
13
+ height: 100%;
14
+ }
15
+
16
+ .fastboard-left {
17
+ display: flex;
18
+ align-items: center;
19
+ position: absolute;
20
+ bottom: 62px;
21
+ top: 8px;
22
+ left: 0;
23
+ z-index: 200;
24
+
25
+ .fastboard-toolbar {
26
+ padding-left: 16px;
27
+ }
28
+ }
29
+
30
+ .fastboard-bottom-left {
31
+ display: flex;
32
+ gap: 10px;
33
+ position: absolute;
34
+ bottom: 8px;
35
+ left: 8px;
36
+ padding: 8px;
37
+ z-index: 200;
38
+ }
39
+
40
+ .fastboard-bottom-right {
41
+ @extend .fastboard-bottom-left;
42
+ left: auto;
43
+ right: 8px;
44
+ }
45
+
46
+ .fastboard-bottom {
47
+ @extend .fastboard-bottom-left;
48
+ right: 8px;
49
+ }
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import type { FastboardApp } from "@netless/fastboard-core";
3
+ import type { Language, Theme } from "../../typings";
4
+ import RedoUndo from "../RedoUndo";
5
+ import ZoomControl from "../ZoomControl";
6
+ import PageControl from "../PageControl";
7
+ import Toolbar from "../Toolbar";
8
+
9
+ export let app: FastboardApp | null | undefined = null;
10
+ export let theme: Theme = "light";
11
+ export let language: Language = "en";
12
+
13
+ const name = "fastboard";
14
+
15
+ let container: HTMLDivElement;
16
+
17
+ $: if (app && container) app.bindContainer(container);
18
+ </script>
19
+
20
+ <div class="{name}-root" class:loading={!app}>
21
+ <div class="{name}-view" bind:this={container} />
22
+ <div class="{name}-left">
23
+ <Toolbar {app} {theme} {language} />
24
+ </div>
25
+ <div class="{name}-bottom-left">
26
+ <RedoUndo {app} {theme} {language} />
27
+ <ZoomControl {app} {theme} {language} />
28
+ </div>
29
+ <div class="{name}-bottom-right">
30
+ <PageControl {app} {theme} {language} />
31
+ </div>
32
+ </div>
@@ -0,0 +1,12 @@
1
+ import type { FastboardApp } from "@netless/fastboard-core";
2
+ import type { Theme, Language } from "../../typings";
3
+ import { SvelteComponentTyped } from "svelte";
4
+
5
+ export declare interface FastboardProps {
6
+ app?: FastboardApp | null;
7
+ theme?: Theme;
8
+ language?: Language;
9
+ }
10
+
11
+ declare class Fastboard extends SvelteComponentTyped<FastboardProps> {}
12
+ export default Fastboard;
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import type { FastboardPlayer } from "@netless/fastboard-core";
3
+ import type { Language, Theme } from "../../typings";
4
+ import PlayerControl from "../PlayerControl";
5
+
6
+ export let player: FastboardPlayer | null | undefined = null;
7
+ export let theme: Theme = "light";
8
+ export let language: Language = "en";
9
+
10
+ const name = "fastboard";
11
+
12
+ let container: HTMLDivElement;
13
+
14
+ $: if (player && container) player.bindContainer(container);
15
+ </script>
16
+
17
+ <div class="{name}-root" class:loading={!player}>
18
+ <div class="{name}-view" bind:this={container} />
19
+ <div class="{name}-bottom">
20
+ <PlayerControl {player} {theme} {language} />
21
+ </div>
22
+ </div>
@@ -0,0 +1,12 @@
1
+ import type { FastboardPlayer } from "@netless/fastboard-core";
2
+ import type { Theme, Language } from "../../typings";
3
+ import { SvelteComponentTyped } from "svelte";
4
+
5
+ export declare interface ReplayFastboardProps {
6
+ player?: FastboardPlayer | null;
7
+ theme?: Theme;
8
+ language?: Language;
9
+ }
10
+
11
+ declare class ReplayFastboard extends SvelteComponentTyped<ReplayFastboardProps> {}
12
+ export default ReplayFastboard;
@@ -0,0 +1,5 @@
1
+ export { default as ReplayFastboard } from "./ReplayFastboard.svelte";
2
+ export * from "./ReplayFastboard.svelte";
3
+
4
+ export { default as Fastboard } from "./Fastboard.svelte";
5
+ export * from "./Fastboard.svelte";
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ export let src = "";
3
+ export let alt = "";
4
+ export let title = "";
5
+ </script>
6
+
7
+ {#if src}
8
+ <img {src} {alt} title={title || alt} />
9
+ {:else}
10
+ <slot />
11
+ {/if}
@@ -0,0 +1,10 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+
3
+ export declare interface IconProps {
4
+ src?: string;
5
+ alt?: string;
6
+ title?: string;
7
+ }
8
+
9
+ declare class Icon extends SvelteComponentTyped<IconProps> {}
10
+ export default Icon;
@@ -0,0 +1,2 @@
1
+ export { default } from "./Icon.svelte";
2
+ export * from "./Icon.svelte";
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ import type { Theme } from "../../typings";
3
+
4
+ export let theme: Theme = "light";
5
+ export let active = false;
6
+ </script>
7
+
8
+ <svg fill="none" viewBox="0 0 24 24" class="fastboard-icon {theme}" class:is-active={active}>
9
+ <rect
10
+ x="5"
11
+ y="5"
12
+ width="6"
13
+ height="6"
14
+ stroke="#5D6066"
15
+ stroke-width="1.25"
16
+ stroke-linejoin="round"
17
+ class="fastboard-icon-stroke-color"
18
+ />
19
+ <rect
20
+ x="13"
21
+ y="5"
22
+ width="6"
23
+ height="6"
24
+ stroke="#5D6066"
25
+ stroke-width="1.25"
26
+ stroke-linejoin="round"
27
+ class="fastboard-icon-stroke-color"
28
+ />
29
+ <rect
30
+ x="5"
31
+ y="13"
32
+ width="6"
33
+ height="6"
34
+ stroke="#5D6066"
35
+ stroke-width="1.25"
36
+ stroke-linejoin="round"
37
+ class="fastboard-icon-stroke-color"
38
+ />
39
+ <rect
40
+ x="13"
41
+ y="13"
42
+ width="6"
43
+ height="6"
44
+ stroke="#5D6066"
45
+ stroke-width="1.25"
46
+ stroke-linejoin="round"
47
+ class="fastboard-icon-stroke-color"
48
+ />
49
+ </svg>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { Theme } from "../../typings";
3
+
4
+ export let theme: Theme = "light";
5
+ export let active = false;
6
+ </script>
7
+
8
+ <svg fill="none" viewBox="0 0 24 24" class="fastboard-icon {theme}" class:is-active={active}>
9
+ <path
10
+ stroke="#5D6066"
11
+ stroke-linejoin="round"
12
+ stroke-width="1.25"
13
+ d="M5 19 15.5 8.5M17 12l2-7-7 2 3.5 1.5L17 12Z"
14
+ class="fastboard-icon-stroke-color"
15
+ />
16
+ </svg>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import type { Theme } from "../../typings";
3
+
4
+ export let theme: Theme = "light";
5
+ export let active = false;
6
+ </script>
7
+
8
+ <svg fill="none" viewBox="0 0 24 24" class="fastboard-icon {theme}" class:is-active={active}>
9
+ <path
10
+ stroke="#5D6066"
11
+ stroke-linejoin="round"
12
+ stroke-width="1.75"
13
+ d="M5 19 15.5 8.5"
14
+ class="fastboard-icon-stroke-color"
15
+ />
16
+ <path fill="#5D6066" d="m17 12 2-7-7 2 3.5 1.5L17 12Z" class="fastboard-icon-fill-color" />
17
+ </svg>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { Theme } from "../../typings";
3
+
4
+ export let theme: Theme = "light";
5
+ export let active = false;
6
+ </script>
7
+
8
+ <svg fill="none" viewBox="0 0 24 24" class="fastboard-icon {theme}" class:is-active={active}>
9
+ <path
10
+ stroke="#5D6066"
11
+ stroke-linejoin="round"
12
+ stroke-width="1.25"
13
+ d="M19 7a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h2v3l2.414-2.414A2 2 0 0 1 12.828 16H17a2 2 0 0 0 2-2V7Z"
14
+ class="fastboard-icon-stroke-color"
15
+ />
16
+ </svg>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { Theme } from "../../typings";
3
+
4
+ export let theme: Theme = "light";
5
+ export let active = false;
6
+ </script>
7
+
8
+ <svg fill="none" viewBox="0 0 24 24" class="fastboard-icon {theme}" class:is-active={active}>
9
+ <path
10
+ stroke="#5D6066"
11
+ stroke-linejoin="round"
12
+ stroke-width="1.75"
13
+ d="M19 7a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h2v3l2.414-2.414A2 2 0 0 1 12.828 16H17a2 2 0 0 0 2-2V7Z"
14
+ class="fastboard-icon-stroke-color"
15
+ />
16
+ </svg>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import type { Theme } from "../../typings";
3
+
4
+ export let theme: Theme = "light";
5
+ export let active = false;
6
+ </script>
7
+
8
+ <svg fill="none" viewBox="0 0 24 24" class="fastboard-icon {theme}" class:is-active={active}>
9
+ <rect
10
+ width="16"
11
+ height="16"
12
+ x="4"
13
+ y="4"
14
+ stroke="#5D6066"
15
+ stroke-linejoin="round"
16
+ stroke-width="1.25"
17
+ rx="8"
18
+ class="fastboard-icon-stroke-color"
19
+ />
20
+ </svg>