mautourco-components 0.2.103 → 0.2.105

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.
@@ -29,6 +29,7 @@ var LocationDropdown = function (_a) {
29
29
  var _q = useState(false), isOpen = _q[0], setIsOpen = _q[1];
30
30
  var _r = useState(''), searchQuery = _r[0], setSearchQuery = _r[1];
31
31
  var dropdownRef = useRef(null);
32
+ var dropdownPanelRef = useRef(null);
32
33
  var inputRef = useRef(null);
33
34
  var searchInputRef = useRef(null);
34
35
  // Close dropdown when clicking outside
@@ -45,7 +46,11 @@ var LocationDropdown = function (_a) {
45
46
  }, []);
46
47
  // Scroll to input when dropdown opens (if scrollOnOpen is true)
47
48
  useEffect(function () {
48
- scrollIntoViewOnOpen(inputRef, isOpen, scrollOnOpen);
49
+ setTimeout(function () {
50
+ if (dropdownPanelRef.current) {
51
+ scrollIntoViewOnOpen(dropdownPanelRef, isOpen, scrollOnOpen);
52
+ }
53
+ }, 10);
49
54
  }, [isOpen, scrollOnOpen]);
50
55
  // Reset search when dropdown closes
51
56
  useEffect(function () {
@@ -88,9 +93,7 @@ var LocationDropdown = function (_a) {
88
93
  if (!searchQuery.trim())
89
94
  return opts;
90
95
  var query = searchQuery.toLowerCase();
91
- return opts.filter(function (option) {
92
- return option.label.toLowerCase().includes(query);
93
- });
96
+ return opts.filter(function (option) { return option.label.toLowerCase().includes(query); });
94
97
  };
95
98
  var getSelectedOption = function () {
96
99
  if (selectedValue) {
@@ -156,13 +159,15 @@ var LocationDropdown = function (_a) {
156
159
  var displayText = selectedOption ? selectedOption.label : placeholder;
157
160
  // Prepare all options (flat or grouped) and filter them
158
161
  var allOptionsRaw = groups.length > 0 ? groups : [{ id: 'default', label: '', options: options }];
159
- var allOptions = allOptionsRaw.map(function (group) { return (__assign(__assign({}, group), { options: filterOptions(group.options) })); }).filter(function (group) { return group.options.length > 0; });
162
+ var allOptions = allOptionsRaw
163
+ .map(function (group) { return (__assign(__assign({}, group), { options: filterOptions(group.options) })); })
164
+ .filter(function (group) { return group.options.length > 0; });
160
165
  // Skeleton loader component
161
166
  var SkeletonOption = function () { return (_jsxs("div", { className: "location-dropdown__option location-dropdown__option--skeleton", children: [_jsx("div", { className: "location-dropdown__skeleton-icon" }), _jsx("div", { className: "location-dropdown__skeleton-text" })] })); };
162
167
  // Render skeleton loading state
163
168
  var renderSkeletonLoading = function () { return (_jsx("div", { className: "location-dropdown__panel", children: _jsx("div", { className: "location-dropdown__content", style: { maxHeight: "".concat(maxHeight, "px") }, children: _jsx("div", { className: "location-dropdown__options-wrapper", children: _jsx("div", { className: "location-dropdown__group", children: _jsx("div", { className: "location-dropdown__group-options", children: __spreadArray([], Array(5), true).map(function (_, index) { return (_jsx(SkeletonOption, {}, "skeleton-".concat(index))); }) }) }) }) }) })); };
164
169
  return (_jsxs("div", { ref: dropdownRef, className: "location-dropdown location-dropdown--".concat(type, " ").concat(disabled ? 'location-dropdown--disabled' : '', " ").concat(className), children: [label && (_jsx("div", { className: "location-dropdown__label", children: _jsx(Text, { size: "sm", variant: "medium", children: label }) })), _jsxs("div", { ref: inputRef, className: "location-dropdown__input location-dropdown__input--".concat(getDropdownState()), onClick: handleToggleDropdown, children: [_jsxs("div", { className: "location-dropdown__input-content", children: [_jsx(Icon, { name: getInputIcon(), size: "sm", className: "location-dropdown__input-icon ".concat(!selectedOption ? 'location-dropdown__input-icon--placeholder' : '') }), isOpen ? (_jsx("input", { ref: searchInputRef, type: "text", className: "location-dropdown__input-text ".concat(!selectedOption && !searchQuery ? 'location-dropdown__input-text--placeholder' : ''), placeholder: displayText, value: searchQuery, onChange: handleSearchChange, onClick: function (e) { return e.stopPropagation(); }, disabled: disabled, autoFocus: true })) : (_jsx("span", { className: "location-dropdown__input-text ".concat(!selectedOption ? 'location-dropdown__input-text--placeholder' : ''), children: displayText }))] }), _jsx(Icon, { name: "chevron-down", size: "sm", className: "location-dropdown__input-chevron" })] }), isOpen &&
165
- (loading ? (renderSkeletonLoading()) : (_jsx("div", { className: "location-dropdown__panel", children: _jsx("div", { className: "location-dropdown__content", style: { maxHeight: "".concat(maxHeight, "px") }, children: _jsx("div", { className: "location-dropdown__options-wrapper", children: allOptions.length === 0 ? (_jsx("div", { className: "location-dropdown__no-results", children: _jsx(Text, { size: "sm", variant: "medium", children: "No locations found" }) })) : (allOptions.map(function (group, groupIndex) { return (_jsxs("div", { className: "location-dropdown__group", children: [showGroupTitles && group.label && groups.length > 0 && (_jsxs(_Fragment, { children: [groupIndex > 0 && _jsx("div", { className: "location-dropdown__divider" }), _jsx("div", { className: "location-dropdown__group-header", children: _jsx(Text, { size: "xs", variant: "bold", children: group.label }) })] })), _jsx("div", { className: "location-dropdown__group-options", children: group.options.map(function (option) {
170
+ (loading ? (renderSkeletonLoading()) : (_jsx("div", { className: "location-dropdown__panel", ref: dropdownPanelRef, children: _jsx("div", { className: "location-dropdown__content", style: { maxHeight: "".concat(maxHeight, "px") }, children: _jsx("div", { className: "location-dropdown__options-wrapper", children: allOptions.length === 0 ? (_jsx("div", { className: "location-dropdown__no-results", children: _jsx(Text, { size: "sm", variant: "medium", children: "No locations found" }) })) : (allOptions.map(function (group, groupIndex) { return (_jsxs("div", { className: "location-dropdown__group", children: [showGroupTitles && group.label && groups.length > 0 && (_jsxs(_Fragment, { children: [groupIndex > 0 && (_jsx("div", { className: "location-dropdown__divider" })), _jsx("div", { className: "location-dropdown__group-header", children: _jsx(Text, { size: "xs", variant: "bold", children: group.label }) })] })), _jsx("div", { className: "location-dropdown__group-options", children: group.options.map(function (option) {
166
171
  var isSelected = effectiveSelectedValue === option.id;
167
172
  var isDisabled = option.disabled || disabled;
168
173
  return (_jsxs("div", { className: "location-dropdown__option ".concat(isSelected ? 'location-dropdown__option--selected' : '', " ").concat(isDisabled ? 'location-dropdown__option--disabled' : ''), onClick: function () { return !isDisabled && handleOptionSelect(option); }, children: [_jsx(Icon, { name: getOptionIcon(option, isSelected), size: "sm", className: "location-dropdown__option-icon" }), _jsx("span", { className: "location-dropdown__option-text", children: option.label })] }, option.id));
@@ -66,6 +66,7 @@ export interface PaxSelectorProps {
66
66
  ageRange?: number[];
67
67
  /** Whether to check if age inputs are empty and show error state */
68
68
  checkEmpty?: boolean;
69
+ onPaxOpenChange?: () => void;
69
70
  }
70
71
  export declare const DEFAULT_PAX_DATA_WITH_ADULTS: PaxData;
71
72
  export declare const CHILD_CATEGORY_AGES: number[];
@@ -183,7 +183,7 @@ var RoomEditor = function (_a) {
183
183
  }) }, "infant-chunk-".concat(chunkIndex))); })] })] })), _jsx(ClientTypeSelector, { value: room.clientType, onChange: function (val) { return handleFieldChange('clientType', val); } })] })] }));
184
184
  };
185
185
  var PaxSelector = function (_a) {
186
- var _b = _a.label, label = _b === void 0 ? 'Number of pax' : _b, value = _a.value, onChange = _a.onChange, onAddRoom = _a.onAddRoom, onDone = _a.onDone, _c = _a.placeholder, placeholder = _c === void 0 ? 'Select pax' : _c, _d = _a.className, className = _d === void 0 ? '' : _d, _e = _a.maxAdults, maxAdults = _e === void 0 ? 10 : _e, _f = _a.maxTeens, maxTeens = _f === void 0 ? 10 : _f, _g = _a.maxChildren, maxChildren = _g === void 0 ? 10 : _g, _h = _a.maxInfants, maxInfants = _h === void 0 ? 10 : _h, _j = _a.showAddRoom, showAddRoom = _j === void 0 ? true : _j, _k = _a.multipleRooms, multipleRooms = _k === void 0 ? false : _k, defaultRooms = _a.defaultRooms, onRoomsChange = _a.onRoomsChange, onRemoveRoom = _a.onRemoveRoom, _l = _a.defaultPaxData, defaultPaxData = _l === void 0 ? DEFAULT_PAX_DATA_WITH_ADULTS : _l, _m = _a.ageRange, ageRange = _m === void 0 ? CHILD_CATEGORY_AGES : _m, _o = _a.scrollOnOpen, scrollOnOpen = _o === void 0 ? false : _o, _p = _a.disabled, disabled = _p === void 0 ? false : _p, _q = _a.checkEmpty, checkEmpty = _q === void 0 ? false : _q;
186
+ var _b = _a.label, label = _b === void 0 ? 'Number of pax' : _b, value = _a.value, onChange = _a.onChange, onAddRoom = _a.onAddRoom, onDone = _a.onDone, _c = _a.placeholder, placeholder = _c === void 0 ? 'Select pax' : _c, _d = _a.className, className = _d === void 0 ? '' : _d, _e = _a.maxAdults, maxAdults = _e === void 0 ? 10 : _e, _f = _a.maxTeens, maxTeens = _f === void 0 ? 10 : _f, _g = _a.maxChildren, maxChildren = _g === void 0 ? 10 : _g, _h = _a.maxInfants, maxInfants = _h === void 0 ? 10 : _h, _j = _a.showAddRoom, showAddRoom = _j === void 0 ? true : _j, _k = _a.multipleRooms, multipleRooms = _k === void 0 ? false : _k, defaultRooms = _a.defaultRooms, onRoomsChange = _a.onRoomsChange, onRemoveRoom = _a.onRemoveRoom, _l = _a.defaultPaxData, defaultPaxData = _l === void 0 ? DEFAULT_PAX_DATA_WITH_ADULTS : _l, _m = _a.ageRange, ageRange = _m === void 0 ? CHILD_CATEGORY_AGES : _m, _o = _a.scrollOnOpen, scrollOnOpen = _o === void 0 ? false : _o, _p = _a.disabled, disabled = _p === void 0 ? false : _p, _q = _a.checkEmpty, checkEmpty = _q === void 0 ? false : _q, onPaxOpenChange = _a.onPaxOpenChange;
187
187
  var _r = useState(false), isOpen = _r[0], setIsOpen = _r[1];
188
188
  var _s = useState(value || defaultPaxData || DEFAULT_PAX_DATA), internalData = _s[0], setInternalData = _s[1];
189
189
  var _t = useState(defaultRooms || [__assign(__assign({}, DEFAULT_PAX_DATA), { roomId: '1' })]), rooms = _t[0], setRooms = _t[1];
@@ -312,7 +312,7 @@ var PaxSelector = function (_a) {
312
312
  if (multipleRooms) {
313
313
  return rooms.some(function (room) { return room.teens > 0 || room.children > 0 || room.infants > 0; });
314
314
  }
315
- return internalData.teens > 0 || internalData.children > 0 || internalData.infants > 0;
315
+ return (internalData.teens > 0 || internalData.children > 0 || internalData.infants > 0);
316
316
  };
317
317
  // Handle clicks outside the dropdown
318
318
  useEffect(function () {
@@ -327,6 +327,7 @@ var PaxSelector = function (_a) {
327
327
  if (isOpen) {
328
328
  document.addEventListener('mousedown', handleClickOutside);
329
329
  }
330
+ onPaxOpenChange === null || onPaxOpenChange === void 0 ? void 0 : onPaxOpenChange();
330
331
  return function () {
331
332
  document.removeEventListener('mousedown', handleClickOutside);
332
333
  };
@@ -33,6 +33,8 @@ export interface SearchBarTransferProps {
33
33
  className?: string;
34
34
  /** Whether to scroll to the input when the calendar opens */
35
35
  scrollOnOpen?: boolean;
36
+ /** Callback when pax selector opens */
37
+ onPaxOpenChange?: () => void;
36
38
  }
37
- declare function SearchBarTransfer({ mode: initialMode, locations, defaultRoundTripData, defaultTransferLines, defaultSameVehicle, onSearch, onChange, onRemove, className, scrollOnOpen, }: SearchBarTransferProps): import("react/jsx-runtime").JSX.Element;
39
+ declare function SearchBarTransfer({ mode: initialMode, locations, defaultRoundTripData, defaultTransferLines, defaultSameVehicle, onSearch, onChange, onRemove, className, scrollOnOpen, onPaxOpenChange, }: SearchBarTransferProps): import("react/jsx-runtime").JSX.Element;
38
40
  export default SearchBarTransfer;
@@ -32,7 +32,7 @@ import RoundTrip from '../RoundTrip/RoundTrip';
32
32
  import TransferLine from '../TransferLine/TransferLine';
33
33
  var transferIdCounter = 0;
34
34
  function SearchBarTransfer(_a) {
35
- var _b = _a.mode, initialMode = _b === void 0 ? 'roundtrip' : _b, _c = _a.locations, locations = _c === void 0 ? { options: [], groups: [] } : _c, defaultRoundTripData = _a.defaultRoundTripData, defaultTransferLines = _a.defaultTransferLines, _d = _a.defaultSameVehicle, defaultSameVehicle = _d === void 0 ? false : _d, onSearch = _a.onSearch, onChange = _a.onChange, onRemove = _a.onRemove, _e = _a.className, className = _e === void 0 ? '' : _e, _f = _a.scrollOnOpen, scrollOnOpen = _f === void 0 ? false : _f;
35
+ var _b = _a.mode, initialMode = _b === void 0 ? 'roundtrip' : _b, _c = _a.locations, locations = _c === void 0 ? { options: [], groups: [] } : _c, defaultRoundTripData = _a.defaultRoundTripData, defaultTransferLines = _a.defaultTransferLines, _d = _a.defaultSameVehicle, defaultSameVehicle = _d === void 0 ? false : _d, onSearch = _a.onSearch, onChange = _a.onChange, onRemove = _a.onRemove, _e = _a.className, className = _e === void 0 ? '' : _e, _f = _a.scrollOnOpen, scrollOnOpen = _f === void 0 ? false : _f, onPaxOpenChange = _a.onPaxOpenChange;
36
36
  // Generate unique ID for transfer lines
37
37
  var generateTransferId = function () {
38
38
  transferIdCounter += 1;
@@ -377,7 +377,7 @@ function SearchBarTransfer(_a) {
377
377
  onSearch === null || onSearch === void 0 ? void 0 : onSearch(data);
378
378
  }
379
379
  };
380
- return (_jsxs("div", { className: "search-bar-transfer ".concat(className), children: [_jsxs("div", { className: "search-bar-transfer__header", children: [_jsx(Heading, { level: 5, variant: "bold", color: "accent", children: "Select your transfer details" }), _jsx("div", { className: "search-bar-transfer__mode-selector", children: _jsx(SegmentedButton, { options: modeOptions, value: mode, onChange: handleModeChange, name: "transfer-mode" }) })] }), mode === 'roundtrip' ? (_jsxs(_Fragment, { children: [_jsx(RoundTrip, { id: "roundtrip-main", locations: locations, paxData: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.paxData, arrivalDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.arrivalDate, departureDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.departureDate, pickupDropoffPoint: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.pickupDropoffPoint, accommodation: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.accommodation, onChange: setRoundTripData, checkEmpty: error !== null, scrollOnOpen: scrollOnOpen }, "roundtrip-".concat(validationTrigger)), _jsx("div", { className: "search-bar-transfer__transfer-type", children: renderTransferTypeButtons(handleAddTransferFromRoundTrip) })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "search-bar-transfer__transfer-type", children: [_jsx(Text, { size: "lg", variant: "bold", color: "subtle", as: "div", className: "search-bar-transfer__transfer-type-label", children: "Select a transfer type you want to add" }), renderTransferTypeButtons(handleAddTransfer)] }), transferLines.length === 0 && (_jsx(TransferLine, { id: "placeholder-transfer", type: "inter-hotel", locations: locations, onDataChange: function () { }, showDelete: false, disabled: true, scrollOnOpen: scrollOnOpen })), transferLines.length > 0 && (_jsx("div", { className: "search-bar-transfer__transfer-lines", children: (function () {
380
+ return (_jsxs("div", { className: "search-bar-transfer ".concat(className), children: [_jsxs("div", { className: "search-bar-transfer__header", children: [_jsx(Heading, { level: 5, variant: "bold", color: "accent", children: "Select your transfer details" }), _jsx("div", { className: "search-bar-transfer__mode-selector", children: _jsx(SegmentedButton, { options: modeOptions, value: mode, onChange: handleModeChange, name: "transfer-mode" }) })] }), mode === 'roundtrip' ? (_jsxs(_Fragment, { children: [_jsx(RoundTrip, { id: "roundtrip-main", locations: locations, paxData: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.paxData, arrivalDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.arrivalDate, departureDate: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.departureDate, pickupDropoffPoint: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.pickupDropoffPoint, accommodation: roundTripData === null || roundTripData === void 0 ? void 0 : roundTripData.accommodation, onChange: setRoundTripData, checkEmpty: error !== null, scrollOnOpen: scrollOnOpen }, "roundtrip-".concat(validationTrigger)), _jsx("div", { className: "search-bar-transfer__transfer-type", children: renderTransferTypeButtons(handleAddTransferFromRoundTrip) })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "search-bar-transfer__transfer-type", children: [_jsx(Text, { size: "lg", variant: "bold", color: "subtle", as: "div", className: "search-bar-transfer__transfer-type-label", children: "Select a transfer type you want to add" }), renderTransferTypeButtons(handleAddTransfer)] }), transferLines.length === 0 && (_jsx(TransferLine, { id: "placeholder-transfer", type: "inter-hotel", locations: locations, onDataChange: function () { }, showDelete: false, disabled: true, scrollOnOpen: scrollOnOpen, onPaxOpenChange: function () { } })), transferLines.length > 0 && (_jsx("div", { className: "search-bar-transfer__transfer-lines", children: (function () {
381
381
  // Group transfers by type
382
382
  var groupedTransfers = {
383
383
  arrival: [],
@@ -54,6 +54,8 @@ export interface TransferLineProps {
54
54
  disabled?: boolean;
55
55
  /** Whether to scroll to the input when the calendar opens */
56
56
  scrollOnOpen?: boolean;
57
+ /** Callback when pax selector opens */
58
+ onPaxOpenChange?: () => void;
57
59
  }
58
60
  declare const TransferLine: React.FC<TransferLineProps>;
59
61
  export default TransferLine;
@@ -27,7 +27,7 @@ import LocationDropdown from '../../molecules/LocationDropdown/LocationDropdown'
27
27
  import DateTimePicker from '../DateTimePicker/DateTimePicker';
28
28
  import PaxSelector from '../PaxSelector/PaxSelector';
29
29
  var TransferLine = function (_a) {
30
- var id = _a.id, type = _a.type, paxData = _a.paxData, transferDate = _a.transferDate, pickupPoint = _a.pickupPoint, dropoffPoint = _a.dropoffPoint, _b = _a.locations, locations = _b === void 0 ? { options: [], groups: [] } : _b, onPaxChange = _a.onPaxChange, onDateChange = _a.onDateChange, onPickupChange = _a.onPickupChange, onDropoffChange = _a.onDropoffChange, onDataChange = _a.onDataChange, onDelete = _a.onDelete, _c = _a.showDelete, showDelete = _c === void 0 ? true : _c, _d = _a.showTitle, showTitle = _d === void 0 ? false : _d, _e = _a.className, className = _e === void 0 ? '' : _e, _f = _a.checkEmpty, checkEmpty = _f === void 0 ? false : _f, _g = _a.disabled, disabled = _g === void 0 ? false : _g, _h = _a.scrollOnOpen, scrollOnOpen = _h === void 0 ? false : _h;
30
+ var id = _a.id, type = _a.type, paxData = _a.paxData, transferDate = _a.transferDate, pickupPoint = _a.pickupPoint, dropoffPoint = _a.dropoffPoint, _b = _a.locations, locations = _b === void 0 ? { options: [], groups: [] } : _b, onPaxChange = _a.onPaxChange, onDateChange = _a.onDateChange, onPickupChange = _a.onPickupChange, onDropoffChange = _a.onDropoffChange, onDataChange = _a.onDataChange, onDelete = _a.onDelete, _c = _a.showDelete, showDelete = _c === void 0 ? true : _c, _d = _a.showTitle, showTitle = _d === void 0 ? false : _d, _e = _a.className, className = _e === void 0 ? '' : _e, _f = _a.checkEmpty, checkEmpty = _f === void 0 ? false : _f, _g = _a.disabled, disabled = _g === void 0 ? false : _g, _h = _a.scrollOnOpen, scrollOnOpen = _h === void 0 ? false : _h, onPaxOpenChange = _a.onPaxOpenChange;
31
31
  var _j = useState(paxData), internalPaxData = _j[0], setInternalPaxData = _j[1];
32
32
  var _k = useState(transferDate), internalTransferDate = _k[0], setInternalTransferDate = _k[1];
33
33
  var _l = useState(null), internalPickupPoint = _l[0], setInternalPickupPoint = _l[1];
@@ -70,7 +70,11 @@ var TransferLine = function (_a) {
70
70
  };
71
71
  // Helper to check if value is LocationOption
72
72
  var isLocationOption = function (value) {
73
- return typeof value === 'object' && value !== null && 'id' in value && 'label' in value && 'type' in value;
73
+ return (typeof value === 'object' &&
74
+ value !== null &&
75
+ 'id' in value &&
76
+ 'label' in value &&
77
+ 'type' in value);
74
78
  };
75
79
  // Initialize location data from IDs, LocationOption objects, or set defaults
76
80
  React.useEffect(function () {
@@ -194,7 +198,10 @@ var TransferLine = function (_a) {
194
198
  var name = locationData.locationName.toLowerCase();
195
199
  var id = String(locationData.id).toLowerCase();
196
200
  var locType = 'accommodation';
197
- if (name.includes('harbour') || name.includes('port') || id.includes('harbour') || id.includes('port')) {
201
+ if (name.includes('harbour') ||
202
+ name.includes('port') ||
203
+ id.includes('harbour') ||
204
+ id.includes('port')) {
198
205
  locType = 'port';
199
206
  }
200
207
  else if (name.includes('airport') || id.includes('airport')) {
@@ -241,7 +248,7 @@ var TransferLine = function (_a) {
241
248
  };
242
249
  var defaultPickupOption = findLocationOption(pickupPoint, 'pickup');
243
250
  var defaultDropoffOption = findLocationOption(dropoffPoint, 'dropoff');
244
- return (_jsxs("div", { className: "transfer-line transfer-line--".concat(type, " ").concat(disabled ? 'transfer-line--disabled' : '', " ").concat(className), "data-transfer-id": id, children: [showTitle && (_jsxs("div", { className: "transfer-line__header", children: [_jsx(Icon, { name: getTypeIcon(), size: "sm", className: "transfer-line__header-icon" }), _jsx(Text, { size: "sm", variant: "medium", className: "transfer-line__header-label", children: getTypeLabel() })] })), _jsxs("div", { className: "transfer-line__content-container", children: [_jsxs("div", { className: "transfer-line__content", children: [_jsx("div", { className: "transfer-line__field transfer-line__field--pax ".concat(isPaxEmpty ? 'transfer-line__field--error' : ''), children: _jsx(PaxSelector, { label: "Number of pax", value: internalPaxData, onChange: handlePaxChange, placeholder: "2 pax", className: isPaxEmpty ? 'pax-selector--error' : '', disabled: disabled, scrollOnOpen: scrollOnOpen, checkEmpty: checkEmpty }) }), _jsxs("div", { className: "transfer-line__field transfer-line__field--date", children: [_jsx(Text, { size: "sm", variant: "regular", className: "transfer-line__field-label", children: "Transfer date" }), _jsx(DateTimePicker, { placeholder: "DD/MM/YYYY", mode: "calendar", iconPosition: "left", numberOfMonths: 1, iconBGFull: false, showChevron: true, onValueChange: handleDateChange, selectionMode: "single", defaultValue: internalTransferDate, inputClassName: "transfer-line__date-picker", state: isDateEmpty ? 'error' : undefined, disabled: disabled, scrollOnOpen: scrollOnOpen })] }), _jsx("div", { className: "transfer-line__field transfer-line__field--pickup", children: _jsx(LocationDropdown, { label: "Pick-up point", options: filterLocations('pickup').options, groups: filterLocations('pickup').groups, selectedValue: (internalPickupPoint === null || internalPickupPoint === void 0 ? void 0 : internalPickupPoint.id) || null, onSelectionChange: handlePickupChange, placeholder: "Select a pick-up point", direction: "pickup", type: type === 'inter-hotel'
251
+ return (_jsxs("div", { className: "transfer-line transfer-line--".concat(type, " ").concat(disabled ? 'transfer-line--disabled' : '', " ").concat(className), "data-transfer-id": id, children: [showTitle && (_jsxs("div", { className: "transfer-line__header", children: [_jsx(Icon, { name: getTypeIcon(), size: "sm", className: "transfer-line__header-icon" }), _jsx(Text, { size: "sm", variant: "medium", className: "transfer-line__header-label", children: getTypeLabel() })] })), _jsxs("div", { className: "transfer-line__content-container", children: [_jsxs("div", { className: "transfer-line__content", children: [_jsx("div", { className: "transfer-line__field transfer-line__field--pax ".concat(isPaxEmpty ? 'transfer-line__field--error' : ''), children: _jsx(PaxSelector, { label: "Number of pax", value: internalPaxData, onChange: handlePaxChange, placeholder: "2 pax", className: isPaxEmpty ? 'pax-selector--error' : '', disabled: disabled, scrollOnOpen: scrollOnOpen, checkEmpty: checkEmpty, onPaxOpenChange: onPaxOpenChange }) }), _jsxs("div", { className: "transfer-line__field transfer-line__field--date", children: [_jsx(Text, { size: "sm", variant: "regular", className: "transfer-line__field-label", children: "Transfer date" }), _jsx(DateTimePicker, { placeholder: "DD/MM/YYYY", mode: "calendar", iconPosition: "left", numberOfMonths: 1, iconBGFull: false, showChevron: true, onValueChange: handleDateChange, selectionMode: "single", defaultValue: internalTransferDate, inputClassName: "transfer-line__date-picker", state: isDateEmpty ? 'error' : undefined, disabled: disabled, scrollOnOpen: scrollOnOpen })] }), _jsx("div", { className: "transfer-line__field transfer-line__field--pickup", children: _jsx(LocationDropdown, { label: "Pick-up point", options: filterLocations('pickup').options, groups: filterLocations('pickup').groups, selectedValue: (internalPickupPoint === null || internalPickupPoint === void 0 ? void 0 : internalPickupPoint.id) || null, onSelectionChange: handlePickupChange, placeholder: "Select a pick-up point", direction: "pickup", type: type === 'inter-hotel'
245
252
  ? 'accommodation'
246
253
  : type === 'arrival'
247
254
  ? 'airport-port'
package/dist/lib/utils.js CHANGED
@@ -21,17 +21,22 @@ export function cn() {
21
21
  export function scrollIntoViewOnOpen(elementRef, isOpen, scrollOnOpen, offset) {
22
22
  if (offset === void 0) { offset = 20; }
23
23
  if (isOpen && scrollOnOpen && elementRef.current) {
24
+ var bodyBottom_1 = document.body.clientHeight;
24
25
  // Use setTimeout to ensure the dropdown is rendered before scrolling
25
26
  setTimeout(function () {
26
27
  if (elementRef.current) {
27
28
  var elementTop = elementRef.current.getBoundingClientRect().top + window.pageYOffset;
29
+ var elementBottom = elementRef.current.getBoundingClientRect().bottom;
30
+ var realBottom = elementBottom + window.scrollY;
28
31
  // Scroll to show the element with some padding from the top
29
- window.scrollTo({
30
- top: elementTop - offset,
31
- behavior: 'smooth',
32
- });
32
+ if (realBottom > bodyBottom_1) {
33
+ window.scrollTo({
34
+ top: elementTop - offset,
35
+ behavior: 'smooth',
36
+ });
37
+ }
33
38
  }
34
- }, 0);
39
+ }, 350);
35
40
  }
36
41
  }
37
42
  /**
@@ -33,7 +33,9 @@
33
33
  }
34
34
 
35
35
  .pax-selector__label {
36
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
36
+ font-family:
37
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
38
+ sans-serif;
37
39
  font-size: 14px;
38
40
  line-height: 1.5;
39
41
  color: var(--input-color-label-default, #262626);
@@ -82,7 +84,9 @@
82
84
  }
83
85
 
84
86
  .pax-selector__input-text {
85
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
87
+ font-family:
88
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
89
+ sans-serif;
86
90
  font-weight: 500;
87
91
  font-size: 14px;
88
92
  line-height: 20px;
@@ -99,7 +103,7 @@
99
103
  }
100
104
 
101
105
  .pax-selector__chevron--open {
102
- transform: rotate(180deg)!important;
106
+ transform: rotate(180deg) !important;
103
107
  }
104
108
 
105
109
  /* Disabled state */
@@ -139,7 +143,9 @@
139
143
  border: 1px solid var(--color-border-subtle, #e5e5e5);
140
144
  border-radius: 12px;
141
145
  padding: 16px;
142
- box-shadow: 0px 4px 8px rgba(48, 54, 66, 0.1), 0px 1px 8px rgba(48, 54, 66, 0.11);
146
+ box-shadow:
147
+ 0px 4px 8px rgba(48, 54, 66, 0.1),
148
+ 0px 1px 8px rgba(48, 54, 66, 0.11);
143
149
  z-index: 100;
144
150
  animation: pax-selector-dropdown-enter 0.2s ease-out;
145
151
  }
@@ -168,7 +174,9 @@
168
174
  background: none;
169
175
  border: none;
170
176
  cursor: pointer;
171
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
177
+ font-family:
178
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
179
+ sans-serif;
172
180
  font-weight: 500;
173
181
  font-size: 14px;
174
182
  line-height: 20px;
@@ -222,7 +230,9 @@
222
230
  background: var(--stepper-color-cta-background-default, #ffffff);
223
231
  color: var(--stepper-color-cta-foreground-default, #000000);
224
232
  cursor: pointer;
225
- box-shadow: 0px 1px 8px rgba(48, 54, 66, 0.11), 0px 4px 8px rgba(48, 54, 66, 0.1);
233
+ box-shadow:
234
+ 0px 1px 8px rgba(48, 54, 66, 0.11),
235
+ 0px 4px 8px rgba(48, 54, 66, 0.1);
226
236
  transition: all 0.2s ease;
227
237
  }
228
238
 
@@ -247,11 +257,16 @@
247
257
  align-items: center;
248
258
  justify-content: center;
249
259
  min-width: 48px;
260
+ flex: 0 0 48px;
250
261
  padding: 4px 24px;
251
262
  background: var(--stepper-color-counter, #ffffff);
252
263
  border-radius: 8px;
253
- box-shadow: 0px 0px 4px rgba(48, 54, 66, 0.11), 0px 2px 2px rgba(48, 54, 66, 0.1);
254
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
264
+ box-shadow:
265
+ 0px 0px 4px rgba(48, 54, 66, 0.11),
266
+ 0px 2px 2px rgba(48, 54, 66, 0.1);
267
+ font-family:
268
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
269
+ sans-serif;
255
270
  font-weight: 700;
256
271
  font-size: 18px;
257
272
  line-height: 24px;
@@ -266,7 +281,9 @@
266
281
  }
267
282
 
268
283
  .pax-selector__client-type-label {
269
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
284
+ font-family:
285
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
286
+ sans-serif;
270
287
  font-size: 14px;
271
288
  line-height: 20px;
272
289
  color: var(--input-color-label-default, #262626);
@@ -307,7 +324,9 @@
307
324
  }
308
325
 
309
326
  .pax-selector__client-type-text {
310
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
327
+ font-family:
328
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
329
+ sans-serif;
311
330
  font-weight: 400;
312
331
  font-size: 14px;
313
332
  line-height: 20px;
@@ -358,7 +377,9 @@
358
377
  border: none;
359
378
  cursor: pointer;
360
379
  text-align: left;
361
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
380
+ font-family:
381
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
382
+ sans-serif;
362
383
  font-weight: 400;
363
384
  font-size: 14px;
364
385
  line-height: 20px;
@@ -390,7 +411,9 @@
390
411
  background: none;
391
412
  border: none;
392
413
  cursor: pointer;
393
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
414
+ font-family:
415
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
416
+ sans-serif;
394
417
  font-weight: 700;
395
418
  font-size: 14px;
396
419
  line-height: 20px;
@@ -412,7 +435,9 @@
412
435
  border: none;
413
436
  border-radius: 9999px;
414
437
  cursor: pointer;
415
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
438
+ font-family:
439
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
440
+ sans-serif;
416
441
  font-weight: 700;
417
442
  font-size: 14px;
418
443
  line-height: 20px;
@@ -509,7 +534,9 @@
509
534
  border: 1px solid var(--chip-color-red-outline-foreground, #991b1b);
510
535
  border-radius: 9999px;
511
536
  cursor: pointer;
512
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
537
+ font-family:
538
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
539
+ sans-serif;
513
540
  font-weight: var(--font-weight-font-medium, 500);
514
541
  font-size: 12px;
515
542
  line-height: 16px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mautourco-components",
3
- "version": "0.2.103",
3
+ "version": "0.2.105",
4
4
  "private": false,
5
5
  "description": "Bibliothèque de composants Mautourco pour le redesign",
6
6
  "main": "dist/index.js",
@@ -64,6 +64,7 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
64
64
  const [isOpen, setIsOpen] = useState(false);
65
65
  const [searchQuery, setSearchQuery] = useState('');
66
66
  const dropdownRef = useRef<HTMLDivElement>(null);
67
+ const dropdownPanelRef = useRef<HTMLDivElement>(null);
67
68
  const inputRef = useRef<HTMLDivElement>(null);
68
69
  const searchInputRef = useRef<HTMLInputElement>(null);
69
70
 
@@ -83,7 +84,11 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
83
84
 
84
85
  // Scroll to input when dropdown opens (if scrollOnOpen is true)
85
86
  useEffect(() => {
86
- scrollIntoViewOnOpen(inputRef, isOpen, scrollOnOpen);
87
+ setTimeout(() => {
88
+ if (dropdownPanelRef.current) {
89
+ scrollIntoViewOnOpen(dropdownPanelRef, isOpen, scrollOnOpen);
90
+ }
91
+ }, 10);
87
92
  }, [isOpen, scrollOnOpen]);
88
93
 
89
94
  // Reset search when dropdown closes
@@ -129,11 +134,9 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
129
134
  // Filter locations based on search query
130
135
  const filterOptions = (opts: LocationOption[]): LocationOption[] => {
131
136
  if (!searchQuery.trim()) return opts;
132
-
137
+
133
138
  const query = searchQuery.toLowerCase();
134
- return opts.filter((option) =>
135
- option.label.toLowerCase().includes(query)
136
- );
139
+ return opts.filter((option) => option.label.toLowerCase().includes(query));
137
140
  };
138
141
 
139
142
  const getSelectedOption = (): LocationOption | null => {
@@ -201,11 +204,14 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
201
204
  const displayText = selectedOption ? selectedOption.label : placeholder;
202
205
 
203
206
  // Prepare all options (flat or grouped) and filter them
204
- const allOptionsRaw = groups.length > 0 ? groups : [{ id: 'default', label: '', options }];
205
- const allOptions = allOptionsRaw.map((group) => ({
206
- ...group,
207
- options: filterOptions(group.options),
208
- })).filter((group) => group.options.length > 0);
207
+ const allOptionsRaw =
208
+ groups.length > 0 ? groups : [{ id: 'default', label: '', options }];
209
+ const allOptions = allOptionsRaw
210
+ .map((group) => ({
211
+ ...group,
212
+ options: filterOptions(group.options),
213
+ }))
214
+ .filter((group) => group.options.length > 0);
209
215
 
210
216
  // Skeleton loader component
211
217
  const SkeletonOption = () => (
@@ -284,7 +290,7 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
284
290
  (loading ? (
285
291
  renderSkeletonLoading()
286
292
  ) : (
287
- <div className="location-dropdown__panel">
293
+ <div className="location-dropdown__panel" ref={dropdownPanelRef}>
288
294
  <div
289
295
  className="location-dropdown__content"
290
296
  style={{ maxHeight: `${maxHeight}px` }}>
@@ -297,41 +303,43 @@ const LocationDropdown: React.FC<LocationDropdownProps> = ({
297
303
  </div>
298
304
  ) : (
299
305
  allOptions.map((group, groupIndex) => (
300
- <div key={group.id} className="location-dropdown__group">
301
- {showGroupTitles && group.label && groups.length > 0 && (
302
- <>
303
- {groupIndex > 0 && <div className="location-dropdown__divider" />}
304
- <div className="location-dropdown__group-header">
305
- <Text size="xs" variant="bold">
306
- {group.label}
307
- </Text>
308
- </div>
309
- </>
310
- )}
311
-
312
- <div className="location-dropdown__group-options">
313
- {group.options.map((option) => {
314
- const isSelected = effectiveSelectedValue === option.id;
315
- const isDisabled = option.disabled || disabled;
316
-
317
- return (
318
- <div
319
- key={option.id}
320
- className={`location-dropdown__option ${isSelected ? 'location-dropdown__option--selected' : ''} ${isDisabled ? 'location-dropdown__option--disabled' : ''}`}
321
- onClick={() => !isDisabled && handleOptionSelect(option)}>
322
- <Icon
323
- name={getOptionIcon(option, isSelected)}
324
- size="sm"
325
- className="location-dropdown__option-icon"
326
- />
327
- <span className="location-dropdown__option-text">
328
- {option.label}
329
- </span>
306
+ <div key={group.id} className="location-dropdown__group">
307
+ {showGroupTitles && group.label && groups.length > 0 && (
308
+ <>
309
+ {groupIndex > 0 && (
310
+ <div className="location-dropdown__divider" />
311
+ )}
312
+ <div className="location-dropdown__group-header">
313
+ <Text size="xs" variant="bold">
314
+ {group.label}
315
+ </Text>
330
316
  </div>
331
- );
332
- })}
317
+ </>
318
+ )}
319
+
320
+ <div className="location-dropdown__group-options">
321
+ {group.options.map((option) => {
322
+ const isSelected = effectiveSelectedValue === option.id;
323
+ const isDisabled = option.disabled || disabled;
324
+
325
+ return (
326
+ <div
327
+ key={option.id}
328
+ className={`location-dropdown__option ${isSelected ? 'location-dropdown__option--selected' : ''} ${isDisabled ? 'location-dropdown__option--disabled' : ''}`}
329
+ onClick={() => !isDisabled && handleOptionSelect(option)}>
330
+ <Icon
331
+ name={getOptionIcon(option, isSelected)}
332
+ size="sm"
333
+ className="location-dropdown__option-icon"
334
+ />
335
+ <span className="location-dropdown__option-text">
336
+ {option.label}
337
+ </span>
338
+ </div>
339
+ );
340
+ })}
341
+ </div>
333
342
  </div>
334
- </div>
335
343
  ))
336
344
  )}
337
345
  </div>
@@ -74,6 +74,7 @@ export interface PaxSelectorProps {
74
74
  ageRange?: number[];
75
75
  /** Whether to check if age inputs are empty and show error state */
76
76
  checkEmpty?: boolean;
77
+ onPaxOpenChange?: () => void;
77
78
  }
78
79
 
79
80
  const DEFAULT_PAX_DATA: PaxData = {
@@ -535,6 +536,7 @@ const PaxSelector: React.FC<PaxSelectorProps> = ({
535
536
  scrollOnOpen = false,
536
537
  disabled = false,
537
538
  checkEmpty = false,
539
+ onPaxOpenChange,
538
540
  }) => {
539
541
  const [isOpen, setIsOpen] = useState(false);
540
542
  const [internalData, setInternalData] = useState<PaxData>(
@@ -676,9 +678,13 @@ const PaxSelector: React.FC<PaxSelectorProps> = ({
676
678
  // Check if there are any minors that need age specification
677
679
  const hasMinorsWithoutAges = (): boolean => {
678
680
  if (multipleRooms) {
679
- return rooms.some(room => room.teens > 0 || room.children > 0 || room.infants > 0);
681
+ return rooms.some(
682
+ (room) => room.teens > 0 || room.children > 0 || room.infants > 0
683
+ );
680
684
  }
681
- return internalData.teens > 0 || internalData.children > 0 || internalData.infants > 0;
685
+ return (
686
+ internalData.teens > 0 || internalData.children > 0 || internalData.infants > 0
687
+ );
682
688
  };
683
689
 
684
690
  // Handle clicks outside the dropdown
@@ -696,6 +702,8 @@ const PaxSelector: React.FC<PaxSelectorProps> = ({
696
702
  document.addEventListener('mousedown', handleClickOutside);
697
703
  }
698
704
 
705
+ onPaxOpenChange?.();
706
+
699
707
  return () => {
700
708
  document.removeEventListener('mousedown', handleClickOutside);
701
709
  };
@@ -52,6 +52,8 @@ export interface SearchBarTransferProps {
52
52
  className?: string;
53
53
  /** Whether to scroll to the input when the calendar opens */
54
54
  scrollOnOpen?: boolean;
55
+ /** Callback when pax selector opens */
56
+ onPaxOpenChange?: () => void;
55
57
  }
56
58
 
57
59
  let transferIdCounter = 0;
@@ -67,6 +69,7 @@ function SearchBarTransfer({
67
69
  onRemove,
68
70
  className = '',
69
71
  scrollOnOpen = false,
72
+ onPaxOpenChange,
70
73
  }: SearchBarTransferProps) {
71
74
  // Generate unique ID for transfer lines
72
75
  const generateTransferId = () => {
@@ -557,6 +560,7 @@ function SearchBarTransfer({
557
560
  showDelete={false}
558
561
  disabled={true}
559
562
  scrollOnOpen={scrollOnOpen}
563
+ onPaxOpenChange={() => {}}
560
564
  />
561
565
  )}
562
566
 
@@ -3,9 +3,9 @@ import '../../../styles/components/organism/transfer-line.css';
3
3
  import Icon from '../../atoms/Icon/Icon';
4
4
  import { Text } from '../../atoms/Typography/Typography';
5
5
  import LocationDropdown, {
6
- LocationData,
7
- LocationGroup,
8
- LocationOption,
6
+ LocationData,
7
+ LocationGroup,
8
+ LocationOption,
9
9
  } from '../../molecules/LocationDropdown/LocationDropdown';
10
10
  import DateTimePicker from '../DateTimePicker/DateTimePicker';
11
11
  import PaxSelector, { PaxData } from '../PaxSelector/PaxSelector';
@@ -66,6 +66,8 @@ export interface TransferLineProps {
66
66
  disabled?: boolean;
67
67
  /** Whether to scroll to the input when the calendar opens */
68
68
  scrollOnOpen?: boolean;
69
+ /** Callback when pax selector opens */
70
+ onPaxOpenChange?: () => void;
69
71
  }
70
72
 
71
73
  const TransferLine: React.FC<TransferLineProps> = ({
@@ -88,6 +90,7 @@ const TransferLine: React.FC<TransferLineProps> = ({
88
90
  checkEmpty = false,
89
91
  disabled = false,
90
92
  scrollOnOpen = false,
93
+ onPaxOpenChange,
91
94
  }) => {
92
95
  const [internalPaxData, setInternalPaxData] = useState<PaxData | undefined>(paxData);
93
96
  const [internalTransferDate, setInternalTransferDate] = useState<string | undefined>(
@@ -154,8 +157,16 @@ const TransferLine: React.FC<TransferLineProps> = ({
154
157
  };
155
158
 
156
159
  // Helper to check if value is LocationOption
157
- const isLocationOption = (value: string | number | LocationOption | undefined): value is LocationOption => {
158
- return typeof value === 'object' && value !== null && 'id' in value && 'label' in value && 'type' in value;
160
+ const isLocationOption = (
161
+ value: string | number | LocationOption | undefined
162
+ ): value is LocationOption => {
163
+ return (
164
+ typeof value === 'object' &&
165
+ value !== null &&
166
+ 'id' in value &&
167
+ 'label' in value &&
168
+ 'type' in value
169
+ );
159
170
  };
160
171
 
161
172
  // Initialize location data from IDs, LocationOption objects, or set defaults
@@ -276,25 +287,33 @@ const TransferLine: React.FC<TransferLineProps> = ({
276
287
  };
277
288
 
278
289
  // Helper to convert LocationData to LocationOption
279
- const toLocationOption = (locationData: LocationData | null, position: 'pickup' | 'dropoff'): LocationOption | null => {
290
+ const toLocationOption = (
291
+ locationData: LocationData | null,
292
+ position: 'pickup' | 'dropoff'
293
+ ): LocationOption | null => {
280
294
  if (!locationData) return null;
281
-
295
+
282
296
  // Try to find in the options to get the type
283
297
  const { options, groups } = filterLocations(position);
284
298
  const allLocations = getAllLocations(options, groups);
285
299
  const found = allLocations.find((loc) => loc.id === locationData.id);
286
300
  if (found) return found;
287
-
301
+
288
302
  // If not found, infer the type
289
303
  const name = locationData.locationName.toLowerCase();
290
304
  const id = String(locationData.id).toLowerCase();
291
305
  let locType: 'airport' | 'port' | 'accommodation' = 'accommodation';
292
- if (name.includes('harbour') || name.includes('port') || id.includes('harbour') || id.includes('port')) {
306
+ if (
307
+ name.includes('harbour') ||
308
+ name.includes('port') ||
309
+ id.includes('harbour') ||
310
+ id.includes('port')
311
+ ) {
293
312
  locType = 'port';
294
313
  } else if (name.includes('airport') || id.includes('airport')) {
295
314
  locType = 'airport';
296
315
  }
297
-
316
+
298
317
  return {
299
318
  id: locationData.id,
300
319
  label: locationData.locationName,
@@ -331,14 +350,17 @@ const TransferLine: React.FC<TransferLineProps> = ({
331
350
  const isDropoffEmpty = checkEmpty && !internalDropoffPoint;
332
351
 
333
352
  // Helper function to find LocationOption from ID or LocationOption for defaultValue
334
- const findLocationOption = (value: string | number | LocationOption | undefined, position: 'pickup' | 'dropoff'): LocationOption | undefined => {
353
+ const findLocationOption = (
354
+ value: string | number | LocationOption | undefined,
355
+ position: 'pickup' | 'dropoff'
356
+ ): LocationOption | undefined => {
335
357
  if (!value) return undefined;
336
-
358
+
337
359
  // If value is already a LocationOption object, use it directly
338
360
  if (isLocationOption(value)) {
339
361
  return value;
340
362
  }
341
-
363
+
342
364
  // Otherwise, look up by ID in the locations
343
365
  const { options, groups } = filterLocations(position);
344
366
  const allLocations = getAllLocations(options, groups);
@@ -377,6 +399,7 @@ const TransferLine: React.FC<TransferLineProps> = ({
377
399
  disabled={disabled}
378
400
  scrollOnOpen={scrollOnOpen}
379
401
  checkEmpty={checkEmpty}
402
+ onPaxOpenChange={onPaxOpenChange}
380
403
  />
381
404
  </div>
382
405
 
@@ -19,7 +19,9 @@
19
19
  }
20
20
 
21
21
  .pax-selector__label {
22
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
22
+ font-family:
23
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
24
+ sans-serif;
23
25
  font-size: 14px;
24
26
  line-height: 1.5;
25
27
  color: var(--input-color-label-default, #262626);
@@ -68,7 +70,9 @@
68
70
  }
69
71
 
70
72
  .pax-selector__input-text {
71
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
73
+ font-family:
74
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
75
+ sans-serif;
72
76
  font-weight: 500;
73
77
  font-size: 14px;
74
78
  line-height: 20px;
@@ -85,7 +89,7 @@
85
89
  }
86
90
 
87
91
  .pax-selector__chevron--open {
88
- transform: rotate(180deg)!important;
92
+ transform: rotate(180deg) !important;
89
93
  }
90
94
 
91
95
  /* Disabled state */
@@ -123,7 +127,9 @@
123
127
  border: 1px solid var(--color-border-subtle, #e5e5e5);
124
128
  border-radius: 12px;
125
129
  padding: 16px;
126
- box-shadow: 0px 4px 8px rgba(48, 54, 66, 0.1), 0px 1px 8px rgba(48, 54, 66, 0.11);
130
+ box-shadow:
131
+ 0px 4px 8px rgba(48, 54, 66, 0.1),
132
+ 0px 1px 8px rgba(48, 54, 66, 0.11);
127
133
  z-index: 100;
128
134
  animation: pax-selector-dropdown-enter 0.2s ease-out;
129
135
  }
@@ -151,7 +157,9 @@
151
157
  background: none;
152
158
  border: none;
153
159
  cursor: pointer;
154
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
160
+ font-family:
161
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
162
+ sans-serif;
155
163
  font-weight: 500;
156
164
  font-size: 14px;
157
165
  line-height: 20px;
@@ -204,7 +212,9 @@
204
212
  background: var(--stepper-color-cta-background-default, #ffffff);
205
213
  color: var(--stepper-color-cta-foreground-default, #000000);
206
214
  cursor: pointer;
207
- box-shadow: 0px 1px 8px rgba(48, 54, 66, 0.11), 0px 4px 8px rgba(48, 54, 66, 0.1);
215
+ box-shadow:
216
+ 0px 1px 8px rgba(48, 54, 66, 0.11),
217
+ 0px 4px 8px rgba(48, 54, 66, 0.1);
208
218
  transition: all 0.2s ease;
209
219
  }
210
220
 
@@ -229,11 +239,16 @@
229
239
  align-items: center;
230
240
  justify-content: center;
231
241
  min-width: 48px;
242
+ flex: 0 0 48px;
232
243
  padding: 4px 24px;
233
244
  background: var(--stepper-color-counter, #ffffff);
234
245
  border-radius: 8px;
235
- box-shadow: 0px 0px 4px rgba(48, 54, 66, 0.11), 0px 2px 2px rgba(48, 54, 66, 0.1);
236
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
246
+ box-shadow:
247
+ 0px 0px 4px rgba(48, 54, 66, 0.11),
248
+ 0px 2px 2px rgba(48, 54, 66, 0.1);
249
+ font-family:
250
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
251
+ sans-serif;
237
252
  font-weight: 700;
238
253
  font-size: 18px;
239
254
  line-height: 24px;
@@ -247,7 +262,9 @@
247
262
  }
248
263
 
249
264
  .pax-selector__client-type-label {
250
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
265
+ font-family:
266
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
267
+ sans-serif;
251
268
  font-size: 14px;
252
269
  line-height: 20px;
253
270
  color: var(--input-color-label-default, #262626);
@@ -288,7 +305,9 @@
288
305
  }
289
306
 
290
307
  .pax-selector__client-type-text {
291
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
308
+ font-family:
309
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
310
+ sans-serif;
292
311
  font-weight: 400;
293
312
  font-size: 14px;
294
313
  line-height: 20px;
@@ -339,7 +358,9 @@
339
358
  border: none;
340
359
  cursor: pointer;
341
360
  text-align: left;
342
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
361
+ font-family:
362
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
363
+ sans-serif;
343
364
  font-weight: 400;
344
365
  font-size: 14px;
345
366
  line-height: 20px;
@@ -370,7 +391,9 @@
370
391
  background: none;
371
392
  border: none;
372
393
  cursor: pointer;
373
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
394
+ font-family:
395
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
396
+ sans-serif;
374
397
  font-weight: 700;
375
398
  font-size: 14px;
376
399
  line-height: 20px;
@@ -392,7 +415,9 @@
392
415
  border: none;
393
416
  border-radius: 9999px;
394
417
  cursor: pointer;
395
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
418
+ font-family:
419
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
420
+ sans-serif;
396
421
  font-weight: 700;
397
422
  font-size: 14px;
398
423
  line-height: 20px;
@@ -432,10 +457,9 @@
432
457
  }
433
458
 
434
459
  .pax-selector__age-groups {
435
- @apply flex flex-wrap gap-4;
460
+ @apply flex flex-wrap gap-4;
436
461
  }
437
462
 
438
-
439
463
  /* Multiple Rooms Styles */
440
464
  .pax-selector__rooms {
441
465
  display: flex;
@@ -485,7 +509,9 @@
485
509
  border: 1px solid var(--chip-color-red-outline-foreground, #991b1b);
486
510
  border-radius: 9999px;
487
511
  cursor: pointer;
488
- font-family: var(--font-font-family-body, "Satoshi"), "Satoshi", "Inter", "Segoe UI", "system-ui", sans-serif;
512
+ font-family:
513
+ var(--font-font-family-body, 'Satoshi'), 'Satoshi', 'Inter', 'Segoe UI', 'system-ui',
514
+ sans-serif;
489
515
  font-weight: var(--font-weight-font-medium, 500);
490
516
  font-size: 12px;
491
517
  line-height: 16px;
@@ -538,4 +564,3 @@
538
564
  .pax-selector__dropdown::-webkit-scrollbar-thumb:hover {
539
565
  background: var(--color-button-brand-background-secondary-hover, #115b5e);
540
566
  }
541
-