@bpd-library/components 1.3.2-beta.13 → 1.3.2-beta.15
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MapOptions, MapSearchOptions } from '@bpd-library/types';
|
|
2
2
|
import mapboxgl from 'mapbox-gl';
|
|
3
3
|
export declare function setDefaultKmPadding(kmPadding: number): number;
|
|
4
|
-
declare const search: (map: mapboxgl.Map, { hook, onSearchSuggestion, noZoomAfterSearch, types }: MapSearchOptions, { searchCountryIsoCodes, language }: MapOptions) => Promise<void>;
|
|
4
|
+
declare const search: (map: mapboxgl.Map, { hook, onSearchSuggestion, noZoomAfterSearch, distanceFilter, types, }: MapSearchOptions, { searchCountryIsoCodes, language }: MapOptions) => Promise<void>;
|
|
5
5
|
export default search;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { h } from '@atomify/jsx';
|
|
2
|
-
import { calculateBoundingBoxCenter, debounce, environmentDetails, expandBoundingBox, getCountryBoundingBox, useClickOutside, withinBoundingBox, } from '@bpd-library/utilities';
|
|
2
|
+
import { calculateBoundingBoxCenter, calculateCenter, calculateDistanceInKm, debounce, environmentDetails, expandBoundingBox, getCountryBoundingBox, useClickOutside, withinBoundingBox, } from '@bpd-library/utilities';
|
|
3
3
|
import mapboxgl from 'mapbox-gl';
|
|
4
4
|
import { clearSearchResult, getMapboxData, mapStore, updateSearchIsMoving, updateSearchResult, } from '../../../store';
|
|
5
5
|
import { fitBounds } from '../../fit-bounds';
|
|
@@ -9,7 +9,7 @@ let defaultKmPadding = 10;
|
|
|
9
9
|
export function setDefaultKmPadding(kmPadding) {
|
|
10
10
|
return (defaultKmPadding = kmPadding);
|
|
11
11
|
}
|
|
12
|
-
const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, types = DEFAULT_TYPES }, { searchCountryIsoCodes = ['nl', 'de'], language = 'nl' }) => {
|
|
12
|
+
const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, distanceFilter, types = DEFAULT_TYPES, }, { searchCountryIsoCodes = ['nl', 'de'], language = 'nl' }) => {
|
|
13
13
|
const element = document.querySelector(hook);
|
|
14
14
|
const bounds = getCountryBoundingBox(searchCountryIsoCodes);
|
|
15
15
|
if (!element) {
|
|
@@ -21,6 +21,7 @@ const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, types
|
|
|
21
21
|
const inputSelectDistanceElement = element.querySelector('[js-hook-map-search-distance-select-input]');
|
|
22
22
|
const form = inputElement.closest('form');
|
|
23
23
|
const suggestionsElement = element.querySelector('[js-hook-map-search-suggestions]');
|
|
24
|
+
const buttonElement = element.querySelector('[js-hook-map-search-button]');
|
|
24
25
|
let geocoder;
|
|
25
26
|
let suggestions;
|
|
26
27
|
init();
|
|
@@ -43,7 +44,7 @@ const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, types
|
|
|
43
44
|
function bindEvents() {
|
|
44
45
|
const debouncedOnKeyDown = debounce(onKeyDown, 300);
|
|
45
46
|
inputElement.addEventListener('keydown', debouncedOnKeyDown);
|
|
46
|
-
|
|
47
|
+
buttonElement.addEventListener('click', handleButtonClick);
|
|
47
48
|
form === null || form === void 0 ? void 0 : form.addEventListener('submit', (e) => e.preventDefault());
|
|
48
49
|
useClickOutside(inputElement, handleClickOutside);
|
|
49
50
|
geocoder.on('results', (results) => {
|
|
@@ -94,17 +95,7 @@ const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, types
|
|
|
94
95
|
function onKeyDown(e) {
|
|
95
96
|
const { value } = inputElement;
|
|
96
97
|
if (e.key === 'Enter') {
|
|
97
|
-
|
|
98
|
-
clearAll();
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
geocoder.on('results', function handleEnter() {
|
|
103
|
-
submitFirstSuggestion();
|
|
104
|
-
inputElement === null || inputElement === void 0 ? void 0 : inputElement.blur();
|
|
105
|
-
geocoder.off('results', handleEnter);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
98
|
+
handleButtonClick();
|
|
108
99
|
}
|
|
109
100
|
if (value.length >= 3) {
|
|
110
101
|
geocoder.setInput(value);
|
|
@@ -122,7 +113,12 @@ const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, types
|
|
|
122
113
|
clearAll();
|
|
123
114
|
}
|
|
124
115
|
else {
|
|
125
|
-
|
|
116
|
+
geocoder.setInput(value).on('results', function handleSubmit(results) {
|
|
117
|
+
suggestions = results;
|
|
118
|
+
submitFirstSuggestion();
|
|
119
|
+
inputElement === null || inputElement === void 0 ? void 0 : inputElement.blur();
|
|
120
|
+
geocoder.off('results', handleSubmit);
|
|
121
|
+
});
|
|
126
122
|
}
|
|
127
123
|
}
|
|
128
124
|
function submitFirstSuggestion() {
|
|
@@ -135,6 +131,7 @@ const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, types
|
|
|
135
131
|
}
|
|
136
132
|
function clearSuggestionsContainer() {
|
|
137
133
|
suggestionsElement.innerHTML = '';
|
|
134
|
+
suggestions = undefined;
|
|
138
135
|
}
|
|
139
136
|
function clearAll() {
|
|
140
137
|
suggestions = undefined;
|
|
@@ -177,7 +174,17 @@ const search = async (map, { hook, onSearchSuggestion, noZoomAfterSearch, types
|
|
|
177
174
|
: [result.center[0], result.center[1], result.center[0], result.center[1]];
|
|
178
175
|
const expandedBoundingBox = expandBoundingBox(originalBoundingBox, kmPadding);
|
|
179
176
|
const mapData = getMapboxData();
|
|
180
|
-
const filteredData = mapData.filter((item) =>
|
|
177
|
+
const filteredData = mapData.filter((item) => {
|
|
178
|
+
switch (distanceFilter) {
|
|
179
|
+
case 'turfDistance':
|
|
180
|
+
const itemCenter = calculateCenter(item.coordinates);
|
|
181
|
+
const distance = calculateDistanceInKm(result.center, itemCenter);
|
|
182
|
+
return distance <= kmPadding;
|
|
183
|
+
case 'bbox':
|
|
184
|
+
default:
|
|
185
|
+
return withinBoundingBox(item.coordinates, expandedBoundingBox);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
181
188
|
if (!noZoomAfterSearch) {
|
|
182
189
|
map.fitBounds(expandedBoundingBox);
|
|
183
190
|
updateSearchIsMoving(true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../../src/molecules/map/utilities/mapbox/search/search.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h } from '@atomify/jsx';\nimport { BoundingBox, MapOptions, MapSearchOptions, MapSearchSuggestion } from '@bpd-library/types';\nimport {\n calculateBoundingBoxCenter,\n debounce,\n environmentDetails,\n expandBoundingBox,\n getCountryBoundingBox,\n useClickOutside,\n withinBoundingBox,\n} from '@bpd-library/utilities';\nimport mapboxgl from 'mapbox-gl';\n\nimport {\n clearSearchResult,\n getMapboxData,\n MapState,\n mapStore,\n SearchResultPlace,\n updateSearchIsMoving,\n updateSearchResult,\n} from '../../../store';\nimport { fitBounds } from '../../fit-bounds';\nimport getCityAlternativeSuggestions from './alternative-city-suggestions';\n\nconst DEFAULT_TYPES = 'region,district,place,neighborhood';\nlet defaultKmPadding = 10;\n\nexport function setDefaultKmPadding(kmPadding: number) {\n return (defaultKmPadding = kmPadding);\n}\n\nconst search = async (\n map: mapboxgl.Map,\n { hook, onSearchSuggestion, noZoomAfterSearch, types = DEFAULT_TYPES }: MapSearchOptions,\n { searchCountryIsoCodes = ['nl', 'de'], language = 'nl' }: MapOptions,\n) => {\n const element = document.querySelector(hook);\n const bounds = getCountryBoundingBox(searchCountryIsoCodes);\n\n if (!element) {\n if (environmentDetails.isLocal) console.error(`Search element can't be found: ${hook}`);\n return;\n }\n\n const inputElement = element.querySelector('[js-hook-map-search-input]') as HTMLInputElement;\n const inputSelectDistanceElement = element.querySelector(\n '[js-hook-map-search-distance-select-input]',\n ) as HTMLSelectElement;\n\n const form = inputElement.closest<HTMLFormElement>('form');\n const suggestionsElement = element.querySelector(\n '[js-hook-map-search-suggestions]',\n ) as HTMLElement;\n\n let geocoder: any | undefined;\n let suggestions: any | undefined;\n\n init();\n\n async function init() {\n // Dynamically import geocoder library\n const { default: MapboxGeocoder } = await import('@mapbox/mapbox-gl-geocoder');\n\n geocoder = new MapboxGeocoder({\n accessToken: mapboxgl.accessToken,\n mapboxgl,\n countries: searchCountryIsoCodes.join(',').toUpperCase(),\n types,\n localGeocoder,\n language,\n enableEventLogging: false,\n marker: false,\n });\n\n map.addControl(geocoder);\n\n bindEvents();\n subscribe();\n }\n\n function bindEvents() {\n const debouncedOnKeyDown = debounce(onKeyDown, 300);\n inputElement.addEventListener('keydown', debouncedOnKeyDown);\n form?.addEventListener('change', handleButtonClick);\n form?.addEventListener('submit', (e) => e.preventDefault());\n\n useClickOutside(inputElement!, handleClickOutside);\n\n geocoder.on('results', (results: any) => {\n suggestions = results;\n\n renderSuggestions(suggestions);\n });\n }\n\n function subscribe() {\n handleManualSearch(mapStore.getState());\n mapStore.subscribe(handleManualSearch, ['manualSearch']);\n }\n\n function handleManualSearch({ manualSearch }: MapState) {\n if (manualSearch) {\n // If manualSearch is an array, it means coordinates are sent.\n // In that case, join them as a string and send it to the geocoder\n let query: string;\n\n if (Array.isArray(manualSearch)) {\n geocoder.options.reverseGeocode = true;\n query = manualSearch.join(', ');\n } else {\n geocoder.options.reverseGeocode = false;\n query = manualSearch;\n }\n\n geocoder.setInput(query).on('results', function handleResults(results: any) {\n suggestions = results;\n\n let firstExactMatch: any;\n\n // First check if there's an exact match, in some cases bigger cities that are not an exact match are returned as first and most relevant result, while doing a manual search you always want an exact match.\n if (typeof manualSearch === 'string') {\n firstExactMatch = results?.features?.find(\n ({ text }: { text?: string }) =>\n text?.toLowerCase() === manualSearch.toLowerCase(),\n );\n }\n\n if (firstExactMatch) {\n submitSuggestion(firstExactMatch);\n } else {\n submitFirstSuggestion();\n }\n\n geocoder.off('results', handleResults);\n });\n }\n }\n\n function handleClickOutside() {\n clearSuggestionsContainer();\n }\n\n function handleFitBounds() {\n if (noZoomAfterSearch) return;\n\n fitBounds(map, bounds);\n }\n\n function onKeyDown(e: KeyboardEvent) {\n const { value } = inputElement!;\n\n if (e.key === 'Enter') {\n if (!value) {\n clearAll();\n return;\n } else {\n geocoder.on('results', function handleEnter() {\n submitFirstSuggestion();\n inputElement?.blur();\n\n geocoder.off('results', handleEnter);\n });\n }\n }\n\n if (value.length >= 3) {\n geocoder.setInput(value);\n } else {\n suggestions = undefined;\n handleFitBounds();\n clearSuggestionsContainer();\n clearSearchResult();\n }\n }\n\n function handleButtonClick() {\n const { value } = inputElement!;\n\n if (!value) {\n clearAll();\n } else {\n submitFirstSuggestion();\n }\n }\n\n function submitFirstSuggestion() {\n const firstSuggestion = suggestions?.features[0];\n\n submitSuggestion(firstSuggestion);\n }\n\n function submitSuggestion(feature: any) {\n updateStore(feature);\n clearSuggestionsContainer();\n }\n\n function clearSuggestionsContainer() {\n suggestionsElement.innerHTML = '';\n }\n\n function clearAll() {\n suggestions = undefined;\n handleFitBounds();\n clearSuggestionsContainer();\n clearSearchResult();\n inputElement?.blur();\n }\n\n function localGeocoder(query: string) {\n const createSuggestion = ({ title, bbox, type, id }: MapSearchSuggestion) => {\n const center = calculateBoundingBoxCenter(bbox);\n\n return {\n place_name: title,\n bbox,\n center,\n type,\n id,\n };\n };\n\n const customSuggestions = onSearchSuggestion\n ? onSearchSuggestion(query.toLowerCase()).map(createSuggestion)\n : [];\n const cityAlternatives = getCityAlternativeSuggestions(query.toLowerCase()).map(\n createSuggestion,\n );\n\n return [...customSuggestions, ...cityAlternatives].slice(0, 4);\n }\n\n function updateStore(result: any) {\n const kmPadding = !!Number(inputSelectDistanceElement?.value)\n ? Number(inputSelectDistanceElement.value)\n : defaultKmPadding;\n\n if (!result) {\n updateSearchResult({\n items: [],\n result: false,\n });\n\n handleFitBounds();\n\n return;\n }\n\n /*\n There might not be a bounding box returned.\n If so, generate one based on the center.\n */\n const originalBoundingBox: BoundingBox = result.bbox\n ? result.bbox\n : [result.center[0], result.center[1], result.center[0], result.center[1]];\n const expandedBoundingBox = expandBoundingBox(originalBoundingBox, kmPadding);\n\n const mapData = getMapboxData();\n const filteredData = mapData.filter((item) =>\n withinBoundingBox(item.coordinates, expandedBoundingBox),\n );\n\n if (!noZoomAfterSearch) {\n map.fitBounds(expandedBoundingBox);\n\n // Update searchIsMoving boolean in store. Is used to block other focus interactions when searched.\n updateSearchIsMoving(true);\n\n map.once('moveend', () => {\n updateSearchIsMoving(false);\n });\n }\n\n const place = parseResultText(result);\n\n updateSearchResult({\n items: filteredData,\n result,\n originalBoundingBox,\n expandedBoundingBox,\n place,\n kmPadding,\n });\n }\n\n function handleSuggestionClick(feature: any) {\n inputElement.value = feature.place_name;\n\n clearSuggestionsContainer();\n updateStore(feature);\n }\n\n function renderSuggestions(suggestions: any) {\n clearSuggestionsContainer();\n\n suggestionsElement.append(\n <ul class=\"map-search__suggestions\">\n {suggestions.features.map((feature: any) => (\n <li class=\"map-search__suggestion\">\n <button onClick={() => handleSuggestionClick(feature)}>\n {feature.place_name}\n </button>\n </li>\n ))}\n </ul>,\n );\n }\n\n function parseResultText(searchResult: any): SearchResultPlace {\n const text: string = searchResult?.place_name || '';\n const isPoi: boolean = searchResult?.place_type?.includes('poi');\n\n if (isPoi) return {};\n\n const [country, province, city, district] = text.split(',').reverse();\n\n return {\n country,\n province,\n city,\n district,\n };\n }\n};\n\nexport default search;\n"]}
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../../../src/molecules/map/utilities/mapbox/search/search.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h } from '@atomify/jsx';\nimport { BoundingBox, MapOptions, MapSearchOptions, MapSearchSuggestion } from '@bpd-library/types';\nimport {\n calculateBoundingBoxCenter,\n calculateCenter,\n calculateDistanceInKm,\n debounce,\n environmentDetails,\n expandBoundingBox,\n getCountryBoundingBox,\n useClickOutside,\n withinBoundingBox,\n} from '@bpd-library/utilities';\nimport mapboxgl from 'mapbox-gl';\n\nimport {\n clearSearchResult,\n getMapboxData,\n MapState,\n mapStore,\n SearchResultPlace,\n updateSearchIsMoving,\n updateSearchResult,\n} from '../../../store';\nimport { fitBounds } from '../../fit-bounds';\nimport getCityAlternativeSuggestions from './alternative-city-suggestions';\n\nconst DEFAULT_TYPES = 'region,district,place,neighborhood';\nlet defaultKmPadding = 10;\n\nexport function setDefaultKmPadding(kmPadding: number) {\n return (defaultKmPadding = kmPadding);\n}\n\nconst search = async (\n map: mapboxgl.Map,\n {\n hook,\n onSearchSuggestion,\n noZoomAfterSearch,\n distanceFilter,\n types = DEFAULT_TYPES,\n }: MapSearchOptions,\n { searchCountryIsoCodes = ['nl', 'de'], language = 'nl' }: MapOptions,\n) => {\n const element = document.querySelector(hook);\n const bounds = getCountryBoundingBox(searchCountryIsoCodes);\n\n if (!element) {\n if (environmentDetails.isLocal) console.error(`Search element can't be found: ${hook}`);\n return;\n }\n\n const inputElement = element.querySelector('[js-hook-map-search-input]') as HTMLInputElement;\n const inputSelectDistanceElement = element.querySelector(\n '[js-hook-map-search-distance-select-input]',\n ) as HTMLSelectElement;\n\n const form = inputElement.closest<HTMLFormElement>('form');\n const suggestionsElement = element.querySelector(\n '[js-hook-map-search-suggestions]',\n ) as HTMLElement;\n const buttonElement = element.querySelector('[js-hook-map-search-button]') as HTMLButtonElement;\n\n let geocoder: any | undefined;\n let suggestions: any | undefined;\n\n init();\n\n async function init() {\n // Dynamically import geocoder library\n const { default: MapboxGeocoder } = await import('@mapbox/mapbox-gl-geocoder');\n\n geocoder = new MapboxGeocoder({\n accessToken: mapboxgl.accessToken,\n mapboxgl,\n countries: searchCountryIsoCodes.join(',').toUpperCase(),\n types,\n localGeocoder,\n language,\n enableEventLogging: false,\n marker: false,\n });\n\n map.addControl(geocoder);\n\n bindEvents();\n subscribe();\n }\n\n function bindEvents() {\n const debouncedOnKeyDown = debounce(onKeyDown, 300);\n inputElement.addEventListener('keydown', debouncedOnKeyDown);\n buttonElement.addEventListener('click', handleButtonClick);\n form?.addEventListener('submit', (e) => e.preventDefault());\n\n useClickOutside(inputElement!, handleClickOutside);\n\n geocoder.on('results', (results: any) => {\n suggestions = results;\n\n renderSuggestions(suggestions);\n });\n }\n\n function subscribe() {\n handleManualSearch(mapStore.getState());\n mapStore.subscribe(handleManualSearch, ['manualSearch']);\n }\n\n function handleManualSearch({ manualSearch }: MapState) {\n if (manualSearch) {\n // If manualSearch is an array, it means coordinates are sent.\n // In that case, join them as a string and send it to the geocoder\n let query: string;\n\n if (Array.isArray(manualSearch)) {\n geocoder.options.reverseGeocode = true;\n query = manualSearch.join(', ');\n } else {\n geocoder.options.reverseGeocode = false;\n query = manualSearch;\n }\n\n geocoder.setInput(query).on('results', function handleResults(results: any) {\n suggestions = results;\n\n let firstExactMatch: any;\n\n // First check if there's an exact match, in some cases bigger cities that are not an exact match are returned as first and most relevant result, while doing a manual search you always want an exact match.\n if (typeof manualSearch === 'string') {\n firstExactMatch = results?.features?.find(\n ({ text }: { text?: string }) =>\n text?.toLowerCase() === manualSearch.toLowerCase(),\n );\n }\n\n if (firstExactMatch) {\n submitSuggestion(firstExactMatch);\n } else {\n submitFirstSuggestion();\n }\n\n geocoder.off('results', handleResults);\n });\n }\n }\n\n function handleClickOutside() {\n clearSuggestionsContainer();\n }\n\n function handleFitBounds() {\n if (noZoomAfterSearch) return;\n\n fitBounds(map, bounds);\n }\n\n function onKeyDown(e: KeyboardEvent) {\n const { value } = inputElement!;\n\n if (e.key === 'Enter') {\n handleButtonClick();\n }\n\n if (value.length >= 3) {\n geocoder.setInput(value);\n } else {\n suggestions = undefined;\n handleFitBounds();\n clearSuggestionsContainer();\n clearSearchResult();\n }\n }\n\n function handleButtonClick() {\n const { value } = inputElement!;\n\n if (!value) {\n clearAll();\n } else {\n geocoder.setInput(value).on('results', function handleSubmit(results: any) {\n suggestions = results;\n submitFirstSuggestion();\n inputElement?.blur();\n\n geocoder.off('results', handleSubmit);\n });\n }\n }\n\n function submitFirstSuggestion() {\n const firstSuggestion = suggestions?.features[0];\n\n submitSuggestion(firstSuggestion);\n }\n\n function submitSuggestion(feature: any) {\n updateStore(feature);\n clearSuggestionsContainer();\n }\n\n function clearSuggestionsContainer() {\n suggestionsElement.innerHTML = '';\n suggestions = undefined;\n }\n\n function clearAll() {\n suggestions = undefined;\n handleFitBounds();\n clearSuggestionsContainer();\n clearSearchResult();\n inputElement?.blur();\n }\n\n function localGeocoder(query: string) {\n const createSuggestion = ({ title, bbox, type, id }: MapSearchSuggestion) => {\n const center = calculateBoundingBoxCenter(bbox);\n\n return {\n place_name: title,\n bbox,\n center,\n type,\n id,\n };\n };\n\n const customSuggestions = onSearchSuggestion\n ? onSearchSuggestion(query.toLowerCase()).map(createSuggestion)\n : [];\n const cityAlternatives = getCityAlternativeSuggestions(query.toLowerCase()).map(\n createSuggestion,\n );\n\n return [...customSuggestions, ...cityAlternatives].slice(0, 4);\n }\n\n function updateStore(result: any) {\n const kmPadding = !!Number(inputSelectDistanceElement?.value)\n ? Number(inputSelectDistanceElement.value)\n : defaultKmPadding;\n\n if (!result) {\n updateSearchResult({\n items: [],\n result: false,\n });\n\n handleFitBounds();\n\n return;\n }\n\n /*\n There might not be a bounding box returned.\n If so, generate one based on the center.\n */\n const originalBoundingBox: BoundingBox = result.bbox\n ? result.bbox\n : [result.center[0], result.center[1], result.center[0], result.center[1]];\n const expandedBoundingBox = expandBoundingBox(originalBoundingBox, kmPadding);\n\n const mapData = getMapboxData();\n const filteredData = mapData.filter((item) => {\n switch (distanceFilter) {\n case 'turfDistance':\n const itemCenter = calculateCenter(item.coordinates!);\n const distance = calculateDistanceInKm(result.center, itemCenter);\n return distance <= kmPadding;\n\n case 'bbox':\n default:\n return withinBoundingBox(item.coordinates, expandedBoundingBox);\n }\n });\n\n if (!noZoomAfterSearch) {\n map.fitBounds(expandedBoundingBox);\n\n // Update searchIsMoving boolean in store. Is used to block other focus interactions when searched.\n updateSearchIsMoving(true);\n\n map.once('moveend', () => {\n updateSearchIsMoving(false);\n });\n }\n\n const place = parseResultText(result);\n\n updateSearchResult({\n items: filteredData,\n result,\n originalBoundingBox,\n expandedBoundingBox,\n place,\n kmPadding,\n });\n }\n\n function handleSuggestionClick(feature: any) {\n inputElement.value = feature.place_name;\n\n clearSuggestionsContainer();\n updateStore(feature);\n }\n\n function renderSuggestions(suggestions: any) {\n clearSuggestionsContainer();\n\n suggestionsElement.append(\n <ul class=\"map-search__suggestions\">\n {suggestions.features.map((feature: any) => (\n <li class=\"map-search__suggestion\">\n <button onClick={() => handleSuggestionClick(feature)}>\n {feature.place_name}\n </button>\n </li>\n ))}\n </ul>,\n );\n }\n\n function parseResultText(searchResult: any): SearchResultPlace {\n const text: string = searchResult?.place_name || '';\n const isPoi: boolean = searchResult?.place_type?.includes('poi');\n\n if (isPoi) return {};\n\n const [country, province, city, district] = text.split(',').reverse();\n\n return {\n country,\n province,\n city,\n district,\n };\n }\n};\n\nexport default search;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpd-library/components",
|
|
3
|
-
"version": "1.3.2-beta.
|
|
3
|
+
"version": "1.3.2-beta.15",
|
|
4
4
|
"description": "Description",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "9e3cc3dc605a2ccd2823ae921e3db6c3e3786208",
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@atomify/core": "2.4.1",
|
|
52
52
|
"@atomify/hooks": "1.1.11",
|
|
53
53
|
"@atomify/jsx": "1.7.1",
|
|
54
54
|
"@atomify/kit": "1.1.11",
|
|
55
|
-
"@bpd-library/types": "^1.3.2-beta.
|
|
56
|
-
"@bpd-library/utilities": "^1.3.2-beta.
|
|
55
|
+
"@bpd-library/types": "^1.3.2-beta.15",
|
|
56
|
+
"@bpd-library/utilities": "^1.3.2-beta.15",
|
|
57
57
|
"@mapbox/mapbox-gl-geocoder": "^4.7.0",
|
|
58
58
|
"@mapbox/mapbox-gl-language": "^0.10.1",
|
|
59
59
|
"@turf/helpers": "^6.5.0",
|