igloo-d2c-components 1.0.6 → 1.0.7
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 +998 -157
- package/dist/cjs/index.js +497 -2
- package/dist/esm/index.js +479 -2
- package/dist/types/index.d.ts +2 -1
- package/dist/types/themes/index.d.ts +40 -0
- package/dist/types/types/tenant.d.ts +31 -17
- package/package.json +7 -3
- package/dist/cjs/index.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,91 +1,336 @@
|
|
|
1
1
|
# D2C Component Library
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
Reusable React component library with **centralized tenant themes** and tenant-aware theming for B2C applications.
|
|
4
|
+
|
|
5
|
+
## 📋 Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Overview](#-overview)
|
|
8
|
+
- [Features](#-features)
|
|
9
|
+
- [Installation](#-installation)
|
|
10
|
+
- [Quick Start](#-quick-start)
|
|
11
|
+
- [Centralized Themes](#-centralized-themes)
|
|
12
|
+
- [Components](#-components)
|
|
13
|
+
- [Hooks & Utilities](#-hooks--utilities)
|
|
14
|
+
- [Development](#-development)
|
|
15
|
+
- [Publishing](#-publishing)
|
|
16
|
+
- [Storybook](#-storybook)
|
|
17
|
+
- [Technical Details](#-technical-details)
|
|
18
|
+
- [Troubleshooting](#-troubleshooting)
|
|
19
|
+
- [Contributing](#-contributing)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🎯 Overview
|
|
24
|
+
|
|
25
|
+
The D2C Component Library provides reusable, tenant-aware UI components with **centralized theme management**. All tenant themes are defined in one place, ensuring consistency across all applications.
|
|
26
|
+
|
|
27
|
+
### Key Highlights
|
|
28
|
+
|
|
29
|
+
- 🎨 **Centralized Themes** - All tenant themes (Igloo, CIMB, AmmetLife) in one library
|
|
30
|
+
- 🧩 **Tenant-Aware Components** - Automatically adapt to tenant branding
|
|
31
|
+
- 📦 **ES2015 Compatible** - Works with older webpack configurations
|
|
32
|
+
- 🔧 **Unminified Output** - Better debugging and tree-shaking
|
|
33
|
+
- 📖 **Full TypeScript Support** - Complete type definitions
|
|
34
|
+
- ⚡ **Tree-Shakeable** - Import only what you need
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## ✨ Features
|
|
39
|
+
|
|
40
|
+
### Centralized Theme System
|
|
41
|
+
|
|
42
|
+
- ✅ **Single source of truth** for all tenant themes
|
|
43
|
+
- ✅ **Type-safe** theme access with TypeScript
|
|
44
|
+
- ✅ **Dynamic theme loading** with `getTenantTheme()`
|
|
45
|
+
- ✅ **~585 lines of code removed** from consuming apps
|
|
46
|
+
- ✅ **Easy to maintain** - update once, reflects everywhere
|
|
47
|
+
|
|
48
|
+
### Available Themes
|
|
49
|
+
|
|
50
|
+
| Tenant | Theme Export | Description |
|
|
51
|
+
|--------|-------------|-------------|
|
|
52
|
+
| **Igloo** | `iglooTheme` | Default insurance brand |
|
|
53
|
+
| **CIMB** | `cimbTheme` | Banking partner theme |
|
|
54
|
+
| **AmmetLife** | `ammetlifeTheme` | Life insurance partner |
|
|
55
|
+
|
|
56
|
+
### Components
|
|
57
|
+
|
|
58
|
+
- **Button** - Tenant-themed button component
|
|
59
|
+
- **Card** - Card with tenant accent border
|
|
60
|
+
- **Banner** - Promotional banner with gradients
|
|
61
|
+
|
|
62
|
+
### Hooks
|
|
63
|
+
|
|
64
|
+
- `useTenantTheme()` - Access tenant theme and ID
|
|
65
|
+
- `useTenantId()` - Get current tenant ID
|
|
66
|
+
- `useIsTenant()` - Check tenant match
|
|
67
|
+
|
|
68
|
+
### Utilities
|
|
69
|
+
|
|
70
|
+
- `getTenantTheme()` - Get theme by tenant ID
|
|
71
|
+
- `isValidTenantId()` - Validate tenant ID
|
|
72
|
+
- `getThemeColor()` - Extract colors from theme
|
|
73
|
+
- `createThemeCSSVariables()` - Generate CSS variables
|
|
74
|
+
|
|
75
|
+
---
|
|
3
76
|
|
|
4
77
|
## 📦 Installation
|
|
5
78
|
|
|
6
|
-
###
|
|
79
|
+
### Option 1: Local Development (Recommended for Development)
|
|
80
|
+
|
|
81
|
+
Perfect for active development when working on the library.
|
|
7
82
|
|
|
8
83
|
```bash
|
|
9
|
-
#
|
|
84
|
+
# 1. Build the library
|
|
85
|
+
cd /path/to/d2c-component-library
|
|
10
86
|
yarn install
|
|
11
87
|
yarn build
|
|
12
|
-
yarn link
|
|
13
88
|
|
|
14
|
-
# In b2c-web-demo
|
|
15
|
-
|
|
89
|
+
# 2. In consuming app (b2c-web-demo)
|
|
90
|
+
cd /path/to/b2c-web-demo
|
|
91
|
+
|
|
92
|
+
# Add to package.json:
|
|
93
|
+
{
|
|
94
|
+
"dependencies": {
|
|
95
|
+
"igloo-d2c-components": "file:../d2c-component-library"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Install
|
|
100
|
+
yarn install
|
|
16
101
|
```
|
|
17
102
|
|
|
18
|
-
|
|
103
|
+
**Workflow:**
|
|
104
|
+
```bash
|
|
105
|
+
# Make changes to library
|
|
106
|
+
cd d2c-component-library
|
|
107
|
+
# ... edit files ...
|
|
108
|
+
yarn build
|
|
109
|
+
|
|
110
|
+
# Update consuming app
|
|
111
|
+
cd ../b2c-web-demo
|
|
112
|
+
yarn install # Copies updated build
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Option 2: NPM Registry (Production)
|
|
116
|
+
|
|
117
|
+
For production deployments and CI/CD.
|
|
19
118
|
|
|
119
|
+
**Install:**
|
|
20
120
|
```bash
|
|
21
121
|
yarn add igloo-d2c-components
|
|
22
122
|
# or
|
|
23
123
|
npm install igloo-d2c-components
|
|
24
124
|
```
|
|
25
125
|
|
|
126
|
+
**Configure authentication (if using private registry):**
|
|
127
|
+
```bash
|
|
128
|
+
# For npm
|
|
129
|
+
export NPM_AUTH_TOKEN="your-npm-token"
|
|
130
|
+
|
|
131
|
+
# For GitLab Package Registry
|
|
132
|
+
export GITLAB_NPM_TOKEN="glpat-your-token"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
26
137
|
## 🚀 Quick Start
|
|
27
138
|
|
|
28
|
-
### 1.
|
|
139
|
+
### 1. Import Pre-built Themes (Recommended)
|
|
29
140
|
|
|
30
141
|
```tsx
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
dark: '#1300A9',
|
|
38
|
-
light: '#8183FF',
|
|
39
|
-
},
|
|
40
|
-
secondary: {
|
|
41
|
-
main: '#FF7D7D',
|
|
42
|
-
light: '#FFB3B1',
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
typography: {
|
|
46
|
-
fontFamily: '"Manrope", "Roboto", sans-serif',
|
|
47
|
-
},
|
|
48
|
-
}
|
|
142
|
+
import {
|
|
143
|
+
TenantThemeProvider,
|
|
144
|
+
iglooTheme,
|
|
145
|
+
cimbTheme,
|
|
146
|
+
ammetlifeTheme
|
|
147
|
+
} from 'igloo-d2c-components'
|
|
49
148
|
|
|
50
149
|
function App() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
150
|
+
return (
|
|
151
|
+
<TenantThemeProvider tenantId="igloo" theme={iglooTheme}>
|
|
152
|
+
<YourApp />
|
|
153
|
+
</TenantThemeProvider>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 2. Dynamic Theme Loading
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import { TenantThemeProvider, getTenantTheme } from 'igloo-d2c-components'
|
|
162
|
+
|
|
163
|
+
function App({ tenantId }) {
|
|
164
|
+
const theme = getTenantTheme(tenantId) // 'igloo', 'cimb', or 'ammetlife'
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<TenantThemeProvider tenantId={tenantId} theme={theme}>
|
|
168
|
+
<YourApp />
|
|
169
|
+
</TenantThemeProvider>
|
|
170
|
+
)
|
|
56
171
|
}
|
|
57
172
|
```
|
|
58
173
|
|
|
59
|
-
###
|
|
174
|
+
### 3. Use Components
|
|
60
175
|
|
|
61
176
|
```tsx
|
|
62
177
|
import { Button, Card, Banner } from 'igloo-d2c-components'
|
|
63
178
|
|
|
64
179
|
function MyPage() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
180
|
+
return (
|
|
181
|
+
<div>
|
|
182
|
+
{/* Tenant-themed button */}
|
|
183
|
+
<Button tenantColored variant="contained">
|
|
184
|
+
Click Me
|
|
185
|
+
</Button>
|
|
186
|
+
|
|
187
|
+
{/* Tenant-themed card */}
|
|
188
|
+
<Card
|
|
189
|
+
title="My Card"
|
|
190
|
+
content="Card content"
|
|
191
|
+
tenantAccent
|
|
192
|
+
/>
|
|
193
|
+
|
|
194
|
+
{/* Tenant-themed banner */}
|
|
195
|
+
<Banner
|
|
196
|
+
title="Welcome"
|
|
197
|
+
description="Get started today"
|
|
198
|
+
gradient
|
|
199
|
+
/>
|
|
200
|
+
</div>
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 🎨 Centralized Themes
|
|
208
|
+
|
|
209
|
+
### Why Centralized Themes?
|
|
210
|
+
|
|
211
|
+
**Before** (❌ Old Way):
|
|
212
|
+
```typescript
|
|
213
|
+
// In each consuming app - duplicated code
|
|
214
|
+
const iglooTheme = {
|
|
215
|
+
palette: {
|
|
216
|
+
primary: { main: '#5656F6', dark: '#1300A9', ... },
|
|
217
|
+
// ... 60+ lines per tenant
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**After** (✅ New Way):
|
|
223
|
+
```typescript
|
|
224
|
+
// Import from library - single source of truth
|
|
225
|
+
import { iglooTheme } from 'igloo-d2c-components'
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Available Theme Exports
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import {
|
|
232
|
+
// Individual themes
|
|
233
|
+
iglooTheme, // Igloo brand theme
|
|
234
|
+
cimbTheme, // CIMB bank theme
|
|
235
|
+
ammetlifeTheme, // AmmetLife insurance theme
|
|
236
|
+
|
|
237
|
+
// Theme registry
|
|
238
|
+
tenantThemes, // { igloo: iglooTheme, cimb: cimbTheme, ... }
|
|
239
|
+
|
|
240
|
+
// Utility functions
|
|
241
|
+
getTenantTheme, // (tenantId: TenantId) => TenantThemeConfig
|
|
242
|
+
isValidTenantId, // (id: string) => boolean
|
|
243
|
+
getAvailableTenants, // () => TenantId[]
|
|
244
|
+
} from 'igloo-d2c-components'
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Theme Structure
|
|
248
|
+
|
|
249
|
+
Each theme includes:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
interface TenantThemeConfig {
|
|
253
|
+
palette: {
|
|
254
|
+
// Core palettes
|
|
255
|
+
primary: { main, dark, light, bright, plain, border }
|
|
256
|
+
secondary: { dim, dark, main, bright, mediumBright, light, lighter }
|
|
257
|
+
tertiary: { dim, dark, main, light, bright }
|
|
258
|
+
natural: { dim, dark, main, light, bright, granite }
|
|
259
|
+
|
|
260
|
+
// Product-specific colors
|
|
261
|
+
motor: { main, light, bright }
|
|
262
|
+
car: { main, light, darkAI }
|
|
263
|
+
travel: { main, light }
|
|
264
|
+
health: { main, light? }
|
|
265
|
+
life: { main, light }
|
|
266
|
+
pet: { main }
|
|
267
|
+
|
|
268
|
+
// CIMB-specific (optional)
|
|
269
|
+
paCimb?: { main, light, bright, buttonBg }
|
|
270
|
+
}
|
|
271
|
+
typography: {
|
|
272
|
+
fontFamily: string
|
|
273
|
+
}
|
|
274
|
+
logo: string
|
|
275
|
+
favicon: string
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Using Themes
|
|
280
|
+
|
|
281
|
+
**In Tenant Configuration:**
|
|
282
|
+
```typescript
|
|
283
|
+
// config/tenants/igloo.ts
|
|
284
|
+
import { iglooTheme } from 'igloo-d2c-components'
|
|
285
|
+
|
|
286
|
+
const iglooConfig: TenantConfig = {
|
|
287
|
+
id: 'igloo',
|
|
288
|
+
theme: iglooTheme, // ✨ That's it!
|
|
289
|
+
// ... other config
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Dynamic Loading:**
|
|
294
|
+
```typescript
|
|
295
|
+
import { getTenantTheme, isValidTenantId } from 'igloo-d2c-components'
|
|
296
|
+
|
|
297
|
+
function loadTheme(tenantId: string) {
|
|
298
|
+
if (isValidTenantId(tenantId)) {
|
|
299
|
+
return getTenantTheme(tenantId)
|
|
300
|
+
}
|
|
301
|
+
throw new Error(`Invalid tenant: ${tenantId}`)
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**In Components:**
|
|
306
|
+
```typescript
|
|
307
|
+
import { useTenantTheme } from 'igloo-d2c-components'
|
|
308
|
+
|
|
309
|
+
function MyComponent() {
|
|
310
|
+
const { theme, tenantId } = useTenantTheme()
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<div style={{
|
|
314
|
+
backgroundColor: theme.palette.primary.main,
|
|
315
|
+
color: theme.palette.primary.bright
|
|
316
|
+
}}>
|
|
317
|
+
Current tenant: {tenantId}
|
|
318
|
+
</div>
|
|
319
|
+
)
|
|
85
320
|
}
|
|
86
321
|
```
|
|
87
322
|
|
|
88
|
-
|
|
323
|
+
### Theme Benefits
|
|
324
|
+
|
|
325
|
+
- ✅ **Single source of truth** - Update in one place
|
|
326
|
+
- ✅ **Type-safe** - Full TypeScript support
|
|
327
|
+
- ✅ **Consistent** - Same themes across all apps
|
|
328
|
+
- ✅ **Maintainable** - Easy to update and extend
|
|
329
|
+
- ✅ **Scalable** - Add new tenants easily
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## 📚 Components
|
|
89
334
|
|
|
90
335
|
### Button
|
|
91
336
|
|
|
@@ -94,17 +339,18 @@ Tenant-aware button component based on MUI Button.
|
|
|
94
339
|
```tsx
|
|
95
340
|
import { Button } from 'igloo-d2c-components'
|
|
96
341
|
|
|
342
|
+
// Tenant-colored button
|
|
97
343
|
<Button tenantColored variant="contained">
|
|
98
|
-
|
|
344
|
+
Tenant Colored Button
|
|
99
345
|
</Button>
|
|
100
346
|
|
|
101
|
-
|
|
102
|
-
|
|
347
|
+
// Standard MUI button
|
|
348
|
+
<Button color="primary" variant="outlined">
|
|
349
|
+
Default Button
|
|
103
350
|
</Button>
|
|
104
351
|
```
|
|
105
352
|
|
|
106
353
|
**Props:**
|
|
107
|
-
|
|
108
354
|
- `tenantColored?: boolean` - Use tenant primary color
|
|
109
355
|
- `variant?: 'text' | 'outlined' | 'contained'` - Button variant
|
|
110
356
|
- All MUI ButtonProps
|
|
@@ -117,19 +363,19 @@ Tenant-aware card component based on MUI Card.
|
|
|
117
363
|
import { Card } from 'igloo-d2c-components'
|
|
118
364
|
|
|
119
365
|
<Card
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
366
|
+
title="Card Title"
|
|
367
|
+
content="Card content goes here"
|
|
368
|
+
actions={<Button>Action</Button>}
|
|
369
|
+
tenantAccent
|
|
124
370
|
/>
|
|
125
371
|
```
|
|
126
372
|
|
|
127
373
|
**Props:**
|
|
128
|
-
|
|
129
374
|
- `title?: React.ReactNode` - Card title
|
|
130
375
|
- `content?: React.ReactNode` - Card content
|
|
131
376
|
- `actions?: React.ReactNode` - Card actions
|
|
132
377
|
- `tenantAccent?: boolean` - Add tenant-colored top border
|
|
378
|
+
- `headerAction?: React.ReactNode` - Action in header
|
|
133
379
|
- All MUI CardProps
|
|
134
380
|
|
|
135
381
|
### Banner
|
|
@@ -140,39 +386,42 @@ Promotional banner with tenant theming.
|
|
|
140
386
|
import { Banner } from 'igloo-d2c-components'
|
|
141
387
|
|
|
142
388
|
<Banner
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
389
|
+
title="Special Offer"
|
|
390
|
+
description="Limited time only"
|
|
391
|
+
action={<Button>Learn More</Button>}
|
|
392
|
+
gradient
|
|
147
393
|
/>
|
|
148
394
|
```
|
|
149
395
|
|
|
150
396
|
**Props:**
|
|
151
|
-
|
|
152
|
-
- `title: string` - Banner title
|
|
397
|
+
- `title: string` - Banner title (required)
|
|
153
398
|
- `description?: string` - Banner description
|
|
154
399
|
- `action?: React.ReactNode` - Action button/element
|
|
155
|
-
- `gradient?: boolean` - Use gradient background
|
|
400
|
+
- `gradient?: boolean` - Use gradient background (default: true)
|
|
156
401
|
- All MUI BoxProps
|
|
157
402
|
|
|
403
|
+
---
|
|
404
|
+
|
|
158
405
|
## 🎨 Hooks & Utilities
|
|
159
406
|
|
|
160
|
-
###
|
|
407
|
+
### Hooks
|
|
408
|
+
|
|
409
|
+
#### useTenantTheme()
|
|
161
410
|
|
|
162
|
-
Access tenant theme configuration.
|
|
411
|
+
Access tenant theme configuration and ID.
|
|
163
412
|
|
|
164
413
|
```tsx
|
|
165
414
|
import { useTenantTheme } from 'igloo-d2c-components'
|
|
166
415
|
|
|
167
416
|
function MyComponent() {
|
|
168
|
-
|
|
169
|
-
|
|
417
|
+
const { theme, tenantId } = useTenantTheme()
|
|
418
|
+
const primaryColor = theme.palette.primary.main
|
|
170
419
|
|
|
171
|
-
|
|
420
|
+
return <div style={{ color: primaryColor }}>...</div>
|
|
172
421
|
}
|
|
173
422
|
```
|
|
174
423
|
|
|
175
|
-
|
|
424
|
+
#### useTenantId()
|
|
176
425
|
|
|
177
426
|
Get current tenant ID.
|
|
178
427
|
|
|
@@ -180,12 +429,12 @@ Get current tenant ID.
|
|
|
180
429
|
import { useTenantId } from 'igloo-d2c-components'
|
|
181
430
|
|
|
182
431
|
function MyComponent() {
|
|
183
|
-
|
|
184
|
-
|
|
432
|
+
const tenantId = useTenantId() // 'igloo' | 'cimb' | 'ammetlife'
|
|
433
|
+
return <div>Current tenant: {tenantId}</div>
|
|
185
434
|
}
|
|
186
435
|
```
|
|
187
436
|
|
|
188
|
-
|
|
437
|
+
#### useIsTenant()
|
|
189
438
|
|
|
190
439
|
Check if current tenant matches a specific ID.
|
|
191
440
|
|
|
@@ -193,140 +442,732 @@ Check if current tenant matches a specific ID.
|
|
|
193
442
|
import { useIsTenant } from 'igloo-d2c-components'
|
|
194
443
|
|
|
195
444
|
function MyComponent() {
|
|
196
|
-
|
|
445
|
+
const isCIMB = useIsTenant('cimb')
|
|
197
446
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
447
|
+
if (isCIMB) {
|
|
448
|
+
return <CIMBSpecificFeature />
|
|
449
|
+
}
|
|
201
450
|
|
|
202
|
-
|
|
451
|
+
return <DefaultFeature />
|
|
203
452
|
}
|
|
204
453
|
```
|
|
205
454
|
|
|
206
|
-
###
|
|
455
|
+
### Utility Functions
|
|
207
456
|
|
|
208
|
-
|
|
457
|
+
#### getTenantTheme()
|
|
458
|
+
|
|
459
|
+
Get theme configuration by tenant ID.
|
|
209
460
|
|
|
210
461
|
```tsx
|
|
211
|
-
import {
|
|
462
|
+
import { getTenantTheme } from 'igloo-d2c-components'
|
|
212
463
|
|
|
213
|
-
const
|
|
464
|
+
const theme = getTenantTheme('igloo')
|
|
465
|
+
console.log(theme.palette.primary.main) // '#5656F6'
|
|
214
466
|
```
|
|
215
467
|
|
|
216
|
-
|
|
468
|
+
**Throws:** Error if tenant ID is invalid
|
|
217
469
|
|
|
218
|
-
|
|
219
|
-
- **TypeScript 4.9+** - Type safety
|
|
220
|
-
- **MUI 5** - Material-UI components
|
|
221
|
-
- **Emotion** - CSS-in-JS
|
|
222
|
-
- **Rollup** - Build tooling
|
|
470
|
+
#### isValidTenantId()
|
|
223
471
|
|
|
224
|
-
|
|
472
|
+
Type guard to check if a string is a valid tenant ID.
|
|
225
473
|
|
|
226
|
-
|
|
474
|
+
```tsx
|
|
475
|
+
import { isValidTenantId } from 'igloo-d2c-components'
|
|
476
|
+
|
|
477
|
+
if (isValidTenantId(userInput)) {
|
|
478
|
+
const theme = getTenantTheme(userInput) // Type-safe!
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
#### getAvailableTenants()
|
|
483
|
+
|
|
484
|
+
Get list of all available tenant IDs.
|
|
227
485
|
|
|
228
486
|
```tsx
|
|
229
|
-
import
|
|
487
|
+
import { getAvailableTenants } from 'igloo-d2c-components'
|
|
488
|
+
|
|
489
|
+
const tenants = getAvailableTenants()
|
|
490
|
+
// ['igloo', 'cimb', 'ammetlife']
|
|
230
491
|
```
|
|
231
492
|
|
|
493
|
+
#### getThemeColor()
|
|
494
|
+
|
|
495
|
+
Extract color from theme using dot notation.
|
|
496
|
+
|
|
497
|
+
```tsx
|
|
498
|
+
import { getThemeColor } from 'igloo-d2c-components'
|
|
499
|
+
|
|
500
|
+
const color = getThemeColor(theme, 'primary.main', '#000')
|
|
501
|
+
// Returns theme.palette.primary.main or '#000' if not found
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
#### createThemeCSSVariables()
|
|
505
|
+
|
|
506
|
+
Create CSS variables from theme.
|
|
507
|
+
|
|
508
|
+
```tsx
|
|
509
|
+
import { createThemeCSSVariables } from 'igloo-d2c-components'
|
|
510
|
+
|
|
511
|
+
const vars = createThemeCSSVariables(theme, '--my-app')
|
|
512
|
+
// { '--my-app-primary-main': '#5656F6', ... }
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
232
517
|
## 🔧 Development
|
|
233
518
|
|
|
234
|
-
###
|
|
519
|
+
### Prerequisites
|
|
235
520
|
|
|
521
|
+
- **Node.js**: `>=16.20.0 <=18.x`
|
|
522
|
+
- **Yarn**: `^1.22.0` (recommended) or npm
|
|
523
|
+
|
|
524
|
+
Check your version:
|
|
236
525
|
```bash
|
|
237
|
-
#
|
|
238
|
-
yarn
|
|
526
|
+
node --version # Should be 16.20.0 - 18.x
|
|
527
|
+
yarn --version # Should be 1.22.x
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Setup
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
# Clone the repository
|
|
534
|
+
git clone https://gitlab.iglooinsure.com/axinan/fe/d2c-component-library.git
|
|
535
|
+
cd d2c-component-library
|
|
536
|
+
|
|
537
|
+
# Install dependencies
|
|
538
|
+
yarn install
|
|
539
|
+
```
|
|
239
540
|
|
|
541
|
+
### Build Commands
|
|
542
|
+
|
|
543
|
+
```bash
|
|
240
544
|
# Production build
|
|
241
545
|
yarn build
|
|
546
|
+
|
|
547
|
+
# Development mode (watch)
|
|
548
|
+
yarn dev
|
|
549
|
+
|
|
550
|
+
# Clean build artifacts
|
|
551
|
+
yarn clean
|
|
552
|
+
|
|
553
|
+
# Clean and rebuild
|
|
554
|
+
yarn clean && yarn build
|
|
242
555
|
```
|
|
243
556
|
|
|
244
|
-
###
|
|
557
|
+
### Code Quality
|
|
245
558
|
|
|
246
559
|
```bash
|
|
560
|
+
# Lint code
|
|
247
561
|
yarn lint
|
|
562
|
+
|
|
563
|
+
# Type check
|
|
564
|
+
yarn type-check
|
|
248
565
|
```
|
|
249
566
|
|
|
250
|
-
###
|
|
567
|
+
### Build Output
|
|
568
|
+
|
|
569
|
+
The library outputs **unminified** code targeting **ES2015** for maximum compatibility:
|
|
251
570
|
|
|
571
|
+
```
|
|
572
|
+
dist/
|
|
573
|
+
├── cjs/
|
|
574
|
+
│ ├── index.js # CommonJS bundle (unminified, ES2015)
|
|
575
|
+
│ └── index.js.map # Source map
|
|
576
|
+
├── esm/
|
|
577
|
+
│ ├── index.js # ES Module bundle (unminified, ES2015)
|
|
578
|
+
│ └── index.js.map # Source map
|
|
579
|
+
└── types/
|
|
580
|
+
└── index.d.ts # TypeScript definitions
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
**Why unminified?**
|
|
584
|
+
- ✅ Consuming apps handle minification
|
|
585
|
+
- ✅ Better debugging experience
|
|
586
|
+
- ✅ Better tree-shaking
|
|
587
|
+
- ✅ No impact on final bundle size
|
|
588
|
+
|
|
589
|
+
**Why ES2015?**
|
|
590
|
+
- ✅ Maximum compatibility with older webpack configs
|
|
591
|
+
- ✅ No babel-loader required in consuming apps
|
|
592
|
+
- ✅ Optional chaining (`?.`) transpiled to verbose checks
|
|
593
|
+
- ✅ Works with webpack 4+
|
|
594
|
+
|
|
595
|
+
### Project Structure
|
|
596
|
+
|
|
597
|
+
```
|
|
598
|
+
d2c-component-library/
|
|
599
|
+
├── src/
|
|
600
|
+
│ ├── components/ # Component implementations
|
|
601
|
+
│ │ ├── Button/
|
|
602
|
+
│ │ ├── Card/
|
|
603
|
+
│ │ └── Banner/
|
|
604
|
+
│ ├── context/
|
|
605
|
+
│ │ └── TenantThemeContext.tsx
|
|
606
|
+
│ ├── themes/
|
|
607
|
+
│ │ └── index.ts # ⭐ Centralized theme definitions
|
|
608
|
+
│ ├── types/
|
|
609
|
+
│ │ └── tenant.ts # TypeScript types
|
|
610
|
+
│ ├── utils/
|
|
611
|
+
│ │ └── theme.ts # Theme utilities
|
|
612
|
+
│ └── index.ts # Main exports
|
|
613
|
+
├── dist/ # Build output (generated)
|
|
614
|
+
├── examples/
|
|
615
|
+
│ └── usage-example.tsx
|
|
616
|
+
├── .storybook/ # Storybook configuration
|
|
617
|
+
├── rollup.config.cjs # Rollup build config
|
|
618
|
+
├── tsconfig.json # TypeScript config
|
|
619
|
+
├── package.json
|
|
620
|
+
├── README.md # This file
|
|
621
|
+
└── CHANGELOG.md # Version history
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
---
|
|
625
|
+
|
|
626
|
+
## 📦 Publishing
|
|
627
|
+
|
|
628
|
+
### Prerequisites
|
|
629
|
+
|
|
630
|
+
1. **Ensure clean working directory:**
|
|
631
|
+
```bash
|
|
632
|
+
git status # Should be clean
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
2. **Update version in package.json:**
|
|
636
|
+
```json
|
|
637
|
+
{
|
|
638
|
+
"version": "1.0.7"
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
3. **Update CHANGELOG.md:**
|
|
643
|
+
Document changes in the new version section
|
|
644
|
+
|
|
645
|
+
4. **Build the library:**
|
|
646
|
+
```bash
|
|
647
|
+
yarn build
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### Publishing to NPM
|
|
651
|
+
|
|
652
|
+
**Set up NPM token:**
|
|
252
653
|
```bash
|
|
253
|
-
|
|
654
|
+
# Get token from https://www.npmjs.com/settings/YOUR_USERNAME/tokens
|
|
655
|
+
export NPM_AUTH_TOKEN="npm_your_actual_token"
|
|
656
|
+
|
|
657
|
+
# Or add to ~/.npmrc globally
|
|
658
|
+
//registry.npmjs.org/:_authToken=npm_your_token
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
**Publish:**
|
|
662
|
+
```bash
|
|
663
|
+
# Automated script with safety checks
|
|
664
|
+
./publish-to-npm.sh
|
|
665
|
+
|
|
666
|
+
# Or manual
|
|
667
|
+
yarn build
|
|
668
|
+
npm publish --access public
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### Publishing to GitLab Package Registry
|
|
672
|
+
|
|
673
|
+
**Set up GitLab token:**
|
|
674
|
+
```bash
|
|
675
|
+
# Get token from https://gitlab.com/-/profile/personal_access_tokens
|
|
676
|
+
# Scopes: api, read_registry, write_registry
|
|
677
|
+
export GITLAB_NPM_TOKEN="glpat-your-token"
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
**Configure `.npmrc` for GitLab:**
|
|
681
|
+
```ini
|
|
682
|
+
@igloo:registry=https://gitlab.com/api/v4/projects/YOUR_PROJECT_ID/packages/npm/
|
|
683
|
+
//gitlab.com/api/v4/projects/YOUR_PROJECT_ID/packages/npm/:_authToken=${GITLAB_NPM_TOKEN}
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
**Publish:**
|
|
687
|
+
```bash
|
|
688
|
+
yarn build
|
|
689
|
+
npm publish
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### CI/CD Publishing
|
|
693
|
+
|
|
694
|
+
The library includes a GitLab CI/CD configuration (`.gitlab-ci.yml`) that automatically:
|
|
695
|
+
|
|
696
|
+
1. **Runs on main branch** or tags
|
|
697
|
+
2. **Lints and type-checks** code
|
|
698
|
+
3. **Builds** the library
|
|
699
|
+
4. **Publishes** to registry (if tag)
|
|
700
|
+
|
|
701
|
+
**Trigger CI/CD publish:**
|
|
702
|
+
```bash
|
|
703
|
+
# Create and push a tag
|
|
704
|
+
git tag v1.0.7
|
|
705
|
+
git push origin v1.0.7
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Version Management
|
|
709
|
+
|
|
710
|
+
**Semantic Versioning:**
|
|
711
|
+
- **Major** (1.0.0 → 2.0.0): Breaking changes
|
|
712
|
+
- **Minor** (1.0.0 → 1.1.0): New features, backwards compatible
|
|
713
|
+
- **Patch** (1.0.0 → 1.0.1): Bug fixes
|
|
714
|
+
|
|
715
|
+
**Update version:**
|
|
716
|
+
```bash
|
|
717
|
+
# Manually in package.json
|
|
718
|
+
"version": "1.0.7"
|
|
719
|
+
|
|
720
|
+
# Or using npm version
|
|
721
|
+
npm version patch # 1.0.6 → 1.0.7
|
|
722
|
+
npm version minor # 1.0.6 → 1.1.0
|
|
723
|
+
npm version major # 1.0.6 → 2.0.0
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### Post-Publishing
|
|
727
|
+
|
|
728
|
+
After publishing:
|
|
729
|
+
|
|
730
|
+
1. **Tag the release:**
|
|
731
|
+
```bash
|
|
732
|
+
git tag v1.0.7
|
|
733
|
+
git push origin v1.0.7
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
2. **Update consuming apps:**
|
|
737
|
+
```bash
|
|
738
|
+
cd ../b2c-web-demo
|
|
739
|
+
yarn upgrade igloo-d2c-components@latest
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
3. **Announce the release** to the team
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## 📖 Storybook
|
|
747
|
+
|
|
748
|
+
The library includes Storybook for component documentation and testing.
|
|
749
|
+
|
|
750
|
+
### Running Storybook
|
|
751
|
+
|
|
752
|
+
```bash
|
|
753
|
+
# Start Storybook dev server
|
|
754
|
+
yarn storybook
|
|
755
|
+
# Opens at http://localhost:6006
|
|
756
|
+
|
|
757
|
+
# Build static Storybook
|
|
758
|
+
yarn build-storybook
|
|
759
|
+
# Output in storybook-static/
|
|
254
760
|
```
|
|
255
761
|
|
|
256
|
-
|
|
762
|
+
### Storybook Features
|
|
763
|
+
|
|
764
|
+
- **Component Playground** - Interactive component testing
|
|
765
|
+
- **Props Documentation** - Auto-generated from TypeScript
|
|
766
|
+
- **Theme Switching** - Test with different tenant themes
|
|
767
|
+
- **Responsive Design** - Test different viewports
|
|
768
|
+
- **Accessibility** - Built-in a11y addon
|
|
769
|
+
|
|
770
|
+
### Adding Stories
|
|
257
771
|
|
|
258
|
-
|
|
772
|
+
Create a `.stories.tsx` file next to your component:
|
|
259
773
|
|
|
260
774
|
```tsx
|
|
261
|
-
//
|
|
262
|
-
import {
|
|
263
|
-
import {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
775
|
+
// src/components/MyComponent/MyComponent.stories.tsx
|
|
776
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
777
|
+
import { TenantThemeProvider, iglooTheme } from '../../index'
|
|
778
|
+
import { MyComponent } from './MyComponent'
|
|
779
|
+
|
|
780
|
+
const meta: Meta<typeof MyComponent> = {
|
|
781
|
+
title: 'Components/MyComponent',
|
|
782
|
+
component: MyComponent,
|
|
783
|
+
decorators: [
|
|
784
|
+
(Story) => (
|
|
785
|
+
<TenantThemeProvider tenantId="igloo" theme={iglooTheme}>
|
|
786
|
+
<Story />
|
|
787
|
+
</TenantThemeProvider>
|
|
788
|
+
),
|
|
789
|
+
],
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
export default meta
|
|
793
|
+
type Story = StoryObj<typeof MyComponent>
|
|
794
|
+
|
|
795
|
+
export const Default: Story = {
|
|
796
|
+
args: {
|
|
797
|
+
prop1: 'value1',
|
|
798
|
+
},
|
|
799
|
+
}
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
---
|
|
803
|
+
|
|
804
|
+
## 🔬 Technical Details
|
|
805
|
+
|
|
806
|
+
### Build Configuration
|
|
807
|
+
|
|
808
|
+
**Rollup Configuration** (`rollup.config.cjs`):
|
|
809
|
+
```javascript
|
|
810
|
+
{
|
|
811
|
+
input: 'src/index.ts',
|
|
812
|
+
output: [
|
|
813
|
+
{
|
|
814
|
+
file: 'dist/cjs/index.js',
|
|
815
|
+
format: 'cjs',
|
|
816
|
+
sourcemap: true,
|
|
817
|
+
exports: 'named',
|
|
818
|
+
banner: '"use client"',
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
file: 'dist/esm/index.js',
|
|
822
|
+
format: 'esm',
|
|
823
|
+
sourcemap: true,
|
|
824
|
+
exports: 'named',
|
|
825
|
+
banner: '"use client"',
|
|
826
|
+
},
|
|
827
|
+
],
|
|
828
|
+
plugins: [
|
|
829
|
+
peerDepsExternal(),
|
|
830
|
+
resolve(),
|
|
831
|
+
commonjs(),
|
|
832
|
+
typescript({
|
|
833
|
+
tsconfig: './tsconfig.json',
|
|
834
|
+
compilerOptions: {
|
|
835
|
+
declaration: false,
|
|
836
|
+
target: 'ES2015', // For compatibility
|
|
837
|
+
},
|
|
838
|
+
}),
|
|
839
|
+
// NO terser() - libraries should not be minified
|
|
840
|
+
],
|
|
281
841
|
}
|
|
282
842
|
```
|
|
283
843
|
|
|
284
|
-
###
|
|
844
|
+
### TypeScript Configuration
|
|
845
|
+
|
|
846
|
+
**Target:** ES2015 for maximum compatibility
|
|
847
|
+
**Module:** ESNext for tree-shaking
|
|
848
|
+
**Strict:** Enabled for type safety
|
|
849
|
+
|
|
850
|
+
### Peer Dependencies
|
|
851
|
+
|
|
852
|
+
```json
|
|
853
|
+
{
|
|
854
|
+
"peerDependencies": {
|
|
855
|
+
"@emotion/react": "^11.11.4",
|
|
856
|
+
"@emotion/styled": "^11.11.5",
|
|
857
|
+
"@mui/icons-material": "^5.15.20",
|
|
858
|
+
"@mui/material": "^5.15.20",
|
|
859
|
+
"@mui/styles": "^5.15.20",
|
|
860
|
+
"react": "^17.0.0",
|
|
861
|
+
"react-dom": "^17.0.0"
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
```
|
|
285
865
|
|
|
286
|
-
|
|
287
|
-
// In any component
|
|
288
|
-
import { Button, Card, Banner } from 'igloo-d2c-components'
|
|
866
|
+
### Package Exports
|
|
289
867
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
868
|
+
```json
|
|
869
|
+
{
|
|
870
|
+
"main": "dist/cjs/index.js",
|
|
871
|
+
"module": "dist/esm/index.js",
|
|
872
|
+
"types": "dist/types/index.d.ts",
|
|
873
|
+
"files": ["dist", "README.md"]
|
|
874
|
+
}
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
---
|
|
878
|
+
|
|
879
|
+
## 🐛 Troubleshooting
|
|
880
|
+
|
|
881
|
+
### Webpack Module Parse Error
|
|
882
|
+
|
|
883
|
+
**Error:**
|
|
884
|
+
```
|
|
885
|
+
Module parse failed: Unexpected token
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
**Cause:** Webpack can't parse the library output.
|
|
889
|
+
|
|
890
|
+
**Solution:**
|
|
891
|
+
|
|
892
|
+
1. **Check library build target:** The library should be built with ES2015 target (✅ already configured)
|
|
893
|
+
2. **Rebuild library:**
|
|
894
|
+
```bash
|
|
895
|
+
cd d2c-component-library
|
|
896
|
+
yarn clean && yarn build
|
|
897
|
+
```
|
|
898
|
+
3. **Reinstall in consuming app:**
|
|
899
|
+
```bash
|
|
900
|
+
cd ../b2c-web-demo
|
|
901
|
+
rm -rf node_modules/igloo-d2c-components
|
|
902
|
+
yarn install
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
**Prevention:** The library is configured to output ES2015 JavaScript which is compatible with webpack 4+. Modern syntax like optional chaining (`?.`) is transpiled to verbose null checks.
|
|
906
|
+
|
|
907
|
+
### Theme Not Found Error
|
|
908
|
+
|
|
909
|
+
**Error:**
|
|
910
|
+
```
|
|
911
|
+
Theme not found for tenant: xxx
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
**Solution:** Use valid tenant IDs: `'igloo'`, `'cimb'`, or `'ammetlife'`.
|
|
915
|
+
|
|
916
|
+
```typescript
|
|
917
|
+
import { isValidTenantId, getTenantTheme } from 'igloo-d2c-components'
|
|
918
|
+
|
|
919
|
+
if (isValidTenantId(tenantId)) {
|
|
920
|
+
const theme = getTenantTheme(tenantId)
|
|
921
|
+
} else {
|
|
922
|
+
console.error('Invalid tenant ID:', tenantId)
|
|
307
923
|
}
|
|
308
924
|
```
|
|
309
925
|
|
|
926
|
+
### TypeScript Errors with Imports
|
|
927
|
+
|
|
928
|
+
**Error:**
|
|
929
|
+
```
|
|
930
|
+
Module '"igloo-d2c-components"' has no exported member 'iglooTheme'
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
**Solution:**
|
|
934
|
+
|
|
935
|
+
1. **Rebuild the library:**
|
|
936
|
+
```bash
|
|
937
|
+
cd d2c-component-library
|
|
938
|
+
yarn build
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
2. **Reinstall in consuming app:**
|
|
942
|
+
```bash
|
|
943
|
+
cd ../b2c-web-demo
|
|
944
|
+
yarn remove igloo-d2c-components
|
|
945
|
+
yarn add igloo-d2c-components@file:../d2c-component-library
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
3. **Restart TypeScript server** in your IDE:
|
|
949
|
+
- VS Code: Cmd+Shift+P → "TypeScript: Restart TS Server"
|
|
950
|
+
|
|
951
|
+
### Build Failures
|
|
952
|
+
|
|
953
|
+
**Error:** Build fails with memory issues
|
|
954
|
+
|
|
955
|
+
**Solution:**
|
|
956
|
+
```bash
|
|
957
|
+
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
958
|
+
yarn build
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
**Error:** Type errors during build
|
|
962
|
+
|
|
963
|
+
**Solution:**
|
|
964
|
+
```bash
|
|
965
|
+
# Check types first
|
|
966
|
+
yarn type-check
|
|
967
|
+
|
|
968
|
+
# Fix any type errors, then build
|
|
969
|
+
yarn build
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
### Missing Peer Dependencies
|
|
973
|
+
|
|
974
|
+
**Warning:** `peer dependency "react" not installed`
|
|
975
|
+
|
|
976
|
+
**Solution:** Install peer dependencies in consuming app:
|
|
977
|
+
```bash
|
|
978
|
+
yarn add react@17 react-dom@17 @mui/material@5 @emotion/react @emotion/styled
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
---
|
|
982
|
+
|
|
310
983
|
## 🎯 Best Practices
|
|
311
984
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
985
|
+
### For Library Development
|
|
986
|
+
|
|
987
|
+
1. **Always build before testing** - Run `yarn build` after changes
|
|
988
|
+
2. **Use ES2015 features** - Avoid ES2020+ syntax
|
|
989
|
+
3. **Test in consuming apps** - Test changes in b2c-web-demo
|
|
990
|
+
4. **Update CHANGELOG** - Document all changes
|
|
991
|
+
5. **Version appropriately** - Follow semantic versioning
|
|
992
|
+
|
|
993
|
+
### For Library Usage
|
|
994
|
+
|
|
995
|
+
1. **Wrap with TenantThemeProvider** - Required for theming to work
|
|
996
|
+
2. **Use pre-built themes** - Import `iglooTheme`, `cimbTheme`, `ammetlifeTheme`
|
|
997
|
+
3. **Use tenantColored prop** - For tenant-specific styling
|
|
998
|
+
4. **Maintain type safety** - Use provided TypeScript types
|
|
999
|
+
5. **Extend via composition** - Don't modify library components
|
|
1000
|
+
|
|
1001
|
+
### For Theme Management
|
|
1002
|
+
|
|
1003
|
+
1. **Update themes in library** - Not in consuming apps
|
|
1004
|
+
2. **Test all tenants** - When changing theme structure
|
|
1005
|
+
3. **Document breaking changes** - If theme interface changes
|
|
1006
|
+
4. **Version bump** - Increment version after theme changes
|
|
1007
|
+
|
|
1008
|
+
---
|
|
1009
|
+
|
|
1010
|
+
## 🤝 Contributing
|
|
1011
|
+
|
|
1012
|
+
### Getting Started
|
|
1013
|
+
|
|
1014
|
+
1. **Fork the repository**
|
|
1015
|
+
2. **Create a feature branch:**
|
|
1016
|
+
```bash
|
|
1017
|
+
git checkout -b feature/my-new-feature
|
|
1018
|
+
```
|
|
1019
|
+
3. **Make your changes**
|
|
1020
|
+
4. **Test thoroughly:**
|
|
1021
|
+
```bash
|
|
1022
|
+
yarn lint
|
|
1023
|
+
yarn type-check
|
|
1024
|
+
yarn build
|
|
1025
|
+
```
|
|
1026
|
+
5. **Test in consuming app:**
|
|
1027
|
+
```bash
|
|
1028
|
+
cd ../b2c-web-demo
|
|
1029
|
+
yarn install
|
|
1030
|
+
yarn start-igloo-dev
|
|
1031
|
+
```
|
|
1032
|
+
6. **Commit your changes:**
|
|
1033
|
+
```bash
|
|
1034
|
+
git commit -m "feat: add new feature"
|
|
1035
|
+
```
|
|
1036
|
+
7. **Push to branch:**
|
|
1037
|
+
```bash
|
|
1038
|
+
git push origin feature/my-new-feature
|
|
1039
|
+
```
|
|
1040
|
+
8. **Create a Pull Request**
|
|
1041
|
+
|
|
1042
|
+
### Commit Message Format
|
|
1043
|
+
|
|
1044
|
+
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
1045
|
+
|
|
1046
|
+
```
|
|
1047
|
+
<type>(<scope>): <description>
|
|
1048
|
+
|
|
1049
|
+
[optional body]
|
|
1050
|
+
|
|
1051
|
+
[optional footer]
|
|
1052
|
+
```
|
|
1053
|
+
|
|
1054
|
+
**Types:**
|
|
1055
|
+
- `feat`: New feature
|
|
1056
|
+
- `fix`: Bug fix
|
|
1057
|
+
- `docs`: Documentation changes
|
|
1058
|
+
- `style`: Code style changes (formatting)
|
|
1059
|
+
- `refactor`: Code refactoring
|
|
1060
|
+
- `test`: Test additions/changes
|
|
1061
|
+
- `chore`: Maintenance tasks
|
|
1062
|
+
|
|
1063
|
+
**Examples:**
|
|
1064
|
+
```
|
|
1065
|
+
feat(themes): add new tenant theme
|
|
1066
|
+
fix(Button): correct hover state color
|
|
1067
|
+
docs: update installation guide
|
|
1068
|
+
chore: bump version to 1.0.7
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
### Adding a New Tenant
|
|
1072
|
+
|
|
1073
|
+
1. **Add theme to `src/themes/index.ts`:**
|
|
1074
|
+
```typescript
|
|
1075
|
+
export const newTenantTheme: TenantThemeConfig = {
|
|
1076
|
+
palette: { /* ... */ },
|
|
1077
|
+
typography: { /* ... */ },
|
|
1078
|
+
logo: '/assets/new-tenant/logo.svg',
|
|
1079
|
+
favicon: 'https://...',
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
export const tenantThemes: Record<TenantId, TenantThemeConfig> = {
|
|
1083
|
+
igloo: iglooTheme,
|
|
1084
|
+
cimb: cimbTheme,
|
|
1085
|
+
ammetlife: ammetlifeTheme,
|
|
1086
|
+
newtenant: newTenantTheme, // Add here
|
|
1087
|
+
}
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
2. **Update TenantId type in `src/types/tenant.ts`:**
|
|
1091
|
+
```typescript
|
|
1092
|
+
export type TenantId = 'igloo' | 'cimb' | 'ammetlife' | 'newtenant'
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
3. **Build and test:**
|
|
1096
|
+
```bash
|
|
1097
|
+
yarn build
|
|
1098
|
+
cd ../b2c-web-demo
|
|
1099
|
+
yarn install
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
4. **Update documentation and CHANGELOG**
|
|
1103
|
+
|
|
1104
|
+
---
|
|
316
1105
|
|
|
317
1106
|
## 📄 License
|
|
318
1107
|
|
|
319
1108
|
MIT
|
|
320
1109
|
|
|
321
|
-
|
|
1110
|
+
---
|
|
1111
|
+
|
|
1112
|
+
## 👥 Team
|
|
1113
|
+
|
|
1114
|
+
Frontend Engineering Team - Axinan/Igloo
|
|
1115
|
+
|
|
1116
|
+
---
|
|
1117
|
+
|
|
1118
|
+
## 🔗 Links
|
|
1119
|
+
|
|
1120
|
+
- **Repository:** https://gitlab.iglooinsure.com/axinan/fe/d2c-component-library
|
|
1121
|
+
- **NPM Package:** https://www.npmjs.com/package/igloo-d2c-components
|
|
1122
|
+
- **Consuming App:** https://gitlab.iglooinsure.com/axinan/fe/b2c-web-demo
|
|
1123
|
+
- **Issue Tracker:** https://gitlab.iglooinsure.com/axinan/fe/d2c-component-library/-/issues
|
|
322
1124
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
1125
|
+
---
|
|
1126
|
+
|
|
1127
|
+
## 📝 Quick Reference
|
|
1128
|
+
|
|
1129
|
+
### Installation
|
|
1130
|
+
```bash
|
|
1131
|
+
# Local development
|
|
1132
|
+
yarn add igloo-d2c-components@file:../d2c-component-library
|
|
1133
|
+
|
|
1134
|
+
# Production
|
|
1135
|
+
yarn add igloo-d2c-components@latest
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
### Import Themes
|
|
1139
|
+
```typescript
|
|
1140
|
+
import { iglooTheme, cimbTheme, ammetlifeTheme, getTenantTheme } from 'igloo-d2c-components'
|
|
1141
|
+
```
|
|
1142
|
+
|
|
1143
|
+
### Import Components
|
|
1144
|
+
```typescript
|
|
1145
|
+
import { Button, Card, Banner, TenantThemeProvider } from 'igloo-d2c-components'
|
|
1146
|
+
```
|
|
1147
|
+
|
|
1148
|
+
### Import Hooks
|
|
1149
|
+
```typescript
|
|
1150
|
+
import { useTenantTheme, useTenantId, useIsTenant } from 'igloo-d2c-components'
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
### Build & Publish
|
|
1154
|
+
```bash
|
|
1155
|
+
# Build
|
|
1156
|
+
yarn build
|
|
1157
|
+
|
|
1158
|
+
# Publish to NPM
|
|
1159
|
+
./publish-to-npm.sh
|
|
1160
|
+
|
|
1161
|
+
# Publish to GitLab
|
|
1162
|
+
npm publish
|
|
1163
|
+
```
|
|
328
1164
|
|
|
329
1165
|
---
|
|
330
1166
|
|
|
331
|
-
**Version:** 1.0.
|
|
332
|
-
**
|
|
1167
|
+
**Version:** 1.0.6
|
|
1168
|
+
**Last Updated:** November 12, 2025
|
|
1169
|
+
**Node.js:** >=16.20.0 <=18.x
|
|
1170
|
+
**Target:** ES2015
|
|
1171
|
+
**Output:** Unminified
|
|
1172
|
+
|
|
1173
|
+
For version history, see [CHANGELOG.md](./CHANGELOG.md)
|