Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix controls #28

Merged
merged 5 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/controls/MMapRouteControl/MMapWaypointInput/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ export class MMapWaypointInput extends mappable.MMapComplexEntity<MMapWaypointIn
return document.activeElement === this._inputEl;
}

public triggerFocus(): void {
this._inputEl.focus();
}

constructor(props: MMapWaypointInputProps) {
super(props, {container: true});

Expand Down Expand Up @@ -151,7 +155,7 @@ export class MMapWaypointInput extends mappable.MMapComplexEntity<MMapWaypointIn
}
}

protected _onUpdate(): void {
protected _onUpdate(diffProps: Partial<MMapWaypointInputProps>): void {
if (this._props.waypoint !== undefined) {
if (this._props.waypoint === null) {
this._props.waypoint = undefined;
Expand All @@ -160,6 +164,10 @@ export class MMapWaypointInput extends mappable.MMapComplexEntity<MMapWaypointIn
this._search({text: this._props.waypoint.toString()}, this._props.waypoint);
}
}

if (diffProps.inputPlaceholder !== undefined) {
this._inputEl.placeholder = diffProps.inputPlaceholder;
}
}

protected _onDetach(): void {
Expand Down
7 changes: 4 additions & 3 deletions src/controls/MMapRouteControl/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const svgIcons: Record<AvailableTypes, string> = {
transit: transitSVG
};

const AVAILABLE_TYPES: AvailableTypes[] = ['driving', 'truck', 'walking', 'transit'];
matthew44-mappable marked this conversation as resolved.
Show resolved Hide resolved

export function createSegmentedControl(availableTypes: AvailableTypes[]): HTMLElement {
const element = document.createElement('mappable');
element.classList.add('mappable--route-control_modes');
Expand All @@ -22,14 +24,13 @@ export function createSegmentedControl(availableTypes: AvailableTypes[]): HTMLEl
container.classList.add('mappable--route-control_modes__container');
element.appendChild(container);

// TODO: Do it normally
if (availableTypes.length < 1) {
throw new Error('The route must contain at least one type of route.');
}

const options: {option: HTMLInputElement; label: HTMLLabelElement}[] = [];
(['driving', 'truck', 'walking', 'transit'] as AvailableTypes[]).forEach((routeType) => {
if (!availableTypes.includes(routeType)) {
availableTypes.forEach((routeType) => {
if (!AVAILABLE_TYPES.includes(routeType)) {
return;
}
const option = document.createElement('input');
Expand Down
86 changes: 77 additions & 9 deletions src/controls/MMapRouteControl/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import debounce from 'lodash/debounce';
import {
BaseRouteResponse,
DomDetach,
Expand All @@ -10,6 +9,9 @@ import {
SuggestResponse
} from '@mappable-world/mappable-types';
import {RouteOptions, TruckParameters} from '@mappable-world/mappable-types/imperative/route';
import {CustomVuefyOptions} from '@mappable-world/mappable-types/modules/vuefy';
import type TVue from '@vue/runtime-core';
import debounce from 'lodash/debounce';
import {CustomSearch, CustomSuggest} from '../MMapSearchControl';
import {MMapWaypointInput, MMapWaypointInputProps, SelectWaypointArgs} from './MMapWaypointInput';
import {
Expand All @@ -22,7 +24,6 @@ import {
} from './helpers';
import './index.css';
import {formatDistance, formatDuration} from './utils';
import {MMapRouteControlVuefyOptions} from './vue';

export type WaypointsArray = Array<SelectWaypointArgs['feature'] | null>;

Expand All @@ -41,6 +42,7 @@ export type MMapRouteControlProps = {
truckParameters?: TruckParameters;
waypoints?: [LngLat | null, LngLat | null];
waypointsPlaceholders?: [string, string];
autofocus?: boolean;
search?: (args: CustomSearch) => Promise<SearchResponse> | SearchResponse;
suggest?: (args: CustomSuggest) => Promise<SuggestResponse> | SuggestResponse;
route?: (args: CustomRoute) => Promise<BaseRouteResponse[]> | BaseRouteResponse[];
Expand All @@ -55,10 +57,34 @@ const defaultProps = Object.freeze({
clearFieldsText: 'Clear all',
changeOrderText: 'Change the order',
waypointsPlaceholders: ['From', 'To'],
availableTypes: ['driving', 'truck', 'walking', 'transit']
availableTypes: ['driving', 'truck', 'walking', 'transit'],
autofocus: true
});
type DefaultProps = typeof defaultProps;

const MMapRouteControlVuefyOptions: CustomVuefyOptions<MMapRouteControl> = {
props: {
geolocationTextInput: String,
clearFieldsText: String,
changeOrderText: String,
availableTypes: Array as TVue.PropType<AvailableTypes[]>,
truckParameters: Object as TVue.PropType<TruckParameters>,
waypoints: Array as unknown as TVue.PropType<[LngLat | null, LngLat | null]>,
waypointsPlaceholders: Array as unknown as TVue.PropType<[string, string]>,
search: Function as TVue.PropType<MMapRouteControlProps['search']>,
suggest: Function as TVue.PropType<MMapRouteControlProps['suggest']>,
route: Function as TVue.PropType<MMapRouteControlProps['route']>,
onMouseMoveOnMap: Function as TVue.PropType<MMapRouteControlProps['onMouseMoveOnMap']>,
onUpdateWaypoints: Function as TVue.PropType<MMapRouteControlProps['onUpdateWaypoints']>,
onRouteResult: Function as TVue.PropType<MMapRouteControlProps['onRouteResult']>,
onBuildRouteError: Function as TVue.PropType<MMapRouteControlProps['onBuildRouteError']>,
autofocus: {
type: Boolean as TVue.PropType<MMapRouteControlProps['autofocus']>,
default: defaultProps.autofocus
}
}
};

export class MMapRouteControl extends mappable.MMapComplexEntity<MMapRouteControlProps, DefaultProps> {
static defaultProps = defaultProps;
static [mappable.optionsKeyVuefy] = MMapRouteControlVuefyOptions;
Expand Down Expand Up @@ -98,6 +124,8 @@ class MMapCommonRouteControl extends mappable.MMapComplexEntity<MMapRouteControl
private _waypointInputFromElement: MMapWaypointInput;
private _waypointInputToElement: MMapWaypointInput;
private _actionsContainerElement: HTMLElement;
private _changeOrderButton: HTMLButtonElement;
private _clearFieldsButton: HTMLButtonElement;

private _waypoints: WaypointsArray = [null, null];

Expand Down Expand Up @@ -132,8 +160,10 @@ class MMapCommonRouteControl extends mappable.MMapComplexEntity<MMapRouteControl
clearFieldsText: this._props.clearFieldsText,
changeOrderText: this._props.changeOrderText
});
changeOrderButton.addEventListener('click', this._changeOrder);
clearFieldsButton.addEventListener('click', this._clearAll);
this._changeOrderButton = changeOrderButton;
this._changeOrderButton.addEventListener('click', this._changeOrder);
this._clearFieldsButton = clearFieldsButton;
this._clearFieldsButton.addEventListener('click', this._clearAll);
this._actionsContainerElement = container;
this._routeParametersElement.appendChild(this._actionsContainerElement);

Expand Down Expand Up @@ -162,10 +192,28 @@ class MMapCommonRouteControl extends mappable.MMapComplexEntity<MMapRouteControl
}

protected _onUpdate(diffProps: Partial<MMapRouteControlProps>): void {
if (diffProps.waypoints) {
if (diffProps.waypoints !== undefined) {
this._waypointInputFromElement.update({waypoint: diffProps.waypoints[0]});
this._waypointInputToElement.update({waypoint: diffProps.waypoints[1]});
}
if (diffProps.geolocationTextInput !== undefined) {
this._waypointInputFromElement.update({geolocationTextInput: diffProps.geolocationTextInput});
this._waypointInputToElement.update({geolocationTextInput: diffProps.geolocationTextInput});
}
if (diffProps.waypointsPlaceholders !== undefined) {
this._waypointInputFromElement.update({inputPlaceholder: diffProps.waypointsPlaceholders[0]});
this._waypointInputToElement.update({inputPlaceholder: diffProps.waypointsPlaceholders[1]});
}
if (diffProps.clearFieldsText !== undefined) {
this._clearFieldsButton.textContent = diffProps.clearFieldsText;
}
if (diffProps.changeOrderText !== undefined) {
this._changeOrderButton.textContent = diffProps.changeOrderText;
}
if (diffProps.availableTypes !== undefined) {
this._routeModesElement.replaceChildren(...createSegmentedControl(diffProps.availableTypes).children);
this._setRouteMode(diffProps.availableTypes[0]);
}
}

protected _onDetach(): void {
Expand Down Expand Up @@ -204,8 +252,12 @@ class MMapCommonRouteControl extends mappable.MMapComplexEntity<MMapRouteControl
}

private _clearAll = () => {
this._waypointInputToElement.update({waypoint: null});
this._waypointInputFromElement.update({waypoint: null});
this._waypointInputToElement.update({waypoint: null});
this._routeInfoElement.replaceChildren();
if (this._routeInfoElement.parentElement === this._rootElement) {
this._rootElement.removeChild(this._routeInfoElement);
}
};

private _changeOrder = () => {
Expand All @@ -218,17 +270,33 @@ class MMapCommonRouteControl extends mappable.MMapComplexEntity<MMapRouteControl
this._waypoints[index] = feature;
this._props.onUpdateWaypoints?.(this._waypoints);

if (this._props.autofocus) {
this._autofocusNextInput(index);
}

if (this._waypoints.every((point) => point !== null)) {
this._route();
}
}

private _autofocusNextInput(index: number): void {
if (index === 0 && this._waypoints[1] === null) {
this._waypointInputToElement.triggerFocus();
} else if (index === 1 && this._waypoints[0] === null) {
this._waypointInputFromElement.triggerFocus();
}
}

private _onUpdateRouteMode = (e: Event) => {
const target = e.target as HTMLInputElement;
this._routeMode = target.value as RouteOptions['type'];
this._route();
this._setRouteMode(target.value as RouteOptions['type']);
};

private _setRouteMode(mode: AvailableTypes): void {
this._routeMode = mode;
this._route();
}

private _route = debounce(async () => {
if (!this._waypoints.every((point) => point !== null)) {
return;
Expand Down
24 changes: 0 additions & 24 deletions src/controls/MMapRouteControl/vue/index.ts

This file was deleted.

17 changes: 15 additions & 2 deletions src/controls/MMapSearchControl/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,19 @@ export type CustomSearch = {
};

type MMapSearchControlProps = {
placeholder?: string;
search?: ({params, map}: CustomSearch) => Promise<SearchResponse> | SearchResponse;
suggest?: ({text, map}: CustomSuggest) => Promise<SuggestResponse> | SuggestResponse;
searchResult: (result: SearchResponse) => void;
};

class MMapSearchCommonControl extends mappable.MMapComplexEntity<MMapSearchControlProps> {
const defaultProps = Object.freeze({
placeholder: 'Enter an address'
});

class MMapSearchCommonControl extends mappable.MMapComplexEntity<MMapSearchControlProps, typeof defaultProps> {
static defaultProps = defaultProps;

private _detachDom?: DomDetach;
private _rootElement?: HTMLElement;
private _clearButton?: HTMLButtonElement;
Expand Down Expand Up @@ -169,7 +176,7 @@ class MMapSearchCommonControl extends mappable.MMapComplexEntity<MMapSearchContr
this._searchInput.type = 'text';
this._searchInput.autocomplete = 'off';
this._searchInput.classList.add(SEARCH_CONTROL_INPUT_CLASS);
this._searchInput.placeholder = 'Enter an address';
this._searchInput.placeholder = this._props.placeholder;
this._searchInput.addEventListener('input', this._onChangeSearchInput);
this._searchInput.addEventListener('focus', this._onFocusBlurSearchInput);
this._searchInput.addEventListener('blur', this._onFocusBlurSearchInput);
Expand Down Expand Up @@ -212,6 +219,12 @@ class MMapSearchCommonControl extends mappable.MMapComplexEntity<MMapSearchContr
);
}

protected _onUpdate(props: Partial<MMapSearchControlProps>): void {
if (props.placeholder !== undefined) {
this._searchInput.placeholder = props.placeholder;
}
}

protected override _onDetach(): void {
this._removeDirectChild(this._suggestComponent);
this._suggestComponent = undefined;
Expand Down
Loading