@mapfirst.ai/react 0.0.14 → 0.0.16

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.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,5 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as _mapfirst_ai_core from '@mapfirst.ai/core';
3
- import { PropertyType, PriceLevel, MapFirstCore, BaseMapFirstOptions, MapState, Property, MapLibreNamespace, GoogleMapsNamespace, MapboxNamespace, MapFirstOptions } from '@mapfirst.ai/core';
2
+ import { PropertyType, PriceLevel, MapFirstCore, BaseMapFirstOptions, MapState, Property, MapLibreNamespace, GoogleMapsNamespace, MapboxNamespace } from '@mapfirst.ai/core';
4
3
  export { ApiFiltersResponse, convertToApiFilters, processApiFilters } from '@mapfirst.ai/core';
5
4
  import * as React$1 from 'react';
6
5
  import React__default, { FunctionComponent, CSSProperties, ReactNode } from 'react';
@@ -93,7 +92,6 @@ declare const Chip: React__default.FC<ChipProps>;
93
92
 
94
93
  interface FilterChipsProps {
95
94
  filters: Filter[];
96
- isPortrait: boolean;
97
95
  currency: string;
98
96
  minRatingSuffix: string;
99
97
  clearAllLabel: string;
@@ -146,12 +144,6 @@ declare const useFilterScroll: (dependency: number) => {
146
144
  scrollByDir: (dir: "prev" | "next") => void;
147
145
  };
148
146
 
149
- /**
150
- * Hook to detect if the viewport is in portrait orientation.
151
- * Updates on window resize.
152
- */
153
- declare const useIsPortrait: () => boolean;
154
-
155
147
  type Locale = "en" | "es" | "de" | "fr" | "it" | "pt";
156
148
  type TranslationFunction = (key: string, params?: Record<string, any>) => string;
157
149
  type FormatCurrencyFunction = (value: number, currency?: string) => string;
@@ -201,14 +193,24 @@ type SmartFilter = {
201
193
  priceLevels?: any[];
202
194
  };
203
195
  /**
204
- * Hook that creates a MapFirstCore instance that can be initialized before maps are ready.
205
- * Supports two-phase initialization: create SDK first, attach map later.
206
- * Returns the instance and reactive state that updates when SDK state changes.
196
+ * Comprehensive hook for MapFirst SDK with all functionality in one place.
197
+ * Creates a MapFirstCore instance with reactive state and provides all necessary methods.
207
198
  *
208
199
  * @example
209
200
  * ```tsx
210
- * // Phase 1: Create SDK instance with location data
211
- * const { mapFirst, state } = useMapFirstCore({
201
+ * // Initialize with location data
202
+ * const {
203
+ * instance,
204
+ * state,
205
+ * setPrimaryType,
206
+ * setSelectedMarker,
207
+ * propertiesSearch,
208
+ * smartFilterSearch,
209
+ * boundsSearch,
210
+ * attachMapLibre,
211
+ * attachGoogle,
212
+ * attachMapbox
213
+ * } = useMapFirst({
212
214
  * initialLocationData: {
213
215
  * city: "New York",
214
216
  * country: "United States",
@@ -217,298 +219,97 @@ type SmartFilter = {
217
219
  * });
218
220
  *
219
221
  * // Access reactive state
220
- * console.log(state.properties); // Updates when properties change
221
- * console.log(state.isSearching); // Updates when search state changes
222
+ * console.log(state?.properties);
223
+ * console.log(state?.isSearching);
224
+ * console.log(state?.selectedPropertyId);
222
225
  *
223
- * // Phase 2: Attach map when ready
226
+ * // Attach map when ready
224
227
  * useEffect(() => {
225
- * if (mapLibreInstance && mapFirst) {
226
- * mapFirst.attachMap(mapLibreInstance, {
227
- * platform: "maplibre",
228
- * maplibregl: maplibregl,
228
+ * if (mapLibreInstance) {
229
+ * attachMapLibre(mapLibreInstance, maplibregl, {
229
230
  * onMarkerClick: (marker) => console.log(marker)
230
231
  * });
231
232
  * }
232
- * }, [mapLibreInstance, mapFirst]);
233
- * ```
234
- */
235
- declare function useMapFirstCore(options: BaseMapFirstOptions): {
236
- mapFirst: MapFirstCore | null;
237
- state: MapState | null;
238
- };
239
- /**
240
- * Hook to access reactive properties from MapFirst SDK.
241
- * Returns the current properties array that updates when properties change.
242
- *
243
- * @example
244
- * ```tsx
245
- * const { mapFirst } = useMapFirstCore({ ... });
246
- * const properties = useMapFirstProperties(mapFirst);
247
- *
248
- * return <div>Found {properties.length} properties</div>;
249
- * ```
250
- */
251
- declare function useMapFirstProperties(mapFirst: MapFirstCore | null): Property[];
252
- /**
253
- * Hook to access the selected property ID from MapFirst SDK.
254
- * Returns the currently selected property ID that updates when selection changes.
255
- *
256
- * @example
257
- * ```tsx
258
- * const { mapFirst } = useMapFirstCore({ ... });
259
- * const selectedId = useMapFirstSelectedProperty(mapFirst);
260
- *
261
- * return <div>Selected: {selectedId || 'None'}</div>;
262
- * ```
263
- */
264
- declare function useMapFirstSelectedProperty(mapFirst: MapFirstCore | null): number | null;
265
- /**
266
- * Hook to access and control the primary property type.
267
- * Returns the current primary type and a setter function.
268
- *
269
- * @example
270
- * ```tsx
271
- * const { mapFirst } = useMapFirstCore({ ... });
272
- * const [primaryType, setPrimaryType] = usePrimaryType(mapFirst);
273
- *
274
- * return (
275
- * <select value={primaryType} onChange={(e) => setPrimaryType(e.target.value as PropertyType)}>
276
- * <option value="Accommodation">Hotels</option>
277
- * <option value="Restaurant">Restaurants</option>
278
- * <option value="Attraction">Attractions</option>
279
- * </select>
280
- * );
281
- * ```
282
- */
283
- declare function usePrimaryType(mapFirst: MapFirstCore | null): [PropertyType, (type: PropertyType) => void];
284
- /**
285
- * Hook to access and control the selected marker.
286
- * Returns the current selected marker ID and a setter function.
287
- * Note: This hook requires the MapFirstCore instance. For simpler usage with reactive updates,
288
- * use state.selectedPropertyId from useMapFirstCore instead.
289
- *
290
- * @example
291
- * ```tsx
292
- * const { mapFirst } = useMapFirstCore({ ... });
293
- * const [selectedMarker, setSelectedMarker] = useSelectedMarker(mapFirst);
294
- *
295
- * return (
296
- * <div>
297
- * <p>Selected: {selectedMarker || 'None'}</p>
298
- * <button onClick={() => setSelectedMarker(null)}>Clear Selection</button>
299
- * </div>
300
- * );
301
- * ```
302
- */
303
- declare function useSelectedMarker(mapFirst: MapFirstCore | null): [number | null, (id: number | null) => void];
304
- /**
305
- * Hook for MapLibre GL JS integration.
306
- * Automatically attaches the map when both the SDK instance and map are available.
307
- *
308
- * @example
309
- * ```tsx
310
- * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: "Paris", country: "France" } });
311
- * const mapRef = useRef<maplibregl.Map | null>(null);
312
- *
313
- * useMapLibreAttachment({
314
- * mapFirst,
315
- * map: mapRef.current,
316
- * maplibregl: maplibregl,
317
- * onMarkerClick: (marker) => console.log(marker)
318
- * });
319
- *
320
- * // Access reactive state
321
- * console.log(state?.properties);
322
- * ```
323
- */
324
- declare function useMapLibreAttachment({ mapFirst, map, maplibregl, onMarkerClick, }: {
325
- mapFirst: MapFirstCore | null;
326
- map: any | null;
327
- maplibregl: MapLibreNamespace;
328
- onMarkerClick?: (marker: Property) => void;
329
- }): void;
330
- /**
331
- * Hook for Google Maps integration.
332
- * Automatically attaches the map when both the SDK instance and map are available.
333
- *
334
- * @example
335
- * ```tsx
336
- * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: "Tokyo", country: "Japan" } });
337
- * const mapRef = useRef<google.maps.Map | null>(null);
233
+ * }, [mapLibreInstance]);
338
234
  *
339
- * useGoogleMapsAttachment({
340
- * mapFirst,
341
- * map: mapRef.current,
342
- * google: window.google,
343
- * onMarkerClick: (marker) => console.log(marker)
235
+ * // Use search methods
236
+ * await propertiesSearch.search({
237
+ * body: { city: "Paris", country: "France" }
344
238
  * });
345
239
  *
346
- * // Access reactive state
347
- * console.log(state?.isSearching);
348
- * ```
349
- */
350
- declare function useGoogleMapsAttachment({ mapFirst, map, google, onMarkerClick, }: {
351
- mapFirst: MapFirstCore | null;
352
- map: any | null;
353
- google: GoogleMapsNamespace;
354
- onMarkerClick?: (marker: Property) => void;
355
- }): void;
356
- /**
357
- * Hook for Mapbox GL JS integration.
358
- * Automatically attaches the map when both the SDK instance and map are available.
359
- *
360
- * @example
361
- * ```tsx
362
- * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: "London", country: "United Kingdom" } });
363
- * const mapRef = useRef<mapboxgl.Map | null>(null);
364
- *
365
- * useMapboxAttachment({
366
- * mapFirst,
367
- * map: mapRef.current,
368
- * mapboxgl: mapboxgl,
369
- * onMarkerClick: (marker) => console.log(marker)
240
+ * await smartFilterSearch.search({
241
+ * query: "hotels near beach with pool"
370
242
  * });
371
243
  *
372
- * // Access reactive state
373
- * console.log(state?.filters);
374
- * ```
375
- */
376
- declare function useMapboxAttachment({ mapFirst, map, mapboxgl, onMarkerClick, }: {
377
- mapFirst: MapFirstCore | null;
378
- map: any | null;
379
- mapboxgl: MapboxNamespace;
380
- onMarkerClick?: (marker: Property) => void;
381
- }): void;
382
- /**
383
- * Legacy hook that creates the MapFirstCore instance with a map immediately.
384
- * Use useMapFirstCore + useMap*Attachment hooks for better control.
385
- *
386
- * @deprecated Use useMapFirstCore and platform-specific attachment hooks instead
387
- */
388
- declare function useMapFirst(options: MapFirstOptions | null): React__default.RefObject<MapFirstCore | null>;
389
- /**
390
- * Hook to run properties search with the MapFirst SDK.
391
- * Returns a function to trigger the search and loading state.
392
- *
393
- * @example
394
- * ```tsx
395
- * const { mapFirst } = useMapFirstCore({ ... });
396
- * const { search, isLoading, error } = usePropertiesSearch(mapFirst);
397
- *
398
- * const handleSearch = async () => {
399
- * await search({
400
- * body: {
401
- * city: "Paris",
402
- * country: "France",
403
- * filters: {
404
- * checkIn: new Date(),
405
- * checkOut: new Date(Date.now() + 86400000),
406
- * numAdults: 2,
407
- * numRooms: 1
408
- * }
409
- * }
410
- * });
411
- * };
412
- * ```
413
- */
414
- declare function usePropertiesSearch(mapFirst: MapFirstCore | null): {
415
- search: (options: {
416
- body: InitialRequestBody;
417
- beforeApplyProperties?: (data: any) => {
418
- price?: any;
419
- limit?: number;
420
- };
421
- smartFiltersClearable?: boolean;
422
- }) => Promise<{
423
- location_id?: number;
424
- filters: _mapfirst_ai_core.FilterSchema;
425
- properties: Property[];
426
- isComplete: boolean | undefined;
427
- pollingLink: string | undefined;
428
- durationSeconds: number;
429
- } | null>;
430
- isLoading: boolean;
431
- error: Error | null;
432
- };
433
- /**
434
- * Hook to run smart filter search with the MapFirst SDK.
435
- * Returns a function to trigger the search and loading state.
436
- *
437
- * @example
438
- * ```tsx
439
- * const { mapFirst } = useMapFirstCore({ ... });
440
- * const { search, isLoading, error } = useSmartFilterSearch(mapFirst);
441
- *
442
- * const handleSearch = async () => {
443
- * await search({
444
- * query: "hotels near beach with pool"
445
- * });
446
- * };
447
- *
448
- * // Or with filters
449
- * const handleFilterSearch = async () => {
450
- * await search({
451
- * filters: [
452
- * { id: "pool", label: "Pool", type: "amenity", value: "pool" },
453
- * { id: "4star", label: "4 Star", type: "starRating", value: "4", numericValue: 4 }
454
- * ]
455
- * });
456
- * };
457
- * ```
458
- */
459
- declare function useSmartFilterSearch(mapFirst: MapFirstCore | null): {
460
- search: (options: {
461
- query?: string;
462
- filters?: SmartFilter[];
463
- onProcessFilters?: (filters: any, location_id?: number) => {
464
- smartFilters?: SmartFilter[];
465
- price?: any;
466
- limit?: number;
467
- language?: string;
468
- };
469
- }) => Promise<{
470
- location_id?: number;
471
- filters: _mapfirst_ai_core.FilterSchema;
472
- properties: Property[];
473
- isComplete: boolean | undefined;
474
- pollingLink: string | undefined;
475
- durationSeconds: number;
476
- } | null>;
477
- isLoading: boolean;
478
- error: Error | null;
479
- };
480
- /**
481
- * Hook to perform a bounds search when the user moves the map
482
- *
483
- * @example
484
- * ```tsx
485
- * const { mapFirst, state } = useMapFirstCore({ ... });
486
- * const { performBoundsSearch, isSearching } = useMapFirstBoundsSearch(mapFirst);
487
- *
488
- * // When user clicks "Search this area" button
489
- * <button onClick={performBoundsSearch} disabled={!state.pendingBounds || isSearching}>
490
- * Search this area
491
- * </button>
244
+ * await boundsSearch.perform();
492
245
  * ```
493
246
  */
494
- declare function useMapFirstBoundsSearch(mapFirst: MapFirstCore | null): {
495
- performBoundsSearch: () => Promise<{
496
- location_id?: number;
497
- filters: _mapfirst_ai_core.FilterSchema;
498
- properties: Property[];
499
- isComplete: boolean | undefined;
500
- pollingLink: string | undefined;
501
- durationSeconds: number;
502
- } | null>;
503
- isSearching: boolean;
504
- error: Error | null;
247
+ declare function useMapFirst(options: BaseMapFirstOptions): {
248
+ instance: MapFirstCore | null;
249
+ state: MapState | null;
250
+ setPrimaryType: (type: PropertyType) => void;
251
+ setSelectedMarker: (id: number | null) => void;
252
+ propertiesSearch: {
253
+ search: (options: {
254
+ body: InitialRequestBody;
255
+ beforeApplyProperties?: (data: any) => {
256
+ price?: any;
257
+ limit?: number;
258
+ };
259
+ smartFiltersClearable?: boolean;
260
+ }) => Promise<{
261
+ location_id?: number;
262
+ filters: _mapfirst_ai_core.FilterSchema;
263
+ properties: Property[];
264
+ isComplete: boolean | undefined;
265
+ pollingLink: string | undefined;
266
+ durationSeconds: number;
267
+ } | null>;
268
+ isLoading: boolean;
269
+ error: Error | null;
270
+ };
271
+ smartFilterSearch: {
272
+ search: (options: {
273
+ query?: string;
274
+ filters?: SmartFilter[];
275
+ onProcessFilters?: (filters: any, location_id?: number) => {
276
+ smartFilters?: SmartFilter[];
277
+ price?: any;
278
+ limit?: number;
279
+ language?: string;
280
+ };
281
+ }) => Promise<{
282
+ location_id?: number;
283
+ filters: _mapfirst_ai_core.FilterSchema;
284
+ properties: Property[];
285
+ isComplete: boolean | undefined;
286
+ pollingLink: string | undefined;
287
+ durationSeconds: number;
288
+ } | null>;
289
+ isLoading: boolean;
290
+ error: Error | null;
291
+ };
292
+ boundsSearch: {
293
+ perform: () => Promise<{
294
+ location_id?: number;
295
+ filters: _mapfirst_ai_core.FilterSchema;
296
+ properties: Property[];
297
+ isComplete: boolean | undefined;
298
+ pollingLink: string | undefined;
299
+ durationSeconds: number;
300
+ } | null>;
301
+ isSearching: boolean;
302
+ error: Error | null;
303
+ };
304
+ attachMapLibre: (map: any, maplibregl: MapLibreNamespace, options?: {
305
+ onMarkerClick?: (marker: Property) => void;
306
+ }) => void;
307
+ attachGoogle: (map: any, google: GoogleMapsNamespace, options?: {
308
+ onMarkerClick?: (marker: Property) => void;
309
+ }) => void;
310
+ attachMapbox: (map: any, mapboxgl: MapboxNamespace, options?: {
311
+ onMarkerClick?: (marker: Property) => void;
312
+ }) => void;
505
313
  };
506
- /**
507
- * Helper component that simply renders the markers it receives so non-React environments
508
- * can verify data flows before wiring the SDK into a map.
509
- */
510
- declare function MarkerDebugList({ markers }: {
511
- markers: Property[];
512
- }): react_jsx_runtime.JSX.Element;
513
314
 
514
- export { Chip, type ChipProps, CloseIcon, EditIcon, type Filter, FilterChips, type FilterChipsProps, type IconProps, type Locale, MarkerDebugList, MinRatingFilterChip, NextIcon, PriceRangeFilterChip, type PriceRangeValue, RestaurantPriceLevelChip, type RestaurantPriceLevelChipProps, SearchIcon, SmartFilter$1 as SmartFilter, type SmartFilterProps, StarIcon, TransformedQueryChip, type TransformedQueryChipProps, createMinRatingFilterLabel, createPriceRangeFilterLabel, formatRatingValue, renderStars, useFilterScroll, useGoogleMapsAttachment, useIsPortrait, useMapFirst, useMapFirstBoundsSearch, useMapFirstCore, useMapFirstProperties, useMapFirstSelectedProperty, useMapLibreAttachment, useMapboxAttachment, usePrimaryType, usePropertiesSearch, useSelectedMarker, useSmartFilterSearch, useTranslation };
315
+ export { Chip, type ChipProps, CloseIcon, EditIcon, type Filter, FilterChips, type FilterChipsProps, type IconProps, type Locale, MinRatingFilterChip, NextIcon, PriceRangeFilterChip, type PriceRangeValue, RestaurantPriceLevelChip, type RestaurantPriceLevelChipProps, SearchIcon, SmartFilter$1 as SmartFilter, type SmartFilterProps, StarIcon, TransformedQueryChip, type TransformedQueryChipProps, createMinRatingFilterLabel, createPriceRangeFilterLabel, formatRatingValue, renderStars, useFilterScroll, useMapFirst, useTranslation };