@netless/fastboard-ui 1.0.0-canary.8 → 1.0.0-canary.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/fastboard-ui",
3
- "version": "1.0.0-canary.8",
3
+ "version": "1.0.0-canary.9",
4
4
  "description": "The front-end of @netless/fastboard-core.",
5
5
  "main": "dist/index.js",
6
6
  "svelte": "dist/index.svelte.mjs",
@@ -13,14 +13,14 @@
13
13
  ],
14
14
  "repository": "netless-io/fastboard",
15
15
  "peerDependencies": {
16
- "@netless/fastboard-core": "1.0.0-canary.8"
16
+ "@netless/fastboard-core": "1.0.0-canary.9"
17
17
  },
18
18
  "dependencies": {
19
19
  "tippy.js": "^6.3.7"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@netless/esbuild-plugin-inline-sass": "0.1.0",
23
- "@netless/fastboard-core": "1.0.0-canary.8"
23
+ "@netless/fastboard-core": "1.0.0-canary.9"
24
24
  },
25
25
  "scripts": {
26
26
  "cleanup": "rimraf dist",
@@ -10,7 +10,7 @@ export const scrollTop: SvelteAction<Writable<number>> = function (node, value)
10
10
 
11
11
  function on_scroll() {
12
12
  clearTimeout(timer);
13
- timer = setTimeout(() => value.set(node.scrollTop), 200);
13
+ timer = window.setTimeout(() => value.set(node.scrollTop), 200);
14
14
  }
15
15
 
16
16
  node.addEventListener("scroll", on_scroll);
@@ -0,0 +1,10 @@
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 stroke="#5D6066" stroke-width="1.25" d="M4 4c16 0 0 16 16 16" class="fastboard-icon-stroke-color" />
10
+ </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-dasharray="1.25 1.25"
12
+ stroke-width="1.25"
13
+ d="M4 4c16 0 0 16 16 16"
14
+ class="fastboard-icon-stroke-color"
15
+ />
16
+ </svg>
@@ -46,6 +46,8 @@ import WhiteboardAdd from "./WhiteboardAdd.svelte";
46
46
  import Play from "./Play.svelte";
47
47
  import Pause from "./Pause.svelte";
48
48
  import Loading from "./Loading.svelte";
49
+ import Curve from "./Curve.svelte";
50
+ import CurveDashed from "./CurveDashed.svelte";
49
51
 
50
52
  const Icons = {
51
53
  Apps,
@@ -93,6 +95,8 @@ const Icons = {
93
95
  Play,
94
96
  Pause,
95
97
  Loading,
98
+ Curve,
99
+ CurveDashed,
96
100
  };
97
101
 
98
102
  export default Icons;
@@ -25,6 +25,7 @@
25
25
  $: computed_height = clamp($container_height, extra_height, $scroll_height + extra_height);
26
26
  $: scrollable = $scroll_height + extra_height > $container_height;
27
27
 
28
+ $: hide_dotted = config.pencil?.dotted === false;
28
29
  $: hide_apps = config.apps?.enable === false;
29
30
  $: eraser_type = config.eraser?.behavior || "both";
30
31
  </script>
@@ -39,6 +40,7 @@
39
40
  {scroll_height}
40
41
  {computed_height}
41
42
  {scrollable}
43
+ {hide_dotted}
42
44
  {hide_apps}
43
45
  {eraser_type}
44
46
  />
@@ -3,6 +3,9 @@ import type { Theme, Language } from "../../typings";
3
3
  import { SvelteComponentTyped } from "svelte";
4
4
 
5
5
  export declare interface ToolbarConfig {
6
+ pencil?: {
7
+ dotted?: boolean;
8
+ };
6
9
  apps?: {
7
10
  enable?: boolean;
8
11
  };
@@ -28,6 +28,7 @@
28
28
  export let scroll_height: Writable<number>;
29
29
  export let computed_height = 0;
30
30
  export let scrollable = false;
31
+ export let hide_dotted = false;
31
32
  export let hide_apps = false;
32
33
  export let eraser_type: "delete" | "pencil" | "both" = "both";
33
34
 
@@ -58,6 +59,7 @@
58
59
  };
59
60
  $: memberState = app?.memberState;
60
61
  $: appliance = $memberState?.currentApplianceName;
62
+ $: dotted = $memberState?.dottedLine;
61
63
  $: shape = $memberState?.shapeType;
62
64
  $: status = app?.appsStatus;
63
65
 
@@ -94,6 +96,12 @@
94
96
  function text() {
95
97
  app?.setAppliance("text");
96
98
  }
99
+ function set_dotted() {
100
+ app?.toggleDottedLine(true);
101
+ }
102
+ function unset_dotted() {
103
+ app?.toggleDottedLine(false);
104
+ }
97
105
  function select_last_shape() {
98
106
  if (applianceShapes.includes(last_shape as Appliance)) {
99
107
  app?.setAppliance(last_shape as Appliance);
@@ -251,6 +259,31 @@
251
259
 
252
260
  <div class="{name}-panel-wrapper" style="display:none">
253
261
  <div class="{name}-panel pencil" bind:this={pencil_panel}>
262
+ {#if !hide_dotted}
263
+ <div class="{name}-panel-btns">
264
+ <Button
265
+ class="pencil"
266
+ active={appliance === "pencil" && !dotted}
267
+ {...btn_props}
268
+ on:click={unset_dotted}
269
+ placement="top"
270
+ content={t.solid}
271
+ >
272
+ <Icons.Curve {theme} active={appliance === "pencil" && !dotted} />
273
+ </Button>
274
+ <Button
275
+ class="pencil"
276
+ active={appliance === "pencil" && dotted}
277
+ {...btn_props}
278
+ on:click={set_dotted}
279
+ placement="top"
280
+ content={t.dashed}
281
+ >
282
+ <Icons.CurveDashed {theme} active={appliance === "pencil" && dotted} />
283
+ </Button>
284
+ </div>
285
+ <div class="{name}-panel-divider" />
286
+ {/if}
254
287
  <StrokeWidth {app} {theme} {disabled} />
255
288
  <div class="{name}-panel-divider" />
256
289
  <StrokeColor {app} {theme} {disabled} />
@@ -39,7 +39,6 @@
39
39
  class="{name}-track {theme}"
40
40
  class:grabbing
41
41
  type="range"
42
- role="slider"
43
42
  {disabled}
44
43
  {min}
45
44
  {max}
@@ -24,7 +24,7 @@ export const shapes = [
24
24
  "speechBalloon",
25
25
  ] as const;
26
26
 
27
- export type Shape = typeof shapes[number];
27
+ export type Shape = (typeof shapes)[number];
28
28
 
29
29
  export const applianceShapes = shapes.slice(0, 4) as Appliance[];
30
30
 
@@ -52,7 +52,7 @@ export const shapesIconActive: Record<Shape, any> = {
52
52
 
53
53
  export const erasers = ["eraser", "pencilEraser"] as const;
54
54
 
55
- export type Eraser = typeof erasers[number];
55
+ export type Eraser = (typeof erasers)[number];
56
56
 
57
57
  export const eraserIcon: Record<Eraser, any> = {
58
58
  eraser: Icons.Eraser,
@@ -65,7 +65,17 @@ export const eraserIconActive: Record<Eraser, any> = {
65
65
  };
66
66
 
67
67
  export const i18n: I18nData<
68
- "clicker" | "selector" | "pencil" | "pencilEraser" | "text" | "shapes" | "eraser" | "clear" | "apps"
68
+ | "clicker"
69
+ | "selector"
70
+ | "pencil"
71
+ | "pencilEraser"
72
+ | "text"
73
+ | "shapes"
74
+ | "eraser"
75
+ | "clear"
76
+ | "apps"
77
+ | "solid"
78
+ | "dashed"
69
79
  > = {
70
80
  en: {
71
81
  clicker: "clicker",
@@ -77,6 +87,8 @@ export const i18n: I18nData<
77
87
  shapes: "shapes",
78
88
  clear: "clear",
79
89
  apps: "apps",
90
+ solid: "solid",
91
+ dashed: "dashed",
80
92
  },
81
93
  "zh-CN": {
82
94
  clicker: "点击",
@@ -88,6 +100,8 @@ export const i18n: I18nData<
88
100
  shapes: "形状",
89
101
  clear: "清屏",
90
102
  apps: "Apps",
103
+ solid: "实线",
104
+ dashed: "虚线",
91
105
  },
92
106
  };
93
107