@postrun/react 2.4.0 → 2.6.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 CHANGED
@@ -10,8 +10,8 @@ var pLimit = require('p-limit');
10
10
  var pRetry = require('p-retry');
11
11
  var axios = require('axios');
12
12
  var reactTweet = require('react-tweet');
13
- var fi = require('react-icons/fi');
14
13
  var jsxRuntime = require('react/jsx-runtime');
14
+ var fi = require('react-icons/fi');
15
15
  var twitterText = require('twitter-text');
16
16
  var lu = require('react-icons/lu');
17
17
  var useEmblaCarousel = require('embla-carousel-react');
@@ -1040,6 +1040,37 @@ function useResolvedMedia(media, altFallbacks, altSignature) {
1040
1040
  [signature, altSignature, objectUrls]
1041
1041
  );
1042
1042
  }
1043
+ function XPoll({ poll }) {
1044
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: wrapStyle, children: [
1045
+ poll.options.map((option, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: optionStyle, children: option }, `${option}-${i}`)),
1046
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: footerStyle, children: [
1047
+ "0 votes \xB7 ",
1048
+ js.xPollDurationLabel(poll.duration_minutes)
1049
+ ] })
1050
+ ] });
1051
+ }
1052
+ var BLUE = "var(--tweet-color-blue-primary, #1d9bf0)";
1053
+ var MUTED = "var(--tweet-color-gray-secondary, #536471)";
1054
+ var wrapStyle = {
1055
+ display: "flex",
1056
+ flexDirection: "column",
1057
+ gap: 8,
1058
+ marginTop: 12
1059
+ };
1060
+ var optionStyle = {
1061
+ border: `1px solid ${BLUE}`,
1062
+ color: BLUE,
1063
+ borderRadius: 999,
1064
+ padding: "8px 16px",
1065
+ textAlign: "center",
1066
+ fontSize: 15,
1067
+ fontWeight: 700
1068
+ };
1069
+ var footerStyle = {
1070
+ fontSize: 13,
1071
+ color: MUTED,
1072
+ marginTop: 2
1073
+ };
1043
1074
  var ROW = {
1044
1075
  display: "flex",
1045
1076
  justifyContent: "space-between",
@@ -1280,6 +1311,7 @@ function XPostPreviewImpl({
1280
1311
  tweet.in_reply_to_screen_name ? /* @__PURE__ */ jsxRuntime.jsx(reactTweet.TweetInReplyTo, { tweet }) : null,
1281
1312
  /* @__PURE__ */ jsxRuntime.jsx(reactTweet.TweetBody, { tweet }),
1282
1313
  tweet.mediaDetails?.length ? /* @__PURE__ */ jsxRuntime.jsx(reactTweet.TweetMedia, { tweet, components }) : null,
1314
+ variant.settings?.poll ? /* @__PURE__ */ jsxRuntime.jsx(XPoll, { poll: variant.settings.poll }) : null,
1283
1315
  tweet.quoted_tweet ? /* @__PURE__ */ jsxRuntime.jsx(reactTweet.QuotedTweet, { tweet: tweet.quoted_tweet }) : null,
1284
1316
  showActions ? /* @__PURE__ */ jsxRuntime.jsx(XPreviewActions, {}) : null
1285
1317
  ] })
@@ -1342,6 +1374,111 @@ function useIsDark(theme) {
1342
1374
  }
1343
1375
  return theme === "dark";
1344
1376
  }
