Преглед на файлове

Add shortcuts (#85)

* Add yarn.lock to .gitignore

* Extract available shapes to one place

* Add event listeners for shapes shortcuts

* fixup! Add event listeners for shapes shortcuts

* Underline first letter of shapes

to indicate interactivity

* fixup! Extract available shapes to one place

* fixup! Add event listeners for shapes shortcuts
vanilla_orig
Alex Bratsos преди 5 години
родител
ревизия
58d81280c9
променени са 3 файла, в които са добавени 64 реда и са изтрити 28 реда
  1. 3
    0
      .gitignore
  2. 53
    28
      src/index.tsx
  3. 8
    0
      src/styles.css

+ 3
- 0
.gitignore Целия файл

@@ -11,6 +11,9 @@ build
11 11
 # Dependency directories
12 12
 node_modules/
13 13
 
14
+# lock file
15
+yarn.lock
16
+
14 17
 # Editors
15 18
 .vscode/
16 19
 

+ 53
- 28
src/index.tsx Целия файл

@@ -118,6 +118,9 @@ function hitTest(element: ExcalidrawElement, x: number, y: number): boolean {
118 118
     const y2 = getElementAbsoluteY2(element);
119 119
 
120 120
     return x >= x1 && x <= x2 && y >= y1 && y <= y2;
121
+  } else if (element.type === "selection") {
122
+    console.warn("This should not happen, we need to investigate why it does.");
123
+    return false;
121 124
   } else {
122 125
     throw new Error("Unimplemented type " + element.type);
123 126
   }
@@ -571,6 +574,40 @@ const KEYS = {
571 574
   BACKSPACE: "Backspace"
572 575
 };
573 576
 
577
+const SHAPES = [
578
+  {
579
+    label: "Rectange",
580
+    value: "rectangle"
581
+  },
582
+  {
583
+    label: "Ellipse",
584
+    value: "ellipse"
585
+  },
586
+  {
587
+    label: "Arrow",
588
+    value: "arrow"
589
+  },
590
+  {
591
+    label: "Text",
592
+    value: "text"
593
+  },
594
+  {
595
+    label: "Selection",
596
+    value: "selection"
597
+  }
598
+];
599
+
600
+const shapesShortcutKeys = SHAPES.map(shape => shape.label[0].toLowerCase());
601
+
602
+function findElementByKey(key: string) {
603
+  const defaultElement = "selection";
604
+  return SHAPES.reduce((element, shape) => {
605
+    if (shape.value[0] !== key) return element;
606
+
607
+    return shape.value;
608
+  }, defaultElement);
609
+}
610
+
574 611
 function isArrowKey(keyCode: string) {
575 612
   return (
576 613
     keyCode === KEYS.ARROW_LEFT ||
@@ -643,32 +680,11 @@ class App extends React.Component<{}, AppState> {
643 680
       });
644 681
       this.forceUpdate();
645 682
       event.preventDefault();
683
+    } else if (shapesShortcutKeys.includes(event.key.toLowerCase())) {
684
+      this.setState({ elementType: findElementByKey(event.key) });
646 685
     }
647 686
   };
648 687
 
649
-  private renderOption({
650
-    type,
651
-    children
652
-  }: {
653
-    type: string;
654
-    children: React.ReactNode;
655
-  }) {
656
-    return (
657
-      <label>
658
-        <input
659
-          type="radio"
660
-          checked={this.state.elementType === type}
661
-          onChange={() => {
662
-            this.setState({ elementType: type });
663
-            clearSelection();
664
-            this.forceUpdate();
665
-          }}
666
-        />
667
-        {children}
668
-      </label>
669
-    );
670
-  }
671
-
672 688
   public render() {
673 689
     return (
674 690
       <div
@@ -713,11 +729,20 @@ class App extends React.Component<{}, AppState> {
713 729
       >
714 730
         <fieldset>
715 731
           <legend>Shapes</legend>
716
-          {this.renderOption({ type: "rectangle", children: "Rectangle" })}
717
-          {this.renderOption({ type: "ellipse", children: "Ellipse" })}
718
-          {this.renderOption({ type: "arrow", children: "Arrow" })}
719
-          {this.renderOption({ type: "text", children: "Text" })}
720
-          {this.renderOption({ type: "selection", children: "Selection" })}
732
+          {SHAPES.map(({ value, label }) => (
733
+            <label>
734
+              <input
735
+                type="radio"
736
+                checked={this.state.elementType === value}
737
+                onChange={() => {
738
+                  this.setState({ elementType: value });
739
+                  clearSelection();
740
+                  this.forceUpdate();
741
+                }}
742
+              />
743
+              <span>{label}</span>
744
+            </label>
745
+          ))}
721 746
         </fieldset>
722 747
 
723 748
         <canvas

+ 8
- 0
src/styles.css Целия файл

@@ -18,6 +18,14 @@ label {
18 18
   margin-right: 10px;
19 19
 }
20 20
 
21
+label span {
22
+  display: inline-block;
23
+}
24
+
25
+label span::first-letter {
26
+  text-decoration: underline;
27
+}
28
+
21 29
 input[type="number"] {
22 30
   width: 30px;
23 31
 }

Loading…
Отказ
Запис