@postrun/react 2.9.0 → 2.10.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.
- package/dist/index.cjs +110 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +110 -39
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1899,6 +1899,8 @@ interface ReelPreviewProps {
|
|
|
1899
1899
|
author: InstagramPreviewAuthor;
|
|
1900
1900
|
body: string;
|
|
1901
1901
|
media: readonly ResolvedMedia[];
|
|
1902
|
+
/** Media is referenced but its pixels aren't resolved yet (still processing). */
|
|
1903
|
+
pending?: boolean;
|
|
1902
1904
|
/** The reel's audio label (`settings.audio_name`); defaults to "Original audio". */
|
|
1903
1905
|
audioName?: string;
|
|
1904
1906
|
className?: string;
|
|
@@ -1911,7 +1913,7 @@ interface ReelPreviewProps {
|
|
|
1911
1913
|
* counts). Always dark, like the real Reels surface. The caption uses the shared
|
|
1912
1914
|
* `ExpandableText` fold so the full text is readable (no silent truncation).
|
|
1913
1915
|
*/
|
|
1914
|
-
declare function ReelPreview({ author, body, media, audioName, className, style, }: ReelPreviewProps): react.JSX.Element;
|
|
1916
|
+
declare function ReelPreview({ author, body, media, pending, audioName, className, style, }: ReelPreviewProps): react.JSX.Element;
|
|
1915
1917
|
|
|
1916
1918
|
/**
|
|
1917
1919
|
* Public props for the TikTok post preview — a faithful render of how a post will
|
package/dist/index.d.ts
CHANGED
|
@@ -1899,6 +1899,8 @@ interface ReelPreviewProps {
|
|
|
1899
1899
|
author: InstagramPreviewAuthor;
|
|
1900
1900
|
body: string;
|
|
1901
1901
|
media: readonly ResolvedMedia[];
|
|
1902
|
+
/** Media is referenced but its pixels aren't resolved yet (still processing). */
|
|
1903
|
+
pending?: boolean;
|
|
1902
1904
|
/** The reel's audio label (`settings.audio_name`); defaults to "Original audio". */
|
|
1903
1905
|
audioName?: string;
|
|
1904
1906
|
className?: string;
|
|
@@ -1911,7 +1913,7 @@ interface ReelPreviewProps {
|
|
|
1911
1913
|
* counts). Always dark, like the real Reels surface. The caption uses the shared
|
|
1912
1914
|
* `ExpandableText` fold so the full text is readable (no silent truncation).
|
|
1913
1915
|
*/
|
|
1914
|
-
declare function ReelPreview({ author, body, media, audioName, className, style, }: ReelPreviewProps): react.JSX.Element;
|
|
1916
|
+
declare function ReelPreview({ author, body, media, pending, audioName, className, style, }: ReelPreviewProps): react.JSX.Element;
|
|
1915
1917
|
|
|
1916
1918
|
/**
|
|
1917
1919
|
* Public props for the TikTok post preview — a faithful render of how a post will
|
package/dist/index.js
CHANGED
|
@@ -1374,6 +1374,7 @@ function XPostPreviewImpl({
|
|
|
1374
1374
|
resolvedQuotedMedia,
|
|
1375
1375
|
replyToHandle
|
|
1376
1376
|
]);
|
|
1377
|
+
const isEmpty = !variant.body && resolvedMedia.length === 0 && !variant.settings?.poll && !tweet.quoted_tweet;
|
|
1377
1378
|
return /* @__PURE__ */ jsx(
|
|
1378
1379
|
"div",
|
|
1379
1380
|
{
|
|
@@ -1383,7 +1384,7 @@ function XPostPreviewImpl({
|
|
|
1383
1384
|
children: /* @__PURE__ */ jsxs(TweetContainer, { children: [
|
|
1384
1385
|
/* @__PURE__ */ jsx(TweetHeader, { tweet, components }),
|
|
1385
1386
|
tweet.in_reply_to_screen_name ? /* @__PURE__ */ jsx(TweetInReplyTo, { tweet }) : null,
|
|
1386
|
-
/* @__PURE__ */ jsx(TweetBody, { tweet }),
|
|
1387
|
+
isEmpty ? /* @__PURE__ */ jsx(EmptyBody, {}) : /* @__PURE__ */ jsx(TweetBody, { tweet }),
|
|
1387
1388
|
tweet.mediaDetails?.length ? /* @__PURE__ */ jsx(TweetMedia, { tweet, components }) : null,
|
|
1388
1389
|
variant.settings?.poll ? /* @__PURE__ */ jsx(XPoll, { poll: variant.settings.poll }) : null,
|
|
1389
1390
|
tweet.quoted_tweet ? /* @__PURE__ */ jsx(QuotedTweet, { tweet: tweet.quoted_tweet }) : null,
|
|
@@ -1392,6 +1393,18 @@ function XPostPreviewImpl({
|
|
|
1392
1393
|
}
|
|
1393
1394
|
);
|
|
1394
1395
|
}
|
|
1396
|
+
function EmptyBody() {
|
|
1397
|
+
return /* @__PURE__ */ jsx("p", { style: emptyBodyStyle, children: "What's happening?" });
|
|
1398
|
+
}
|
|
1399
|
+
var emptyBodyStyle = {
|
|
1400
|
+
margin: "var(--tweet-body-margin)",
|
|
1401
|
+
fontSize: "var(--tweet-body-font-size)",
|
|
1402
|
+
fontWeight: "var(--tweet-body-font-weight)",
|
|
1403
|
+
lineHeight: "var(--tweet-body-line-height)",
|
|
1404
|
+
color: "var(--tweet-font-color-secondary)",
|
|
1405
|
+
whiteSpace: "pre-wrap",
|
|
1406
|
+
overflowWrap: "break-word"
|
|
1407
|
+
};
|
|
1395
1408
|
var XPostPreview = memo(XPostPreviewImpl);
|
|
1396
1409
|
|
|
1397
1410
|
// src/preview/linkedin/theme.ts
|
|
@@ -1680,12 +1693,13 @@ function ImageMosaic({ media }) {
|
|
|
1680
1693
|
return null;
|
|
1681
1694
|
}
|
|
1682
1695
|
if (media.length === 1) {
|
|
1696
|
+
const ratio = only.width && only.height ? `${only.width} / ${only.height}` : void 0;
|
|
1683
1697
|
return /* @__PURE__ */ jsx(
|
|
1684
1698
|
"img",
|
|
1685
1699
|
{
|
|
1686
1700
|
src: only.src,
|
|
1687
1701
|
alt: only.alt ?? "",
|
|
1688
|
-
style: { width: "100%", height: "auto", display: "block" }
|
|
1702
|
+
style: { width: "100%", height: "auto", display: "block", aspectRatio: ratio }
|
|
1689
1703
|
}
|
|
1690
1704
|
);
|
|
1691
1705
|
}
|
|
@@ -1919,11 +1933,16 @@ function LinkedInPostPreviewImpl({
|
|
|
1919
1933
|
color: varRef(LI_VAR.text),
|
|
1920
1934
|
border: `1px solid ${varRef(LI_VAR.border)}`,
|
|
1921
1935
|
borderRadius: 10,
|
|
1936
|
+
// Pin the width (see InstagramPostPreview): without it the card shrinks to its
|
|
1937
|
+
// content, so an empty post collapses to a fraction of a populated card's width.
|
|
1938
|
+
width: "100%",
|
|
1922
1939
|
maxWidth: 552,
|
|
1940
|
+
boxSizing: "border-box",
|
|
1923
1941
|
overflow: "hidden",
|
|
1924
1942
|
fontFamily: FONT_STACK,
|
|
1925
1943
|
...style
|
|
1926
1944
|
};
|
|
1945
|
+
const hasContent = Boolean(variant.body) || resolvedMedia.length > 0 || Boolean(variant.settings?.content_kind && variant.settings.content_kind !== "text");
|
|
1927
1946
|
return /* @__PURE__ */ jsxs("div", { className, style: cardStyle5, children: [
|
|
1928
1947
|
/* @__PURE__ */ jsx(Header, { author, visibility, time }),
|
|
1929
1948
|
variant.body ? /* @__PURE__ */ jsx("div", { style: { padding: "8px 16px 0" }, children: /* @__PURE__ */ jsx(
|
|
@@ -1935,9 +1954,16 @@ function LinkedInPostPreviewImpl({
|
|
|
1935
1954
|
}
|
|
1936
1955
|
) }) : null,
|
|
1937
1956
|
renderContent(variant, resolvedMedia),
|
|
1957
|
+
hasContent ? null : /* @__PURE__ */ jsx("p", { style: { ...emptyBodyStyle2, color: BODY_COLORS.muted }, children: "What do you want to talk about?" }),
|
|
1938
1958
|
showActions ? /* @__PURE__ */ jsx(EngagementBar, {}) : null
|
|
1939
1959
|
] });
|
|
1940
1960
|
}
|
|
1961
|
+
var emptyBodyStyle2 = {
|
|
1962
|
+
margin: 0,
|
|
1963
|
+
padding: "8px 16px 4px",
|
|
1964
|
+
fontSize: 14,
|
|
1965
|
+
lineHeight: 1.4
|
|
1966
|
+
};
|
|
1941
1967
|
function renderContent(variant, media) {
|
|
1942
1968
|
const settings = variant.settings;
|
|
1943
1969
|
const kind = settings?.content_kind;
|
|
@@ -2094,9 +2120,57 @@ var wrapStyle3 = {
|
|
|
2094
2120
|
lineHeight: 1.4,
|
|
2095
2121
|
color: varRef2(IG_VAR.text)
|
|
2096
2122
|
};
|
|
2097
|
-
function
|
|
2123
|
+
function MediaPlaceholder({
|
|
2124
|
+
label,
|
|
2125
|
+
color,
|
|
2126
|
+
background,
|
|
2127
|
+
shimmer = false
|
|
2128
|
+
}) {
|
|
2129
|
+
return /* @__PURE__ */ jsxs("div", { style: { ...fillStyle, background, color }, children: [
|
|
2130
|
+
shimmer ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2131
|
+
/* @__PURE__ */ jsx("style", { children: SHIMMER_KEYFRAME }),
|
|
2132
|
+
/* @__PURE__ */ jsx("div", { style: shimmerStyle })
|
|
2133
|
+
] }) : null,
|
|
2134
|
+
/* @__PURE__ */ jsx("span", { style: labelStyle, children: label })
|
|
2135
|
+
] });
|
|
2136
|
+
}
|
|
2137
|
+
var SHIMMER_KEYFRAME = "@keyframes pr-media-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}";
|
|
2138
|
+
var fillStyle = {
|
|
2139
|
+
position: "absolute",
|
|
2140
|
+
inset: 0,
|
|
2141
|
+
display: "flex",
|
|
2142
|
+
alignItems: "center",
|
|
2143
|
+
justifyContent: "center",
|
|
2144
|
+
overflow: "hidden"
|
|
2145
|
+
};
|
|
2146
|
+
var labelStyle = {
|
|
2147
|
+
position: "relative",
|
|
2148
|
+
zIndex: 1,
|
|
2149
|
+
fontSize: 13,
|
|
2150
|
+
letterSpacing: 0.1
|
|
2151
|
+
};
|
|
2152
|
+
var shimmerStyle = {
|
|
2153
|
+
position: "absolute",
|
|
2154
|
+
inset: 0,
|
|
2155
|
+
background: "linear-gradient(90deg, transparent 0%, color-mix(in srgb, currentColor 12%, transparent) 50%, transparent 100%)",
|
|
2156
|
+
backgroundSize: "200% 100%",
|
|
2157
|
+
animation: "pr-media-shimmer 1.4s ease-in-out infinite"
|
|
2158
|
+
};
|
|
2159
|
+
function FeedMedia({
|
|
2160
|
+
media,
|
|
2161
|
+
pending = false
|
|
2162
|
+
}) {
|
|
2098
2163
|
if (media.length <= 1) {
|
|
2099
|
-
|
|
2164
|
+
const item = media[0];
|
|
2165
|
+
return /* @__PURE__ */ jsx("div", { style: frameStyle, children: item ? /* @__PURE__ */ jsx(Tile2, { item }) : /* @__PURE__ */ jsx(
|
|
2166
|
+
MediaPlaceholder,
|
|
2167
|
+
{
|
|
2168
|
+
label: pending ? "Processing media\u2026" : "No media yet",
|
|
2169
|
+
color: varRef2(IG_VAR.muted),
|
|
2170
|
+
background: EMPTY_BG,
|
|
2171
|
+
shimmer: pending
|
|
2172
|
+
}
|
|
2173
|
+
) });
|
|
2100
2174
|
}
|
|
2101
2175
|
return /* @__PURE__ */ jsx(Carousel, { media });
|
|
2102
2176
|
}
|
|
@@ -2145,6 +2219,7 @@ var frameStyle = {
|
|
|
2145
2219
|
background: "#000",
|
|
2146
2220
|
overflow: "hidden"
|
|
2147
2221
|
};
|
|
2222
|
+
var EMPTY_BG = "light-dark(#efefef, #1c1c1c)";
|
|
2148
2223
|
var mediaStyle = {
|
|
2149
2224
|
position: "absolute",
|
|
2150
2225
|
inset: 0,
|
|
@@ -2259,6 +2334,7 @@ function ReelPreview({
|
|
|
2259
2334
|
author,
|
|
2260
2335
|
body,
|
|
2261
2336
|
media,
|
|
2337
|
+
pending = false,
|
|
2262
2338
|
audioName,
|
|
2263
2339
|
className,
|
|
2264
2340
|
style
|
|
@@ -2277,7 +2353,15 @@ function ReelPreview({
|
|
|
2277
2353
|
playsInline: true,
|
|
2278
2354
|
style: coverStyle2
|
|
2279
2355
|
}
|
|
2280
|
-
) : /* @__PURE__ */ jsx("img", { src: first.src, alt: first.alt ?? "", style: coverStyle2 }) :
|
|
2356
|
+
) : /* @__PURE__ */ jsx("img", { src: first.src, alt: first.alt ?? "", style: coverStyle2 }) : /* @__PURE__ */ jsx(
|
|
2357
|
+
MediaPlaceholder,
|
|
2358
|
+
{
|
|
2359
|
+
label: pending ? "Processing media\u2026" : "No media yet",
|
|
2360
|
+
color: "rgba(255,255,255,0.55)",
|
|
2361
|
+
background: "transparent",
|
|
2362
|
+
shimmer: pending
|
|
2363
|
+
}
|
|
2364
|
+
),
|
|
2281
2365
|
/* @__PURE__ */ jsx("div", { style: scrimStyle }),
|
|
2282
2366
|
/* @__PURE__ */ jsxs("div", { style: infoStyle, children: [
|
|
2283
2367
|
/* @__PURE__ */ jsxs("div", { style: authorRowStyle, children: [
|
|
@@ -2382,6 +2466,7 @@ function InstagramPostPreviewImpl({
|
|
|
2382
2466
|
);
|
|
2383
2467
|
const settings = variant.settings;
|
|
2384
2468
|
const isReel = variant.post_type === "reel";
|
|
2469
|
+
const pending = (media?.length ?? 0) > 0 && resolvedMedia.length === 0;
|
|
2385
2470
|
if (isReel) {
|
|
2386
2471
|
return /* @__PURE__ */ jsx(
|
|
2387
2472
|
ReelPreview,
|
|
@@ -2389,6 +2474,7 @@ function InstagramPostPreviewImpl({
|
|
|
2389
2474
|
author,
|
|
2390
2475
|
body: variant.body ?? "",
|
|
2391
2476
|
media: resolvedMedia,
|
|
2477
|
+
pending,
|
|
2392
2478
|
audioName: settings?.audio_name,
|
|
2393
2479
|
className,
|
|
2394
2480
|
style
|
|
@@ -2403,14 +2489,20 @@ function InstagramPostPreviewImpl({
|
|
|
2403
2489
|
color: varRef2(IG_VAR.text),
|
|
2404
2490
|
border: `1px solid ${varRef2(IG_VAR.border)}`,
|
|
2405
2491
|
borderRadius: 8,
|
|
2492
|
+
// Fill the container up to IG's feed width. WITHOUT an explicit width the card
|
|
2493
|
+
// shrinks to its content, so an empty post (no caption/media to widen it) would
|
|
2494
|
+
// collapse to a fraction of a populated card's width — a jarring size change as
|
|
2495
|
+
// you type. Pinning width keeps every state the SAME size (zero layout shift).
|
|
2496
|
+
width: "100%",
|
|
2406
2497
|
maxWidth: 470,
|
|
2498
|
+
boxSizing: "border-box",
|
|
2407
2499
|
overflow: "hidden",
|
|
2408
2500
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
|
|
2409
2501
|
...style
|
|
2410
2502
|
};
|
|
2411
2503
|
return /* @__PURE__ */ jsxs("div", { className, style: cardStyle5, children: [
|
|
2412
2504
|
/* @__PURE__ */ jsx(Header2, { author, collaborators }),
|
|
2413
|
-
/* @__PURE__ */ jsx(FeedMedia, { media: resolvedMedia }),
|
|
2505
|
+
/* @__PURE__ */ jsx(FeedMedia, { media: resolvedMedia, pending }),
|
|
2414
2506
|
/* @__PURE__ */ jsx(Actions, {}),
|
|
2415
2507
|
variant.body ? /* @__PURE__ */ jsx("div", { style: { paddingBottom: 12 }, children: /* @__PURE__ */ jsx(Caption, { username: author.username, body: variant.body }) }) : null
|
|
2416
2508
|
] });
|
|
@@ -2435,7 +2527,15 @@ function Media2({
|
|
|
2435
2527
|
}) {
|
|
2436
2528
|
const [first] = media;
|
|
2437
2529
|
if (!first) {
|
|
2438
|
-
return
|
|
2530
|
+
return /* @__PURE__ */ jsx(
|
|
2531
|
+
MediaPlaceholder,
|
|
2532
|
+
{
|
|
2533
|
+
label: pending ? "Processing media\u2026" : "No media yet",
|
|
2534
|
+
color: "rgba(255,255,255,0.55)",
|
|
2535
|
+
background: "linear-gradient(180deg,#1c1c20,#101013)",
|
|
2536
|
+
shimmer: pending
|
|
2537
|
+
}
|
|
2538
|
+
);
|
|
2439
2539
|
}
|
|
2440
2540
|
if (first.kind === "video") {
|
|
2441
2541
|
return /* @__PURE__ */ jsx(
|
|
@@ -2484,17 +2584,6 @@ function PhotoCarousel({ media }) {
|
|
|
2484
2584
|
)) }) : null
|
|
2485
2585
|
] });
|
|
2486
2586
|
}
|
|
2487
|
-
function EmptyMedia() {
|
|
2488
|
-
return /* @__PURE__ */ jsx("div", { style: emptyStyle, children: "No media yet" });
|
|
2489
|
-
}
|
|
2490
|
-
function ProcessingMedia() {
|
|
2491
|
-
return /* @__PURE__ */ jsxs("div", { style: emptyStyle, children: [
|
|
2492
|
-
/* @__PURE__ */ jsx("style", { children: SHIMMER_KEYFRAME }),
|
|
2493
|
-
/* @__PURE__ */ jsx("div", { style: shimmerStyle }),
|
|
2494
|
-
/* @__PURE__ */ jsx("span", { style: { position: "relative", zIndex: 1 }, children: "Processing media\u2026" })
|
|
2495
|
-
] });
|
|
2496
|
-
}
|
|
2497
|
-
var SHIMMER_KEYFRAME = `@keyframes pr-tt-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}`;
|
|
2498
2587
|
var coverStyle3 = {
|
|
2499
2588
|
position: "absolute",
|
|
2500
2589
|
inset: 0,
|
|
@@ -2533,24 +2622,6 @@ var dotStyle2 = {
|
|
|
2533
2622
|
background: "#fff",
|
|
2534
2623
|
transition: "opacity 160ms ease"
|
|
2535
2624
|
};
|
|
2536
|
-
var emptyStyle = {
|
|
2537
|
-
position: "absolute",
|
|
2538
|
-
inset: 0,
|
|
2539
|
-
display: "flex",
|
|
2540
|
-
alignItems: "center",
|
|
2541
|
-
justifyContent: "center",
|
|
2542
|
-
color: "rgba(255,255,255,0.55)",
|
|
2543
|
-
fontSize: 13,
|
|
2544
|
-
background: "linear-gradient(180deg,#1c1c20,#101013)",
|
|
2545
|
-
overflow: "hidden"
|
|
2546
|
-
};
|
|
2547
|
-
var shimmerStyle = {
|
|
2548
|
-
position: "absolute",
|
|
2549
|
-
inset: 0,
|
|
2550
|
-
background: "linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.06) 50%, rgba(255,255,255,0) 100%)",
|
|
2551
|
-
backgroundSize: "200% 100%",
|
|
2552
|
-
animation: "pr-tt-shimmer 1.4s ease-in-out infinite"
|
|
2553
|
-
};
|
|
2554
2625
|
var Icon = ({
|
|
2555
2626
|
size = 24,
|
|
2556
2627
|
viewBox,
|
|
@@ -2798,7 +2869,7 @@ var discImgStyle = {
|
|
|
2798
2869
|
borderRadius: "50%",
|
|
2799
2870
|
objectFit: "cover"
|
|
2800
2871
|
};
|
|
2801
|
-
var KEYFRAMES = `@keyframes pr-tt-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
|
|
2872
|
+
var KEYFRAMES = `@keyframes pr-tt-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}`;
|
|
2802
2873
|
var TikTokPostPreview = memo(TikTokPostPreviewImpl);
|
|
2803
2874
|
|
|
2804
2875
|
// src/preview/tiktok/theme.ts
|
|
@@ -3020,7 +3091,7 @@ function TikTokCaptionField({
|
|
|
3020
3091
|
const over = count > max;
|
|
3021
3092
|
return /* @__PURE__ */ jsxs("div", { className, style: { ...wrapStyle5, ...style }, children: [
|
|
3022
3093
|
/* @__PURE__ */ jsxs("div", { style: labelRowStyle, children: [
|
|
3023
|
-
/* @__PURE__ */ jsx("label", { htmlFor: id, style:
|
|
3094
|
+
/* @__PURE__ */ jsx("label", { htmlFor: id, style: labelStyle2, children: "Caption" }),
|
|
3024
3095
|
/* @__PURE__ */ jsxs(
|
|
3025
3096
|
"span",
|
|
3026
3097
|
{
|
|
@@ -3063,7 +3134,7 @@ var labelRowStyle = {
|
|
|
3063
3134
|
alignItems: "baseline",
|
|
3064
3135
|
justifyContent: "space-between"
|
|
3065
3136
|
};
|
|
3066
|
-
var
|
|
3137
|
+
var labelStyle2 = {
|
|
3067
3138
|
fontSize: 13,
|
|
3068
3139
|
fontWeight: 600,
|
|
3069
3140
|
color: "inherit"
|