@uniqode/card-templates 1.0.0

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.
@@ -0,0 +1,538 @@
1
+ // Core TypeScript definitions for Uniqode Card Templates
2
+ import * as React from 'react';
3
+ import {
4
+ PRODUCT_STATE,
5
+ LEAD_COLLECT_TYPE,
6
+ DBC_BACKGROUND_TYPE,
7
+ CONTACT_DETAIL,
8
+ TEXT_FIELD_VALIDATIONS,
9
+ contactInfoType,
10
+ default_contact_info_ordering
11
+ } from './enums';
12
+
13
+ // Re-export enums for external use
14
+ export {
15
+ PRODUCT_STATE,
16
+ LEAD_COLLECT_TYPE,
17
+ DBC_BACKGROUND_TYPE,
18
+ CONTACT_DETAIL,
19
+ TEXT_FIELD_VALIDATIONS,
20
+ contactInfoType,
21
+ default_contact_info_ordering
22
+ };
23
+
24
+ // ============================================================================
25
+ // CORE DATA INTERFACES
26
+ // ============================================================================
27
+
28
+ /**
29
+ * Contact information structure (phone, email, website, custom fields)
30
+ * Used in phone_v2, email_v2, website_v2, custom_fields arrays
31
+ */
32
+ export interface ContactInfo {
33
+ value: string;
34
+ label: string;
35
+ valid?: TEXT_FIELD_VALIDATIONS | 'valid' | 'error' | 'warning'; // Validation state
36
+ }
37
+
38
+ export interface SocialLinks {
39
+ linkedin?: string;
40
+ twitter?: string;
41
+ github?: string;
42
+ instagram?: string;
43
+ facebook?: string;
44
+ youtube?: string;
45
+ whatsapp?: string;
46
+ telegram?: string;
47
+ tiktok?: string;
48
+ snapchat?: string;
49
+ vimeo?: string;
50
+ wistia?: string;
51
+ twitch?: string;
52
+ discord?: string;
53
+ pinterest?: string;
54
+ yelp?: string;
55
+ paypal?: string;
56
+ venmo?: string;
57
+ cashapp?: string;
58
+ calendly?: string;
59
+ shopify?: string;
60
+ dribbble?: string;
61
+ behance?: string;
62
+ custom_url?: string;
63
+ }
64
+
65
+ /**
66
+ * Typography configuration structure
67
+ * Aligned with Angular model - uses 'personal_info' not 'user_info'
68
+ */
69
+ export interface Typography {
70
+ font_type?: 'google' | 'custom';
71
+ font_family?: string; // e.g., 'Open Sans', 'Roboto'
72
+
73
+ personal_info?: { // ⚠️ Changed from 'user_info' to match Angular model
74
+ google_font_style?: string;
75
+ google_font_colour?: string;
76
+ google_font_size?: number;
77
+ };
78
+ company_details?: {
79
+ google_font_style?: string;
80
+ google_font_colour?: string;
81
+ google_font_size?: number;
82
+ };
83
+ contact_details?: {
84
+ google_font_style?: string;
85
+ google_font_colour?: string;
86
+ google_font_size?: number;
87
+ };
88
+ button?: {
89
+ google_font_style?: string;
90
+ google_font_colour?: string;
91
+ google_font_size?: number;
92
+ };
93
+ bio?: {
94
+ google_font_style?: string;
95
+ google_font_colour?: string;
96
+ google_font_size?: number;
97
+ };
98
+
99
+ // @deprecated - Use 'personal_info' instead (kept for backward compatibility)
100
+ user_info?: {
101
+ google_font_style?: string;
102
+ google_font_colour?: string;
103
+ google_font_size?: number;
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Background configuration for card
109
+ */
110
+ export interface Background {
111
+ type: DBC_BACKGROUND_TYPE | 'color' | 'gradient' | 'image';
112
+ value: string; // Hex color, image URL, or gradient CSS
113
+ }
114
+
115
+ /**
116
+ * Card customization options (colors, fonts, styling)
117
+ * Based on Angular backend model - these are the ONLY customizable properties
118
+ */
119
+ export interface Customizations {
120
+ // Colors
121
+ background_color?: string;
122
+ user_info_color?: string;
123
+ secondary_color?: string;
124
+ button_color?: string;
125
+ icon_color?: string;
126
+
127
+ // Typography
128
+ font_style?: string;
129
+ title_font_size?: number;
130
+ font_type?: 'google' | 'custom';
131
+ custom_font_url?: string;
132
+ custom_font_style?: string;
133
+ profile_info?: string;
134
+ company_details?: string;
135
+ contact_details?: string;
136
+ button?: string;
137
+ typography?: Typography;
138
+
139
+ // Background
140
+ background?: Background;
141
+ }
142
+
143
+ /**
144
+ * Lead collection attribute configuration
145
+ */
146
+ export interface LeadAttribute {
147
+ phone: boolean;
148
+ designation: boolean;
149
+ notes: boolean;
150
+ connection: LEAD_COLLECT_TYPE;
151
+ company: boolean;
152
+ }
153
+
154
+ /**
155
+ * User agreement links for lead collection
156
+ */
157
+ export interface AgreementLinksModal {
158
+ label: string;
159
+ url: string;
160
+ }
161
+
162
+ /**
163
+ * Lead user agreement configuration
164
+ */
165
+ export interface LeadUserAgreementAttribute {
166
+ user_agreement_urls: AgreementLinksModal[];
167
+ }
168
+
169
+ /**
170
+ * Contact info list item (used internally for rendering)
171
+ */
172
+ export interface ContactInfoListType {
173
+ key: contactInfoType;
174
+ value: ContactInfo[];
175
+ }
176
+
177
+ /**
178
+ * Multi-language content structure
179
+ * Contains all translatable fields for a specific language
180
+ */
181
+ export interface MultiLanguageContent {
182
+ first_name?: string;
183
+ last_name?: string;
184
+ prefix?: string;
185
+ suffix?: string;
186
+ designation?: string;
187
+ department?: string;
188
+ pronouns_v2?: string;
189
+ company?: string;
190
+ summary?: string;
191
+ logo_url?: string;
192
+ logo_size?: number;
193
+ phone_v2?: ContactInfo[];
194
+ email_v2?: ContactInfo[];
195
+ website_v2?: ContactInfo[];
196
+ custom_fields?: ContactInfo[];
197
+ address_url?: string;
198
+ address_v2?: string;
199
+ social_links?: SocialLinks;
200
+ user_image_url?: string;
201
+ cover_image_url?: string;
202
+ contact_info_ordering?: Record<string, contactInfoType>;
203
+ __contact_info_list__?: ContactInfoListType[];
204
+ }
205
+
206
+ // ============================================================================
207
+ // MAIN CARD DATA INTERFACE (Complete Schema)
208
+ // ============================================================================
209
+
210
+ /**
211
+ * Complete Digital Business Card data structure
212
+ * Aligned with Django backend model and Angular frontend
213
+ */
214
+ export interface CardData {
215
+ // ===== BASIC INFO =====
216
+ id?: number;
217
+ first_name?: string;
218
+ last_name?: string;
219
+ name?: string; // Computed full name
220
+ designation?: string;
221
+ company?: string;
222
+ department?: string;
223
+ summary?: string;
224
+ prefix?: string;
225
+ suffix?: string;
226
+ pronouns_v2?: string;
227
+
228
+ // ===== CONTACT INFORMATION (v2 arrays) =====
229
+ phone_v2?: ContactInfo[];
230
+ email_v2?: ContactInfo[];
231
+ website_v2?: ContactInfo[];
232
+ custom_fields?: ContactInfo[];
233
+
234
+ // Legacy contact info (for backward compatibility)
235
+ phone?: {
236
+ mobile?: string;
237
+ work?: string;
238
+ home?: string;
239
+ };
240
+ email?: string;
241
+ website?: string;
242
+
243
+ // ===== ADDRESS =====
244
+ address_v2?: string; // Full address string
245
+ address_line1?: string;
246
+ address_line2?: string;
247
+ city?: string;
248
+ address_state?: string; // State/Province
249
+ country?: string;
250
+ zip?: string;
251
+ address_url?: string; // Google Maps URL
252
+
253
+ // ===== MEDIA =====
254
+ user_image_url?: string;
255
+ cover_image_url?: string; // Hero/cover image
256
+ logo_url?: string;
257
+ logo_size?: number;
258
+
259
+ // ===== SOCIAL LINKS =====
260
+ social_links?: SocialLinks;
261
+ social_links_ordering?: string[]; // Order of social links display
262
+
263
+ // ===== STYLING & CUSTOMIZATION =====
264
+ customizations?: Customizations;
265
+
266
+ // ===== CONFIGURATION =====
267
+ layout?: string;
268
+ template?: any;
269
+ card_template?: any;
270
+
271
+ // Contact info ordering (⚠️ Changed from string[] to Record)
272
+ contact_info_ordering?: Record<string, contactInfoType>;
273
+ __contact_info_list__?: ContactInfoListType[]; // Computed field
274
+
275
+ // ===== LEAD COLLECTION =====
276
+ lead_collection?: boolean;
277
+ lead_attribute?: LeadAttribute;
278
+ lead_user_agreement?: boolean;
279
+ lead_user_agreement_attribute?: LeadUserAgreementAttribute;
280
+ name_in_lead_consent?: string;
281
+ consent_placeholder?: string; // Used for lead form consent text
282
+
283
+ // Follow-up email
284
+ follow_up_email?: boolean;
285
+ follow_up_email_subject?: string;
286
+ follow_up_email_body?: string;
287
+ follow_up_email_delay?: number;
288
+
289
+ // ===== MULTI-LANGUAGE SUPPORT =====
290
+ default_language?: string; // e.g., 'en', 'fr', 'es'
291
+ language_data?: { [languageCode: string]: MultiLanguageContent };
292
+
293
+ // ===== METADATA =====
294
+ state?: PRODUCT_STATE;
295
+ url?: string;
296
+ slug?: string;
297
+ created?: string;
298
+ updated?: string;
299
+ organization?: number;
300
+ maintainer?: number;
301
+ card_owner?: any;
302
+ threat_active?: boolean;
303
+ meta?: object;
304
+ is_template?: boolean;
305
+
306
+ // ===== ANALYTICS =====
307
+ views?: number;
308
+ saves?: number;
309
+
310
+ // ===== FEATURES =====
311
+ autodownload_v2?: boolean;
312
+ autodownload_url?: string; // vCard download URL
313
+ location_enabled?: boolean;
314
+ ip_location_enabled?: boolean;
315
+ branding_footer?: boolean;
316
+
317
+ // Marketing pixels
318
+ fb_pixel_id?: string;
319
+ google_conversion_id?: string;
320
+
321
+ // ===== TAGS =====
322
+ tags?: any[];
323
+ tags_data?: any[];
324
+
325
+ // ===== SERVER/PREVIEW ONLY FIELDS (prefixed with __) =====
326
+ __views__?: number;
327
+ __downloads__?: number;
328
+ __auto_generated_slug__?: boolean;
329
+ __show_lead_form_in_preview__?: boolean;
330
+ __show_new_sticky_btn__?: boolean;
331
+ __zoom__?: number;
332
+ __footer__branding__text__?: boolean;
333
+ __onboarding_layout__?: boolean;
334
+ __work_email__?: boolean;
335
+ __show_add_to_contacts__?: boolean;
336
+ __consent_placeholder__?: string;
337
+
338
+ // ===== SERVER-SPECIFIC FIELDS =====
339
+ jwt_update_token?: string;
340
+ static_assets_url?: string; // Base URL for static assets
341
+
342
+ // Additional fields that might be used by specific templates
343
+ [key: string]: any;
344
+ }
345
+
346
+ // ============================================================================
347
+ // EVENT SYSTEM
348
+ // ============================================================================
349
+
350
+ export interface CardEvent<T = any> {
351
+ type: string;
352
+ data: T;
353
+ templateId: string;
354
+ timestamp: number;
355
+ }
356
+
357
+ export interface ContactClickEvent {
358
+ contactType: 'phone' | 'email' | 'website' | 'social' | 'custom';
359
+ value: string;
360
+ label?: string;
361
+ }
362
+
363
+ export interface ShareEvent {
364
+ method: 'native' | 'copy' | 'qr' | 'download';
365
+ format?: 'vcard' | 'url' | 'image';
366
+ }
367
+
368
+ export interface LeadCollectEvent {
369
+ fields: Record<string, any>;
370
+ source: string;
371
+ }
372
+
373
+ // ============================================================================
374
+ // TEMPLATE-SPECIFIC CONFIGURATIONS
375
+ // ============================================================================
376
+
377
+ // Base template props that all templates support
378
+ export interface BaseTemplateProps {
379
+ cardData?: CardData;
380
+
381
+ // Data setters - allow external control of specific data points
382
+ dataSetters?: {
383
+ setName?: (first: string, last: string) => void;
384
+ setCompany?: (company: string, designation?: string) => void;
385
+ setContact?: (type: 'phone' | 'email' | 'website', value: string, label?: string) => void;
386
+ setSocialLink?: (platform: keyof SocialLinks, url: string) => void;
387
+ setCustomization?: (key: keyof Customizations, value: any) => void;
388
+ };
389
+
390
+ // Event handlers
391
+ onContactClick?: (event: ContactClickEvent) => void;
392
+ onShare?: (event: ShareEvent) => void;
393
+ onLeadCollect?: (event: LeadCollectEvent) => void;
394
+ onCustomEvent?: (event: CardEvent) => void;
395
+
396
+ // Configuration - uses BaseCardConfig for comprehensive type safety
397
+ config?: BaseCardConfig;
398
+
399
+ // Styling overrides
400
+ style?: React.CSSProperties;
401
+ className?: string;
402
+ }
403
+
404
+ // Template-specific props (each template can extend BaseTemplateProps)
405
+
406
+ /**
407
+ * Layout 12 - Modern Business Card Layout
408
+ * Professional design with customizable colors, typography, and multi-language support
409
+ */
410
+ export interface Layout12Props extends BaseTemplateProps {
411
+ // CardLayout12 uses CardLayout12Config which extends BaseCardConfig
412
+ // No additional layout-specific props currently
413
+ config?: CardLayout12Config;
414
+ }
415
+
416
+ // ============================================================================
417
+ // WEB COMPONENT DECLARATIONS FOR JSX/TSX
418
+ // ============================================================================
419
+
420
+ declare global {
421
+ namespace JSX {
422
+ interface IntrinsicElements {
423
+ 'uniqode-layout-12': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
424
+ ref?: React.Ref<HTMLElement & UniqodeCardElement>;
425
+ };
426
+ }
427
+ }
428
+ }
429
+
430
+ // ============================================================================
431
+ // WEB COMPONENT ELEMENT INTERFACE
432
+ // ============================================================================
433
+
434
+ /**
435
+ * Extended HTMLElement interface for Uniqode Card Web Components
436
+ * Use this for type-safe access to card properties and methods
437
+ */
438
+ export interface UniqodeCardElement extends HTMLElement {
439
+ // Properties
440
+ cardData: CardData;
441
+ config: BaseCardConfig;
442
+
443
+ // Event handlers are attached via addEventListener
444
+ // See event types below for detail structures
445
+ }
446
+
447
+ // ============================================================================
448
+ // CONFIGURATION TYPES
449
+ // ============================================================================
450
+
451
+ /**
452
+ * Layout configuration for card rendering
453
+ * Controls dimensions, positioning, and responsive behavior
454
+ */
455
+ export interface LayoutConfig {
456
+ /** Card width - 'auto', '100%', '500px', or any CSS value */
457
+ width?: string;
458
+ /** Maximum width constraint */
459
+ maxWidth?: string;
460
+ /** Card height - 'auto', '100%', '100vh', or any CSS value */
461
+ height?: string;
462
+ /** Minimum height constraint */
463
+ minHeight?: string;
464
+ /** Center the card horizontally */
465
+ centered?: boolean;
466
+ /** Force full width (for mobile/Flutter) */
467
+ fullWidth?: boolean;
468
+ /** Content padding */
469
+ padding?: string;
470
+ /** Disable all click interactions (contact info, social icons, footer buttons) */
471
+ clicksDisabled?: boolean;
472
+ /** Disable ONLY footer button clicks (Exchange Contacts, Add to Contact, Connect, Create) - social icons and contact info remain clickable */
473
+ footerClicksDisabled?: boolean;
474
+ /** Hero image height ('361px', '50%', 'auto') */
475
+ heroHeight?: string;
476
+ }
477
+
478
+ /**
479
+ * Base configuration options available for all card layouts
480
+ * These options control common features across all templates
481
+ */
482
+ export interface BaseCardConfig {
483
+ // Display toggles
484
+ /** Show user profile image */
485
+ showProfileImage?: boolean;
486
+ /** Show company/organization logo */
487
+ showLogo?: boolean;
488
+ /** Enable sharing functionality */
489
+ enableSharing?: boolean;
490
+ /** Enable lead collection form */
491
+ enableLeadCollection?: boolean;
492
+ /** Enable compact/minimal mode */
493
+ compactMode?: boolean;
494
+
495
+ // Theme
496
+ /** Theme mode - 'light', 'dark', or 'auto' (system preference) */
497
+ theme?: 'light' | 'dark' | 'auto';
498
+
499
+ // Lead collection & footer controls
500
+ /** Enable lead collection (shows "Exchange Contacts" button) */
501
+ leadCollection?: boolean;
502
+ /** Show language dropdown for multi-language support */
503
+ showLanguageDropdown?: boolean | 'auto';
504
+ /** Show footer with branding */
505
+ showFooter?: boolean;
506
+ /** Hide footer completely */
507
+ hideFooter?: boolean;
508
+ /** Hide "Powered by Uniqode" branding text */
509
+ hidePoweredBy?: boolean;
510
+ /** Show animation frame for card exchange */
511
+ showAnimation?: boolean;
512
+ /** PWA preview mode (hides sticky buttons) */
513
+ pwaPreview?: boolean;
514
+
515
+ // Internal state (set programmatically)
516
+ /** Show "Connect" and "Create Now" buttons (after lead exchange) */
517
+ showConnectButtons?: boolean;
518
+
519
+ // Platform-specific
520
+ /** Platform identifier - 'mobile', 'dashboard', 'server', 'web' */
521
+ platform?: 'mobile' | 'dashboard' | 'server' | 'web';
522
+
523
+ // Layout configuration
524
+ /** Layout-specific configuration (dimensions, positioning) */
525
+ layoutConfig?: LayoutConfig;
526
+ }
527
+
528
+ /**
529
+ * Configuration options specific to CardLayout12
530
+ * Inherits all options from BaseCardConfig
531
+ */
532
+ export interface CardLayout12Config extends BaseCardConfig {
533
+ // CardLayout12 doesn't have layout-specific config currently
534
+ // All config is inherited from BaseCardConfig
535
+ // Future layout-specific options can be added here
536
+ }
537
+
538
+ // End of type definitions
package/package.json ADDED
@@ -0,0 +1,97 @@
1
+ {
2
+ "name": "@uniqode/card-templates",
3
+ "version": "1.0.0",
4
+ "description": "Universal Web Components library for digital business card templates. Framework-agnostic, customizable, and production-ready.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist/",
11
+ "README.md"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "scripts": {
17
+ "dev": "storybook dev -p 6006",
18
+ "build": "npm run build:lib && npm run build:storybook",
19
+ "build:lib": "webpack --mode=production",
20
+ "build:storybook": "storybook build",
21
+ "build:dev": "webpack --mode=development --watch",
22
+ "start": "npm run dev",
23
+ "prepublishOnly": "npm run build:lib",
24
+ "lint": "eslint src/ --ext .js",
25
+ "lint:fix": "eslint src/ --ext .js --fix",
26
+ "size": "npm run build:lib && ls -lh dist/",
27
+ "clean": "rimraf dist/ storybook-static/",
28
+ "prepack": "npm run clean && npm run build:lib",
29
+ "postpack": "npm run clean"
30
+ },
31
+ "keywords": [
32
+ "web-components",
33
+ "custom-elements",
34
+ "card-templates",
35
+ "digital-business-cards",
36
+ "vcard",
37
+ "templates",
38
+ "uniqode",
39
+ "beaconstac",
40
+ "business-cards",
41
+ "contact-cards",
42
+ "profile-cards",
43
+ "react-components",
44
+ "angular-components",
45
+ "vue-components",
46
+ "framework-agnostic",
47
+ "shadow-dom",
48
+ "responsive-design",
49
+ "customizable",
50
+ "professional"
51
+ ],
52
+ "author": "Uniqode Team <dev@uniqode.com>",
53
+ "license": "MIT",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "https://github.com/uniqode/card-templates.git"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/uniqode/card-templates/issues"
60
+ },
61
+ "homepage": "https://github.com/uniqode/card-templates#readme",
62
+ "devDependencies": {
63
+ "@babel/core": "^7.28.5",
64
+ "@babel/preset-env": "^7.28.5",
65
+ "@playwright/test": "^1.40.0",
66
+ "@storybook/addon-essentials": "^8.6.14",
67
+ "@storybook/html-webpack5": "^8.6.14",
68
+ "@types/jest": "^29.5.0",
69
+ "babel-loader": "^9.2.1",
70
+ "copy-webpack-plugin": "^13.0.1",
71
+ "css-loader": "^6.11.0",
72
+ "eslint": "^8.50.0",
73
+ "express": "^4.18.0",
74
+ "jest": "^29.7.0",
75
+ "jest-environment-jsdom": "^29.7.0",
76
+ "jsdom": "^27.1.0",
77
+ "prettier": "^3.0.0",
78
+ "rimraf": "^5.0.0",
79
+ "style-loader": "^3.3.4",
80
+ "webpack": "^5.102.1",
81
+ "webpack-cli": "^5.1.4",
82
+ "webpack-dev-server": "^4.15.0"
83
+ },
84
+ "peerDependencies": {
85
+ "@webcomponents/webcomponentsjs": "^2.8.0"
86
+ },
87
+ "browserslist": [
88
+ "> 1%",
89
+ "last 2 versions",
90
+ "not dead",
91
+ "not ie 11"
92
+ ],
93
+ "engines": {
94
+ "node": ">=16.0.0",
95
+ "npm": ">=8.0.0"
96
+ }
97
+ }