@asdp/ferryui 0.1.0 → 0.1.3
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 +27 -0
- package/dist/assets/images/banner/promo-akhir-tahun.png +0 -0
- package/dist/assets/images/banner/promo-indomaret.png +0 -0
- package/dist/assets/images/banner/promo-shopee.png +0 -0
- package/dist/assets/images/banner/usemanifest-banner.svg +9 -0
- package/dist/assets/images/illustrations/mobile-pay.svg +218 -0
- package/dist/assets/images/illustrations/pay.svg +294 -0
- package/dist/assets/images/illustrations/radius.svg +68 -0
- package/dist/assets/images/illustrations/sessionexp.svg +486 -0
- package/dist/assets/logo/asdp-default.svg +184 -0
- package/dist/index.d.mts +516 -14
- package/dist/index.d.ts +516 -14
- package/dist/index.js +3004 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2988 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +73 -50
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React$1, { ReactNode } from 'react';
|
|
2
|
+
import { CarouselAnnouncerFunction } from '@fluentui/react-components';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { FieldValues, Path, Control } from 'react-hook-form';
|
|
2
5
|
|
|
3
|
-
interface
|
|
6
|
+
interface ModalIllustrationButton {
|
|
7
|
+
/**
|
|
8
|
+
* Button text
|
|
9
|
+
*/
|
|
10
|
+
text: string;
|
|
11
|
+
/**
|
|
12
|
+
* Button click handler
|
|
13
|
+
*/
|
|
14
|
+
onClick: () => void;
|
|
15
|
+
/**
|
|
16
|
+
* Button appearance
|
|
17
|
+
* @default "primary"
|
|
18
|
+
*/
|
|
19
|
+
appearance?: 'primary' | 'outline' | 'secondary' | 'subtle' | 'transparent';
|
|
20
|
+
}
|
|
21
|
+
interface ModalIllustrationProps {
|
|
4
22
|
/**
|
|
5
23
|
* Whether the modal is open
|
|
6
24
|
*/
|
|
@@ -11,22 +29,25 @@ interface ModalRadiusProps {
|
|
|
11
29
|
onClose: () => void;
|
|
12
30
|
/**
|
|
13
31
|
* Modal title
|
|
14
|
-
* @default "Anda berada di luar area pemesanan"
|
|
15
32
|
*/
|
|
16
|
-
title
|
|
33
|
+
title: string;
|
|
17
34
|
/**
|
|
18
35
|
* Modal message content
|
|
19
|
-
*
|
|
36
|
+
* Can be a string or React node for more complex content
|
|
20
37
|
*/
|
|
21
|
-
message
|
|
38
|
+
message: string | ReactNode;
|
|
22
39
|
/**
|
|
23
40
|
* Image source URL
|
|
24
41
|
* @default "/assets/images/illustrations/radius.svg"
|
|
42
|
+
* @remarks
|
|
43
|
+
* When using this component in your application, ensure the asset is available at this path
|
|
44
|
+
* in your public directory, or provide a custom imageSrc prop pointing to your own image.
|
|
45
|
+
* The asset is included in the published package at `node_modules/@asdp/ferryui/dist/assets/images/illustrations/`
|
|
25
46
|
*/
|
|
26
47
|
imageSrc?: string;
|
|
27
48
|
/**
|
|
28
49
|
* Image alt text
|
|
29
|
-
* @default "
|
|
50
|
+
* @default "Illustration"
|
|
30
51
|
*/
|
|
31
52
|
imageAlt?: string;
|
|
32
53
|
/**
|
|
@@ -40,15 +61,496 @@ interface ModalRadiusProps {
|
|
|
40
61
|
*/
|
|
41
62
|
imageHeight?: number;
|
|
42
63
|
/**
|
|
43
|
-
*
|
|
44
|
-
|
|
64
|
+
* Primary button configuration
|
|
65
|
+
*/
|
|
66
|
+
primaryButton: ModalIllustrationButton;
|
|
67
|
+
/**
|
|
68
|
+
* Optional secondary button configuration
|
|
69
|
+
* If provided, buttons will be displayed side by side
|
|
70
|
+
*/
|
|
71
|
+
secondaryButton?: ModalIllustrationButton;
|
|
72
|
+
}
|
|
73
|
+
declare const ModalIllustration: React$1.FC<ModalIllustrationProps>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Preset configurations for common modal use cases
|
|
77
|
+
*/
|
|
78
|
+
declare const MODAL_PRESETS: {
|
|
79
|
+
/**
|
|
80
|
+
* Modal for radius/location restriction
|
|
81
|
+
*/
|
|
82
|
+
readonly RADIUS: {
|
|
83
|
+
readonly title: "Anda berada di luar area pemesanan";
|
|
84
|
+
readonly message: "Pemesanan tiket tidak dapat dilakukan dari lokasi Anda saat ini. Fitur pembatasan wilayah sedang aktif untuk mencegah pemesanan tidak sah.";
|
|
85
|
+
readonly imageSrc: "/assets/images/illustrations/radius.svg";
|
|
86
|
+
readonly imageAlt: "Radius Limitation Illustration";
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Modal for expired session
|
|
90
|
+
*/
|
|
91
|
+
readonly SESSION_EXPIRED: {
|
|
92
|
+
readonly title: "Sesi anda telah berakhir";
|
|
93
|
+
readonly message: "Waktu sesi Anda telah habis untuk alasan keamanan. Silakan klik tombol dibawah untuk masuk kembali.";
|
|
94
|
+
readonly imageSrc: "/assets/images/illustrations/sessionexp.svg";
|
|
95
|
+
readonly imageAlt: "Session Expired Illustration";
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Modal for purchase period expired
|
|
99
|
+
*/
|
|
100
|
+
readonly PURCHASE_PERIOD_EXPIRED: {
|
|
101
|
+
readonly title: "Waktu pembelian telah berakhir";
|
|
102
|
+
readonly message: "Pemesanan tiket ditutup 1 jam sebelum jadwal keberangkatan. Silakan pilih jadwal keberangkatan lain yang masih tersedia.";
|
|
103
|
+
readonly imageSrc: "/assets/images/illustrations/pay.svg";
|
|
104
|
+
readonly imageAlt: "Purchase Period Expired Illustration";
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Modal for transaction limit reached
|
|
108
|
+
*/
|
|
109
|
+
readonly TRANSACTION_LIMIT: {
|
|
110
|
+
readonly title: "Anda mencapai batas transaksi tertunda";
|
|
111
|
+
readonly message: "Anda telah mencapai batas transaksi tertunda. Pemesanan dapat dilakukan kembali setelah transaksi sebelumnya diselesaikan.";
|
|
112
|
+
readonly imageSrc: "/assets/images/illustrations/mobile-pay.svg";
|
|
113
|
+
readonly imageAlt: "Transaction Limit Illustration";
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Type for preset keys
|
|
118
|
+
*/
|
|
119
|
+
type ModalPresetKey = keyof typeof MODAL_PRESETS;
|
|
120
|
+
/**
|
|
121
|
+
* Helper function to get preset configuration
|
|
122
|
+
*/
|
|
123
|
+
declare const getModalPreset: (presetKey: ModalPresetKey) => Partial<ModalIllustrationProps>;
|
|
124
|
+
|
|
125
|
+
interface CarouselWithCustomNavProps {
|
|
126
|
+
/**
|
|
127
|
+
* Carousel items/children
|
|
128
|
+
*/
|
|
129
|
+
children: ReactNode;
|
|
130
|
+
/**
|
|
131
|
+
* Whether carousel should loop (circular)
|
|
132
|
+
* @default true
|
|
133
|
+
*/
|
|
134
|
+
circular?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Whether carousel is draggable
|
|
137
|
+
* @default true
|
|
138
|
+
*/
|
|
139
|
+
draggable?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Alignment of carousel items
|
|
142
|
+
* @default "start"
|
|
143
|
+
*/
|
|
144
|
+
align?: 'start' | 'center' | 'end';
|
|
145
|
+
/**
|
|
146
|
+
* Whether to remove whitespace between items
|
|
147
|
+
* @default false
|
|
148
|
+
*/
|
|
149
|
+
whitespace?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Announcement function for accessibility
|
|
152
|
+
*/
|
|
153
|
+
announcement?: CarouselAnnouncerFunction;
|
|
154
|
+
/**
|
|
155
|
+
* Active index (controlled)
|
|
156
|
+
*/
|
|
157
|
+
activeIndex?: number;
|
|
158
|
+
/**
|
|
159
|
+
* Callback when active index changes
|
|
160
|
+
*/
|
|
161
|
+
onActiveIndexChange?: (index: number) => void;
|
|
162
|
+
/**
|
|
163
|
+
* ARIA label for the carousel slider
|
|
164
|
+
* @default "Carousel"
|
|
165
|
+
*/
|
|
166
|
+
ariaLabel?: string;
|
|
167
|
+
/**
|
|
168
|
+
* Whether to use dark background for navigation
|
|
169
|
+
* @default true
|
|
170
|
+
*/
|
|
171
|
+
darkNavBackground?: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Additional className for carousel container
|
|
174
|
+
*/
|
|
175
|
+
className?: string;
|
|
176
|
+
/**
|
|
177
|
+
* Whether to enable card focus mode
|
|
178
|
+
* @default false
|
|
179
|
+
*/
|
|
180
|
+
cardFocus?: boolean;
|
|
181
|
+
}
|
|
182
|
+
declare const CarouselWithCustomNav: React$1.FC<CarouselWithCustomNavProps>;
|
|
183
|
+
|
|
184
|
+
interface CardPromoProps {
|
|
185
|
+
/**
|
|
186
|
+
* Image URL for the promo
|
|
187
|
+
*/
|
|
188
|
+
imageUrl: string;
|
|
189
|
+
/**
|
|
190
|
+
* Promo title/heading
|
|
191
|
+
*/
|
|
192
|
+
title: string;
|
|
193
|
+
/**
|
|
194
|
+
* Promo description/subtitle
|
|
195
|
+
*/
|
|
196
|
+
description: string;
|
|
197
|
+
/**
|
|
198
|
+
* Image alt text
|
|
199
|
+
* @default "Promo image"
|
|
200
|
+
*/
|
|
201
|
+
imageAlt?: string;
|
|
202
|
+
/**
|
|
203
|
+
* Index of the card (for accessibility)
|
|
204
|
+
*/
|
|
205
|
+
index?: number;
|
|
206
|
+
/**
|
|
207
|
+
* Total number of cards (for accessibility)
|
|
208
|
+
*/
|
|
209
|
+
totalCards?: number;
|
|
210
|
+
/**
|
|
211
|
+
* Click handler for the card
|
|
212
|
+
*/
|
|
213
|
+
onClick?: () => void;
|
|
214
|
+
}
|
|
215
|
+
declare const CardPromo: React$1.FC<CardPromoProps>;
|
|
216
|
+
|
|
217
|
+
interface CardBannerProps {
|
|
218
|
+
/**
|
|
219
|
+
* Banner image URL
|
|
220
|
+
*/
|
|
221
|
+
imageUrl: string;
|
|
222
|
+
/**
|
|
223
|
+
* Banner alt text
|
|
224
|
+
*/
|
|
225
|
+
alt: string;
|
|
226
|
+
/**
|
|
227
|
+
* Index of the banner (for accessibility)
|
|
228
|
+
*/
|
|
229
|
+
index?: number;
|
|
230
|
+
/**
|
|
231
|
+
* Total number of banners (for accessibility)
|
|
232
|
+
*/
|
|
233
|
+
totalBanners?: number;
|
|
234
|
+
/**
|
|
235
|
+
* Click handler for the banner
|
|
236
|
+
*/
|
|
237
|
+
onClick?: () => void;
|
|
238
|
+
}
|
|
239
|
+
declare const CardBanner: React$1.FC<CardBannerProps>;
|
|
240
|
+
|
|
241
|
+
interface CardTicketButton {
|
|
242
|
+
label: string;
|
|
243
|
+
icon?: JSX.Element;
|
|
244
|
+
onClick?: () => void;
|
|
245
|
+
}
|
|
246
|
+
interface CardTicketProps {
|
|
247
|
+
/**
|
|
248
|
+
* Ship type badge configuration
|
|
249
|
+
*/
|
|
250
|
+
shipType: {
|
|
251
|
+
label: string;
|
|
252
|
+
color: 'brand' | 'danger' | 'important' | 'informative' | 'severe' | 'subtle' | 'success' | 'warning';
|
|
253
|
+
tooltip?: string;
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Logo image source
|
|
257
|
+
* @default "/assets/logo/asdp-default.svg"
|
|
258
|
+
*/
|
|
259
|
+
logoSrc?: string;
|
|
260
|
+
/**
|
|
261
|
+
* Ship name
|
|
262
|
+
*/
|
|
263
|
+
shipName: string;
|
|
264
|
+
/**
|
|
265
|
+
* Available seats configuration
|
|
266
|
+
*/
|
|
267
|
+
availableSeats: {
|
|
268
|
+
count: number;
|
|
269
|
+
threshold?: number;
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Departure information
|
|
273
|
+
*/
|
|
274
|
+
departure: {
|
|
275
|
+
day: string;
|
|
276
|
+
time: string;
|
|
277
|
+
location: string;
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Arrival information
|
|
281
|
+
*/
|
|
282
|
+
arrival: {
|
|
283
|
+
day: string;
|
|
284
|
+
time: string;
|
|
285
|
+
location: string;
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* Duration text
|
|
289
|
+
*/
|
|
290
|
+
duration: string;
|
|
291
|
+
/**
|
|
292
|
+
* Middle section action buttons (max 2)
|
|
293
|
+
*/
|
|
294
|
+
actionButtons?: CardTicketButton[];
|
|
295
|
+
/**
|
|
296
|
+
* Price display (formatted string)
|
|
297
|
+
*/
|
|
298
|
+
price: string;
|
|
299
|
+
/**
|
|
300
|
+
* Primary button configuration
|
|
301
|
+
*/
|
|
302
|
+
primaryButton: CardTicketButton;
|
|
303
|
+
/**
|
|
304
|
+
* List of facilities
|
|
305
|
+
*/
|
|
306
|
+
facilities: string[];
|
|
307
|
+
/**
|
|
308
|
+
* Custom icon for ship indicator
|
|
309
|
+
*/
|
|
310
|
+
shipIcon?: JSX.Element;
|
|
311
|
+
/**
|
|
312
|
+
* Custom icon for facilities checkmark
|
|
313
|
+
*/
|
|
314
|
+
facilityIcon?: JSX.Element;
|
|
315
|
+
}
|
|
316
|
+
declare const CardTicket: React$1.FC<CardTicketProps>;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Horizontal ticket card background with decorative perforated edges
|
|
320
|
+
* Use this for desktop/landscape layouts
|
|
321
|
+
*/
|
|
322
|
+
declare const BackgroundTicketCard: (props: React$1.SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Vertical ticket card background with decorative perforated edges
|
|
326
|
+
* Use this for mobile/portrait layouts
|
|
327
|
+
*/
|
|
328
|
+
declare const BackgroundTicketCardVertical: (props: React$1.SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
|
|
329
|
+
|
|
330
|
+
interface ServiceMenuItem {
|
|
331
|
+
id: string;
|
|
332
|
+
label: string;
|
|
333
|
+
logo?: string;
|
|
334
|
+
description?: string;
|
|
335
|
+
customStyle?: React$1.CSSProperties;
|
|
336
|
+
}
|
|
337
|
+
interface CardServiceMenuProps {
|
|
338
|
+
/**
|
|
339
|
+
* Array of menu items to display
|
|
340
|
+
*/
|
|
341
|
+
items: ServiceMenuItem[];
|
|
342
|
+
/**
|
|
343
|
+
* Currently active item ID
|
|
344
|
+
*/
|
|
345
|
+
activeItemId?: string;
|
|
346
|
+
/**
|
|
347
|
+
* Callback when an item is clicked
|
|
348
|
+
*/
|
|
349
|
+
onItemClick?: (itemId: string) => void;
|
|
350
|
+
/**
|
|
351
|
+
* Whether to show descriptions on desktop
|
|
352
|
+
* @default true
|
|
353
|
+
*/
|
|
354
|
+
showDescriptions?: boolean;
|
|
355
|
+
/**
|
|
356
|
+
* Custom className for the card
|
|
357
|
+
*/
|
|
358
|
+
className?: string;
|
|
359
|
+
}
|
|
360
|
+
declare const CardServiceMenu: React$1.FC<CardServiceMenuProps>;
|
|
361
|
+
|
|
362
|
+
type InputType = 'checkbox' | 'date' | 'datetime-local' | 'email' | 'file' | 'identity' | 'emailOrPhone' | 'number' | 'otp' | 'passport' | 'password' | 'phone' | 'radio' | 'radiobutton' | 'select' | 'switch' | 'tel' | 'text' | 'textarea' | 'time' | 'url';
|
|
363
|
+
interface SelectOption {
|
|
364
|
+
value: string;
|
|
365
|
+
label: string;
|
|
366
|
+
disabled?: boolean;
|
|
367
|
+
}
|
|
368
|
+
interface RadioOption {
|
|
369
|
+
value: string;
|
|
370
|
+
label: string;
|
|
371
|
+
disabled?: boolean;
|
|
372
|
+
}
|
|
373
|
+
interface CountryCode {
|
|
374
|
+
code: string;
|
|
375
|
+
name: string;
|
|
376
|
+
dialCode: string;
|
|
377
|
+
flag?: string;
|
|
378
|
+
passportRegex?: string;
|
|
379
|
+
}
|
|
380
|
+
interface InputDynamicProps<T extends FieldValues = FieldValues> {
|
|
381
|
+
name: Path<T>;
|
|
382
|
+
control: Control<T>;
|
|
383
|
+
label?: string;
|
|
384
|
+
type: InputType;
|
|
385
|
+
placeholder?: string;
|
|
386
|
+
required?: boolean;
|
|
387
|
+
disabled?: boolean;
|
|
388
|
+
options?: SelectOption[] | RadioOption[];
|
|
389
|
+
multiple?: boolean;
|
|
390
|
+
accept?: string;
|
|
391
|
+
rows?: number;
|
|
392
|
+
min?: number | string;
|
|
393
|
+
max?: number | string;
|
|
394
|
+
step?: number | string;
|
|
395
|
+
isMultiSelect?: boolean;
|
|
396
|
+
selectScrollbarColor?: string;
|
|
397
|
+
contentBefore?: React.ReactNode;
|
|
398
|
+
appearance?: 'outline' | 'underline' | 'filled-darker' | 'filled-lighter' | 'filled-darker-shadow' | 'filled-lighter-shadow';
|
|
399
|
+
validationRules?: {
|
|
400
|
+
required?: string | boolean;
|
|
401
|
+
minLength?: {
|
|
402
|
+
value: number;
|
|
403
|
+
message: string;
|
|
404
|
+
};
|
|
405
|
+
maxLength?: {
|
|
406
|
+
value: number;
|
|
407
|
+
message: string;
|
|
408
|
+
};
|
|
409
|
+
pattern?: {
|
|
410
|
+
value: RegExp;
|
|
411
|
+
message: string;
|
|
412
|
+
};
|
|
413
|
+
min?: {
|
|
414
|
+
value: number;
|
|
415
|
+
message: string;
|
|
416
|
+
};
|
|
417
|
+
max?: {
|
|
418
|
+
value: number;
|
|
419
|
+
message: string;
|
|
420
|
+
};
|
|
421
|
+
validate?: (value: any) => string | boolean;
|
|
422
|
+
};
|
|
423
|
+
helperText?: string;
|
|
424
|
+
className?: string;
|
|
425
|
+
layout?: 'horizontal' | 'vertical';
|
|
426
|
+
size?: 'small' | 'medium' | 'large';
|
|
427
|
+
onClick?: () => void;
|
|
428
|
+
style?: React.CSSProperties;
|
|
429
|
+
countryCodes?: CountryCode[];
|
|
430
|
+
defaultCountry?: string;
|
|
431
|
+
maxLength?: number;
|
|
432
|
+
autoAdvance?: boolean;
|
|
433
|
+
otpIndex?: number;
|
|
434
|
+
hasError?: boolean;
|
|
435
|
+
autoComplete?: string;
|
|
436
|
+
onInput?: (e: React.FormEvent<HTMLInputElement>) => void;
|
|
437
|
+
contentAfter?: React.ReactNode;
|
|
438
|
+
onChange?: (value: any) => void;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
declare function InputDynamic<T extends FieldValues = FieldValues>({ name, control, label, type, placeholder, required, disabled, options, multiple, accept, rows, min, max, step, isMultiSelect, selectScrollbarColor, contentBefore, appearance, validationRules, helperText, className, layout, size, onClick, style, countryCodes, defaultCountry, maxLength, autoAdvance, otpIndex, hasError, autoComplete, onInput, contentAfter, onChange, }: InputDynamicProps<T>): react_jsx_runtime.JSX.Element;
|
|
442
|
+
|
|
443
|
+
declare const DEFAULT_COUNTRY_CODES: CountryCode[];
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Harbor item interface
|
|
447
|
+
*/
|
|
448
|
+
interface HarborItem {
|
|
449
|
+
/**
|
|
450
|
+
* Unique identifier for the harbor
|
|
451
|
+
*/
|
|
452
|
+
id: number;
|
|
453
|
+
/**
|
|
454
|
+
* Display name of the harbor
|
|
455
|
+
*/
|
|
456
|
+
name: string;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Props for ModalSearchHarbor component
|
|
460
|
+
*/
|
|
461
|
+
interface ModalSearchHarborProps {
|
|
462
|
+
/**
|
|
463
|
+
* Whether the modal is open
|
|
464
|
+
*/
|
|
465
|
+
open: boolean;
|
|
466
|
+
/**
|
|
467
|
+
* Callback when modal should close
|
|
468
|
+
*/
|
|
469
|
+
onClose: () => void;
|
|
470
|
+
/**
|
|
471
|
+
* Modal title
|
|
472
|
+
* @default "Pilih Pelabuhan"
|
|
473
|
+
*/
|
|
474
|
+
title?: string;
|
|
475
|
+
/**
|
|
476
|
+
* Type of modal - origin or destination
|
|
477
|
+
* @default "origin"
|
|
478
|
+
*/
|
|
479
|
+
modalType?: 'origin' | 'destination';
|
|
480
|
+
/**
|
|
481
|
+
* List of harbors to display
|
|
482
|
+
*/
|
|
483
|
+
harbors: HarborItem[];
|
|
484
|
+
/**
|
|
485
|
+
* List of favorite harbors
|
|
486
|
+
*/
|
|
487
|
+
favoriteHarbors: HarborItem[];
|
|
488
|
+
/**
|
|
489
|
+
* List of last searched harbors
|
|
490
|
+
*/
|
|
491
|
+
lastSearchedHarbors: HarborItem[];
|
|
492
|
+
/**
|
|
493
|
+
* Loading state
|
|
494
|
+
* @default false
|
|
495
|
+
*/
|
|
496
|
+
isLoading?: boolean;
|
|
497
|
+
/**
|
|
498
|
+
* Current search query value
|
|
499
|
+
*/
|
|
500
|
+
searchQuery: string;
|
|
501
|
+
/**
|
|
502
|
+
* Callback when search query changes
|
|
503
|
+
*/
|
|
504
|
+
onSearchChange: (query: string) => void;
|
|
505
|
+
/**
|
|
506
|
+
* Callback when a harbor is selected
|
|
507
|
+
*/
|
|
508
|
+
onSelectHarbor: (harbor: HarborItem) => void;
|
|
509
|
+
/**
|
|
510
|
+
* Callback when favorite is toggled
|
|
511
|
+
*/
|
|
512
|
+
onToggleFavorite: (harbor: HarborItem) => void;
|
|
513
|
+
/**
|
|
514
|
+
* Callback when adding to last searched
|
|
515
|
+
*/
|
|
516
|
+
onAddLastSearched: (harbor: HarborItem) => void;
|
|
517
|
+
/**
|
|
518
|
+
* Callback when removing from last searched
|
|
45
519
|
*/
|
|
46
|
-
|
|
520
|
+
onRemoveLastSearched: (harborId: number) => void;
|
|
47
521
|
/**
|
|
48
|
-
*
|
|
522
|
+
* Callback when clearing all last searched
|
|
49
523
|
*/
|
|
50
|
-
|
|
524
|
+
onClearLastSearched: () => void;
|
|
51
525
|
}
|
|
52
|
-
|
|
526
|
+
/**
|
|
527
|
+
* ModalSearchHarbor - A reusable modal component for searching and selecting harbors
|
|
528
|
+
*
|
|
529
|
+
* This component provides a searchable modal interface for selecting harbors with features like:
|
|
530
|
+
* - Search functionality
|
|
531
|
+
* - Favorite harbors quick access
|
|
532
|
+
* - Last searched history
|
|
533
|
+
* - Loading states
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```tsx
|
|
537
|
+
* <ModalSearchHarbor
|
|
538
|
+
* open={isOpen}
|
|
539
|
+
* onClose={() => setIsOpen(false)}
|
|
540
|
+
* title="Pilih Pelabuhan Asal"
|
|
541
|
+
* harbors={harborList}
|
|
542
|
+
* favoriteHarbors={favorites}
|
|
543
|
+
* lastSearchedHarbors={history}
|
|
544
|
+
* searchQuery={search}
|
|
545
|
+
* onSearchChange={setSearch}
|
|
546
|
+
* onSelectHarbor={handleSelect}
|
|
547
|
+
* onToggleFavorite={handleToggleFavorite}
|
|
548
|
+
* onAddLastSearched={handleAddHistory}
|
|
549
|
+
* onRemoveLastSearched={handleRemoveHistory}
|
|
550
|
+
* onClearLastSearched={handleClearHistory}
|
|
551
|
+
* />
|
|
552
|
+
* ```
|
|
553
|
+
*/
|
|
554
|
+
declare const ModalSearchHarbor: React.FC<ModalSearchHarborProps>;
|
|
53
555
|
|
|
54
|
-
export {
|
|
556
|
+
export { BackgroundTicketCard, BackgroundTicketCardVertical, CardBanner, type CardBannerProps, CardPromo, type CardPromoProps, CardServiceMenu, type CardServiceMenuProps, CardTicket, type CardTicketButton, type CardTicketProps, CarouselWithCustomNav, type CarouselWithCustomNavProps, type CountryCode, DEFAULT_COUNTRY_CODES, type HarborItem, InputDynamic, type InputDynamicProps, type InputType, MODAL_PRESETS, ModalIllustration, type ModalIllustrationButton, type ModalIllustrationProps, type ModalPresetKey, ModalSearchHarbor, type ModalSearchHarborProps, type RadioOption, type SelectOption, type ServiceMenuItem, getModalPreset };
|