Skip to content

Commit

Permalink
feat: allow keyEvents to be set to null to prevent keyboard interacti…
Browse files Browse the repository at this point in the history
…ons on modes
  • Loading branch information
JamesLMilner committed Jan 22, 2023
1 parent 559b6db commit 6af865c
Show file tree
Hide file tree
Showing 13 changed files with 692 additions and 200 deletions.
19 changes: 13 additions & 6 deletions src/modes/circle/circle.mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { getDefaultStyling } from "../../util/styling";
import { TerraDrawBaseDrawMode } from "../base.mode";

type TerraDrawCircleModeKeyEvents = {
cancel: KeyboardEvent["key"];
finish: KeyboardEvent["key"];
cancel: KeyboardEvent["key"] | null;
finish: KeyboardEvent["key"] | null;
};

type FreehandPolygonStyling = {
Expand All @@ -29,16 +29,23 @@ export class TerraDrawCircleMode extends TerraDrawBaseDrawMode<FreehandPolygonSt
private center: Position | undefined;
private clickCount = 0;
private currentCircleId: string | undefined;
private keyEvents: TerraDrawCircleModeKeyEvents;
private keyEvents: TerraDrawCircleModeKeyEvents

constructor(options?: {
styles?: Partial<FreehandPolygonStyling>;
keyEvents?: TerraDrawCircleModeKeyEvents;
keyEvents?: TerraDrawCircleModeKeyEvents | null;
}) {
super(options);

this.keyEvents =
options && options.keyEvents ? options.keyEvents : { cancel: "Escape", finish: 'Enter' };
// We want to have some defaults, but also allow key bindings
// to be explicitly turned off
if (options?.keyEvents === null) {
this.keyEvents = { cancel: null, finish: null }
} else {
const defaultKeyEvents = { cancel: "Escape", finish: 'Enter' }
this.keyEvents =
options && options.keyEvents ? { ...defaultKeyEvents, ...options.keyEvents } : defaultKeyEvents;
}
}

private close() {
Expand Down
79 changes: 62 additions & 17 deletions src/modes/circle/circle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ describe("TerraDrawCircleMode", () => {
fillColor: "#ffffff",
});
});

it("constructs with null key events", () => {
new TerraDrawCircleMode({
styles: { fillColor: "#ffffff" },
keyEvents: null
});

new TerraDrawCircleMode({
styles: { fillColor: "#ffffff" },
keyEvents: { cancel: null, finish: null }
});

});
});

