@proveanything/smartlinks 1.2.3 → 1.3.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.
- package/README.md +75 -0
- package/dist/README.md +569 -0
- package/dist/api/asset.js +6 -5
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +2 -0
- package/dist/api/realtime.d.ts +103 -0
- package/dist/api/realtime.js +113 -0
- package/{API_SUMMARY.md → dist/docs/API_SUMMARY.md} +226 -1
- package/dist/docs/i18n.md +287 -0
- package/dist/docs/liquid-templates.md +484 -0
- package/dist/docs/realtime.md +764 -0
- package/dist/docs/theme-defaults.md +100 -0
- package/dist/docs/theme.system.md +338 -0
- package/dist/docs/widgets.md +510 -0
- package/dist/http.js +132 -19
- package/dist/types/asset.d.ts +2 -0
- package/dist/types/error.d.ts +69 -3
- package/dist/types/error.js +98 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/realtime.d.ts +44 -0
- package/dist/types/realtime.js +2 -0
- package/package.json +3 -4
- package/dist/api/actions.d.ts +0 -32
- package/dist/api/actions.js +0 -99
- package/dist/build-docs.js +0 -61
- package/dist/types/actions.d.ts +0 -123
- package/dist/types/actions.js +0 -2
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# SmartLinks Theme Default Colors
|
|
2
|
+
|
|
3
|
+
Default color values for the SmartLinks theme system. Use these when no theme is provided via URL parameter.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Light Mode (Default)
|
|
8
|
+
|
|
9
|
+
| Theme Key | CSS Variable | HSL Value | RGB | Hex |
|
|
10
|
+
|-----------|--------------------------|---------------------|---------------|-----------|
|
|
11
|
+
| `bg` | `--background` | 0 0% 100% | 255, 255, 255 | #FFFFFF |
|
|
12
|
+
| `fg` | `--foreground` | 222.2 84% 4.9% | 2, 8, 23 | #020817 |
|
|
13
|
+
| `p` | `--primary` | 222.2 47.4% 11.2% | 15, 23, 42 | #0F172A |
|
|
14
|
+
| `pf` | `--primary-foreground` | 210 40% 98% | 248, 250, 252 | #F8FAFC |
|
|
15
|
+
| `s` | `--secondary` | 210 40% 96.1% | 241, 245, 249 | #F1F5F9 |
|
|
16
|
+
| `sf` | `--secondary-foreground` | 222.2 47.4% 11.2% | 15, 23, 42 | #0F172A |
|
|
17
|
+
| `a` | `--accent` | 210 40% 96.1% | 241, 245, 249 | #F1F5F9 |
|
|
18
|
+
| `af` | `--accent-foreground` | 222.2 47.4% 11.2% | 15, 23, 42 | #0F172A |
|
|
19
|
+
| `mt` | `--muted` | 210 40% 96.1% | 241, 245, 249 | #F1F5F9 |
|
|
20
|
+
| `mf` | `--muted-foreground` | 215.4 16.3% 46.9% | 100, 116, 139 | #64748B |
|
|
21
|
+
| `bd` | `--border` | 214.3 31.8% 91.4% | 226, 232, 240 | #E2E8F0 |
|
|
22
|
+
| `inp` | `--input` | 214.3 31.8% 91.4% | 226, 232, 240 | #E2E8F0 |
|
|
23
|
+
| `ring` | `--ring` | 222.2 84% 4.9% | 2, 8, 23 | #020817 |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Dark Mode
|
|
28
|
+
|
|
29
|
+
| Theme Key | CSS Variable | HSL Value | RGB | Hex |
|
|
30
|
+
|-----------|--------------------------|---------------------|---------------|-----------|
|
|
31
|
+
| `bg` | `--background` | 222.2 84% 4.9% | 2, 8, 23 | #020817 |
|
|
32
|
+
| `fg` | `--foreground` | 210 40% 98% | 248, 250, 252 | #F8FAFC |
|
|
33
|
+
| `p` | `--primary` | 210 40% 98% | 248, 250, 252 | #F8FAFC |
|
|
34
|
+
| `pf` | `--primary-foreground` | 222.2 47.4% 11.2% | 15, 23, 42 | #0F172A |
|
|
35
|
+
| `s` | `--secondary` | 217.2 32.6% 17.5% | 30, 41, 59 | #1E293B |
|
|
36
|
+
| `sf` | `--secondary-foreground` | 210 40% 98% | 248, 250, 252 | #F8FAFC |
|
|
37
|
+
| `a` | `--accent` | 217.2 32.6% 17.5% | 30, 41, 59 | #1E293B |
|
|
38
|
+
| `af` | `--accent-foreground` | 210 40% 98% | 248, 250, 252 | #F8FAFC |
|
|
39
|
+
| `mt` | `--muted` | 217.2 32.6% 17.5% | 30, 41, 59 | #1E293B |
|
|
40
|
+
| `mf` | `--muted-foreground` | 215 20.2% 65.1% | 148, 163, 184 | #94A3B8 |
|
|
41
|
+
| `bd` | `--border` | 217.2 32.6% 17.5% | 30, 41, 59 | #1E293B |
|
|
42
|
+
| `inp` | `--input` | 217.2 32.6% 17.5% | 30, 41, 59 | #1E293B |
|
|
43
|
+
| `ring` | `--ring` | 212.7 26.8% 83.9% | 203, 213, 225 | #CBD5E1 |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Non-Color Defaults
|
|
48
|
+
|
|
49
|
+
| Theme Key | CSS Variable | Default Value |
|
|
50
|
+
|-----------|-----------------|----------------------------------------|
|
|
51
|
+
| `r` | `--radius` | 0.5rem |
|
|
52
|
+
| `fn` | `--font-family` | system-ui, -apple-system, sans-serif |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Quick Copy (JSON)
|
|
57
|
+
|
|
58
|
+
### Light Mode Defaults
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"m": "l",
|
|
63
|
+
"bg": "0 0% 100%",
|
|
64
|
+
"fg": "222.2 84% 4.9%",
|
|
65
|
+
"p": "222.2 47.4% 11.2%",
|
|
66
|
+
"pf": "210 40% 98%",
|
|
67
|
+
"s": "210 40% 96.1%",
|
|
68
|
+
"sf": "222.2 47.4% 11.2%",
|
|
69
|
+
"a": "210 40% 96.1%",
|
|
70
|
+
"af": "222.2 47.4% 11.2%",
|
|
71
|
+
"mt": "210 40% 96.1%",
|
|
72
|
+
"mf": "215.4 16.3% 46.9%",
|
|
73
|
+
"bd": "214.3 31.8% 91.4%",
|
|
74
|
+
"inp": "214.3 31.8% 91.4%",
|
|
75
|
+
"ring": "222.2 84% 4.9%",
|
|
76
|
+
"r": "0.5rem"
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Dark Mode Defaults
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"m": "d",
|
|
85
|
+
"bg": "222.2 84% 4.9%",
|
|
86
|
+
"fg": "210 40% 98%",
|
|
87
|
+
"p": "210 40% 98%",
|
|
88
|
+
"pf": "222.2 47.4% 11.2%",
|
|
89
|
+
"s": "217.2 32.6% 17.5%",
|
|
90
|
+
"sf": "210 40% 98%",
|
|
91
|
+
"a": "217.2 32.6% 17.5%",
|
|
92
|
+
"af": "210 40% 98%",
|
|
93
|
+
"mt": "217.2 32.6% 17.5%",
|
|
94
|
+
"mf": "215 20.2% 65.1%",
|
|
95
|
+
"bd": "217.2 32.6% 17.5%",
|
|
96
|
+
"inp": "217.2 32.6% 17.5%",
|
|
97
|
+
"ring": "212.7 26.8% 83.9%",
|
|
98
|
+
"r": "0.5rem"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
# SmartLinks Theme System
|
|
2
|
+
|
|
3
|
+
Dynamic theming for SmartLinks iframe apps. Allows parent frames to pass branding configuration via URL parameters or postMessage.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### URL Parameter (Recommended)
|
|
8
|
+
|
|
9
|
+
Pass a base64-encoded JSON theme in the `theme` parameter:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
https://your-app.com/#/?collectionId=xyz&theme=eyJtIjoiZCIsInAiOiIyMTcgOTElIDYwJSJ9
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### PostMessage (Live Updates)
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
iframe.contentWindow.postMessage({
|
|
19
|
+
type: 'smartlinks-theme',
|
|
20
|
+
theme: {
|
|
21
|
+
m: 'd',
|
|
22
|
+
p: '217 91% 60%',
|
|
23
|
+
fn: 'Inter',
|
|
24
|
+
fu: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'
|
|
25
|
+
}
|
|
26
|
+
}, '*');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Theme Schema
|
|
32
|
+
|
|
33
|
+
### Property Reference
|
|
34
|
+
|
|
35
|
+
| Key | CSS Variable | Description | Example |
|
|
36
|
+
| ------ | ------------------------ | ----------------------------------- | --------------- |
|
|
37
|
+
| `m` | - | Mode: `'d'` (dark) or `'l'` (light) | `"d"` |
|
|
38
|
+
| `bg` | `--background` | Background color | `"222 84% 5%"` |
|
|
39
|
+
| `fg` | `--foreground` | Foreground/text color | `"210 40% 98%"` |
|
|
40
|
+
| `p` | `--primary` | Primary brand color | `"217 91% 60%"` |
|
|
41
|
+
| `pf` | `--primary-foreground` | Text on primary | `"210 40% 98%"` |
|
|
42
|
+
| `s` | `--secondary` | Secondary color | `"217 33% 18%"` |
|
|
43
|
+
| `sf` | `--secondary-foreground` | Text on secondary | `"210 40% 98%"` |
|
|
44
|
+
| `a` | `--accent` | Accent color | `"217 33% 18%"` |
|
|
45
|
+
| `af` | `--accent-foreground` | Text on accent | `"210 40% 98%"` |
|
|
46
|
+
| `mt` | `--muted` | Muted backgrounds | `"217 33% 18%"` |
|
|
47
|
+
| `mf` | `--muted-foreground` | Muted text | `"215 20% 65%"` |
|
|
48
|
+
| `bd` | `--border` | Border color | `"217 33% 18%"` |
|
|
49
|
+
| `inp` | `--input` | Input border color | `"217 33% 18%"` |
|
|
50
|
+
| `ring` | `--ring` | Focus ring color | `"213 27% 84%"` |
|
|
51
|
+
| `r` | `--radius` | Border radius | `"0.5rem"` |
|
|
52
|
+
| `fn` | `--font-family` | Font family name | `"Inter"` |
|
|
53
|
+
| `fu` | - | Font URL (CSS or woff2) | See below |
|
|
54
|
+
|
|
55
|
+
### Color Format
|
|
56
|
+
|
|
57
|
+
**All colors must be raw HSL values** (no `hsl()` wrapper):
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
"217 91% 60%" ✅ Correct
|
|
61
|
+
"hsl(217, 91%, 60%)" ❌ Wrong
|
|
62
|
+
"#3b82f6" ⚠️ Works (auto-converted) but HSL preferred
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Font Loading
|
|
66
|
+
|
|
67
|
+
The `fu` property supports:
|
|
68
|
+
|
|
69
|
+
1. **Google Fonts CSS URL**:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. **Direct font file URL**:
|
|
76
|
+
```
|
|
77
|
+
https://example.com/fonts/custom-font.woff2
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Example Themes
|
|
83
|
+
|
|
84
|
+
### Dark Theme with Custom Font
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"m": "d",
|
|
89
|
+
"bg": "222 84% 5%",
|
|
90
|
+
"fg": "210 40% 98%",
|
|
91
|
+
"p": "217 91% 60%",
|
|
92
|
+
"pf": "210 40% 98%",
|
|
93
|
+
"s": "217 33% 18%",
|
|
94
|
+
"sf": "210 40% 98%",
|
|
95
|
+
"bd": "217 33% 18%",
|
|
96
|
+
"r": "0.75rem",
|
|
97
|
+
"fn": "Inter",
|
|
98
|
+
"fu": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Base64 encoded:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
eyJtIjoiZCIsImJnIjoiMjIyIDg0JSA1JSIsImZnIjoiMjEwIDQwJSA5OCUiLCJwIjoiMjE3IDkxJSA2MCUiLCJwZiI6IjIxMCA0MCUgOTglIiwicyI6IjIxNyAzMyUgMTglIiwic2YiOiIyMTAgNDAlIDk4JSIsImJkIjoiMjE3IDMzJSAxOCUiLCJyIjoiMC43NXJlbSIsImZuIjoiSW50ZXIiLCJmdSI6Imh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9SW50ZXI6d2dodEA0MDA7NTAwOzYwMDs3MDAmZGlzcGxheT1zd2FwIn0=
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Light Theme (Minimal)
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"m": "l",
|
|
113
|
+
"p": "221 83% 53%",
|
|
114
|
+
"r": "0.5rem"
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Base64 encoded:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
eyJtIjoibCIsInAiOiIyMjEgODMlIDUzJSIsInIiOiIwLjVyZW0ifQ==
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Integration
|
|
127
|
+
|
|
128
|
+
### Files Required
|
|
129
|
+
|
|
130
|
+
Copy these files to your SmartLinks app:
|
|
131
|
+
|
|
132
|
+
1. **`src/utils/theme.ts`** - Core theme utilities
|
|
133
|
+
2. **`src/hooks/useSmartLinksTheme.ts`** - React hook for state management
|
|
134
|
+
|
|
135
|
+
### Setup Steps
|
|
136
|
+
|
|
137
|
+
#### 1. Update `index.html`
|
|
138
|
+
|
|
139
|
+
Add this inline script in `<body>` before your app script. **CRITICAL**: This handles both CSS font URLs (Google Fonts) AND direct font files (.otf, .ttf, .woff, .woff2):
|
|
140
|
+
|
|
141
|
+
```html
|
|
142
|
+
<script>
|
|
143
|
+
// Early theme application to prevent flash
|
|
144
|
+
(function() {
|
|
145
|
+
try {
|
|
146
|
+
function getThemeParam() {
|
|
147
|
+
var search = window.location.search;
|
|
148
|
+
var hash = window.location.hash;
|
|
149
|
+
|
|
150
|
+
var searchParams = new URLSearchParams(search);
|
|
151
|
+
if (searchParams.get('theme')) return searchParams.get('theme');
|
|
152
|
+
|
|
153
|
+
if (hash && hash.indexOf('?') !== -1) {
|
|
154
|
+
var hashParams = new URLSearchParams(hash.substring(hash.indexOf('?')));
|
|
155
|
+
if (hashParams.get('theme')) return hashParams.get('theme');
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function applyEarlyTheme(theme) {
|
|
161
|
+
var root = document.documentElement;
|
|
162
|
+
|
|
163
|
+
// Apply dark/light mode
|
|
164
|
+
if (theme.m === 'd') root.classList.add('dark');
|
|
165
|
+
else if (theme.m === 'l') root.classList.remove('dark');
|
|
166
|
+
|
|
167
|
+
// CSS variable mapping
|
|
168
|
+
var props = {
|
|
169
|
+
bg: '--background', fg: '--foreground',
|
|
170
|
+
p: '--primary', pf: '--primary-foreground',
|
|
171
|
+
s: '--secondary', sf: '--secondary-foreground',
|
|
172
|
+
a: '--accent', af: '--accent-foreground',
|
|
173
|
+
mt: '--muted', mf: '--muted-foreground',
|
|
174
|
+
bd: '--border', inp: '--input', ring: '--ring', r: '--radius'
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Apply CSS variables
|
|
178
|
+
for (var key in props) {
|
|
179
|
+
if (theme[key]) root.style.setProperty(props[key], theme[key]);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Load custom font - IMPORTANT: handle both CSS and direct font files
|
|
183
|
+
if (theme.fn) {
|
|
184
|
+
root.style.setProperty('--font-family', "'" + theme.fn + "', system-ui, sans-serif");
|
|
185
|
+
if (theme.fu) {
|
|
186
|
+
var fontUrl = theme.fu;
|
|
187
|
+
|
|
188
|
+
// Check if it's a CSS file (Google Fonts, etc.)
|
|
189
|
+
if (fontUrl.indexOf('fonts.googleapis.com') !== -1 || fontUrl.indexOf('.css') !== -1) {
|
|
190
|
+
// CSS file - inject as stylesheet link
|
|
191
|
+
var link = document.createElement('link');
|
|
192
|
+
link.id = 'smartlinks-custom-font';
|
|
193
|
+
link.rel = 'stylesheet';
|
|
194
|
+
link.href = fontUrl;
|
|
195
|
+
document.head.appendChild(link);
|
|
196
|
+
} else {
|
|
197
|
+
// Direct font file (.otf, .ttf, .woff, .woff2) - inject @font-face
|
|
198
|
+
var format = 'opentype'; // default for .otf
|
|
199
|
+
var lowerUrl = fontUrl.toLowerCase();
|
|
200
|
+
if (lowerUrl.indexOf('.woff2') !== -1) format = 'woff2';
|
|
201
|
+
else if (lowerUrl.indexOf('.woff') !== -1) format = 'woff';
|
|
202
|
+
else if (lowerUrl.indexOf('.ttf') !== -1) format = 'truetype';
|
|
203
|
+
else if (lowerUrl.indexOf('.otf') !== -1) format = 'opentype';
|
|
204
|
+
|
|
205
|
+
var style = document.createElement('style');
|
|
206
|
+
style.id = 'smartlinks-custom-font';
|
|
207
|
+
style.textContent = "@font-face { font-family: '" + theme.fn + "'; src: url('" + fontUrl + "') format('" + format + "'); font-weight: 100 900; font-display: swap; }";
|
|
208
|
+
document.head.appendChild(style);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
var themeParam = getThemeParam();
|
|
215
|
+
if (themeParam) {
|
|
216
|
+
var theme = JSON.parse(atob(themeParam));
|
|
217
|
+
applyEarlyTheme(theme);
|
|
218
|
+
}
|
|
219
|
+
} catch(e) {
|
|
220
|
+
console.warn('Early theme application failed:', e);
|
|
221
|
+
}
|
|
222
|
+
})();
|
|
223
|
+
</script>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Key Font Loading Logic
|
|
227
|
+
|
|
228
|
+
The script must handle two types of font URLs differently:
|
|
229
|
+
|
|
230
|
+
| Font URL Type | Example | Loading Method |
|
|
231
|
+
| ------------------ | ---------------------------------------- | ----------------------------------- |
|
|
232
|
+
| Google Fonts / CSS | `fonts.googleapis.com/css2?family=Inter` | `<link rel="stylesheet">` |
|
|
233
|
+
| Direct font file | `cdn.example.com/font.otf` | `<style>@font-face { ... }</style>` |
|
|
234
|
+
|
|
235
|
+
**Font Format Mapping** (for `@font-face`):
|
|
236
|
+
|
|
237
|
+
| Extension | Format Value |
|
|
238
|
+
| --------- | ------------ |
|
|
239
|
+
| `.otf` | `opentype` |
|
|
240
|
+
| `.ttf` | `truetype` |
|
|
241
|
+
| `.woff` | `woff` |
|
|
242
|
+
| `.woff2` | `woff2` |
|
|
243
|
+
|
|
244
|
+
#### 2. Update `src/index.css`
|
|
245
|
+
|
|
246
|
+
Add the font-family variable:
|
|
247
|
+
|
|
248
|
+
```css
|
|
249
|
+
:root {
|
|
250
|
+
--font-family: system-ui, -apple-system, sans-serif;
|
|
251
|
+
/* ... other variables ... */
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
body {
|
|
255
|
+
font-family: var(--font-family);
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### 3. Use the Hook in App.tsx
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
import { useSmartLinksTheme } from '@/hooks/useSmartLinksTheme';
|
|
263
|
+
|
|
264
|
+
const AppContent = () => {
|
|
265
|
+
// Initialize theme system (handles URL params and postMessage)
|
|
266
|
+
useSmartLinksTheme();
|
|
267
|
+
|
|
268
|
+
// ... rest of your app
|
|
269
|
+
};
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## PostMessage Protocol
|
|
275
|
+
|
|
276
|
+
### Theme Push (Parent → Iframe)
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
iframe.contentWindow.postMessage({
|
|
280
|
+
type: 'smartlinks-theme',
|
|
281
|
+
theme: { m: 'd', p: '217 91% 60%' }
|
|
282
|
+
}, '*');
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Acknowledgment (Iframe → Parent)
|
|
286
|
+
|
|
287
|
+
The app automatically sends acknowledgment when theme is applied:
|
|
288
|
+
|
|
289
|
+
```javascript
|
|
290
|
+
// Listen in parent
|
|
291
|
+
window.addEventListener('message', (event) => {
|
|
292
|
+
if (event.data.type === 'smartlinks-theme-applied') {
|
|
293
|
+
console.log('Theme applied:', event.data.success);
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Utilities
|
|
301
|
+
|
|
302
|
+
### Encode Theme (for testing)
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
import { encodeTheme } from '@/utils/theme';
|
|
306
|
+
|
|
307
|
+
const theme = { m: 'd', p: '217 91% 60%' };
|
|
308
|
+
const encoded = encodeTheme(theme);
|
|
309
|
+
// Use: ?theme=encoded
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Manual Theme Application
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import { applyTheme } from '@/utils/theme';
|
|
316
|
+
|
|
317
|
+
applyTheme({
|
|
318
|
+
m: 'd',
|
|
319
|
+
p: '217 91% 60%',
|
|
320
|
+
fn: 'Inter',
|
|
321
|
+
fu: 'https://fonts.googleapis.com/css2?family=Inter'
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## URL Length Considerations
|
|
328
|
+
|
|
329
|
+
- Safe URL limit: ~2,000 characters
|
|
330
|
+
- Typical theme JSON: 300-500 characters
|
|
331
|
+
- Base64 overhead: ~33% increase
|
|
332
|
+
- **Result**: Standard themes safely fit within limits
|
|
333
|
+
|
|
334
|
+
To minimize size:
|
|
335
|
+
|
|
336
|
+
- Only include properties that differ from defaults
|
|
337
|
+
- Use short HSL values where possible
|
|
338
|
+
- Omit font URL if using system fonts
|