@hotelcard/ui 0.0.2

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 ADDED
@@ -0,0 +1,410 @@
1
+ # @hotelcard/ui
2
+
3
+ Shared UI component library for HotelCard applications (mobile app and website).
4
+
5
+ ## Quick Start
6
+
7
+ ### Installation
8
+
9
+ ```bash
10
+ # In your project
11
+ npm install @hotelcard/ui
12
+
13
+ # Or with local development (file: protocol)
14
+ "@hotelcard/ui": "file:../hotelcard-monorepo/packages/ui"
15
+ ```
16
+
17
+ ### Import Components
18
+
19
+ ```tsx
20
+ import { Button, Badge, Rating } from '@hotelcard/ui';
21
+ import type { ButtonProps, BadgeProps } from '@hotelcard/ui';
22
+ ```
23
+
24
+ ### Import Styles (REQUIRED)
25
+
26
+ You **must** import the CSS in your app's entry point (e.g., `main.tsx`):
27
+
28
+ ```tsx
29
+ // main.tsx or App.tsx
30
+ import '@hotelcard/ui/dist/index.css';
31
+ ```
32
+
33
+ **If you skip this step, components will render without styling!**
34
+
35
+ ---
36
+
37
+ ## Available Components
38
+
39
+ ### Button
40
+
41
+ ```tsx
42
+ import { Button } from '@hotelcard/ui';
43
+
44
+ // Primary button (default)
45
+ <Button onClick={handleClick}>Submit</Button>
46
+
47
+ // Secondary button
48
+ <Button variant="secondary">Cancel</Button>
49
+
50
+ // Small size
51
+ <Button size="small">Small Button</Button>
52
+
53
+ // Link style
54
+ <Button variant="link">Learn More</Button>
55
+
56
+ // With icons
57
+ <Button leftIcon={<SearchIcon />}>Search</Button>
58
+
59
+ // Icon-only button
60
+ <Button iconOnly><HeartIcon /></Button>
61
+ ```
62
+
63
+ **Props:**
64
+ | Prop | Type | Default | Description |
65
+ |------|------|---------|-------------|
66
+ | `variant` | `'primary' \| 'secondary' \| 'link'` | `'primary'` | Button style |
67
+ | `size` | `'small' \| 'medium'` | `'medium'` | Button size |
68
+ | `iconOnly` | `boolean` | `false` | Icon-only circular button |
69
+ | `leftIcon` | `ReactNode` | - | Icon on the left |
70
+ | `rightIcon` | `ReactNode` | - | Icon on the right |
71
+ | `disabled` | `boolean` | `false` | Disabled state |
72
+
73
+ ### Badge
74
+
75
+ ```tsx
76
+ import { Badge } from '@hotelcard/ui';
77
+
78
+ // Discount badge
79
+ <Badge color="primary" size="small" style="heavy">
80
+ -50%
81
+ </Badge>
82
+
83
+ // Status badge
84
+ <Badge color="success" style="light">
85
+ Available
86
+ </Badge>
87
+ ```
88
+
89
+ **Props:**
90
+ | Prop | Type | Default | Description |
91
+ |------|------|---------|-------------|
92
+ | `color` | `'primary' \| 'secondary' \| 'neutral' \| 'success' \| 'warning'` | `'primary'` | Badge color |
93
+ | `size` | `'small' \| 'large'` | `'large'` | Badge size |
94
+ | `style` | `'heavy' \| 'light'` | `'heavy'` | Solid or light background |
95
+
96
+ ### Rating
97
+
98
+ ```tsx
99
+ import { Rating } from '@hotelcard/ui';
100
+
101
+ // Star rating
102
+ <Rating value={4.5} />
103
+
104
+ // Show numeric value
105
+ <Rating value={4.5} showValue />
106
+
107
+ // Different sizes
108
+ <Rating value={3} size="small" />
109
+ <Rating value={3} size="large" />
110
+ ```
111
+
112
+ **Props:**
113
+ | Prop | Type | Default | Description |
114
+ |------|------|---------|-------------|
115
+ | `value` | `number` | - | Rating value (0-5) |
116
+ | `maxValue` | `number` | `5` | Maximum stars |
117
+ | `showValue` | `boolean` | `false` | Show numeric value |
118
+ | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | Star size |
119
+
120
+ ### Icons
121
+
122
+ ```tsx
123
+ import { HeartIcon, StarIcon, ChevronLeftIcon, ChevronRightIcon, PinIcon } from '@hotelcard/ui';
124
+
125
+ <HeartIcon filled={false} size={24} />
126
+ <StarIcon size={9} />
127
+ <ChevronLeftIcon size={20} />
128
+ <ChevronRightIcon size={20} />
129
+ <PinIcon size={16} />
130
+ ```
131
+
132
+ ---
133
+
134
+ ## CSS Variables (Theming)
135
+
136
+ Components use CSS variables for theming. Your app should define these in a global CSS file:
137
+
138
+ ```css
139
+ :root {
140
+ /* Colors */
141
+ --background-action-primary-idle: #C81E4C;
142
+ --background-action-primary-hover: #a3183d;
143
+ --content-action-primary-inverse-idle: #ffffff;
144
+ --content-general-primary: #1F2937;
145
+ --content-general-secondary: #6B7280;
146
+ --border-general-divider: #D1D5DB;
147
+
148
+ /* Typography */
149
+ --font-primary: system-ui, -apple-system, sans-serif;
150
+ --font-weight-medium: 500;
151
+ --font-weight-semibold: 600;
152
+
153
+ /* Spacing & Sizing */
154
+ --radius-lg: 12px;
155
+ --radius-full: 9999px;
156
+
157
+ /* ... see tokens.css for full list */
158
+ }
159
+ ```
160
+
161
+ Components have fallback values, so they work without custom CSS variables.
162
+
163
+ ---
164
+
165
+ ## Types
166
+
167
+ ```tsx
168
+ import type {
169
+ ButtonProps,
170
+ BadgeProps,
171
+ RatingProps,
172
+ } from '@hotelcard/ui';
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Development Guide
178
+
179
+ ### Project Structure
180
+
181
+ ```
182
+ packages/ui/
183
+ ├── src/
184
+ │ ├── components/
185
+ │ │ ├── Button/
186
+ │ │ │ ├── Button.tsx
187
+ │ │ │ ├── Button.css # Prefixed classes (hc-btn-*)
188
+ │ │ │ ├── Button.types.ts
189
+ │ │ │ └── index.ts
190
+ │ │ ├── Badge/
191
+ │ │ ├── Rating/
192
+ │ │ └── icons/
193
+ │ └── index.ts # Main exports
194
+ ├── dist/ # Built output
195
+ ├── package.json
196
+ └── tsup.config.ts
197
+ ```
198
+
199
+ ### Adding a New Component
200
+
201
+ 1. **Create component folder:**
202
+ ```
203
+ src/components/NewComponent/
204
+ ├── NewComponent.tsx
205
+ ├── NewComponent.css
206
+ ├── NewComponent.types.ts
207
+ └── index.ts
208
+ ```
209
+
210
+ 2. **Use prefixed CSS classes** (NOT CSS modules):
211
+ ```tsx
212
+ // NewComponent.tsx
213
+ import './NewComponent.css';
214
+
215
+ const cx = (className: string) => `hc-newcomp-${className}`;
216
+
217
+ export const NewComponent = () => (
218
+ <div className={cx('container')}>
219
+ <span className={cx('text')}>Hello</span>
220
+ </div>
221
+ );
222
+ ```
223
+
224
+ 3. **Define CSS with prefixes:**
225
+ ```css
226
+ /* NewComponent.css */
227
+ .hc-newcomp-container {
228
+ display: flex;
229
+ padding: var(--size-rem-1, 16px);
230
+ }
231
+
232
+ .hc-newcomp-text {
233
+ color: var(--content-general-primary, #1F2937);
234
+ }
235
+ ```
236
+
237
+ 4. **Export from index.ts:**
238
+ ```tsx
239
+ // src/index.ts
240
+ export { NewComponent } from './components/NewComponent';
241
+ export type { NewComponentProps } from './components/NewComponent';
242
+ ```
243
+
244
+ 5. **Build and test:**
245
+ ```bash
246
+ pnpm build
247
+ ```
248
+
249
+ ### CSS Class Naming Convention
250
+
251
+ **Why prefixed classes instead of CSS Modules?**
252
+
253
+ CSS Modules don't work well with tsup bundling - the class name mappings become empty objects. We use prefixed classes instead:
254
+
255
+ - `hc-btn-*` for Button
256
+ - `hc-badge-*` for Badge
257
+ - `hc-rating-*` for Rating
258
+
259
+ This prevents conflicts with consuming app's styles while ensuring styles are always applied.
260
+
261
+ ### Building
262
+
263
+ ```bash
264
+ cd packages/ui
265
+
266
+ # Build once
267
+ pnpm build
268
+
269
+ # Watch mode for development
270
+ pnpm dev
271
+ ```
272
+
273
+ ### Testing Changes Locally
274
+
275
+ 1. Build the package: `pnpm build`
276
+ 2. In consuming app, reinstall: `npm install`
277
+ 3. Restart dev server if needed
278
+
279
+ ---
280
+
281
+ ## Publishing to NPM
282
+
283
+ ### Prerequisites
284
+
285
+ 1. NPM account with access to `@hotelcard` organization
286
+ 2. Logged in: `npm login`
287
+
288
+ ### Publish Process
289
+
290
+ ```bash
291
+ cd packages/ui
292
+
293
+ # 1. Make sure everything builds
294
+ pnpm build
295
+
296
+ # 2. Update version
297
+ npm version patch # 0.0.2 -> 0.0.3
298
+ # or
299
+ npm version minor # 0.0.2 -> 0.1.0
300
+ # or
301
+ npm version major # 0.0.2 -> 1.0.0
302
+
303
+ # 3. Publish
304
+ npm publish --access public
305
+
306
+ # 4. Commit version bump
307
+ git add package.json
308
+ git commit -m "chore(ui): release v0.0.3"
309
+ git push
310
+ ```
311
+
312
+ ### Version Guidelines
313
+
314
+ - `patch` (0.0.x): Bug fixes, style tweaks
315
+ - `minor` (0.x.0): New components, new features
316
+ - `major` (x.0.0): Breaking changes (API changes, removed props)
317
+
318
+ ---
319
+
320
+ ## Using in Apps
321
+
322
+ ### hotelcard-app-v2 (Mobile App)
323
+
324
+ ```tsx
325
+ // src/main.tsx
326
+ import '@hotelcard/ui/dist/index.css'; // REQUIRED
327
+
328
+ // src/library/index.ts (barrel export)
329
+ export { Button, Badge } from '@hotelcard/ui';
330
+ export type { ButtonProps, BadgeProps } from '@hotelcard/ui';
331
+
332
+ // src/pages/SomePage.tsx
333
+ import { Button, Badge } from '@/library';
334
+ ```
335
+
336
+ ### hotelcard-ui (Website)
337
+
338
+ ```tsx
339
+ // src/main.tsx or app entry
340
+ import '@hotelcard/ui/dist/index.css'; // REQUIRED
341
+
342
+ // Use directly
343
+ import { Button, Badge } from '@hotelcard/ui';
344
+ ```
345
+
346
+ ### Updating the Package
347
+
348
+ ```bash
349
+ # After a new version is published
350
+ npm update @hotelcard/ui
351
+
352
+ # Or for local development
353
+ rm -rf node_modules/.cache
354
+ npm install
355
+ ```
356
+
357
+ ---
358
+
359
+ ## Troubleshooting
360
+
361
+ ### "Components render without styles"
362
+
363
+ Make sure you imported the CSS:
364
+ ```tsx
365
+ import '@hotelcard/ui/dist/index.css';
366
+ ```
367
+
368
+ ### "Module not found" errors
369
+
370
+ ```bash
371
+ # Clear cache and reinstall
372
+ rm -rf node_modules/.cache
373
+ npm install
374
+ ```
375
+
376
+ ### "Types not found"
377
+
378
+ Make sure you're importing types with `type`:
379
+ ```tsx
380
+ import type { ButtonProps } from '@hotelcard/ui';
381
+ ```
382
+
383
+ ### Local changes not reflecting
384
+
385
+ ```bash
386
+ # In @hotelcard/ui
387
+ pnpm build
388
+
389
+ # In consuming app
390
+ npm install
391
+ # Restart dev server
392
+ ```
393
+
394
+ ---
395
+
396
+ ## Component Checklist
397
+
398
+ When adding/modifying components:
399
+
400
+ - [ ] Uses prefixed CSS classes (not CSS modules)
401
+ - [ ] All CSS variables have fallback values
402
+ - [ ] Props are typed in `.types.ts`
403
+ - [ ] Exported from `src/index.ts`
404
+ - [ ] Build passes: `pnpm build`
405
+ - [ ] Tested in consuming app
406
+ - [ ] README updated if new component
407
+
408
+ ## License
409
+
410
+ MIT