@zencemarketing/spin-scratch-sdk 0.1.0-alpha.1 → 0.1.0-alpha.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/dist/react.cjs.js +79 -17
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.esm.mjs +79 -17
- package/dist/react.esm.mjs.map +1 -1
- package/dist/spin-wheel-sdk.cjs.js +79 -17
- package/dist/spin-wheel-sdk.cjs.js.map +1 -1
- package/dist/spin-wheel-sdk.d.ts +1 -1
- package/dist/spin-wheel-sdk.esm.mjs +79 -17
- package/dist/spin-wheel-sdk.esm.mjs.map +1 -1
- package/dist/spin-wheel-sdk.umd.js +77 -18
- package/dist/spin-wheel-sdk.umd.js.map +1 -1
- package/dist/spin-wheel-sdk.umd.min.js +1 -1
- package/dist/spin-wheel-sdk.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SpinWheel SDK v0.1.0-alpha.
|
|
2
|
+
* SpinWheel SDK v0.1.0-alpha.2
|
|
3
3
|
* (c) 2026 – MIT License
|
|
4
4
|
* A dynamic, configurable Spin & Win wheel and Scratch Card SDK for Vanilla JS & React.
|
|
5
5
|
*/
|
|
@@ -32,6 +32,51 @@
|
|
|
32
32
|
*/
|
|
33
33
|
function buildCSS(config, hexToRGBA) {
|
|
34
34
|
const t = config.theme || {};
|
|
35
|
+
const isHexColor = (value) => typeof value === 'string' && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value.trim());
|
|
36
|
+
const parseRgbLike = (value) => {
|
|
37
|
+
if (typeof value !== 'string') return null;
|
|
38
|
+
const m = value.trim().match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+)\s*)?\)$/i);
|
|
39
|
+
if (!m) return null;
|
|
40
|
+
const r = Math.min(255, Math.max(0, Number(m[1])));
|
|
41
|
+
const g = Math.min(255, Math.max(0, Number(m[2])));
|
|
42
|
+
const b = Math.min(255, Math.max(0, Number(m[3])));
|
|
43
|
+
if ([r, g, b].some((n) => Number.isNaN(n))) return null;
|
|
44
|
+
return { r, g, b };
|
|
45
|
+
};
|
|
46
|
+
const parseHex = (value) => {
|
|
47
|
+
if (!isHexColor(value)) return null;
|
|
48
|
+
const hex = value.trim().slice(1);
|
|
49
|
+
if (hex.length === 3) {
|
|
50
|
+
const r = parseInt(hex[0] + hex[0], 16);
|
|
51
|
+
const g = parseInt(hex[1] + hex[1], 16);
|
|
52
|
+
const b = parseInt(hex[2] + hex[2], 16);
|
|
53
|
+
return { r, g, b };
|
|
54
|
+
}
|
|
55
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
56
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
57
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
58
|
+
return { r, g, b };
|
|
59
|
+
};
|
|
60
|
+
const toRGBA = (value, alpha) => {
|
|
61
|
+
const rgb = parseHex(value) || parseRgbLike(value);
|
|
62
|
+
if (!rgb) return `rgba(0,0,0,${alpha})`;
|
|
63
|
+
return `rgba(${rgb.r},${rgb.g},${rgb.b},${alpha})`;
|
|
64
|
+
};
|
|
65
|
+
const darkenColor = (value, amount = 0.22) => {
|
|
66
|
+
const rgb = parseHex(value) || parseRgbLike(value);
|
|
67
|
+
if (!rgb) return null;
|
|
68
|
+
const factor = 1 - Math.min(0.9, Math.max(0, amount));
|
|
69
|
+
const r = Math.round(rgb.r * factor);
|
|
70
|
+
const g = Math.round(rgb.g * factor);
|
|
71
|
+
const b = Math.round(rgb.b * factor);
|
|
72
|
+
return `rgb(${r},${g},${b})`;
|
|
73
|
+
};
|
|
74
|
+
const readableTextOn = (bg) => {
|
|
75
|
+
const rgb = parseHex(bg) || parseRgbLike(bg);
|
|
76
|
+
if (!rgb) return '#1a1a1f';
|
|
77
|
+
const luma = (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b) / 255;
|
|
78
|
+
return luma < 0.55 ? '#ffffff' : '#1a1a1f';
|
|
79
|
+
};
|
|
35
80
|
|
|
36
81
|
// Extract theme colors with fallbacks
|
|
37
82
|
const gold = t.gold || '#e8c547';
|
|
@@ -41,11 +86,16 @@
|
|
|
41
86
|
const textMuted = t.textMuted || '#9ca3af';
|
|
42
87
|
|
|
43
88
|
// Configurable colors
|
|
44
|
-
const
|
|
89
|
+
const hasCustomTitleColor = config.titleColor !== null && config.titleColor !== undefined;
|
|
90
|
+
const titleSpinColor = hasCustomTitleColor ? config.titleColor : goldLight;
|
|
91
|
+
const titleWinColor = hasCustomTitleColor ? config.titleColor : goldDark;
|
|
45
92
|
const subtitleColor = config.subtitleColor || textMuted;
|
|
46
93
|
const ringColor = config.ringColor || gold;
|
|
47
94
|
const pointerColor = config.pointerColor || gold;
|
|
48
|
-
const
|
|
95
|
+
const hasCustomButtonColor = config.buttonColor !== null && config.buttonColor !== undefined;
|
|
96
|
+
const buttonBaseColor = hasCustomButtonColor ? config.buttonColor : gold;
|
|
97
|
+
const buttonTextColor = hasCustomButtonColor ? readableTextOn(buttonBaseColor) : '#1a1a1f';
|
|
98
|
+
const buttonEdgeColor = hasCustomButtonColor ? (darkenColor(buttonBaseColor) || 'rgba(0,0,0,0.25)') : goldDark;
|
|
49
99
|
const redeemBtnTop = config.winCardRedeemButtonColorTop || '#15803d';
|
|
50
100
|
const redeemBtnBottom = config.winCardRedeemButtonColorBottom || '#166534';
|
|
51
101
|
const redeemBtnText = config.winCardRedeemButtonTextColor || '#ffffff';
|
|
@@ -59,7 +109,7 @@
|
|
|
59
109
|
// Computed values
|
|
60
110
|
hexToRGBA(gold, 0.4);
|
|
61
111
|
const ringGlow = hexToRGBA(ringColor, 0.4);
|
|
62
|
-
const buttonGlow =
|
|
112
|
+
const buttonGlow = toRGBA(buttonBaseColor, 0.4);
|
|
63
113
|
|
|
64
114
|
// Background styles
|
|
65
115
|
const bgStyle = config.backgroundColor
|
|
@@ -80,17 +130,25 @@
|
|
|
80
130
|
|
|
81
131
|
// Button shadow and animation
|
|
82
132
|
const buttonBoxShadow = buttonShadow
|
|
83
|
-
? `box-shadow:0 4px 0 ${
|
|
84
|
-
: `box-shadow:
|
|
133
|
+
? `box-shadow:0 4px 0 ${buttonEdgeColor}, 0 6px 20px ${buttonGlow}, inset 0 1px 0 rgba(255,255,255,.3);`
|
|
134
|
+
: `box-shadow:inset 0 1px 0 rgba(255,255,255,.25);`;
|
|
85
135
|
|
|
86
136
|
const buttonHoverStyle = buttonAnimation
|
|
87
|
-
?
|
|
137
|
+
? (buttonShadow
|
|
138
|
+
? `.sw-spin-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 0 ${buttonEdgeColor},0 8px 28px ${buttonGlow},inset 0 1px 0 rgba(255,255,255,.3)}`
|
|
139
|
+
: `.sw-spin-btn:hover:not(:disabled){transform:translateY(-2px);filter:brightness(1.05)}`)
|
|
88
140
|
: `.sw-spin-btn:hover:not(:disabled){filter:brightness(1.05)}`;
|
|
89
141
|
|
|
90
142
|
const buttonActiveStyle = buttonAnimation
|
|
91
|
-
?
|
|
143
|
+
? (buttonShadow
|
|
144
|
+
? `.sw-spin-btn:active:not(:disabled){transform:translateY(2px);box-shadow:0 2px 0 ${buttonEdgeColor},0 4px 15px ${buttonGlow},inset 0 1px 0 rgba(255,255,255,.2)}`
|
|
145
|
+
: `.sw-spin-btn:active:not(:disabled){transform:translateY(1px);filter:brightness(0.98)}`)
|
|
92
146
|
: `.sw-spin-btn:active:not(:disabled){transform:translateY(1px)}`;
|
|
93
147
|
|
|
148
|
+
const buttonBackground = hasCustomButtonColor
|
|
149
|
+
? `background:${buttonBaseColor};`
|
|
150
|
+
: `background:linear-gradient(180deg,${goldLight},${goldDark});`;
|
|
151
|
+
|
|
94
152
|
return `
|
|
95
153
|
/* === SpinWheel SDK v2.1 === */
|
|
96
154
|
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;800&family=Outfit:wght@300;500;600;700&display=swap');
|
|
@@ -111,10 +169,10 @@
|
|
|
111
169
|
font-size:clamp(2rem,6vw,3.5rem); font-weight:800; letter-spacing:.02em;
|
|
112
170
|
}
|
|
113
171
|
.sw-title .sw-spin-text {
|
|
114
|
-
color:${
|
|
115
|
-
text-shadow:0 0 30px ${
|
|
172
|
+
color:${titleSpinColor};
|
|
173
|
+
text-shadow:0 0 30px ${toRGBA(titleSpinColor, 0.4)}, 0 0 60px ${toRGBA(titleSpinColor, 0.2)};
|
|
116
174
|
}
|
|
117
|
-
.sw-title .sw-win-text { color:${
|
|
175
|
+
.sw-title .sw-win-text { color:${titleWinColor}; }
|
|
118
176
|
.sw-subtitle { margin-top:.5rem; color:${subtitleColor}; font-size:1rem; font-weight:300; }
|
|
119
177
|
|
|
120
178
|
/* ── wheel ── */
|
|
@@ -196,7 +254,7 @@ ${ringAnimation ? `
|
|
|
196
254
|
.sw-spin-btn {
|
|
197
255
|
font-family:'Outfit',sans-serif; font-size:1.25rem; font-weight:700;
|
|
198
256
|
letter-spacing:.15em; padding:1rem 3rem; border:none; border-radius:12px;
|
|
199
|
-
|
|
257
|
+
${buttonBackground} color:${buttonTextColor};
|
|
200
258
|
cursor:pointer;
|
|
201
259
|
${buttonBoxShadow}
|
|
202
260
|
transition:transform .15s ease, box-shadow .2s ease, filter .2s ease;
|
|
@@ -1457,7 +1515,7 @@ ${buttonActiveStyle}
|
|
|
1457
1515
|
static Instance = SpinWheelInstance;
|
|
1458
1516
|
|
|
1459
1517
|
/** Current SDK version – kept in sync with package.json via build banner */
|
|
1460
|
-
static VERSION = '0.1.0-alpha.
|
|
1518
|
+
static VERSION = '0.1.0-alpha.2';
|
|
1461
1519
|
|
|
1462
1520
|
/** Export defaults for reference */
|
|
1463
1521
|
static DEFAULTS = DEFAULTS$1;
|
|
@@ -1721,7 +1779,10 @@ ${buttonActiveStyle}
|
|
|
1721
1779
|
|
|
1722
1780
|
// Background configs
|
|
1723
1781
|
const cardBg = config.cardBackground || `linear-gradient(180deg, #faf8fc 0%, #f0ebf5 100%)`;
|
|
1724
|
-
const
|
|
1782
|
+
const hasCustomScratchZoneBg = config.scratchZoneBackground !== null && config.scratchZoneBackground !== undefined;
|
|
1783
|
+
const scratchZoneBg = hasCustomScratchZoneBg
|
|
1784
|
+
? config.scratchZoneBackground
|
|
1785
|
+
: `linear-gradient(145deg, ${purpleDark} 0%, ${purpleMid} 50%, #5a3a7a 100%)`;
|
|
1725
1786
|
const modalBtnBg = config.modalButtonColor || `linear-gradient(145deg, ${purpleMid} 0%, ${purpleDark} 100%)`;
|
|
1726
1787
|
|
|
1727
1788
|
// Computed values
|
|
@@ -1841,9 +1902,7 @@ ${buttonActiveStyle}
|
|
|
1841
1902
|
align-items:center;
|
|
1842
1903
|
justify-content:center;
|
|
1843
1904
|
padding:20px;
|
|
1844
|
-
background:
|
|
1845
|
-
radial-gradient(circle at 30% 30%, rgba(255,255,255,0.08) 0%, transparent 45%),
|
|
1846
|
-
linear-gradient(145deg, ${purpleDark} 0%, ${purpleMid} 100%);
|
|
1905
|
+
background:${hasCustomScratchZoneBg ? scratchZoneBg : `radial-gradient(circle at 30% 30%, rgba(255,255,255,0.08) 0%, transparent 45%), linear-gradient(145deg, ${purpleDark} 0%, ${purpleMid} 100%)`};
|
|
1847
1906
|
}
|
|
1848
1907
|
|
|
1849
1908
|
.sc-prize-content::before {
|
|
@@ -3462,7 +3521,7 @@ ${buttonActiveStyle}
|
|
|
3462
3521
|
Instance: ScratchCardInstance,
|
|
3463
3522
|
|
|
3464
3523
|
/** Current SDK version */
|
|
3465
|
-
VERSION: '0.1.0-alpha.
|
|
3524
|
+
VERSION: '0.1.0-alpha.2',
|
|
3466
3525
|
|
|
3467
3526
|
/** Export defaults for reference */
|
|
3468
3527
|
DEFAULTS: DEFAULTS,
|