@zencemarketing/spin-scratch-sdk 0.1.0-alpha.1

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,513 @@
1
+ /**
2
+ * SpinWheel SDK v0.1.0-alpha.1
3
+ * TypeScript declarations
4
+ */
5
+
6
+ // ── SpinWheel Types ──
7
+
8
+ export interface SegmentConfig {
9
+ /** Text displayed on the wheel segment */
10
+ label: string;
11
+ /** Segment background color (hex) */
12
+ color: string;
13
+ /** Emoji/icon displayed on the segment */
14
+ icon?: string;
15
+ /** Title shown on the win card (falls back to label) */
16
+ title?: string;
17
+ /** "WORTH ₹xxx" text on the win card */
18
+ worth?: string;
19
+ /** Fixed coupon code – overrides auto-generate */
20
+ code?: string;
21
+ }
22
+
23
+ export interface SpinWheelTheme {
24
+ gold?: string;
25
+ goldLight?: string;
26
+ goldDark?: string;
27
+ bgDark?: string;
28
+ textMuted?: string;
29
+ }
30
+
31
+ /** @deprecated Use SpinWheelTheme instead */
32
+ export type ThemeConfig = SpinWheelTheme;
33
+
34
+ export interface SpinWheelOptions {
35
+ /** CSS selector or DOM element to mount into */
36
+ container: string | HTMLElement;
37
+ /** Array of prize segments (min 2) */
38
+ segments: SegmentConfig[];
39
+ /**
40
+ * Pre-determined winning segment index (0-based).
41
+ * If set, spin() will always land on this segment unless overridden by forceIndex.
42
+ * Must be within bounds (0 <= index < segments.length), otherwise ignored.
43
+ * Default: null (random selection)
44
+ */
45
+ winningIndex?: number | null;
46
+
47
+ // ── Spin Behavior ──
48
+ /** Total spin animation duration in ms (default: 5000) */
49
+ spinDuration?: number;
50
+ /** Minimum full rotations (default: 5) */
51
+ minSpins?: number;
52
+ /** Maximum full rotations (default: 8) */
53
+ maxSpins?: number;
54
+ /** Max number of spins allowed. null = unlimited (default: null) */
55
+ spinLimit?: number | null;
56
+
57
+ // ── Header UI ──
58
+ /** If set, renders a header above the wheel */
59
+ headerTitle?: string | null;
60
+ /** Subtitle below the header */
61
+ headerSubtitle?: string | null;
62
+ /** Custom title color (uses theme.goldLight if null) */
63
+ titleColor?: string | null;
64
+ /** Custom subtitle color (uses theme.textMuted if null) */
65
+ subtitleColor?: string | null;
66
+
67
+ // ── Hub ──
68
+ /** Text inside the center hub (default: 'Spin & win') */
69
+ hubLabel?: string;
70
+ /** Icon inside the center hub (default: '▲') */
71
+ hubIcon?: string;
72
+
73
+ // ── Spin Button ──
74
+ /** Render the external SPIN! button (default: true) */
75
+ showButton?: boolean;
76
+ /** Button label text (default: 'SPIN!') */
77
+ buttonText?: string;
78
+
79
+ // ── Wheel Appearance ──
80
+ /** Container background color (uses theme.bgDark if null) */
81
+ backgroundColor?: string | null;
82
+ /** Background image URL */
83
+ backgroundImage?: string | null;
84
+ /** Wheel ring color (uses theme gradient if null) */
85
+ ringColor?: string | null;
86
+ /** Enable ring shadow/glow effect (default: true) */
87
+ ringShadow?: boolean;
88
+ /** Enable pulsing ring animation (default: true) */
89
+ ringAnimation?: boolean;
90
+ /** Pointer/arrow color (uses theme.gold if null) */
91
+ pointerColor?: string | null;
92
+ /** Spin button gradient color (uses theme gradient if null) */
93
+ buttonColor?: string | null;
94
+ /** Enable button shadow effect (default: true) */
95
+ buttonShadow?: boolean;
96
+ /** Enable button hover/active animations (default: true) */
97
+ buttonAnimation?: boolean;
98
+
99
+ // ── Win Card ──
100
+ /** Show the built-in win card overlay (default: true) */
101
+ showWinCard?: boolean;
102
+ /** Auto-generate a random coupon code (default: true) */
103
+ generateCode?: boolean;
104
+ /** Length of auto-generated codes (default: 9) */
105
+ codeLength?: number;
106
+ /** If set, "Redeem Now" opens this URL */
107
+ redeemUrl?: string | null;
108
+ /** Brand label on win card (uses hubLabel if null) */
109
+ winCardBrandLabel?: string | null;
110
+ /** Label before worth value (default: 'WORTH') */
111
+ winCardWorthLabel?: string;
112
+ /** Redeem button text (default: 'Redeem Now') */
113
+ winCardRedeemButtonText?: string;
114
+ /** Redeem button gradient top color (default: '#15803d') */
115
+ winCardRedeemButtonColorTop?: string;
116
+ /** Redeem button gradient bottom color (default: '#166534') */
117
+ winCardRedeemButtonColorBottom?: string;
118
+ /** Redeem button text color (default: '#ffffff') */
119
+ winCardRedeemButtonTextColor?: string;
120
+
121
+ // ── Confetti ──
122
+ /** Show confetti on win (default: true) */
123
+ confettiOnWin?: boolean;
124
+ /** Array of confetti colors (uses defaults if null) */
125
+ confettiColors?: string[] | null;
126
+ /** Number of confetti pieces (default: 40) */
127
+ confettiCount?: number;
128
+
129
+ // ── Theme ──
130
+ /** Color theme overrides */
131
+ theme?: SpinWheelTheme;
132
+
133
+ // ── Callbacks ──
134
+ /** Called when spin starts */
135
+ onSpinStart?: (winIndex: number) => void;
136
+ /** Called when spin ends */
137
+ onSpinEnd?: (prize: SegmentConfig, winIndex: number) => void;
138
+ /** Called when redeem is clicked */
139
+ onRedeem?: (prize: SegmentConfig) => void;
140
+ /** Called when spin limit is reached */
141
+ onSpinLimitReached?: (count: number) => void;
142
+ }
143
+
144
+ /**
145
+ * Options passed to {@link SpinWheel.init}.
146
+ *
147
+ * VS Code hover on `SpinWheel.init` typically shows only the parameter type name.
148
+ * To see all available option fields, go to the type definition of `SpinWheelInitOptions`
149
+ * (or `SpinWheelOptions`) and/or use IntelliSense inside the object literal:
150
+ *
151
+ * @example
152
+ * SpinWheel.init({
153
+ * container: '#spin-wheel-container',
154
+ * segments: [{ label: 'Prize', color: '#55efc4' }],
155
+ * spinDuration: 5000,
156
+ * onSpinEnd: (prize) => console.log(prize)
157
+ * })
158
+ */
159
+ export type SpinWheelInitOptions = SpinWheelOptions;
160
+
161
+ export declare class SpinWheelInstance {
162
+ constructor(opts: SpinWheelOptions);
163
+
164
+ /** Current cumulative rotation in degrees */
165
+ currentRotation: number;
166
+ /** Whether the wheel is currently animating */
167
+ isSpinning: boolean;
168
+
169
+ /**
170
+ * Spin the wheel.
171
+ * @param forceIndex – optional index to force the result
172
+ */
173
+ spin(forceIndex?: number): void;
174
+
175
+ /**
176
+ * Replace all segments at runtime and re-render the wheel.
177
+ * @param newSegments – array of new segments (min 2)
178
+ */
179
+ updateSegments(newSegments: SegmentConfig[]): void;
180
+
181
+ /** Programmatically close the win card overlay */
182
+ hideWinCard(): void;
183
+
184
+ /**
185
+ * Update configuration options at runtime.
186
+ * @param newOptions – partial options to merge
187
+ */
188
+ updateOptions(newOptions: Partial<SpinWheelOptions>): void;
189
+
190
+ /**
191
+ * Reset the spin count to allow more spins.
192
+ * @param count – new spin count to set (default: 0)
193
+ */
194
+ resetSpinCount(count?: number): void;
195
+
196
+ /** Remove all SDK-created DOM and clean up */
197
+ destroy(): void;
198
+
199
+ /** The last prize that was won */
200
+ readonly lastWonPrize: SegmentConfig | null;
201
+
202
+ /** The last won segment index */
203
+ readonly lastWonIndex: number;
204
+
205
+ /** The current spin count */
206
+ readonly spinCount: number;
207
+
208
+ /** The remaining spins (null if unlimited) */
209
+ readonly remainingSpins: number | null;
210
+ }
211
+
212
+ export declare class SpinWheel {
213
+ /**
214
+ * Initialise and mount a new Spin Wheel.
215
+ *
216
+ * Required: `container`, `segments`.
217
+ */
218
+ static init(options: SpinWheelInitOptions): SpinWheelInstance;
219
+ /** The underlying class */
220
+ static Instance: typeof SpinWheelInstance;
221
+ /** Current SDK version */
222
+ static VERSION: string;
223
+ /** Default configuration */
224
+ static DEFAULTS: Readonly<SpinWheelOptions>;
225
+ }
226
+
227
+ // ── ScratchCard Types ──
228
+
229
+ export interface ScratchPrize {
230
+ /** Prize name (displayed in modal) */
231
+ name: string;
232
+ /** Emoji/icon */
233
+ icon?: string;
234
+ /** Label above prize name */
235
+ label?: string;
236
+ }
237
+
238
+ export interface ScratchCardTheme {
239
+ purpleDark?: string;
240
+ purpleMid?: string;
241
+ purpleLight?: string;
242
+ gold?: string;
243
+ goldLight?: string;
244
+ goldDark?: string;
245
+ white?: string;
246
+ textDark?: string;
247
+ textMuted?: string;
248
+ }
249
+
250
+ export interface ScratchCardOptions {
251
+ /** CSS selector or DOM element to mount into */
252
+ container: string | HTMLElement;
253
+ /** Prize object */
254
+ prize: ScratchPrize;
255
+
256
+ // ── Header UI ──
257
+ /** Header text (default: 'Scratch the Card to Win Exciting Prizes!') */
258
+ headerTitle?: string;
259
+ /** Header title color (uses theme.textDark if null) */
260
+ headerTitleColor?: string | null;
261
+
262
+ // ── Instruction ──
263
+ /** Instruction text */
264
+ instruction?: string;
265
+ /** Instruction text color (uses theme.textMuted if null) */
266
+ instructionColor?: string | null;
267
+
268
+ // ── Scratch Behavior ──
269
+ /** % scratched to auto-reveal, 10-90 (default: 55) */
270
+ revealThreshold?: number;
271
+ /** Scratch brush radius in px (default: 28) */
272
+ brushSize?: number;
273
+
274
+ // ── Coin (Eraser Tool) ──
275
+ /** Draggable eraser size in px (default: 56) */
276
+ coinSize?: number;
277
+ /** Show the draggable coin eraser (default: true) */
278
+ showCoin?: boolean;
279
+ /** Icon/text inside the coin (default: '$') */
280
+ coinIcon?: string;
281
+ /** Coin gradient start color (uses theme.goldLight if null) */
282
+ coinGradientStart?: string | null;
283
+ /** Coin gradient end color (uses theme.goldDark if null) */
284
+ coinGradientEnd?: string | null;
285
+
286
+ // ── Card Appearance ──
287
+ /** Card background CSS (uses default gradient if null) */
288
+ cardBackground?: string | null;
289
+ /** Enable card shadow (default: true) */
290
+ cardShadow?: boolean;
291
+ /** Card border radius in px (default: 24) */
292
+ cardBorderRadius?: number;
293
+
294
+ // ── Scratch Zone ──
295
+ /** Scratch zone background (uses theme gradient if null) */
296
+ scratchZoneBackground?: string | null;
297
+ /** Enable scratch zone shadow (default: true) */
298
+ scratchZoneShadow?: boolean;
299
+ /** Scratch zone border radius in px (default: 20) */
300
+ scratchZoneBorderRadius?: number;
301
+
302
+ // ── Scratch Layer ──
303
+ /** Scratch layer color (default: 'rgb(150, 130, 180)') */
304
+ scratchLayerColor?: string;
305
+ /** Show sparkle effects on scratch layer (default: true) */
306
+ scratchLayerSparkles?: boolean;
307
+ /** Number of sparkles (default: 40) */
308
+ scratchLayerSparkleCount?: number;
309
+
310
+ // ── Prize Display ──
311
+ /** Prize label color (uses white if null) */
312
+ prizeTextColor?: string | null;
313
+ /** Prize name color (uses theme.goldLight if null) */
314
+ prizeNameColor?: string | null;
315
+ /** Prize icon background (uses white opacity if null) */
316
+ prizeIconBackground?: string | null;
317
+
318
+ // ── Gift Icon (Hint) ──
319
+ /** Show gift icon hint on scratch layer (default: true) */
320
+ showGiftIcon?: boolean;
321
+ /** Gift icon emoji (default: '🎁') */
322
+ giftIcon?: string;
323
+ /** Gift icon background (uses white opacity if null) */
324
+ giftIconBackground?: string | null;
325
+
326
+ // ── Modal ──
327
+ /** Show the win modal on reveal (default: true) */
328
+ showModal?: boolean;
329
+ /** Modal title text (default: 'Congratulations!') */
330
+ modalTitle?: string;
331
+ /** Modal title color (uses theme.textDark if null) */
332
+ modalTitleColor?: string | null;
333
+ /** Modal button text prefix (default: 'Claim your') */
334
+ modalButtonText?: string;
335
+ /** Modal button background (uses theme gradient if null) */
336
+ modalButtonColor?: string | null;
337
+ /** Modal button text color (uses theme.white if null) */
338
+ modalButtonTextColor?: string | null;
339
+ /** Enable backdrop blur effect (default: true) */
340
+ modalBackdropBlur?: boolean;
341
+
342
+ // ── Confetti ──
343
+ /** Enable confetti on reveal (default: true) */
344
+ confettiEnabled?: boolean;
345
+ /** Array of confetti colors (uses defaults if null) */
346
+ confettiColors?: string[] | null;
347
+ /** Number of confetti pieces (default: 100) */
348
+ confettiCount?: number;
349
+ /** Confetti animation duration in ms (default: 5500) */
350
+ confettiDuration?: number;
351
+
352
+ // ── Animation ──
353
+ /** Animation type: 'default' | 'bounce' | 'none' (default: 'default') */
354
+ animationType?: 'default' | 'bounce' | 'none';
355
+ /** Animation duration in ms (default: 600) */
356
+ animationDuration?: number;
357
+
358
+ // ── Theme ──
359
+ /** Color theme overrides */
360
+ theme?: ScratchCardTheme;
361
+
362
+ // ── Callbacks ──
363
+ /** Called when scratching begins */
364
+ onScratchStart?: () => void;
365
+ /** Called with scratch percentage */
366
+ onScratchProgress?: (percent: number) => void;
367
+ /** Called when prize is revealed */
368
+ onReveal?: (prize: ScratchPrize) => void;
369
+ /** Called when claim is clicked */
370
+ onClaim?: (prize: ScratchPrize) => void;
371
+ }
372
+
373
+ export declare class ScratchCardInstance {
374
+ constructor(opts: ScratchCardOptions);
375
+
376
+ /** Current scratch percentage (0-100) */
377
+ scratchPercent: number;
378
+ /** Whether user is currently scratching */
379
+ isScratching: boolean;
380
+ /** Whether prize has been revealed */
381
+ hasRevealed: boolean;
382
+
383
+ /** Programmatically reveal the prize */
384
+ reveal(): void;
385
+ /** Reset the card for replay */
386
+ reset(): void;
387
+ /** Hide the win modal */
388
+ hideModal(): void;
389
+ /** Show the win modal */
390
+ showModal(): void;
391
+ /** Update prize at runtime and reset card */
392
+ updatePrize(prize: Partial<ScratchPrize>): void;
393
+ /**
394
+ * Update configuration options at runtime.
395
+ * @param newOptions – partial options to merge
396
+ */
397
+ updateOptions(newOptions: Partial<ScratchCardOptions>): void;
398
+ /** Remove all SDK-created DOM and clean up */
399
+ destroy(): void;
400
+
401
+ /** Get the current prize object */
402
+ readonly prize: ScratchPrize | null;
403
+ }
404
+
405
+ export declare const ScratchCard: {
406
+ /** Create and return a new ScratchCardInstance */
407
+ init(opts: ScratchCardOptions): ScratchCardInstance;
408
+ /** The underlying class */
409
+ Instance: typeof ScratchCardInstance;
410
+ /** Current SDK version */
411
+ VERSION: string;
412
+ /** Default configuration */
413
+ DEFAULTS: Readonly<ScratchCardOptions>;
414
+ };
415
+
416
+ // ── React Wrappers ──
417
+ // These types are self-contained — vanilla TS users do NOT need @types/react.
418
+
419
+ export interface SpinWheelReactProps extends Omit<SpinWheelOptions, 'container'> {
420
+ className?: string;
421
+ style?: Record<string, any>;
422
+ }
423
+
424
+ export interface SpinWheelReactHandle {
425
+ spin(forceIndex?: number): void;
426
+ updateSegments(segments: SegmentConfig[]): void;
427
+ hideWinCard(): void;
428
+ updateOptions(opts: Partial<SpinWheelOptions>): void;
429
+ resetSpinCount(count?: number): void;
430
+ readonly spinCount: number;
431
+ readonly remainingSpins: number | null;
432
+ readonly lastWonPrize: SegmentConfig | null;
433
+ readonly lastWonIndex: number;
434
+ readonly instance: SpinWheelInstance | null;
435
+ }
436
+
437
+ export interface ScratchCardReactProps extends Omit<ScratchCardOptions, 'container'> {
438
+ className?: string;
439
+ style?: Record<string, any>;
440
+ }
441
+
442
+ export interface ScratchCardReactHandle {
443
+ reveal(): void;
444
+ reset(): void;
445
+ hideModal(): void;
446
+ showModal(): void;
447
+ updatePrize(prize: Partial<ScratchPrize>): void;
448
+ updateOptions(opts: Partial<ScratchCardOptions>): void;
449
+ readonly scratchPercent: number;
450
+ readonly hasRevealed: boolean;
451
+ readonly prize: ScratchPrize | null;
452
+ readonly instance: ScratchCardInstance | null;
453
+ }
454
+
455
+ /**
456
+ * Creates a SpinWheelReact component using the provided React instance.
457
+ * Factory pattern avoids bundling React into the SDK.
458
+ *
459
+ * @param React – your app's React module
460
+ * @returns A ForwardRef component accepting {@link SpinWheelReactProps}.
461
+ *
462
+ * @example
463
+ * ```tsx
464
+ * import React, { useRef } from 'react';
465
+ * import { createSpinWheelReact, type SpinWheelReactHandle } from '@zencemarketing/spin-scratch-sdk';
466
+ *
467
+ * const SpinWheelReact = createSpinWheelReact(React);
468
+ * const ref = useRef<SpinWheelReactHandle>(null);
469
+ *
470
+ * <SpinWheelReact ref={ref} segments={[...]} onSpinEnd={(prize) => {}} />
471
+ * ```
472
+ */
473
+ export declare function createSpinWheelReact(React: any): import('react').ForwardRefExoticComponent<
474
+ SpinWheelReactProps & import('react').RefAttributes<SpinWheelReactHandle>
475
+ >;
476
+
477
+ /**
478
+ * Creates a ScratchCardReact component using the provided React instance.
479
+ * Factory pattern avoids bundling React into the SDK.
480
+ *
481
+ * @param React – your app's React module
482
+ * @returns A ForwardRef component accepting {@link ScratchCardReactProps}.
483
+ *
484
+ * @example
485
+ * ```tsx
486
+ * import React, { useRef } from 'react';
487
+ * import { createScratchCardReact, type ScratchCardReactHandle } from '@zencemarketing/spin-scratch-sdk';
488
+ *
489
+ * const ScratchCardReact = createScratchCardReact(React);
490
+ * const ref = useRef<ScratchCardReactHandle>(null);
491
+ *
492
+ * <ScratchCardReact ref={ref} prize={{ name: 'Gift' }} onReveal={(p) => {}} />
493
+ * ```
494
+ */
495
+ export declare function createScratchCardReact(React: any): import('react').ForwardRefExoticComponent<
496
+ ScratchCardReactProps & import('react').RefAttributes<ScratchCardReactHandle>
497
+ >;
498
+
499
+ /**
500
+ * Auto-detected SpinWheelReact (only available when `window.React` exists, e.g. UMD/CDN).
501
+ * In ESM/CJS bundler apps, import from `'@zencemarketing/spin-scratch-sdk/react'` instead.
502
+ */
503
+ export declare const SpinWheelReact: import('react').ForwardRefExoticComponent<
504
+ SpinWheelReactProps & import('react').RefAttributes<SpinWheelReactHandle>
505
+ > | undefined;
506
+
507
+ /**
508
+ * Auto-detected ScratchCardReact (only available when `window.React` exists, e.g. UMD/CDN).
509
+ * In ESM/CJS bundler apps, import from `'@zencemarketing/spin-scratch-sdk/react'` instead.
510
+ */
511
+ export declare const ScratchCardReact: import('react').ForwardRefExoticComponent<
512
+ ScratchCardReactProps & import('react').RefAttributes<ScratchCardReactHandle>
513
+ > | undefined;