@hotelcard/ui 0.0.2 → 0.0.4

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
@@ -17,8 +17,8 @@ npm install @hotelcard/ui
17
17
  ### Import Components
18
18
 
19
19
  ```tsx
20
- import { Button, Badge, Rating } from '@hotelcard/ui';
21
- import type { ButtonProps, BadgeProps } from '@hotelcard/ui';
20
+ import { Button, Badge, Rating, Input, Checkbox, Modal } from '@hotelcard/ui';
21
+ import type { ButtonProps, BadgeProps, InputProps } from '@hotelcard/ui';
22
22
  ```
23
23
 
24
24
  ### Import Styles (REQUIRED)
@@ -117,6 +117,324 @@ import { Rating } from '@hotelcard/ui';
117
117
  | `showValue` | `boolean` | `false` | Show numeric value |
118
118
  | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | Star size |
119
119
 
120
+ ### Input
121
+
122
+ ```tsx
123
+ import { Input } from '@hotelcard/ui';
124
+
125
+ // Basic input
126
+ <Input
127
+ label="Email"
128
+ placeholder="Enter your email"
129
+ value={email}
130
+ onChange={setEmail}
131
+ />
132
+
133
+ // With helper text
134
+ <Input
135
+ label="Password"
136
+ type="password"
137
+ helper="Must be at least 8 characters"
138
+ />
139
+
140
+ // Error state
141
+ <Input
142
+ label="Email"
143
+ error
144
+ helper="Invalid email address"
145
+ />
146
+
147
+ // With icons
148
+ <Input
149
+ leftIcon={<SearchIcon />}
150
+ placeholder="Search..."
151
+ />
152
+
153
+ // Disabled
154
+ <Input
155
+ label="Disabled"
156
+ disabled
157
+ value="Cannot edit"
158
+ />
159
+ ```
160
+
161
+ **Props:**
162
+ | Prop | Type | Default | Description |
163
+ |------|------|---------|-------------|
164
+ | `label` | `string` | - | Label text above input |
165
+ | `placeholder` | `string` | `'Placeholder'` | Placeholder text |
166
+ | `helper` | `string` | - | Helper text below input |
167
+ | `value` | `string` | - | Controlled value |
168
+ | `onChange` | `(value: string) => void` | - | Change handler |
169
+ | `type` | `'text' \| 'email' \| 'password' \| 'tel' \| 'number'` | `'text'` | Input type |
170
+ | `error` | `boolean` | `false` | Show error state |
171
+ | `disabled` | `boolean` | `false` | Disable input |
172
+ | `leftIcon` | `ReactNode` | - | Icon on the left |
173
+ | `rightIcon` | `ReactNode` | - | Icon on the right |
174
+
175
+ ### Checkbox
176
+
177
+ ```tsx
178
+ import { Checkbox } from '@hotelcard/ui';
179
+
180
+ // Controlled checkbox
181
+ <Checkbox
182
+ label="Accept terms"
183
+ checked={accepted}
184
+ onChange={setAccepted}
185
+ />
186
+
187
+ // Uncontrolled with default
188
+ <Checkbox
189
+ label="Remember me"
190
+ defaultChecked
191
+ />
192
+
193
+ // Error state
194
+ <Checkbox
195
+ label="Required field"
196
+ error
197
+ />
198
+
199
+ // Sizes
200
+ <Checkbox label="Medium" size="medium" />
201
+ <Checkbox label="Small" size="small" />
202
+ ```
203
+
204
+ **Props:**
205
+ | Prop | Type | Default | Description |
206
+ |------|------|---------|-------------|
207
+ | `label` | `string` | - | Label text |
208
+ | `checked` | `boolean` | - | Controlled checked state |
209
+ | `defaultChecked` | `boolean` | `false` | Default checked state |
210
+ | `onChange` | `(checked: boolean) => void` | - | Change handler |
211
+ | `size` | `'small' \| 'medium'` | `'medium'` | Checkbox size |
212
+ | `disabled` | `boolean` | `false` | Disable checkbox |
213
+ | `error` | `boolean` | `false` | Show error state |
214
+
215
+ ### RadioButton
216
+
217
+ ```tsx
218
+ import { RadioButton } from '@hotelcard/ui';
219
+
220
+ // Radio group
221
+ <RadioButton
222
+ label="Option 1"
223
+ checked={selected === '1'}
224
+ onChange={() => setSelected('1')}
225
+ name="options"
226
+ />
227
+ <RadioButton
228
+ label="Option 2"
229
+ checked={selected === '2'}
230
+ onChange={() => setSelected('2')}
231
+ name="options"
232
+ />
233
+ ```
234
+
235
+ **Props:**
236
+ | Prop | Type | Default | Description |
237
+ |------|------|---------|-------------|
238
+ | `label` | `string` | - | Label text |
239
+ | `checked` | `boolean` | - | Checked state (required) |
240
+ | `onChange` | `(checked: boolean) => void` | - | Change handler (required) |
241
+ | `name` | `string` | - | Group name for form |
242
+ | `disabled` | `boolean` | `false` | Disable radio |
243
+
244
+ ### Dropdown
245
+
246
+ ```tsx
247
+ import { Dropdown } from '@hotelcard/ui';
248
+
249
+ const options = [
250
+ { value: '1', label: 'Option 1' },
251
+ { value: '2', label: 'Option 2' },
252
+ { value: '3', label: 'Option 3' },
253
+ ];
254
+
255
+ // Controlled
256
+ <Dropdown
257
+ options={options}
258
+ value={selected}
259
+ onChange={setSelected}
260
+ placeholder="Select..."
261
+ />
262
+
263
+ // Uncontrolled with default
264
+ <Dropdown
265
+ options={options}
266
+ defaultValue="1"
267
+ />
268
+ ```
269
+
270
+ **Props:**
271
+ | Prop | Type | Default | Description |
272
+ |------|------|---------|-------------|
273
+ | `options` | `Array<{value, label}>` | `[]` | Dropdown options |
274
+ | `value` | `string` | - | Controlled value |
275
+ | `defaultValue` | `string` | - | Default value |
276
+ | `onChange` | `(value: string) => void` | - | Change handler |
277
+ | `placeholder` | `string` | `'Select...'` | Placeholder text |
278
+ | `disabled` | `boolean` | `false` | Disable dropdown |
279
+ | `error` | `boolean` | `false` | Show error state |
280
+
281
+ ### Modal
282
+
283
+ ```tsx
284
+ import { Modal } from '@hotelcard/ui';
285
+
286
+ <Modal
287
+ isOpen={isOpen}
288
+ onClose={() => setIsOpen(false)}
289
+ width="500px"
290
+ >
291
+ <h2>Modal Title</h2>
292
+ <p>Modal content goes here.</p>
293
+ </Modal>
294
+
295
+ // Without close button
296
+ <Modal
297
+ isOpen={isOpen}
298
+ onClose={handleClose}
299
+ showCloseButton={false}
300
+ >
301
+ <CustomCloseButton />
302
+ </Modal>
303
+
304
+ // Disable backdrop click
305
+ <Modal
306
+ isOpen={isOpen}
307
+ onClose={handleClose}
308
+ disableBackdropClick
309
+ >
310
+ Must use close button
311
+ </Modal>
312
+ ```
313
+
314
+ **Props:**
315
+ | Prop | Type | Default | Description |
316
+ |------|------|---------|-------------|
317
+ | `isOpen` | `boolean` | - | Show/hide modal |
318
+ | `onClose` | `() => void` | - | Close handler |
319
+ | `children` | `ReactNode` | - | Modal content |
320
+ | `width` | `string` | `'600px'` | Max width |
321
+ | `showCloseButton` | `boolean` | `true` | Show X button |
322
+ | `disableBackdropClick` | `boolean` | `false` | Prevent backdrop close |
323
+
324
+ ### Chip
325
+
326
+ ```tsx
327
+ import { Chip } from '@hotelcard/ui';
328
+
329
+ // Basic chip
330
+ <Chip label="Filter" />
331
+
332
+ // With count
333
+ <Chip label="Hotels" count={42} />
334
+
335
+ // Active state
336
+ <Chip label="Selected" state="active" />
337
+
338
+ // Non-removable
339
+ <Chip label="Category" removable={false} onClick={() => {}} />
340
+
341
+ // Sizes
342
+ <Chip label="Medium" size="medium" />
343
+ <Chip label="Small" size="small" />
344
+ ```
345
+
346
+ **Props:**
347
+ | Prop | Type | Default | Description |
348
+ |------|------|---------|-------------|
349
+ | `label` | `string` | - | Chip text |
350
+ | `count` | `number \| string` | - | Badge count |
351
+ | `state` | `'idle' \| 'active' \| 'disabled'` | `'idle'` | State variant |
352
+ | `size` | `'small' \| 'medium'` | `'small'` | Chip size |
353
+ | `removable` | `boolean` | `true` | Show X button |
354
+ | `onRemove` | `() => void` | - | Remove handler |
355
+ | `onClick` | `() => void` | - | Click handler |
356
+
357
+ ### Divider
358
+
359
+ ```tsx
360
+ import { Divider } from '@hotelcard/ui';
361
+
362
+ // Horizontal divider
363
+ <Divider />
364
+
365
+ // With label
366
+ <Divider label="OR" />
367
+
368
+ // Vertical divider
369
+ <Divider orientation="vertical" />
370
+ ```
371
+
372
+ **Props:**
373
+ | Prop | Type | Default | Description |
374
+ |------|------|---------|-------------|
375
+ | `label` | `string` | - | Center label text |
376
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Divider direction |
377
+
378
+ ### SectionHeader
379
+
380
+ ```tsx
381
+ import { SectionHeader } from '@hotelcard/ui';
382
+
383
+ // With "Show all" button
384
+ <SectionHeader
385
+ title="Latest Hotels"
386
+ showAllLabel="Show all"
387
+ onShowAllClick={() => navigate('/hotels')}
388
+ />
389
+
390
+ // Title only
391
+ <SectionHeader title="Featured" />
392
+ ```
393
+
394
+ **Props:**
395
+ | Prop | Type | Default | Description |
396
+ |------|------|---------|-------------|
397
+ | `title` | `string` | - | Section title |
398
+ | `showAllLabel` | `string` | - | "Show all" button text |
399
+ | `onShowAllClick` | `() => void` | - | Button click handler |
400
+
401
+ ### CompactCard
402
+
403
+ ```tsx
404
+ import { CompactCard } from '@hotelcard/ui';
405
+
406
+ <CompactCard
407
+ image="/hotel.jpg"
408
+ imageAlt="Hotel Grand"
409
+ label="Hotel Grand Zurich"
410
+ price="From CHF 120"
411
+ stars={4}
412
+ isSuperior
413
+ badge={{ text: '-30%', variant: 'primary' }}
414
+ onClick={() => navigate('/hotel/123')}
415
+ />
416
+
417
+ // Swiss Lodge (stars = 6)
418
+ <CompactCard
419
+ label="Swiss Lodge Hotel"
420
+ stars={6}
421
+ swissLodgeLabel="Swiss Lodge"
422
+ />
423
+ ```
424
+
425
+ **Props:**
426
+ | Prop | Type | Default | Description |
427
+ |------|------|---------|-------------|
428
+ | `image` | `string` | - | Image URL |
429
+ | `imageAlt` | `string` | `''` | Image alt text |
430
+ | `label` | `string` | - | Hotel name |
431
+ | `price` | `string` | - | Price text |
432
+ | `stars` | `number` | - | Star rating (1-6) |
433
+ | `isSuperior` | `boolean` | `false` | Superior indicator |
434
+ | `badge` | `{text, variant}` | - | Badge config |
435
+ | `onClick` | `() => void` | - | Click handler |
436
+ | `swissLodgeLabel` | `string` | `'Swiss Lodge'` | Label for 6-star |
437
+
120
438
  ### Icons
