|  | @@ -118,6 +118,9 @@ function hitTest(element: ExcalidrawElement, x: number, y: number): boolean {
 | 
	
		
			
				|  |  |      const y2 = getElementAbsoluteY2(element);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      return x >= x1 && x <= x2 && y >= y1 && y <= y2;
 | 
	
		
			
				|  |  | +  } else if (element.type === "selection") {
 | 
	
		
			
				|  |  | +    console.warn("This should not happen, we need to investigate why it does.");
 | 
	
		
			
				|  |  | +    return false;
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  |      throw new Error("Unimplemented type " + element.type);
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -571,6 +574,40 @@ const KEYS = {
 | 
	
		
			
				|  |  |    BACKSPACE: "Backspace"
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +const SHAPES = [
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    label: "Rectange",
 | 
	
		
			
				|  |  | +    value: "rectangle"
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    label: "Ellipse",
 | 
	
		
			
				|  |  | +    value: "ellipse"
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    label: "Arrow",
 | 
	
		
			
				|  |  | +    value: "arrow"
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    label: "Text",
 | 
	
		
			
				|  |  | +    value: "text"
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  {
 | 
	
		
			
				|  |  | +    label: "Selection",
 | 
	
		
			
				|  |  | +    value: "selection"
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const shapesShortcutKeys = SHAPES.map(shape => shape.label[0].toLowerCase());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function findElementByKey(key: string) {
 | 
	
		
			
				|  |  | +  const defaultElement = "selection";
 | 
	
		
			
				|  |  | +  return SHAPES.reduce((element, shape) => {
 | 
	
		
			
				|  |  | +    if (shape.value[0] !== key) return element;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return shape.value;
 | 
	
		
			
				|  |  | +  }, defaultElement);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  function isArrowKey(keyCode: string) {
 | 
	
		
			
				|  |  |    return (
 | 
	
		
			
				|  |  |      keyCode === KEYS.ARROW_LEFT ||
 | 
	
	
		
			
				|  | @@ -643,32 +680,11 @@ class App extends React.Component<{}, AppState> {
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |        this.forceUpdate();
 | 
	
		
			
				|  |  |        event.preventDefault();
 | 
	
		
			
				|  |  | +    } else if (shapesShortcutKeys.includes(event.key.toLowerCase())) {
 | 
	
		
			
				|  |  | +      this.setState({ elementType: findElementByKey(event.key) });
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  private renderOption({
 | 
	
		
			
				|  |  | -    type,
 | 
	
		
			
				|  |  | -    children
 | 
	
		
			
				|  |  | -  }: {
 | 
	
		
			
				|  |  | -    type: string;
 | 
	
		
			
				|  |  | -    children: React.ReactNode;
 | 
	
		
			
				|  |  | -  }) {
 | 
	
		
			
				|  |  | -    return (
 | 
	
		
			
				|  |  | -      <label>
 | 
	
		
			
				|  |  | -        <input
 | 
	
		
			
				|  |  | -          type="radio"
 | 
	
		
			
				|  |  | -          checked={this.state.elementType === type}
 | 
	
		
			
				|  |  | -          onChange={() => {
 | 
	
		
			
				|  |  | -            this.setState({ elementType: type });
 | 
	
		
			
				|  |  | -            clearSelection();
 | 
	
		
			
				|  |  | -            this.forceUpdate();
 | 
	
		
			
				|  |  | -          }}
 | 
	
		
			
				|  |  | -        />
 | 
	
		
			
				|  |  | -        {children}
 | 
	
		
			
				|  |  | -      </label>
 | 
	
		
			
				|  |  | -    );
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    public render() {
 | 
	
		
			
				|  |  |      return (
 | 
	
		
			
				|  |  |        <div
 | 
	
	
		
			
				|  | @@ -713,11 +729,20 @@ class App extends React.Component<{}, AppState> {
 | 
	
		
			
				|  |  |        >
 | 
	
		
			
				|  |  |          <fieldset>
 | 
	
		
			
				|  |  |            <legend>Shapes</legend>
 | 
	
		
			
				|  |  | -          {this.renderOption({ type: "rectangle", children: "Rectangle" })}
 | 
	
		
			
				|  |  | -          {this.renderOption({ type: "ellipse", children: "Ellipse" })}
 | 
	
		
			
				|  |  | -          {this.renderOption({ type: "arrow", children: "Arrow" })}
 | 
	
		
			
				|  |  | -          {this.renderOption({ type: "text", children: "Text" })}
 | 
	
		
			
				|  |  | -          {this.renderOption({ type: "selection", children: "Selection" })}
 | 
	
		
			
				|  |  | +          {SHAPES.map(({ value, label }) => (
 | 
	
		
			
				|  |  | +            <label>
 | 
	
		
			
				|  |  | +              <input
 | 
	
		
			
				|  |  | +                type="radio"
 | 
	
		
			
				|  |  | +                checked={this.state.elementType === value}
 | 
	
		
			
				|  |  | +                onChange={() => {
 | 
	
		
			
				|  |  | +                  this.setState({ elementType: value });
 | 
	
		
			
				|  |  | +                  clearSelection();
 | 
	
		
			
				|  |  | +                  this.forceUpdate();
 | 
	
		
			
				|  |  | +                }}
 | 
	
		
			
				|  |  | +              />
 | 
	
		
			
				|  |  | +              <span>{label}</span>
 | 
	
		
			
				|  |  | +            </label>
 | 
	
		
			
				|  |  | +          ))}
 | 
	
		
			
				|  |  |          </fieldset>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          <canvas
 |