1377
+ function domainOf(source) {
1378
+ try {
1379
+ return new URL(source).hostname.replace(/^www\./, "");
1380
+ } catch {
1381
+ return source;
1382
+ }
1383
+ }
1384
+ function ArticleCard({ article, thumbnail }) {
1385
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardStyle, children: [
1386
+ thumbnail ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: thumbnail.src, alt: thumbnail.alt ?? "", style: thumbStyle }) : null,
1387
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: metaStyle, children: [
1388
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: domainStyle, children: domainOf(article.source) }),
1389
+ article.title ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: titleStyle, children: article.title }) : null,
1390
+ article.description ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: descStyle, children: article.description }) : null
1391
+ ] })
1392
+ ] });
1393
+ }
1394
+ var cardStyle = {
1395
+ border: `1px solid ${varRef(LI_VAR.border)}`,
1396
+ borderRadius: 8,
1397
+ overflow: "hidden"
1398
+ };
1399
+ var thumbStyle = {
1400
+ width: "100%",
1401
+ display: "block",
1402
+ aspectRatio: "1.91 / 1",
1403
+ objectFit: "cover"
1404
+ };
1405
+ var metaStyle = {
1406
+ padding: "8px 12px",
1407
+ display: "flex",
1408
+ flexDirection: "column",
1409
+ gap: 2
1410
+ };
1411
+ var domainStyle = {
1412
+ fontSize: 12,
1413
+ color: varRef(LI_VAR.muted)
1414
+ };
1415
+ var titleStyle = {
1416
+ fontSize: 14,
1417
+ fontWeight: 600,
1418
+ color: varRef(LI_VAR.text),
1419
+ lineHeight: 1.3,
1420
+ display: "-webkit-box",
1421
+ WebkitLineClamp: 2,
1422
+ WebkitBoxOrient: "vertical",
1423
+ overflow: "hidden"
1424
+ };
1425
+ var descStyle = {
1426
+ fontSize: 12,
1427
+ color: varRef(LI_VAR.muted),
1428
+ lineHeight: 1.3,
1429
+ display: "-webkit-box",
1430
+ WebkitLineClamp: 1,
1431
+ WebkitBoxOrient: "vertical",
1432
+ overflow: "hidden"
1433
+ };
1434
+ function DocumentCard({ document, cover }) {
1435
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardStyle2, children: [
1436
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: pageStyle, children: cover ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: cover.src, alt: cover.alt ?? "", style: coverStyle }) : /* @__PURE__ */ jsxRuntime.jsx(fi.FiFileText, { size: 56, "aria-hidden": true, style: { opacity: 0.5 } }) }),
1437
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: barStyle, children: [
1438
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: titleStyle2, children: document.title }),
1439
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: kindStyle, children: "Document" })
1440
+ ] })
1441
+ ] });
1442
+ }
1443
+ var cardStyle2 = {
1444
+ border: `1px solid ${varRef(LI_VAR.border)}`,
1445
+ borderRadius: 8,
1446
+ overflow: "hidden"
1447
+ };
1448
+ var pageStyle = {
1449
+ position: "relative",
1450
+ aspectRatio: "4 / 3",
1451
+ background: "rgba(127,127,127,0.12)",
1452
+ display: "grid",
1453
+ placeItems: "center",
1454
+ color: varRef(LI_VAR.muted)
1455
+ };
1456
+ var coverStyle = {
1457
+ width: "100%",
1458
+ height: "100%",
1459
+ objectFit: "cover"
1460
+ };
1461
+ var barStyle = {
1462
+ background: "rgba(0,0,0,0.85)",
1463
+ color: "#fff",
1464
+ padding: "10px 14px",
1465
+ display: "flex",
1466
+ flexDirection: "column",
1467
+ gap: 1
1468
+ };
1469
+ var titleStyle2 = {
1470
+ fontSize: 14,
1471
+ fontWeight: 600,
1472
+ lineHeight: 1.3,
1473
+ display: "-webkit-box",
1474
+ WebkitLineClamp: 2,
1475
+ WebkitBoxOrient: "vertical",
1476
+ overflow: "hidden"
1477
+ };
1478
+ var kindStyle = {
1479
+ fontSize: 12,
1480
+ color: "rgba(255,255,255,0.7)"
1481
+ };
1345
1482
  var ROW2 = {
1346
1483
  display: "flex",
1347
1484
  justifyContent: "space-around",
@@ -1495,11 +1632,11 @@ function Tile({
1495
1632
  ] });
1496
1633
  }
