@hotelcard/ui 0.0.41 → 0.0.43

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/README.md CHANGED
@@ -107,13 +107,41 @@ The package includes built-in translations for `de`, `en`, `fr`, and `it` locale
107
107
  | `FAQ` | Expandable FAQ accordion |
108
108
  | `Benefits` | Benefits list with icons |
109
109
  | `Pin` | Location pin marker |
110
+
111
+ ### Search Components
112
+
113
+ | Component | Description |
114
+ |-----------|-------------|
110
115
  | `DateSelector` | Date selector container component |
111
116
  | `WhenContent` | Date/month picker for search |
112
117
  | `DualCalendar` | Calendar component for date range selection |
113
- | `GuestContent` | Guest selector with adults, children (with ages), and pet toggle |
118
+ | `GuestContent` | Guest selector content with adults, children (with ages), and pet toggle |
119
+ | `GuestSelector` | Full guest selector with dropdown trigger |
114
120
  | `HotelCard` | Hotel card for search results with image carousel, rating, and pricing |
121
+ | `HotelCardImage` | Hotel image carousel component |
122
+ | `HotelCardContent` | Hotel card content with rating, price, benefits |
115
123
  | `SearchModal` | Full-screen search modal with destination, dates, and guest selection |
116
124
  | `SearchModalContent` | Content-only version for custom modal wrappers (e.g., IonModal) |
125
+ | `LocationAutocomplete` | Location search input with autocomplete suggestions |
126
+ | `MobileSortModal` | Mobile-friendly sort options modal |
127
+ | `SearchControlsBar` | Search controls bar with sort, view toggle, and result count |
128
+
129
+ ### Filter Components
130
+
131
+ | Component | Description |
132
+ |-----------|-------------|
133
+ | `FilterCheckboxItem` | Base checkbox item for filters |
134
+ | `CollapsibleFilterSection` | Expandable/collapsible filter section wrapper |
135
+ | `PriceRangeFilter` | Price range slider filter |
136
+ | `HotelCategoryFilter` | Hotel star rating filter (1-5 stars) |
137
+ | `ReviewsFilter` | Guest review rating filter |
138
+ | `ExperienceFilter` | Experience/theme filter |
139
+ | `RegionsFilter` | Region/location filter with search |
140
+ | `CheckboxFilter` | Generic checkbox filter component |
141
+ | `MealsFilter` | Meal plan filter (breakfast, half-board, etc.) |
142
+ | `TransportFilter` | Transport options filter |
143
+ | `WellnessFilter` | Wellness amenities filter |
144
+ | `SelectedFiltersRow` | Display row showing active filters with remove option |
117
145
 
118
146
  ### Icons
119
147
 
@@ -348,6 +376,118 @@ import { Checkbox, RadioButton } from '@hotelcard/ui';
348
376
  />
349
377
  ```
350
378
 
379
+ ### LocationAutocomplete
380
+
381
+ ```tsx
382
+ import { LocationAutocomplete, type LocationSuggestion } from '@hotelcard/ui';
383
+
384
+ const fetchSuggestions = async (query: string): Promise<LocationSuggestion[]> => {
385
+ const response = await fetch(`/api/autocomplete?q=${query}`);
386
+ return response.json();
387
+ };
388
+
389
+ <LocationAutocomplete
390
+ value={query}
391
+ onChange={setQuery}
392
+ onAutocomplete={fetchSuggestions}
393
+ onSelect={(suggestion) => console.log('Selected:', suggestion)}
394
+ onSubmit={(value, coordinates, regionId) => {
395
+ // Handle search with coordinates or region
396
+ }}
397
+ placeholder="Search destination..."
398
+ />
399
+ ```
400
+
401
+ ### MobileSortModal
402
+
403
+ ```tsx
404
+ import { MobileSortModal, type SortOption } from '@hotelcard/ui';
405
+
406
+ const [sortBy, setSortBy] = useState<SortOption>('relevance');
407
+ const [isOpen, setIsOpen] = useState(false);
408
+
409
+ <MobileSortModal
410
+ isOpen={isOpen}
411
+ onClose={() => setIsOpen(false)}
412
+ value={sortBy}
413
+ onChange={setSortBy}
414
+ />
415
+ ```
416
+
417
+ Sort options: `'relevance'` | `'price_asc'` | `'price_desc'` | `'rating'`
418
+
419
+ ### SearchControlsBar
420
+
421
+ ```tsx
422
+ import { SearchControlsBar, type SearchParams, type ViewMode } from '@hotelcard/ui';
423
+
424
+ <SearchControlsBar
425
+ onSearch={(params: SearchParams) => {
426
+ // params: { query, guests, petFilter, dateRange, monthFilter, coordinates }
427
+ performSearch(params);
428
+ }}
429
+ onGuestChange={setGuests}
430
+ onAutocomplete={fetchLocationSuggestions}
431
+ getGuestsDisplay={() => `${guests.adults} adults, ${guests.children} children`}
432
+ getDateDisplay={() => dateRange ? formatDateRange(dateRange) : 'Anytime'}
433
+ onMobileClick={() => openSearchModal()}
434
+ onFilterClick={() => openFilterModal()}
435
+ onSortClick={() => openSortModal()}
436
+ initialQuery=""
437
+ initialGuests={{ adults: 2, children: 0, childrenAges: [] }}
438
+ viewMode={viewMode}
439
+ onViewModeChange={setViewMode}
440
+ />
441
+ ```
442
+
443
+ ### Filter Components
444
+
445
+ ```tsx
446
+ import {
447
+ PriceRangeFilter,
448
+ HotelCategoryFilter,
449
+ ReviewsFilter,
450
+ RegionsFilter,
451
+ SelectedFiltersRow,
452
+ type SelectedFilter,
453
+ } from '@hotelcard/ui';
454
+
455
+ // Price range filter with dual slider
456
+ <PriceRangeFilter
457
+ minPrice={0}
458
+ maxPrice={500}
459
+ value={[priceMin, priceMax]}
460
+ onChange={(range) => setPriceRange(range)}
461
+ currency="CHF"
462
+ />
463
+
464
+ // Hotel star rating filter
465
+ <HotelCategoryFilter
466
+ selectedStars={selectedStars}
467
+ onStarsChange={setSelectedStars}
468
+ />
469
+
470
+ // Guest review rating filter
471
+ <ReviewsFilter
472
+ selectedRatings={selectedRatings}
473
+ onRatingsChange={setSelectedRatings}
474
+ />
475
+
476
+ // Region filter with search
477
+ <RegionsFilter
478
+ regions={regionOptions}
479
+ selectedRegions={selectedRegions}
480
+ onRegionsChange={setSelectedRegions}
481
+ />
482
+
483
+ // Display active filters with remove buttons
484
+ <SelectedFiltersRow
485
+ filters={activeFilters}
486
+ onRemove={(filter) => removeFilter(filter)}
487
+ onClearAll={() => clearAllFilters()}
488
+ />
489
+ ```
490
+
351
491
  ---
352
492
 
353
493
  ## Types
@@ -356,7 +496,7 @@ All components export their prop types:
356
496
 
357
497
  ```typescript
