@tangle-network/sandbox-ui 0.131.1 → 0.131.3
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/assets.d.ts +21 -1
- package/dist/assets.js +338 -199
- package/dist/globals.css +17 -11
- package/dist/styles.css +17 -11
- package/package.json +1 -1
package/dist/assets.d.ts
CHANGED
|
@@ -237,6 +237,8 @@ interface CopyPreviewProps {
|
|
|
237
237
|
content: CopyContent;
|
|
238
238
|
className?: string;
|
|
239
239
|
}
|
|
240
|
+
export declare const COPY_PLATFORM_LABEL: Record<CopyPlatform, string>;
|
|
241
|
+
/** Copy as it will read: the channel and its length budget, the headline, the body and its hashtags. */
|
|
240
242
|
export declare function CopyPreview({ content, className }: CopyPreviewProps): import("react").JSX.Element;
|
|
241
243
|
//#endregion
|
|
242
244
|
//#region src/assets/preview/email-preview.d.ts
|
|
@@ -246,7 +248,25 @@ interface EmailPreviewProps {
|
|
|
246
248
|
previewUrl?: string;
|
|
247
249
|
className?: string;
|
|
248
250
|
}
|
|
249
|
-
|
|
251
|
+
/**
|
|
252
|
+
* The colours an email body renders in. A brand whose text colour is light
|
|
253
|
+
* writes on a dark page; any brand colour that would not read on that page
|
|
254
|
+
* falls back to the page's own ink.
|
|
255
|
+
*/
|
|
256
|
+
export declare function emailPalette(brand: BrandTokens): {
|
|
257
|
+
scheme: string;
|
|
258
|
+
paper: "#111218" | "#ffffff";
|
|
259
|
+
ink: string;
|
|
260
|
+
accent: string;
|
|
261
|
+
button: string;
|
|
262
|
+
buttonText: string;
|
|
263
|
+
quote: string;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* An email as a reader meets it: who it is from, the subject and the inbox
|
|
267
|
+
* preview line, then the body on the brand's page and in its typeface.
|
|
268
|
+
*/
|
|
269
|
+
export declare function EmailPreview({ content, brand, previewUrl, className }: EmailPreviewProps): import("react").JSX.Element;
|
|
250
270
|
//#endregion
|
|
251
271
|
//#region src/assets/preview/image-preview.d.ts
|
|
252
272
|
type ImageFormat = "feed" | "story" | "carousel";
|
package/dist/assets.js
CHANGED
|
@@ -118,6 +118,283 @@ function ImagePreview({ content, brand, format = "feed", className }) {
|
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
120
|
//#endregion
|
|
121
|
+
//#region src/assets/preview/email-preview.tsx
|
|
122
|
+
/** sRGB relative luminance of a #rgb or #rrggbb colour; null for anything else. */
|
|
123
|
+
function luminance(color) {
|
|
124
|
+
const hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color.trim())?.[1];
|
|
125
|
+
if (!hex) return null;
|
|
126
|
+
const full = hex.length === 3 ? hex.split("").map((c) => c + c).join("") : hex;
|
|
127
|
+
const [r, g, b] = [
|
|
128
|
+
0,
|
|
129
|
+
2,
|
|
130
|
+
4
|
|
131
|
+
].map((i) => {
|
|
132
|
+
const channel = parseInt(full.slice(i, i + 2), 16) / 255;
|
|
133
|
+
return channel <= .03928 ? channel / 12.92 : ((channel + .055) / 1.055) ** 2.4;
|
|
134
|
+
});
|
|
135
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
136
|
+
}
|
|
137
|
+
function contrast(a, b) {
|
|
138
|
+
return (Math.max(a, b) + .05) / (Math.min(a, b) + .05);
|
|
139
|
+
}
|
|
140
|
+
const PAPER = {
|
|
141
|
+
light: "#ffffff",
|
|
142
|
+
dark: "#111218"
|
|
143
|
+
};
|
|
144
|
+
const INK = {
|
|
145
|
+
light: "#16171d",
|
|
146
|
+
dark: "#f4f4f6"
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* The colours an email body renders in. A brand whose text colour is light
|
|
150
|
+
* writes on a dark page; any brand colour that would not read on that page
|
|
151
|
+
* falls back to the page's own ink.
|
|
152
|
+
*/
|
|
153
|
+
function emailPalette(brand) {
|
|
154
|
+
const text = luminance(brand.textColor);
|
|
155
|
+
const scheme = text !== null && text > .5 ? "dark" : "light";
|
|
156
|
+
const paper = PAPER[scheme];
|
|
157
|
+
const paperLum = luminance(paper);
|
|
158
|
+
const readable = (color, minimum) => {
|
|
159
|
+
const lum = luminance(color);
|
|
160
|
+
return lum !== null && contrast(lum, paperLum) >= minimum;
|
|
161
|
+
};
|
|
162
|
+
const ink = readable(brand.textColor, 4.5) ? brand.textColor : INK[scheme];
|
|
163
|
+
const accent = readable(brand.primaryColor, 3) ? brand.primaryColor : ink;
|
|
164
|
+
const primary = luminance(brand.primaryColor);
|
|
165
|
+
const buttonText = primary !== null && contrast(primary, 1) < contrast(primary, 0) ? "#111111" : "#ffffff";
|
|
166
|
+
return {
|
|
167
|
+
scheme,
|
|
168
|
+
paper,
|
|
169
|
+
ink,
|
|
170
|
+
accent,
|
|
171
|
+
button: brand.primaryColor,
|
|
172
|
+
buttonText,
|
|
173
|
+
quote: brand.accentColor
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function Button$1({ href, label, palette }) {
|
|
177
|
+
return /* @__PURE__ */ jsx("a", {
|
|
178
|
+
href,
|
|
179
|
+
onClick: (event) => event.preventDefault(),
|
|
180
|
+
className: "inline-block rounded-md px-5 py-2.5 text-sm font-semibold no-underline",
|
|
181
|
+
style: {
|
|
182
|
+
background: palette.button,
|
|
183
|
+
color: palette.buttonText
|
|
184
|
+
},
|
|
185
|
+
children: label
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function Section({ section, palette }) {
|
|
189
|
+
const muted = {
|
|
190
|
+
color: palette.ink,
|
|
191
|
+
opacity: .72
|
|
192
|
+
};
|
|
193
|
+
switch (section.type) {
|
|
194
|
+
case "hero": return /* @__PURE__ */ jsxs("div", {
|
|
195
|
+
className: "flex flex-col items-center gap-3 py-2 text-center",
|
|
196
|
+
children: [
|
|
197
|
+
section.imageUrl && /* @__PURE__ */ jsx("img", {
|
|
198
|
+
src: section.imageUrl,
|
|
199
|
+
alt: "",
|
|
200
|
+
className: "w-full rounded-md object-cover"
|
|
201
|
+
}),
|
|
202
|
+
/* @__PURE__ */ jsx("h2", {
|
|
203
|
+
className: "text-2xl font-bold leading-tight tracking-tight",
|
|
204
|
+
style: { color: palette.accent },
|
|
205
|
+
children: section.headline
|
|
206
|
+
}),
|
|
207
|
+
section.subheadline && /* @__PURE__ */ jsx("p", {
|
|
208
|
+
className: "text-base leading-relaxed",
|
|
209
|
+
style: muted,
|
|
210
|
+
children: section.subheadline
|
|
211
|
+
}),
|
|
212
|
+
section.ctaLabel && /* @__PURE__ */ jsx("div", {
|
|
213
|
+
className: "pt-1",
|
|
214
|
+
children: /* @__PURE__ */ jsx(Button$1, {
|
|
215
|
+
href: section.ctaUrl ?? "#",
|
|
216
|
+
label: section.ctaLabel,
|
|
217
|
+
palette
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
]
|
|
221
|
+
});
|
|
222
|
+
case "body": return /* @__PURE__ */ jsx("p", {
|
|
223
|
+
className: "text-base leading-7 whitespace-pre-wrap",
|
|
224
|
+
children: section.text
|
|
225
|
+
});
|
|
226
|
+
case "feature": return /* @__PURE__ */ jsxs("div", {
|
|
227
|
+
className: "flex items-start gap-4",
|
|
228
|
+
children: [section.imageUrl && /* @__PURE__ */ jsx("img", {
|
|
229
|
+
src: section.imageUrl,
|
|
230
|
+
alt: "",
|
|
231
|
+
className: "size-16 shrink-0 rounded-md object-cover"
|
|
232
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
233
|
+
className: "flex flex-col gap-1",
|
|
234
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
235
|
+
className: "text-base font-semibold",
|
|
236
|
+
children: section.headline
|
|
237
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
238
|
+
className: "text-sm leading-relaxed",
|
|
239
|
+
style: muted,
|
|
240
|
+
children: section.description
|
|
241
|
+
})]
|
|
242
|
+
})]
|
|
243
|
+
});
|
|
244
|
+
case "testimonial": return /* @__PURE__ */ jsxs("blockquote", {
|
|
245
|
+
className: "border-l-4 pl-4",
|
|
246
|
+
style: { borderColor: palette.quote },
|
|
247
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
248
|
+
className: "text-base italic leading-relaxed",
|
|
249
|
+
children: [
|
|
250
|
+
"“",
|
|
251
|
+
section.quote,
|
|
252
|
+
"”"
|
|
253
|
+
]
|
|
254
|
+
}), /* @__PURE__ */ jsxs("footer", {
|
|
255
|
+
className: "mt-2 text-sm font-medium",
|
|
256
|
+
style: muted,
|
|
257
|
+
children: [section.author, section.role ? `, ${section.role}` : ""]
|
|
258
|
+
})]
|
|
259
|
+
});
|
|
260
|
+
case "cta": return /* @__PURE__ */ jsxs("div", {
|
|
261
|
+
className: "flex flex-col items-center gap-2 py-2 text-center",
|
|
262
|
+
children: [/* @__PURE__ */ jsx(Button$1, {
|
|
263
|
+
href: section.url,
|
|
264
|
+
label: section.label,
|
|
265
|
+
palette
|
|
266
|
+
}), section.subtext && /* @__PURE__ */ jsx("p", {
|
|
267
|
+
className: "text-sm",
|
|
268
|
+
style: muted,
|
|
269
|
+
children: section.subtext
|
|
270
|
+
})]
|
|
271
|
+
});
|
|
272
|
+
case "divider": return /* @__PURE__ */ jsx("hr", {
|
|
273
|
+
className: "border-0 border-t",
|
|
274
|
+
style: {
|
|
275
|
+
borderColor: palette.ink,
|
|
276
|
+
opacity: .15
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
default: return null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* An email as a reader meets it: who it is from, the subject and the inbox
|
|
284
|
+
* preview line, then the body on the brand's page and in its typeface.
|
|
285
|
+
*/
|
|
286
|
+
function EmailPreview({ content, brand, previewUrl, className }) {
|
|
287
|
+
const palette = emailPalette(brand);
|
|
288
|
+
return /* @__PURE__ */ jsxs("article", {
|
|
289
|
+
className: cn("overflow-hidden rounded-lg border border-border bg-card shadow-sm", className),
|
|
290
|
+
children: [/* @__PURE__ */ jsxs("header", {
|
|
291
|
+
className: "flex flex-col gap-1 border-b border-border px-5 py-4",
|
|
292
|
+
children: [
|
|
293
|
+
/* @__PURE__ */ jsxs("div", {
|
|
294
|
+
className: "flex items-center gap-2 text-sm",
|
|
295
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
296
|
+
"aria-hidden": true,
|
|
297
|
+
className: "flex size-7 shrink-0 items-center justify-center rounded-full text-xs font-semibold",
|
|
298
|
+
style: {
|
|
299
|
+
background: palette.button,
|
|
300
|
+
color: palette.buttonText
|
|
301
|
+
},
|
|
302
|
+
children: brand.businessName.trim().charAt(0).toUpperCase() || "?"
|
|
303
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
304
|
+
className: "font-medium",
|
|
305
|
+
children: brand.businessName
|
|
306
|
+
})]
|
|
307
|
+
}),
|
|
308
|
+
/* @__PURE__ */ jsx("h3", {
|
|
309
|
+
className: "text-base font-semibold leading-snug",
|
|
310
|
+
children: content.subject
|
|
311
|
+
}),
|
|
312
|
+
content.preheader && /* @__PURE__ */ jsx("p", {
|
|
313
|
+
className: "text-sm text-muted-foreground",
|
|
314
|
+
children: content.preheader
|
|
315
|
+
})
|
|
316
|
+
]
|
|
317
|
+
}), previewUrl ? /* @__PURE__ */ jsx("iframe", {
|
|
318
|
+
src: previewUrl,
|
|
319
|
+
title: "Email preview",
|
|
320
|
+
sandbox: "allow-same-origin",
|
|
321
|
+
className: "block h-[480px] w-full bg-white"
|
|
322
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
323
|
+
className: "px-5 py-8 sm:px-8",
|
|
324
|
+
style: {
|
|
325
|
+
background: palette.paper,
|
|
326
|
+
color: palette.ink,
|
|
327
|
+
fontFamily: brand.fontFamily
|
|
328
|
+
},
|
|
329
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
330
|
+
className: "mx-auto flex max-w-[560px] flex-col gap-5",
|
|
331
|
+
children: content.sections.map((section, index) => /* @__PURE__ */ jsx(Section, {
|
|
332
|
+
section,
|
|
333
|
+
palette
|
|
334
|
+
}, index))
|
|
335
|
+
})
|
|
336
|
+
})]
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
//#endregion
|
|
340
|
+
//#region src/assets/preview/copy-preview.tsx
|
|
341
|
+
const PLATFORM_LIMITS = {
|
|
342
|
+
instagram: 2200,
|
|
343
|
+
tiktok: 2200,
|
|
344
|
+
x: 280,
|
|
345
|
+
linkedin: 3e3,
|
|
346
|
+
sms: 160,
|
|
347
|
+
"email-subject": 60
|
|
348
|
+
};
|
|
349
|
+
const COPY_PLATFORM_LABEL = {
|
|
350
|
+
instagram: "Instagram",
|
|
351
|
+
tiktok: "TikTok",
|
|
352
|
+
x: "X",
|
|
353
|
+
linkedin: "LinkedIn",
|
|
354
|
+
sms: "SMS",
|
|
355
|
+
"email-subject": "Email subject"
|
|
356
|
+
};
|
|
357
|
+
/** Copy as it will read: the channel and its length budget, the headline, the body and its hashtags. */
|
|
358
|
+
function CopyPreview({ content, className }) {
|
|
359
|
+
const limit = PLATFORM_LIMITS[content.platform];
|
|
360
|
+
const length = content.body.length;
|
|
361
|
+
const over = limit !== null && length > limit;
|
|
362
|
+
const near = !over && limit !== null && length >= limit * .9;
|
|
363
|
+
return /* @__PURE__ */ jsxs("article", {
|
|
364
|
+
className: cn("flex flex-col gap-4 rounded-xl border border-border bg-card p-6 shadow-sm", className),
|
|
365
|
+
children: [
|
|
366
|
+
/* @__PURE__ */ jsxs("div", {
|
|
367
|
+
className: "flex items-center justify-between gap-3",
|
|
368
|
+
children: [/* @__PURE__ */ jsx(Badge, {
|
|
369
|
+
variant: "secondary",
|
|
370
|
+
className: "text-xs",
|
|
371
|
+
children: COPY_PLATFORM_LABEL[content.platform] ?? content.platform
|
|
372
|
+
}), limit !== null && /* @__PURE__ */ jsxs("span", {
|
|
373
|
+
className: cn("text-xs tabular-nums", over ? "font-medium text-destructive" : near ? "text-warning" : "text-muted-foreground"),
|
|
374
|
+
children: [
|
|
375
|
+
length,
|
|
376
|
+
" / ",
|
|
377
|
+
limit,
|
|
378
|
+
" characters"
|
|
379
|
+
]
|
|
380
|
+
})]
|
|
381
|
+
}),
|
|
382
|
+
content.headline && /* @__PURE__ */ jsx("h3", {
|
|
383
|
+
className: "text-xl font-semibold leading-snug tracking-tight",
|
|
384
|
+
children: content.headline
|
|
385
|
+
}),
|
|
386
|
+
/* @__PURE__ */ jsx("p", {
|
|
387
|
+
className: "text-base leading-7 whitespace-pre-wrap [overflow-wrap:anywhere]",
|
|
388
|
+
children: content.body
|
|
389
|
+
}),
|
|
390
|
+
content.hashtags && content.hashtags.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
391
|
+
className: "flex flex-wrap gap-x-2 gap-y-1 text-sm text-primary",
|
|
392
|
+
children: content.hashtags.map((tag) => /* @__PURE__ */ jsxs("span", { children: ["#", tag.replace(/^#/, "")] }, tag))
|
|
393
|
+
})
|
|
394
|
+
]
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
//#endregion
|
|
121
398
|
//#region src/assets/labels.ts
|
|
122
399
|
/** Reader-facing name for each asset format. */
|
|
123
400
|
const ASSET_FORMAT_LABEL = {
|
|
@@ -163,6 +440,7 @@ function videoPosterUrl(content) {
|
|
|
163
440
|
}
|
|
164
441
|
return null;
|
|
165
442
|
}
|
|
443
|
+
const FADE_OUT = "[mask-image:linear-gradient(to_bottom,black_75%,transparent)]";
|
|
166
444
|
function formatDuration(seconds) {
|
|
167
445
|
const whole = Math.max(0, Math.round(seconds));
|
|
168
446
|
return `${Math.floor(whole / 60)}:${String(whole % 60).padStart(2, "0")}`;
|
|
@@ -177,15 +455,46 @@ function Thumbnail({ spec }) {
|
|
|
177
455
|
const { format, brand, content } = spec;
|
|
178
456
|
if (format === "email") {
|
|
179
457
|
const ec = content;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
className: "
|
|
187
|
-
children: [
|
|
188
|
-
|
|
458
|
+
const palette = emailPalette(brand);
|
|
459
|
+
const hero = ec.sections.find((section) => section.type === "hero");
|
|
460
|
+
const body = ec.sections.find((section) => section.type === "body");
|
|
461
|
+
return /* @__PURE__ */ jsx("div", {
|
|
462
|
+
className: "flex h-full flex-col p-3",
|
|
463
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
464
|
+
className: "flex h-full flex-col overflow-hidden rounded-md border border-border bg-card shadow-sm",
|
|
465
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
466
|
+
className: "flex shrink-0 flex-col gap-0.5 border-b border-border px-3 py-2",
|
|
467
|
+
children: [
|
|
468
|
+
/* @__PURE__ */ jsx("div", {
|
|
469
|
+
className: "truncate text-xs text-muted-foreground",
|
|
470
|
+
children: brand.businessName
|
|
471
|
+
}),
|
|
472
|
+
/* @__PURE__ */ jsx("div", {
|
|
473
|
+
className: "line-clamp-2 text-sm font-semibold leading-snug",
|
|
474
|
+
children: ec.subject
|
|
475
|
+
}),
|
|
476
|
+
ec.preheader && /* @__PURE__ */ jsx("div", {
|
|
477
|
+
className: "truncate text-xs text-muted-foreground",
|
|
478
|
+
children: ec.preheader
|
|
479
|
+
})
|
|
480
|
+
]
|
|
481
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
482
|
+
className: cn("flex min-h-0 flex-1 flex-col gap-1 overflow-hidden px-3 py-2", FADE_OUT),
|
|
483
|
+
style: {
|
|
484
|
+
background: palette.paper,
|
|
485
|
+
color: palette.ink,
|
|
486
|
+
fontFamily: brand.fontFamily
|
|
487
|
+
},
|
|
488
|
+
children: [hero?.type === "hero" && /* @__PURE__ */ jsx("div", {
|
|
489
|
+
className: "line-clamp-2 shrink-0 text-sm font-bold leading-snug",
|
|
490
|
+
style: { color: palette.accent },
|
|
491
|
+
children: hero.headline
|
|
492
|
+
}), body?.type === "body" && /* @__PURE__ */ jsx("div", {
|
|
493
|
+
className: "text-xs leading-relaxed opacity-75",
|
|
494
|
+
children: body.text
|
|
495
|
+
})]
|
|
496
|
+
})]
|
|
497
|
+
})
|
|
189
498
|
});
|
|
190
499
|
}
|
|
191
500
|
if (format.startsWith("image:")) {
|
|
@@ -196,7 +505,7 @@ function Thumbnail({ spec }) {
|
|
|
196
505
|
alt: "",
|
|
197
506
|
loading: "lazy",
|
|
198
507
|
decoding: "async",
|
|
199
|
-
className: "h-full w-full object-contain"
|
|
508
|
+
className: "h-full w-full object-contain p-2"
|
|
200
509
|
});
|
|
201
510
|
return /* @__PURE__ */ jsx("div", {
|
|
202
511
|
className: "h-full overflow-hidden",
|
|
@@ -218,7 +527,7 @@ function Thumbnail({ spec }) {
|
|
|
218
527
|
alt: "",
|
|
219
528
|
loading: "lazy",
|
|
220
529
|
decoding: "async",
|
|
221
|
-
className: "h-full w-full object-contain"
|
|
530
|
+
className: "h-full w-full object-contain p-2"
|
|
222
531
|
}) : /* @__PURE__ */ jsx("div", {
|
|
223
532
|
className: "flex h-full flex-col gap-1 p-3 text-sm",
|
|
224
533
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -244,14 +553,21 @@ function Thumbnail({ spec }) {
|
|
|
244
553
|
if (format.startsWith("copy:")) {
|
|
245
554
|
const cc = content;
|
|
246
555
|
return /* @__PURE__ */ jsxs("div", {
|
|
247
|
-
className: "flex h-full flex-col gap-
|
|
248
|
-
children: [
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
556
|
+
className: "flex h-full flex-col gap-2 overflow-hidden p-4",
|
|
557
|
+
children: [
|
|
558
|
+
/* @__PURE__ */ jsx("span", {
|
|
559
|
+
className: "shrink-0 text-xs font-medium text-muted-foreground",
|
|
560
|
+
children: COPY_PLATFORM_LABEL[cc.platform] ?? cc.platform
|
|
561
|
+
}),
|
|
562
|
+
cc.headline && /* @__PURE__ */ jsx("div", {
|
|
563
|
+
className: "line-clamp-2 shrink-0 text-base font-semibold leading-snug sm:line-clamp-3",
|
|
564
|
+
children: cc.headline
|
|
565
|
+
}),
|
|
566
|
+
/* @__PURE__ */ jsx("div", {
|
|
567
|
+
className: cn("min-h-0 flex-1 overflow-hidden text-sm leading-relaxed text-muted-foreground [overflow-wrap:anywhere]", FADE_OUT),
|
|
568
|
+
children: cc.body
|
|
569
|
+
})
|
|
570
|
+
]
|
|
255
571
|
});
|
|
256
572
|
}
|
|
257
573
|
return null;
|
|
@@ -281,10 +597,10 @@ function AssetCard({ spec, variantCount, onApprove, onReject, onEdit, onOpen, cl
|
|
|
281
597
|
})]
|
|
282
598
|
}),
|
|
283
599
|
/* @__PURE__ */ jsxs("div", {
|
|
284
|
-
className: "flex items-center gap-2 px-2.5 py-2",
|
|
600
|
+
className: "flex flex-wrap items-center justify-between gap-x-2 gap-y-1 px-2.5 py-2",
|
|
285
601
|
children: [
|
|
286
602
|
/* @__PURE__ */ jsx("span", {
|
|
287
|
-
className: "min-w-0
|
|
603
|
+
className: "min-w-0 truncate text-xs text-muted-foreground",
|
|
288
604
|
children: formatLabel
|
|
289
605
|
}),
|
|
290
606
|
/* @__PURE__ */ jsx(Badge, {
|
|
@@ -325,125 +641,6 @@ function AssetCard({ spec, variantCount, onApprove, onReject, onEdit, onOpen, cl
|
|
|
325
641
|
});
|
|
326
642
|
}
|
|
327
643
|
//#endregion
|
|
328
|
-
//#region src/assets/preview/email-preview.tsx
|
|
329
|
-
function EmailPreview({ content, brand, previewUrl, className }) {
|
|
330
|
-
if (previewUrl) return jsxs("div", {
|
|
331
|
-
className: cn("flex flex-col gap-1", className),
|
|
332
|
-
children: [
|
|
333
|
-
jsx("div", {
|
|
334
|
-
className: "text-xs text-muted-foreground font-medium truncate",
|
|
335
|
-
children: content.subject
|
|
336
|
-
}),
|
|
337
|
-
content.preheader && jsx("div", {
|
|
338
|
-
className: "text-xs text-muted-foreground/60 truncate",
|
|
339
|
-
children: content.preheader
|
|
340
|
-
}),
|
|
341
|
-
jsx("iframe", {
|
|
342
|
-
src: previewUrl,
|
|
343
|
-
className: "w-full rounded border border-border",
|
|
344
|
-
style: {
|
|
345
|
-
height: 480,
|
|
346
|
-
background: "#fff"
|
|
347
|
-
},
|
|
348
|
-
title: "Email preview",
|
|
349
|
-
sandbox: "allow-same-origin"
|
|
350
|
-
})
|
|
351
|
-
]
|
|
352
|
-
});
|
|
353
|
-
return jsxs("div", {
|
|
354
|
-
className: cn("flex flex-col gap-2", className),
|
|
355
|
-
children: [
|
|
356
|
-
jsx("div", {
|
|
357
|
-
className: "text-sm font-semibold truncate",
|
|
358
|
-
children: content.subject
|
|
359
|
-
}),
|
|
360
|
-
content.preheader && jsx("div", {
|
|
361
|
-
className: "text-xs text-muted-foreground truncate",
|
|
362
|
-
children: content.preheader
|
|
363
|
-
}),
|
|
364
|
-
jsx("div", {
|
|
365
|
-
className: "rounded border border-border p-4 space-y-3 overflow-y-auto",
|
|
366
|
-
style: {
|
|
367
|
-
maxHeight: 480,
|
|
368
|
-
fontFamily: brand.fontFamily,
|
|
369
|
-
color: brand.textColor
|
|
370
|
-
},
|
|
371
|
-
children: content.sections.map((section, i) => {
|
|
372
|
-
if (section.type === "hero") return jsxs("div", {
|
|
373
|
-
className: "text-center py-4 space-y-2",
|
|
374
|
-
children: [
|
|
375
|
-
section.imageUrl && jsx("img", {
|
|
376
|
-
src: section.imageUrl,
|
|
377
|
-
alt: "",
|
|
378
|
-
className: "mx-auto max-h-40 object-cover rounded"
|
|
379
|
-
}),
|
|
380
|
-
jsx("div", {
|
|
381
|
-
className: "text-xl font-bold",
|
|
382
|
-
style: { color: brand.primaryColor },
|
|
383
|
-
children: section.headline
|
|
384
|
-
}),
|
|
385
|
-
section.subheadline && jsx("div", {
|
|
386
|
-
className: "text-sm text-muted-foreground",
|
|
387
|
-
children: section.subheadline
|
|
388
|
-
}),
|
|
389
|
-
section.ctaLabel && jsx("a", {
|
|
390
|
-
href: section.ctaUrl ?? "#",
|
|
391
|
-
className: "inline-block px-4 py-2 rounded text-sm font-medium text-white",
|
|
392
|
-
style: { background: brand.primaryColor },
|
|
393
|
-
children: section.ctaLabel
|
|
394
|
-
})
|
|
395
|
-
]
|
|
396
|
-
}, i);
|
|
397
|
-
if (section.type === "body") return jsx("p", {
|
|
398
|
-
className: "text-sm leading-relaxed whitespace-pre-wrap",
|
|
399
|
-
children: section.text
|
|
400
|
-
}, i);
|
|
401
|
-
if (section.type === "feature") return jsxs("div", {
|
|
402
|
-
className: "flex gap-3 items-start",
|
|
403
|
-
children: [section.imageUrl && jsx("img", {
|
|
404
|
-
src: section.imageUrl,
|
|
405
|
-
alt: "",
|
|
406
|
-
className: "w-16 h-16 object-cover rounded shrink-0"
|
|
407
|
-
}), jsxs("div", { children: [jsx("div", {
|
|
408
|
-
className: "text-sm font-semibold",
|
|
409
|
-
children: section.headline
|
|
410
|
-
}), jsx("div", {
|
|
411
|
-
className: "text-xs text-muted-foreground mt-0.5",
|
|
412
|
-
children: section.description
|
|
413
|
-
})] })]
|
|
414
|
-
}, i);
|
|
415
|
-
if (section.type === "testimonial") return jsxs("blockquote", {
|
|
416
|
-
className: "border-l-2 pl-3 italic text-sm text-muted-foreground",
|
|
417
|
-
style: { borderColor: brand.accentColor },
|
|
418
|
-
children: [jsxs("p", { children: [
|
|
419
|
-
"\"",
|
|
420
|
-
section.quote,
|
|
421
|
-
"\""
|
|
422
|
-
] }), jsxs("footer", {
|
|
423
|
-
className: "mt-1 text-xs not-italic font-medium",
|
|
424
|
-
children: [section.author, section.role ? `, ${section.role}` : ""]
|
|
425
|
-
})]
|
|
426
|
-
}, i);
|
|
427
|
-
if (section.type === "cta") return jsxs("div", {
|
|
428
|
-
className: "text-center py-3 space-y-1",
|
|
429
|
-
children: [jsx("a", {
|
|
430
|
-
href: section.url,
|
|
431
|
-
className: "inline-block px-5 py-2.5 rounded font-medium text-white text-sm",
|
|
432
|
-
style: { background: brand.primaryColor },
|
|
433
|
-
children: section.label
|
|
434
|
-
}), section.subtext && jsx("p", {
|
|
435
|
-
className: "text-xs text-muted-foreground",
|
|
436
|
-
children: section.subtext
|
|
437
|
-
})]
|
|
438
|
-
}, i);
|
|
439
|
-
if (section.type === "divider") return jsx("hr", { className: "border-border" }, i);
|
|
440
|
-
return null;
|
|
441
|
-
})
|
|
442
|
-
})
|
|
443
|
-
]
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
//#endregion
|
|
447
644
|
//#region src/assets/preview/video-preview.tsx
|
|
448
645
|
function VideoPreview({ content, brand, onRenderRequest, isRendering, className }) {
|
|
449
646
|
if (content.renderedUrl) return /* @__PURE__ */ jsx("div", {
|
|
@@ -534,64 +731,6 @@ function VideoPreview({ content, brand, onRenderRequest, isRendering, className
|
|
|
534
731
|
});
|
|
535
732
|
}
|
|
536
733
|
//#endregion
|
|
537
|
-
//#region src/assets/preview/copy-preview.tsx
|
|
538
|
-
const PLATFORM_LIMITS = {
|
|
539
|
-
instagram: 2200,
|
|
540
|
-
tiktok: 2200,
|
|
541
|
-
x: 280,
|
|
542
|
-
linkedin: 3e3,
|
|
543
|
-
sms: 160,
|
|
544
|
-
"email-subject": 60
|
|
545
|
-
};
|
|
546
|
-
const PLATFORM_LABELS = {
|
|
547
|
-
instagram: "Instagram",
|
|
548
|
-
tiktok: "TikTok",
|
|
549
|
-
x: "X / Twitter",
|
|
550
|
-
linkedin: "LinkedIn",
|
|
551
|
-
sms: "SMS",
|
|
552
|
-
"email-subject": "Email Subject"
|
|
553
|
-
};
|
|
554
|
-
function CopyPreview({ content, className }) {
|
|
555
|
-
const limit = PLATFORM_LIMITS[content.platform];
|
|
556
|
-
const bodyLen = content.body.length;
|
|
557
|
-
const isOverLimit = limit !== null && bodyLen > limit;
|
|
558
|
-
const warningThreshold = limit !== null ? limit * .9 : null;
|
|
559
|
-
const isNearLimit = !isOverLimit && warningThreshold !== null && bodyLen >= warningThreshold;
|
|
560
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
561
|
-
className: cn("flex flex-col gap-2", className),
|
|
562
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
563
|
-
className: "flex items-center justify-between",
|
|
564
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
565
|
-
className: "text-xs font-medium text-muted-foreground",
|
|
566
|
-
children: PLATFORM_LABELS[content.platform]
|
|
567
|
-
}), limit !== null && /* @__PURE__ */ jsxs("span", {
|
|
568
|
-
className: cn("text-xs tabular-nums", isOverLimit ? "text-destructive font-medium" : isNearLimit ? "text-warning" : "text-muted-foreground"),
|
|
569
|
-
children: [
|
|
570
|
-
bodyLen,
|
|
571
|
-
" / ",
|
|
572
|
-
limit
|
|
573
|
-
]
|
|
574
|
-
})]
|
|
575
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
576
|
-
className: "rounded border border-border p-3 space-y-2 bg-card",
|
|
577
|
-
children: [
|
|
578
|
-
content.headline && /* @__PURE__ */ jsx("div", {
|
|
579
|
-
className: "text-sm font-semibold",
|
|
580
|
-
children: content.headline
|
|
581
|
-
}),
|
|
582
|
-
/* @__PURE__ */ jsx("p", {
|
|
583
|
-
className: "text-sm whitespace-pre-wrap leading-relaxed",
|
|
584
|
-
children: content.body
|
|
585
|
-
}),
|
|
586
|
-
content.hashtags && content.hashtags.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
587
|
-
className: "text-sm text-blue-500 flex flex-wrap gap-1",
|
|
588
|
-
children: content.hashtags.map((tag) => /* @__PURE__ */ jsxs("span", { children: ["#", tag] }, tag))
|
|
589
|
-
})
|
|
590
|
-
]
|
|
591
|
-
})]
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
//#endregion
|
|
595
734
|
//#region src/assets/asset-editor.tsx
|
|
596
735
|
function BrandPanel({ brand, onChange }) {
|
|
597
736
|
const [open, setOpen] = React$1.useState(false);
|
|
@@ -1126,4 +1265,4 @@ function ApprovalQueue({ assets, variantCounts = {}, onApprove, onReject, onEdit
|
|
|
1126
1265
|
});
|
|
1127
1266
|
}
|
|
1128
1267
|
//#endregion
|
|
1129
|
-
export { ASSET_FORMAT_LABEL, ASSET_STATUS_LABEL, ApprovalQueue, AssetCard, AssetEditor, CopyPreview, EmailPreview, ImagePreview, VideoPreview, imageOnlyUrl, videoPosterUrl };
|
|
1268
|
+
export { ASSET_FORMAT_LABEL, ASSET_STATUS_LABEL, ApprovalQueue, AssetCard, AssetEditor, COPY_PLATFORM_LABEL, CopyPreview, EmailPreview, ImagePreview, VideoPreview, emailPalette, imageOnlyUrl, videoPosterUrl };
|
package/dist/globals.css
CHANGED
|
@@ -1007,9 +1007,6 @@
|
|
|
1007
1007
|
.h-screen {
|
|
1008
1008
|
height: 100vh;
|
|
1009
1009
|
}
|
|
1010
|
-
.max-h-40 {
|
|
1011
|
-
max-height: calc(var(--spacing) * 40);
|
|
1012
|
-
}
|
|
1013
1010
|
.max-h-64 {
|
|
1014
1011
|
max-height: calc(var(--spacing) * 64);
|
|
1015
1012
|
}
|
|
@@ -2184,9 +2181,9 @@
|
|
|
2184
2181
|
border-left-style: var(--tw-border-style);
|
|
2185
2182
|
border-left-width: 0px;
|
|
2186
2183
|
}
|
|
2187
|
-
.border-l-
|
|
2184
|
+
.border-l-4 {
|
|
2188
2185
|
border-left-style: var(--tw-border-style);
|
|
2189
|
-
border-left-width:
|
|
2186
|
+
border-left-width: 4px;
|
|
2190
2187
|
}
|
|
2191
2188
|
.border-dashed {
|
|
2192
2189
|
--tw-border-style: dashed;
|
|
@@ -3002,6 +2999,9 @@
|
|
|
3002
2999
|
--tw-gradient-to: transparent;
|
|
3003
3000
|
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
|
3004
3001
|
}
|
|
3002
|
+
.\[mask-image\:linear-gradient\(to_bottom\,black_75\%\,transparent\)\] {
|
|
3003
|
+
mask-image: linear-gradient(to bottom,black 75%,transparent);
|
|
3004
|
+
}
|
|
3005
3005
|
.fill-current {
|
|
3006
3006
|
fill: currentcolor;
|
|
3007
3007
|
}
|
|
@@ -3747,9 +3747,6 @@
|
|
|
3747
3747
|
.text-blue-400 {
|
|
3748
3748
|
color: var(--color-blue-400);
|
|
3749
3749
|
}
|
|
3750
|
-
.text-blue-500 {
|
|
3751
|
-
color: var(--color-blue-500);
|
|
3752
|
-
}
|
|
3753
3750
|
.text-border {
|
|
3754
3751
|
color: hsl(var(--border));
|
|
3755
3752
|
}
|
|
@@ -3894,13 +3891,13 @@
|
|
|
3894
3891
|
.italic {
|
|
3895
3892
|
font-style: italic;
|
|
3896
3893
|
}
|
|
3897
|
-
.not-italic {
|
|
3898
|
-
font-style: normal;
|
|
3899
|
-
}
|
|
3900
3894
|
.tabular-nums {
|
|
3901
3895
|
--tw-numeric-spacing: tabular-nums;
|
|
3902
3896
|
font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
|
|
3903
3897
|
}
|
|
3898
|
+
.no-underline {
|
|
3899
|
+
text-decoration-line: none;
|
|
3900
|
+
}
|
|
3904
3901
|
.underline {
|
|
3905
3902
|
text-decoration-line: underline;
|
|
3906
3903
|
}
|
|
@@ -5276,6 +5273,12 @@
|
|
|
5276
5273
|
-webkit-box-orient: vertical;
|
|
5277
5274
|
-webkit-line-clamp: 1;
|
|
5278
5275
|
}
|
|
5276
|
+
.sm\:line-clamp-3 {
|
|
5277
|
+
overflow: hidden;
|
|
5278
|
+
display: -webkit-box;
|
|
5279
|
+
-webkit-box-orient: vertical;
|
|
5280
|
+
-webkit-line-clamp: 3;
|
|
5281
|
+
}
|
|
5279
5282
|
.sm\:grid {
|
|
5280
5283
|
display: grid;
|
|
5281
5284
|
}
|
|
@@ -5376,6 +5379,9 @@
|
|
|
5376
5379
|
.sm\:px-6 {
|
|
5377
5380
|
padding-inline: calc(var(--spacing) * 6);
|
|
5378
5381
|
}
|
|
5382
|
+
.sm\:px-8 {
|
|
5383
|
+
padding-inline: calc(var(--spacing) * 8);
|
|
5384
|
+
}
|
|
5379
5385
|
.sm\:py-1 {
|
|
5380
5386
|
padding-block: var(--spacing);
|
|
5381
5387
|
}
|
package/dist/styles.css
CHANGED
|
@@ -1007,9 +1007,6 @@
|
|
|
1007
1007
|
.h-screen {
|
|
1008
1008
|
height: 100vh;
|
|
1009
1009
|
}
|
|
1010
|
-
.max-h-40 {
|
|
1011
|
-
max-height: calc(var(--spacing) * 40);
|
|
1012
|
-
}
|
|
1013
1010
|
.max-h-64 {
|
|
1014
1011
|
max-height: calc(var(--spacing) * 64);
|
|
1015
1012
|
}
|
|
@@ -2184,9 +2181,9 @@
|
|
|
2184
2181
|
border-left-style: var(--tw-border-style);
|
|
2185
2182
|
border-left-width: 0px;
|
|
2186
2183
|
}
|
|
2187
|
-
.border-l-
|
|
2184
|
+
.border-l-4 {
|
|
2188
2185
|
border-left-style: var(--tw-border-style);
|
|
2189
|
-
border-left-width:
|
|
2186
|
+
border-left-width: 4px;
|
|
2190
2187
|
}
|
|
2191
2188
|
.border-dashed {
|
|
2192
2189
|
--tw-border-style: dashed;
|
|
@@ -3002,6 +2999,9 @@
|
|
|
3002
2999
|
--tw-gradient-to: transparent;
|
|
3003
3000
|
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
|
3004
3001
|
}
|
|
3002
|
+
.\[mask-image\:linear-gradient\(to_bottom\,black_75\%\,transparent\)\] {
|
|
3003
|
+
mask-image: linear-gradient(to bottom,black 75%,transparent);
|
|
3004
|
+
}
|
|
3005
3005
|
.fill-current {
|
|
3006
3006
|
fill: currentcolor;
|
|
3007
3007
|
}
|
|
@@ -3747,9 +3747,6 @@
|
|
|
3747
3747
|
.text-blue-400 {
|
|
3748
3748
|
color: var(--color-blue-400);
|
|
3749
3749
|
}
|
|
3750
|
-
.text-blue-500 {
|
|
3751
|
-
color: var(--color-blue-500);
|
|
3752
|
-
}
|
|
3753
3750
|
.text-border {
|
|
3754
3751
|
color: hsl(var(--border));
|
|
3755
3752
|
}
|
|
@@ -3894,13 +3891,13 @@
|
|
|
3894
3891
|
.italic {
|
|
3895
3892
|
font-style: italic;
|
|
3896
3893
|
}
|
|
3897
|
-
.not-italic {
|
|
3898
|
-
font-style: normal;
|
|
3899
|
-
}
|
|
3900
3894
|
.tabular-nums {
|
|
3901
3895
|
--tw-numeric-spacing: tabular-nums;
|
|
3902
3896
|
font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
|
|
3903
3897
|
}
|
|
3898
|
+
.no-underline {
|
|
3899
|
+
text-decoration-line: none;
|
|
3900
|
+
}
|
|
3904
3901
|
.underline {
|
|
3905
3902
|
text-decoration-line: underline;
|
|
3906
3903
|
}
|
|
@@ -5276,6 +5273,12 @@
|
|
|
5276
5273
|
-webkit-box-orient: vertical;
|
|
5277
5274
|
-webkit-line-clamp: 1;
|
|
5278
5275
|
}
|
|
5276
|
+
.sm\:line-clamp-3 {
|
|
5277
|
+
overflow: hidden;
|
|
5278
|
+
display: -webkit-box;
|
|
5279
|
+
-webkit-box-orient: vertical;
|
|
5280
|
+
-webkit-line-clamp: 3;
|
|
5281
|
+
}
|
|
5279
5282
|
.sm\:grid {
|
|
5280
5283
|
display: grid;
|
|
5281
5284
|
}
|
|
@@ -5376,6 +5379,9 @@
|
|
|
5376
5379
|
.sm\:px-6 {
|
|
5377
5380
|
padding-inline: calc(var(--spacing) * 6);
|
|
5378
5381
|
}
|
|
5382
|
+
.sm\:px-8 {
|
|
5383
|
+
padding-inline: calc(var(--spacing) * 8);
|
|
5384
|
+
}
|
|
5379
5385
|
.sm\:py-1 {
|
|
5380
5386
|
padding-block: var(--spacing);
|
|
5381
5387
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-ui",
|
|
3
|
-
"version": "0.131.
|
|
3
|
+
"version": "0.131.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
|
|
6
6
|
"repository": {
|