1497
1634
  function ImageMosaic({ media }) {
1498
- if (media.length === 0) {
1635
+ const [only] = media;
1636
+ if (!only) {
1499
1637
  return null;
1500
1638
  }
1501
1639
  if (media.length === 1) {
1502
- const only = media[0];
1503
1640
  return /* @__PURE__ */ jsxRuntime.jsx(
1504
1641
  "img",
1505
1642
  {
@@ -1545,6 +1682,48 @@ function Media({ media }) {
1545
1682
  const images = media.filter((item) => item.kind === "image");
1546
1683
  return /* @__PURE__ */ jsxRuntime.jsx(ImageMosaic, { media: images });
1547
1684
  }
1685
+ function Poll({ poll }) {
1686
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: wrapStyle2, children: [
1687
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: questionStyle, children: poll.question }),
1688
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: optionsStyle, children: poll.options.map((option, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: optionStyle2, children: option }, `${option}-${i}`)) }),
1689
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: footerStyle2, children: [
1690
+ "0 votes \u2022 ",
1691
+ js.linkedinPollDurationLabel(poll.duration)
1692
+ ] })
1693
+ ] });
1694
+ }
1695
+ var wrapStyle2 = {
1696
+ border: `1px solid ${varRef(LI_VAR.border)}`,
1697
+ borderRadius: 8,
1698
+ padding: 12,
1699
+ display: "flex",
1700
+ flexDirection: "column",
1701
+ gap: 10
1702
+ };
1703
+ var questionStyle = {
1704
+ fontSize: 14,
1705
+ fontWeight: 600,
1706
+ color: varRef(LI_VAR.text),
1707
+ lineHeight: 1.35
1708
+ };
1709
+ var optionsStyle = {
1710
+ display: "flex",
1711
+ flexDirection: "column",
1712
+ gap: 8
1713
+ };
1714
+ var optionStyle2 = {
1715
+ border: `1px solid ${varRef(LI_VAR.accent)}`,
1716
+ borderRadius: 999,
1717
+ padding: "8px 16px",
1718
+ textAlign: "center",
1719
+ fontSize: 14,
1720
+ fontWeight: 600,
1721
+ color: varRef(LI_VAR.accent)
1722
+ };
1723
+ var footerStyle2 = {
1724
+ fontSize: 12,
1725
+ color: varRef(LI_VAR.muted)
1726
+ };
1548
1727
  var FOLD_CHARS = 200;
1549
1728
  var BODY_STYLE = {
1550
1729
  whiteSpace: "pre-wrap",
@@ -1672,7 +1851,7 @@ function LinkedInPostPreviewImpl({
1672
1851
  accent: varRef(LI_VAR.accent),
1673
1852
  muted: varRef(LI_VAR.muted)
1674
1853
  };
1675
- const cardStyle2 = {
1854
+ const cardStyle4 = {
1676
1855
  ...paletteVars(dark),
1677
1856
  background: varRef(LI_VAR.bg),
1678
1857
  color: varRef(LI_VAR.text),
@@ -1683,7 +1862,7 @@ function LinkedInPostPreviewImpl({
1683
1862
  fontFamily: FONT_STACK,
1684
1863
  ...style
1685
1864
  };
1686
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: cardStyle2, children: [
1865
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: cardStyle4, children: [
1687
1866
  /* @__PURE__ */ jsxRuntime.jsx(Header, { author, visibility, time }),
1688
1867
  variant.body ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "8px 16px 0" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1689
1868
  PostBody,
@@ -1693,10 +1872,26 @@ function LinkedInPostPreviewImpl({
1693
1872
  colors: bodyColors
1694
1873
  }
1695
1874
  ) }) : null,
1696
- resolvedMedia.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12 }, children: /* @__PURE__ */ jsxRuntime.jsx(Media, { media: resolvedMedia }) }) : null,
1875
+ renderContent(variant, resolvedMedia),
1697
1876
  showActions ? /* @__PURE__ */ jsxRuntime.jsx(EngagementBar, {}) : null
1698
1877
  ] });
1699
1878
  }