describe("lifecycle", () => {
Expand Down Expand Up @@ -332,28 +345,60 @@ describe("TerraDrawCircleMode", () => {
circleMode.register(mockConfig);
});

it("Escape - does nothing when no circle is present", () => {
circleMode.onKeyUp({ key: "Escape" });
});
describe('cancel', () => {
it("does nothing when no circle is present", () => {
circleMode.onKeyUp({ key: "Escape" });
});

it("Escape - deletes the circle when currently editing", () => {
circleMode.onClick({
lng: 0,
lat: 0,
containerX: 0,
containerY: 0,
button: "left",
heldKeys: [],
it("deletes the circle when currently editing", () => {
circleMode.onClick({
lng: 0,
lat: 0,
containerX: 0,
containerY: 0,
button: "left",
heldKeys: [],
});

let features = store.copyAll();
expect(features.length).toBe(1);

circleMode.onKeyUp({ key: "Escape" });

features = store.copyAll();
expect(features.length).toBe(0);
});

let features = store.copyAll();
expect(features.length).toBe(1);
it("does not delete the circle when currently editing if keyEvents is null", () => {
jest.resetAllMocks();
circleMode = new TerraDrawCircleMode({ keyEvents: null });

const mockConfig = getMockModeConfig(circleMode.mode);
store = mockConfig.store;
onChange = mockConfig.onChange;
project = mockConfig.project;
circleMode.register(mockConfig);

circleMode.onClick({
lng: 0,
lat: 0,
containerX: 0,
containerY: 0,
button: "left",
heldKeys: [],
});

let features = store.copyAll();
expect(features.length).toBe(1);

circleMode.onKeyUp({ key: "Escape" });

features = store.copyAll();
expect(features.length).toBe(1);
});
})

circleMode.onKeyUp({ key: "Escape" });

features = store.copyAll();
expect(features.length).toBe(0);
});
});

describe("onDrag", () => {
Expand Down
20 changes: 14 additions & 6 deletions src/modes/freehand/freehand.mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { GeoJSONStoreFeatures } from "../../store/store";
import { pixelDistance } from "../../geometry/measure/pixel-distance";

type TerraDrawFreehandModeKeyEvents = {
cancel: KeyboardEvent["key"];
finish: KeyboardEvent["key"];
cancel: KeyboardEvent["key"] | null;
finish: KeyboardEvent["key"] | null
};

type FreehandPolygonStyling = {
Expand All @@ -39,13 +39,21 @@ export class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygon
constructor(options?: {
styles?: Partial<FreehandPolygonStyling>;
minDistance?: number;
keyEvents?: TerraDrawFreehandModeKeyEvents;
keyEvents?: TerraDrawFreehandModeKeyEvents | null
}) {
super(options);

this.minDistance = (options && options.minDistance) || 20;
this.keyEvents =
options && options.keyEvents ? options.keyEvents : { cancel: "Escape", finish: 'Enter' };

// We want to have some defaults, but also allow key bindings
// to be explicitly turned off
if (options?.keyEvents === null) {
this.keyEvents = { cancel: null, finish: null }
} else {
const defaultKeyEvents = { cancel: "Escape", finish: 'Enter' }
this.keyEvents =
options && options.keyEvents ? { ...defaultKeyEvents, ...options.keyEvents } : defaultKeyEvents;
}
}

private close() {
Expand Down Expand Up @@ -81,7 +89,7 @@ export class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygon

const [previousLng, previousLat] =
currentLineGeometry.coordinates[0][
currentLineGeometry.coordinates[0].length - 2
currentLineGeometry.coordinates[0].length - 2
];
const { x, y } = this.project(previousLng, previousLat);
const distance = pixelDistance(
Expand Down
68 changes: 68 additions & 0 deletions src/modes/freehand/freehand.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ describe("TerraDrawFreehandMode", () => {
outlineColor: "#ffffff",
});
});

it("constructs with null key events", () => {
new TerraDrawFreehandMode({
styles: { fillColor: "#ffffff" },
keyEvents: null
});

new TerraDrawFreehandMode({
styles: { fillColor: "#ffffff" },
keyEvents: { cancel: null, finish: null }
});
});
});

describe("lifecycle", () => {
Expand Down Expand Up @@ -333,6 +345,33 @@ describe("TerraDrawFreehandMode", () => {
features = store.copyAll();
expect(features.length).toBe(0);
});

it("does not delete the freehand when currently editing if cancel is null", () => {
freehandMode = new TerraDrawFreehandMode({ keyEvents: null });

const mockConfig = getMockModeConfig(freehandMode.mode);
store = mockConfig.store;
onChange = mockConfig.onChange;
project = mockConfig.project;
freehandMode.register(mockConfig);

freehandMode.onClick({
lng: 0,
lat: 0,
containerX: 0,
containerY: 0,
button: "left",
heldKeys: [],
});

let features = store.copyAll();
expect(features.length).toBe(2);

freehandMode.onKeyUp({ key: "Escape" });

features = store.copyAll();
expect(features.length).toBe(2);
});
});

describe('finish', () => {
Expand Down Expand Up @@ -362,6 +401,35 @@ describe("TerraDrawFreehandMode", () => {
expect(onChange).toHaveBeenNthCalledWith(2, [expect.any(String)], "delete");

});

it("finishes drawing polygon on finish key press", () => {
freehandMode = new TerraDrawFreehandMode({ keyEvents: null });

const mockConfig = getMockModeConfig(freehandMode.mode);
store = mockConfig.store;
onChange = mockConfig.onChange;
project = mockConfig.project;
freehandMode.register(mockConfig);

freehandMode.onClick({
lng: 0,
lat: 0,
containerX: 0,
containerY: 0,
button: "left",
heldKeys: [],
});

let features = store.copyAll();
expect(features.length).toBe(2);

freehandMode.onKeyUp({
key: 'Enter'
});

features = store.copyAll();
expect(features.length).toBe(2);
});
});


Expand Down
22 changes: 14 additions & 8 deletions src/modes/linestring/linestring.mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ import { PixelDistanceBehavior } from "../pixel-distance.behavior";
import { SnappingBehavior } from "../snapping.behavior";
import { getDefaultStyling } from "../../util/styling";
import { GeoJSONStoreFeatures } from "../../store/store";
import { createSourceMapSource } from "typescript";

type TerraDrawLineStringModeKeyEvents = {
cancel: KeyboardEvent["key"];
finish: KeyboardEvent["key"]
cancel: KeyboardEvent["key"] | null
finish: KeyboardEvent["key"] | null
};

type LineStringStyling = {
Expand Down Expand Up @@ -49,7 +48,7 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
allowSelfIntersections?: boolean;
pointerDistance?: number;
styles?: Partial<LineStringStyling>;
keyEvents?: TerraDrawLineStringModeKeyEvents;
keyEvents?: TerraDrawLineStringModeKeyEvents | null
}) {
super(options);

Expand All @@ -61,8 +60,15 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
? options.allowSelfIntersections
: true;

this.keyEvents =
options && options.keyEvents ? options.keyEvents : { cancel: "Escape", finish: "Enter" };
// We want to have some defaults, but also allow key bindings
// to be explicitly turned off
if (options?.keyEvents === null) {
this.keyEvents = { cancel: null, finish: null }
} else {
const defaultKeyEvents = { cancel: "Escape", finish: 'Enter' }
this.keyEvents =
options && options.keyEvents ? { ...defaultKeyEvents, ...options.keyEvents } : defaultKeyEvents;
}
}

private close() {
Expand Down Expand Up @@ -141,7 +147,7 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
if (this.closingPointId) {
const [previousLng, previousLat] =
currentLineGeometry.coordinates[
currentLineGeometry.coordinates.length - 1
currentLineGeometry.coordinates.length - 1
];
const { x, y } = this.project(previousLng, previousLat);
const distance = pixelDistance(
Expand Down Expand Up @@ -236,7 +242,7 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty

const [previousLng, previousLat] =
currentLineGeometry.coordinates[
currentLineGeometry.coordinates.length - 2
currentLineGeometry.coordinates.length - 2
];
const { x, y } = this.project(previousLng, previousLat);
const distance = pixelDistance(
Expand Down
Loading

0 comments on commit 6af865c

Please sign in to comment.