121
439
 
122
440
  ```tsx
@@ -169,6 +487,15 @@ import type {
169
487
  ButtonProps,
170
488
  BadgeProps,
171
489
  RatingProps,
490
+ InputProps,
491
+ CheckboxProps,
492
+ RadioButtonProps,
493
+ DropdownProps,
494
+ ModalProps,
495
+ ChipProps,
496
+ DividerProps,
497
+ SectionHeaderProps,
498
+ CompactCardProps,
172
499
  } from '@hotelcard/ui';
173
500
  ```
174
501
 
@@ -189,6 +516,15 @@ packages/ui/
189
516
  │ │ │ └── index.ts
190
517
  │ │ ├── Badge/
191
518
  │ │ ├── Rating/
519
+ │ │ ├── Input/
520
+ │ │ ├── Checkbox/
521
+ │ │ ├── RadioButton/
522
+ │ │ ├── Dropdown/
523
+ │ │ ├── Modal/
524
+ │ │ ├── Chip/
525
+ │ │ ├── Divider/
526
+ │ │ ├── SectionHeader/
527
+ │ │ ├── CompactCard/
192
528
  │ │ └── icons/
193
529
  │ └── index.ts # Main exports
194
530
  ├── dist/ # Built output
@@ -254,7 +590,15 @@ CSS Modules don't work well with tsup bundling - the class name mappings become
254
590
 