1879
+ function renderContent(variant, media) {
1880
+ const settings = variant.settings;
1881
+ const kind = settings?.content_kind;
1882
+ const [firstMedia] = media;
1883
+ if (kind === "article" && settings?.article) {
1884
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: INSET, children: /* @__PURE__ */ jsxRuntime.jsx(ArticleCard, { article: settings.article, thumbnail: firstMedia }) });
1885
+ }
1886
+ if (kind === "poll" && settings?.poll) {
1887
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: INSET, children: /* @__PURE__ */ jsxRuntime.jsx(Poll, { poll: settings.poll }) });
1888
+ }
1889
+ if (kind === "document" && settings?.document) {
1890
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: INSET, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentCard, { document: settings.document, cover: firstMedia }) });
1891
+ }
1892
+ return media.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12 }, children: /* @__PURE__ */ jsxRuntime.jsx(Media, { media }) }) : null;
1893
+ }
1894
+ var INSET = { padding: "12px 16px 0" };
1700
1895
  var LinkedInPostPreview = react.memo(LinkedInPostPreviewImpl);
1701
1896
  var LINK_COLOR = "#8ab4ff";
1702
1897
  var TOKEN = /([#@][\p{L}\p{N}_.]+)/gu;
@@ -1713,7 +1908,7 @@ function Caption({ body }) {
1713
1908
  setOverflowing(el.scrollHeight > el.clientHeight + 1);
1714
1909
  }, [body, expanded]);
1715
1910
  const parts = body.split(TOKEN);
1716
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: wrapStyle, children: [
1911
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: wrapStyle3, children: [
1717
1912
  /* @__PURE__ */ jsxRuntime.jsx("div", { ref, style: expanded ? expandedTextStyle : clampedTextStyle, children: parts.map(
1718
1913
  (part, i) => IS_TOKEN.test(part) ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: LINK_COLOR }, children: part }, i) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: part }, i)
1719
1914
  ) }),
@@ -1730,7 +1925,7 @@ function Caption({ body }) {
1730
1925
  ) : null
1731
1926
  ] });
1732
1927
  }
1733
- var wrapStyle = {
1928
+ var wrapStyle3 = {
1734
1929
  fontSize: 14,
1735
1930
  lineHeight: 1.35
1736
1931
  };
@@ -1779,7 +1974,7 @@ function Media2({
1779
1974
  muted: true,
1780
1975
  loop: true,
1781
1976
  playsInline: true,
1782
- style: coverStyle
1977
+ style: coverStyle2
1783
1978
  }
1784
1979
  );
1785
1980
  }
@@ -1806,7 +2001,7 @@ function PhotoCarousel({ media }) {
1806
2001
  };
1807
2002
  }, [emblaApi, sync]);
1808
2003
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "absolute", inset: 0 }, children: [
1809
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: emblaRef, style: viewportStyle, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: media.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: slideStyle, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: m.src, alt: m.alt ?? "", style: coverStyle }) }, `${m.src}-${i}`)) }) }),
2004
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: emblaRef, style: viewportStyle, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: media.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: slideStyle, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: m.src, alt: m.alt ?? "", style: coverStyle2 }) }, `${m.src}-${i}`)) }) }),
1810
2005
  media.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: dotsStyle, children: media.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx(
1811
2006
  "span",
1812
2007
  {
@@ -1825,7 +2020,7 @@ function ProcessingMedia() {
1825
2020
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children: "Processing media\u2026" })
1826
2021
  ] });
1827
2022
  }
1828
- var coverStyle = {
2023
+ var coverStyle2 = {
1829
2024
  position: "absolute",
1830
2025
  inset: 0,
1831
2026
  width: "100%",
@@ -1951,7 +2146,7 @@ function TikTokPostPreviewImpl({
1951
2146
  const label = commercialLabel(variant.settings);
1952
2147
  const isAigc = Boolean(variant.settings?.is_aigc);
1953
2148
  const pending = (media?.length ?? 0) > 0 && resolvedMedia.length === 0;
1954
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...cardStyle, ...style }, children: [
2149
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...cardStyle3, ...style }, children: [
1955
2150
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: KEYFRAMES }),
1956
2151
  /* @__PURE__ */ jsxRuntime.jsx(Media2, { media: resolvedMedia, pending }),
1957
2152
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: scrimStyle }),
@@ -1998,7 +2193,7 @@ function Avatar({ url, name }) {
1998
2193
  function Disc({ url }) {
1999
2194
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: discStyle, children: url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: url, alt: "", style: discImgStyle }) : null });
2000
2195
  }