358
498
  import type {
359
- // Component Props
499
+ // UI Component Props
360
500
  ButtonProps,
361
501
  BadgeProps,
362
502
  InputProps,
@@ -376,10 +516,13 @@ import type {
376
516
  BenefitsProps,
377
517
  BenefitItem,
378
518
  PinProps,
519
+
520
+ // Search Component Props
379
521
  DateSelectorProps,
380
522
  WhenContentProps,
381
523
  DateRange,
382
524
  GuestContentProps,
525
+ GuestSelectorProps,
383
526
  GuestCounts,
384
527
  ChildAgeError,
385
528
  HotelCardProps,
@@ -389,6 +532,30 @@ import type {
389
532
  SearchModalProps,
390
533
  SearchModalContentProps,
391
534
  SearchModalSearchParams,
535
+ LocationAutocompleteProps,
536
+ LocationSuggestion,
537
+ MobileSortModalProps,
538
+ SortOption,
539
+ SearchControlsBarProps,
540
+ SearchControlsBarSearchParams,
541
+ ViewMode,
542
+
543
+ // Filter Component Props
544
+ FilterCheckboxItemProps,
545
+ CollapsibleFilterSectionProps,
546
+ PriceRangeFilterProps,
547
+ HotelCategoryFilterProps,
548
+ CategoryOption,
549
+ ReviewsFilterProps,
550
+ ReviewOption,
551
+ ExperienceFilterProps,
552
+ ThemeAggregation,
553
+ RegionsFilterProps,
554
+ RegionOption,
555
+ CheckboxFilterProps,
556
+ FilterOption,
557
+ SelectedFiltersRowProps,
558
+ SelectedFilter,
392
559
 
393
560
  // Context Types
394
561
  UIContextValue,
@@ -415,7 +582,7 @@ import type {
415
582
  ## Hooks
416
583
 
417
584
  ```typescript
418
- import { useDebounce, useResponsive, useWindowData, useUIContext } from '@hotelcard/ui';
585
+ import { useDebounce, useResponsive, useWindowData, useUIContext, useTranslation } from '@hotelcard/ui';
419
586
 
420
587
  // Debounce a value
421
588
  const debouncedSearch = useDebounce(searchTerm, 300);
@@ -429,8 +596,19 @@ const { locale, currency } = useWindowData();
429
596
  // UI Context with translation function
430
597
  const { locale, currency, isDesktop, t } = useUIContext();
431
598
  t('label.rating-excellent', 'Excellent'); // Returns translated string
599
+
600
+ // Translation helper (wraps UIContext for convenience)
601
+ const { t, i18n } = useTranslation();
432
602
  ```
433
603
 
604
+ | Hook | Description | Returns |
605
+ |------|-------------|---------|
606
+ | `useDebounce` | Debounce a value | Debounced value |
607
+ | `useResponsive` | Breakpoint detection | `{ isDesktop }` |
608
+ | `useWindowData` | Window/context data | `{ locale, currency }` |
609
+ | `useUIContext` | Full UI context access | `{ locale, currency, isDesktop, t }` |
610
+ | `useTranslation` | i18n helper | `{ t, i18n }` |
611
+
434
612
  ---
435
613
 
436
614
  ## Utilities