255
591
  - `hc-btn-*` for Button
256
592
  - `hc-badge-*` for Badge
257
- - `hc-rating-*` for Rating
593
+ - `hc-input-*` for Input
594
+ - `hc-checkbox-*` for Checkbox
595
+ - `hc-radio-*` for RadioButton
596
+ - `hc-dropdown-*` for Dropdown
597
+ - `hc-modal-*` for Modal
598
+ - `hc-chip-*` for Chip
599
+ - `hc-divider-*` for Divider
600
+ - `hc-section-*` for SectionHeader
601
+ - `hc-compact-*` for CompactCard
258
602
 
259
603
  This prevents conflicts with consuming app's styles while ensuring styles are always applied.
260
604
 
@@ -326,11 +670,11 @@ git push
326
670
  import '@hotelcard/ui/dist/index.css'; // REQUIRED
327
671
 
328
672
  // src/library/index.ts (barrel export)
329
- export { Button, Badge } from '@hotelcard/ui';
330
- export type { ButtonProps, BadgeProps } from '@hotelcard/ui';
673
+ export { Button, Badge, Input, Checkbox } from '@hotelcard/ui';
674
+ export type { ButtonProps, BadgeProps, InputProps } from '@hotelcard/ui';
331
675
 
332
676
  // src/pages/SomePage.tsx
333
- import { Button, Badge } from '@/library';
677
+ import { Button, Input } from '@/library';
334
678
  ```
335
679
 
336
680
  ### hotelcard-ui (Website)
@@ -340,7 +684,7 @@ import { Button, Badge } from '@/library';
340
684
  import '@hotelcard/ui/dist/index.css'; // REQUIRED
341
685
 
342
686
  // Use directly
343
- import { Button, Badge } from '@hotelcard/ui';
687
+ import { Button, Badge, Modal } from '@hotelcard/ui';
344
688
  ```
345
689
 
346
690
  ### Updating the Package