2001
- var cardStyle = {
2196
+ var cardStyle3 = {
2002
2197
  position: "relative",
2003
2198
  width: "100%",
2004
2199
  maxWidth: 320,
@@ -2185,7 +2380,7 @@ function useIsDark2(theme) {
2185
2380
  }
2186
2381
  return theme === "dark";
2187
2382
  }
2188
- var MUTED = varRef2(TT_VAR.muted);
2383
+ var MUTED2 = varRef2(TT_VAR.muted);
2189
2384
  var BORDER = varRef2(TT_VAR.border);
2190
2385
  var ACCENT = varRef2(TT_VAR.accent);
2191
2386
  var SWITCH_OFF = varRef2(TT_VAR.switchOff);
@@ -2199,7 +2394,7 @@ function Row({
2199
2394
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
2200
2395
  /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
2201
2396
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 14 }, children: label }),
2202
- sublabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: MUTED }, children: sublabel }) : null
2397
+ sublabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: MUTED2 }, children: sublabel }) : null
2203
2398
  ] }),
2204
2399
  control
2205
2400
  ] });
@@ -2307,7 +2502,7 @@ var hintStyle = {
2307
2502
  var noticeStyle = {
2308
2503
  margin: 0,
2309
2504
  fontSize: 12,
2310
- color: MUTED,
2505
+ color: MUTED2,
2311
2506
  lineHeight: 1.4
2312
2507
  };
2313
2508
  var checkRowStyle = {
@@ -2316,7 +2511,7 @@ var checkRowStyle = {
2316
2511
  gap: 10,
2317
2512
  cursor: "pointer"
2318
2513
  };
2319
- var TOKENS = { MUTED, BORDER, ACCENT};
2514
+ var TOKENS = { MUTED: MUTED2, BORDER, ACCENT};
2320
2515
  function AudienceSelect({
2321
2516
  creatorInfo,
2322
2517
  value,
@@ -2373,7 +2568,7 @@ function TikTokCaptionField({
2373
2568
  const max = js.captionMaxFor(postType);
2374
2569
  const count = value.length;
2375
2570
  const over = count > max;
2376
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...wrapStyle2, ...style }, children: [
2571
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...wrapStyle4, ...style }, children: [
2377
2572
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: labelRowStyle, children: [
2378
2573
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, style: labelStyle, children: "Caption" }),
2379
2574
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2407,7 +2602,7 @@ function TikTokCaptionField({
2407
2602
  )
2408
2603
  ] });
2409
2604
  }
2410
- var wrapStyle2 = {
2605
+ var wrapStyle4 = {
2411
2606
  display: "flex",
2412
2607
  flexDirection: "column",
2413
2608
  gap: 6,
@@ -2674,17 +2869,21 @@ Object.defineProperty(exports, "captionMaxFor", {
2674
2869
  enumerable: true,
2675
2870
  get: function () { return js.captionMaxFor; }
2676
2871
  });
2872
+ exports.ArticleCard = ArticleCard;
2677
2873
  exports.AudienceSelect = AudienceSelect;
2678
2874
  exports.CommercialDisclosure = CommercialDisclosure;
2679
2875
  exports.Connect = Connect;
2680
2876
  exports.Declaration = Declaration;
2877
+ exports.DocumentCard = DocumentCard;
2681
2878
  exports.InteractionToggles = InteractionToggles;
2682
2879
  exports.LinkedInPostPreview = LinkedInPostPreview;
2880
+ exports.Poll = Poll;
2683
2881
  exports.PostrunProvider = PostrunProvider;
2684
2882
  exports.TikTokCaptionField = TikTokCaptionField;
2685
2883
  exports.TikTokPostPreview = TikTokPostPreview;
2686
2884
  exports.TikTokPublishPanel = TikTokPublishPanel;
2687
2885
  exports.UploadError = UploadError;
2886
+ exports.XPoll = XPoll;
2688
2887
  exports.XPostPreview = XPostPreview;
2689
2888
  exports.connectionKeys = connectionKeys;
2690
2889
  exports.mediaKeys = mediaKeys;