@automattic/social-previews 2.0.0 → 2.0.1-beta.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.
Files changed (128) hide show
  1. package/dist/cjs/facebook-preview/custom-text.js +4 -3
  2. package/dist/cjs/facebook-preview/custom-text.js.map +1 -1
  3. package/dist/cjs/facebook-preview/helpers.js +2 -4
  4. package/dist/cjs/facebook-preview/helpers.js.map +1 -1
  5. package/dist/cjs/helpers.js +80 -17
  6. package/dist/cjs/helpers.js.map +1 -1
  7. package/dist/cjs/index.js +1 -0
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/instagram-preview/constants.js +6 -0
  10. package/dist/cjs/instagram-preview/constants.js.map +1 -0
  11. package/dist/cjs/instagram-preview/icons/bookmark.js +9 -0
  12. package/dist/cjs/instagram-preview/icons/bookmark.js.map +1 -0
  13. package/dist/cjs/instagram-preview/icons/comment.js +9 -0
  14. package/dist/cjs/instagram-preview/icons/comment.js.map +1 -0
  15. package/dist/cjs/instagram-preview/icons/default-avatar.js +9 -0
  16. package/dist/cjs/instagram-preview/icons/default-avatar.js.map +1 -0
  17. package/dist/cjs/instagram-preview/icons/heart.js +9 -0
  18. package/dist/cjs/instagram-preview/icons/heart.js.map +1 -0
  19. package/dist/cjs/instagram-preview/icons/menu.js +9 -0
  20. package/dist/cjs/instagram-preview/icons/menu.js.map +1 -0
  21. package/dist/cjs/instagram-preview/icons/share.js +9 -0
  22. package/dist/cjs/instagram-preview/icons/share.js.map +1 -0
  23. package/dist/cjs/instagram-preview/index.js +6 -0
  24. package/dist/cjs/instagram-preview/index.js.map +1 -0
  25. package/dist/cjs/instagram-preview/post-preview.js +25 -0
  26. package/dist/cjs/instagram-preview/post-preview.js.map +1 -0
  27. package/dist/cjs/instagram-preview/previews.js +15 -0
  28. package/dist/cjs/instagram-preview/previews.js.map +1 -0
  29. package/dist/cjs/instagram-preview/style.scss +102 -0
  30. package/dist/cjs/instagram-preview/types.js +3 -0
  31. package/dist/cjs/instagram-preview/types.js.map +1 -0
  32. package/dist/cjs/linkedin-preview/post-preview.js +5 -10
  33. package/dist/cjs/linkedin-preview/post-preview.js.map +1 -1
  34. package/dist/cjs/twitter-preview/post-preview.js +1 -1
  35. package/dist/cjs/twitter-preview/post-preview.js.map +1 -1
  36. package/dist/cjs/twitter-preview/text.js +1 -6
  37. package/dist/cjs/twitter-preview/text.js.map +1 -1
  38. package/dist/esm/facebook-preview/custom-text.js +6 -5
  39. package/dist/esm/facebook-preview/custom-text.js.map +1 -1
  40. package/dist/esm/facebook-preview/helpers.js +1 -2
  41. package/dist/esm/facebook-preview/helpers.js.map +1 -1
  42. package/dist/esm/helpers.js +79 -16
  43. package/dist/esm/helpers.js.map +1 -1
  44. package/dist/esm/index.js +1 -0
  45. package/dist/esm/index.js.map +1 -1
  46. package/dist/esm/instagram-preview/constants.js +3 -0
  47. package/dist/esm/instagram-preview/constants.js.map +1 -0
  48. package/dist/esm/instagram-preview/icons/bookmark.js +5 -0
  49. package/dist/esm/instagram-preview/icons/bookmark.js.map +1 -0
  50. package/dist/esm/instagram-preview/icons/comment.js +5 -0
  51. package/dist/esm/instagram-preview/icons/comment.js.map +1 -0
  52. package/dist/esm/instagram-preview/icons/default-avatar.js +5 -0
  53. package/dist/esm/instagram-preview/icons/default-avatar.js.map +1 -0
  54. package/dist/esm/instagram-preview/icons/heart.js +5 -0
  55. package/dist/esm/instagram-preview/icons/heart.js.map +1 -0
  56. package/dist/esm/instagram-preview/icons/menu.js +5 -0
  57. package/dist/esm/instagram-preview/icons/menu.js.map +1 -0
  58. package/dist/esm/instagram-preview/icons/share.js +5 -0
  59. package/dist/esm/instagram-preview/icons/share.js.map +1 -0
  60. package/dist/esm/instagram-preview/index.js +3 -0
  61. package/dist/esm/instagram-preview/index.js.map +1 -0
  62. package/dist/esm/instagram-preview/post-preview.js +21 -0
  63. package/dist/esm/instagram-preview/post-preview.js.map +1 -0
  64. package/dist/esm/instagram-preview/previews.js +10 -0
  65. package/dist/esm/instagram-preview/previews.js.map +1 -0
  66. package/dist/esm/instagram-preview/style.scss +102 -0
  67. package/dist/esm/instagram-preview/types.js +2 -0
  68. package/dist/esm/instagram-preview/types.js.map +1 -0
  69. package/dist/esm/linkedin-preview/post-preview.js +5 -10
  70. package/dist/esm/linkedin-preview/post-preview.js.map +1 -1
  71. package/dist/esm/twitter-preview/post-preview.js +1 -1
  72. package/dist/esm/twitter-preview/post-preview.js.map +1 -1
  73. package/dist/esm/twitter-preview/text.js +1 -6
  74. package/dist/esm/twitter-preview/text.js.map +1 -1
  75. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  76. package/dist/tsconfig.tsbuildinfo +1 -1
  77. package/dist/types/facebook-preview/custom-text.d.ts.map +1 -1
  78. package/dist/types/facebook-preview/helpers.d.ts +1 -1
  79. package/dist/types/facebook-preview/helpers.d.ts.map +1 -1
  80. package/dist/types/helpers.d.ts +5 -2
  81. package/dist/types/helpers.d.ts.map +1 -1
  82. package/dist/types/index.d.ts +1 -0
  83. package/dist/types/index.d.ts.map +1 -1
  84. package/dist/types/instagram-preview/constants.d.ts +3 -0
  85. package/dist/types/instagram-preview/constants.d.ts.map +1 -0
  86. package/dist/types/instagram-preview/icons/bookmark.d.ts +2 -0
  87. package/dist/types/instagram-preview/icons/bookmark.d.ts.map +1 -0
  88. package/dist/types/instagram-preview/icons/comment.d.ts +2 -0
  89. package/dist/types/instagram-preview/icons/comment.d.ts.map +1 -0
  90. package/dist/types/instagram-preview/icons/default-avatar.d.ts +2 -0
  91. package/dist/types/instagram-preview/icons/default-avatar.d.ts.map +1 -0
  92. package/dist/types/instagram-preview/icons/heart.d.ts +2 -0
  93. package/dist/types/instagram-preview/icons/heart.d.ts.map +1 -0
  94. package/dist/types/instagram-preview/icons/menu.d.ts +2 -0
  95. package/dist/types/instagram-preview/icons/menu.d.ts.map +1 -0
  96. package/dist/types/instagram-preview/icons/share.d.ts +2 -0
  97. package/dist/types/instagram-preview/icons/share.d.ts.map +1 -0
  98. package/dist/types/instagram-preview/index.d.ts +3 -0
  99. package/dist/types/instagram-preview/index.d.ts.map +1 -0
  100. package/dist/types/instagram-preview/post-preview.d.ts +4 -0
  101. package/dist/types/instagram-preview/post-preview.d.ts.map +1 -0
  102. package/dist/types/instagram-preview/previews.d.ts +3 -0
  103. package/dist/types/instagram-preview/previews.d.ts.map +1 -0
  104. package/dist/types/instagram-preview/types.d.ts +8 -0
  105. package/dist/types/instagram-preview/types.d.ts.map +1 -0
  106. package/dist/types/linkedin-preview/post-preview.d.ts.map +1 -1
  107. package/dist/types/twitter-preview/text.d.ts.map +1 -1
  108. package/package.json +1 -1
  109. package/src/facebook-preview/custom-text.tsx +8 -6
  110. package/src/facebook-preview/helpers.ts +1 -7
  111. package/src/helpers.tsx +186 -0
  112. package/src/index.ts +1 -0
  113. package/src/instagram-preview/constants.tsx +2 -0
  114. package/src/instagram-preview/icons/bookmark.tsx +21 -0
  115. package/src/instagram-preview/icons/comment.tsx +20 -0
  116. package/src/instagram-preview/icons/default-avatar.tsx +10 -0
  117. package/src/instagram-preview/icons/heart.tsx +14 -0
  118. package/src/instagram-preview/icons/menu.tsx +24 -0
  119. package/src/instagram-preview/icons/share.tsx +30 -0
  120. package/src/instagram-preview/index.tsx +2 -0
  121. package/src/instagram-preview/post-preview.tsx +71 -0
  122. package/src/instagram-preview/previews.tsx +33 -0
  123. package/src/instagram-preview/style.scss +102 -0
  124. package/src/instagram-preview/types.ts +9 -0
  125. package/src/linkedin-preview/post-preview.tsx +7 -12
  126. package/src/twitter-preview/post-preview.tsx +1 -1
  127. package/src/twitter-preview/text.tsx +3 -9
  128. package/src/helpers.ts +0 -107
@@ -0,0 +1,102 @@
1
+
2
+
3
+ .instagram-preview {
4
+ &__wrapper {
5
+ padding: 20px;
6
+ background-color: #fff;
7
+ margin-inline: auto;
8
+ max-width: clamp(200px, 100%, 555px);
9
+ }
10
+
11
+ // When the preview is in a section of all previews
12
+ &__section &__wrapper {
13
+ padding: 0;
14
+ }
15
+
16
+ &__section.social-preview__section {
17
+ width: clamp(200px, 100%, 555px);
18
+ }
19
+
20
+ &__container {
21
+
22
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
23
+ overflow: hidden;
24
+ }
25
+
26
+ &__header {
27
+
28
+ padding: 0.5rem 1rem;
29
+ display: flex;
30
+ gap: 0.5rem;
31
+
32
+ &--avatar {
33
+ display: flex;
34
+ align-items: center;
35
+ max-width: 32px;
36
+ max-height: 32px;
37
+ }
38
+
39
+ &--avatar img {
40
+ width: 100%;
41
+ height: 100%;
42
+ border-radius: 50%;
43
+ }
44
+
45
+ &--profile {
46
+ display: flex;
47
+ align-items: center;
48
+ justify-content: space-between;
49
+ flex-grow: 1;
50
+ }
51
+
52
+ &--profile-name {
53
+ font-weight: 700;
54
+ }
55
+ }
56
+
57
+ &__media {
58
+ display: flex;
59
+
60
+ &--image {
61
+ width: 100%;
62
+ object-fit: cover;
63
+ }
64
+ }
65
+
66
+ &__content {
67
+ display: flex;
68
+ flex-direction: column;
69
+ gap: 0.5rem;
70
+ padding: 0.5rem 1rem;
71
+
72
+ a {
73
+ text-decoration: none;
74
+ color: rgb(0, 55, 107);
75
+ }
76
+
77
+ &--actions {
78
+ display: flex;
79
+ justify-content: space-between;
80
+ }
81
+
82
+ &--actions-primary {
83
+ display: flex;
84
+ align-items: center;
85
+ gap: 1rem;
86
+ }
87
+
88
+ &--name {
89
+ font-weight: 600;
90
+ display: inline;
91
+ }
92
+
93
+ &--text {
94
+ display: inline;
95
+ }
96
+
97
+ &--footer {
98
+ font-weight: 400;
99
+ color: rgb(115, 115, 115);
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,9 @@
1
+ import { SocialPreviewBaseProps, SocialPreviewsBaseProps } from '../types';
2
+
3
+ export type InstagramPreviewProps = Pick< SocialPreviewBaseProps, 'image' > & {
4
+ name: string;
5
+ profileImage: string;
6
+ caption?: string;
7
+ };
8
+
9
+ export type InstagramPreviewsProps = InstagramPreviewProps & SocialPreviewsBaseProps;
@@ -56,18 +56,13 @@ export function LinkedInPostPreview( {
56
56
  </div>
57
57
  <div className="linkedin-preview__content">
58
58
  { description ? (
59
- <div
60
- className="linkedin-preview__caption"
61
- // TODO: Replace `dangerouslySetInnerHTML` with `createInterpolateElement` inside `preparePreviewText`
62
- // eslint-disable-next-line react/no-danger
63
- dangerouslySetInnerHTML={ {
64
- __html: preparePreviewText( description, {
65
- platform: 'linkedin',
66
- maxChars: FEED_TEXT_MAX_LENGTH,
67
- maxLines: FEED_TEXT_MAX_LINES,
68
- } ),
69
- } }
70
- />
59
+ <div className="linkedin-preview__caption">
60
+ { preparePreviewText( description, {
61
+ platform: 'linkedin',
62
+ maxChars: FEED_TEXT_MAX_LENGTH,
63
+ maxLines: FEED_TEXT_MAX_LINES,
64
+ } ) }
65
+ </div>
71
66
  ) : null }
72
67
  { hasMedia ? (
73
68
  <div className="linkedin-preview__media">
@@ -36,7 +36,7 @@ export const TwitterPostPreview: React.FC< TwitterPreviewProps > = ( {
36
36
  { text ? <Text text={ text } url={ url || '' } retainUrl={ hasMedia } /> : null }
37
37
  { hasMedia ? <Media media={ media } /> : null }
38
38
  { tweet ? <QuoteTweet tweet={ tweet } /> : null }
39
- { ! hasMedia && title && description && image && url && (
39
+ { ! hasMedia && title && description && url && (
40
40
  <Card
41
41
  description={ description }
42
42
  image={ image }
@@ -11,15 +11,9 @@ export const Text: React.FC< TextProps > = ( { text, url, retainUrl } ) => {
11
11
  ? text.substring( 0, text.lastIndexOf( url ) )
12
12
  : text;
13
13
 
14
- const __html = preparePreviewText( tweetText, { platform: 'twitter' } );
15
-
16
14
  return (
17
- <div
18
- className="twitter-preview__text"
19
- // We can enable dangerouslySetInnerHTML here, since the text we're using is stripped
20
- // of all HTML tags, then only has safe tags added in createTweetMarkup().
21
- // eslint-disable-next-line react/no-danger
22
- dangerouslySetInnerHTML={ { __html } }
23
- />
15
+ <div className="twitter-preview__text">
16
+ { preparePreviewText( tweetText, { platform: 'twitter' } ) }
17
+ </div>
24
18
  );
25
19
  };
package/src/helpers.ts DELETED
@@ -1,107 +0,0 @@
1
- export type Formatter = ( text: string, options?: any ) => string;
2
- type AugmentFormatterReturnType< T extends Formatter, TNewReturn > = (
3
- ...a: Parameters< T >
4
- ) => ReturnType< T > | TNewReturn;
5
- type ConditionalFormatter = AugmentFormatterReturnType< Formatter, boolean >;
6
- type NullableFormatter = AugmentFormatterReturnType< Formatter, undefined >;
7
-
8
- export const baseDomain = ( url: string ): string =>
9
- url
10
- .replace( /^[^/]+[/]*/, '' ) // strip leading protocol
11
- .replace( /\/.*$/, '' ); // strip everything after the domain
12
-
13
- export const shortEnough: ( n: number ) => ConditionalFormatter = ( limit ) => ( title ) =>
14
- title.length <= limit ? title : false;
15
-
16
- export const truncatedAtSpace: ( a: number, b: number ) => ConditionalFormatter =
17
- ( lower, upper ) => ( fullTitle ) => {
18
- const title = fullTitle.slice( 0, upper );
19
- const lastSpace = title.lastIndexOf( ' ' );
20
-
21
- return lastSpace > lower && lastSpace < upper
22
- ? title.slice( 0, lastSpace ).concat( '…' )
23
- : false;
24
- };
25
-
26
- export const hardTruncation: ( n: number ) => Formatter = ( limit ) => ( title ) =>
27
- title.slice( 0, limit ).concat( '…' );
28
-
29
- export const firstValid: ( ...args: ConditionalFormatter[] ) => NullableFormatter =
30
- ( ...predicates ) =>
31
- ( a ) =>
32
- ( predicates.find( ( p ) => false !== p( a ) ) as Formatter )?.( a );
33
-
34
- export const stripHtmlTags: Formatter = ( description, allowedTags = [] ) => {
35
- const pattern = new RegExp( `(<([^${ allowedTags.join( '' ) }>]+)>)`, 'gi' );
36
-
37
- return description ? description.replace( pattern, '' ) : '';
38
- };
39
-
40
- export const hasTag = ( text: string, tag: string ): boolean => {
41
- const pattern = new RegExp( `<${ tag }[^>]*>`, 'gi' );
42
-
43
- return pattern.test( text );
44
- };
45
-
46
- export const formatTweetDate = new Intl.DateTimeFormat( 'en-US', {
47
- // Result: "Apr 7", "Dec 31"
48
- month: 'short',
49
- day: 'numeric',
50
- } ).format;
51
-
52
- type Platform = 'twitter' | 'facebook' | 'linkedin';
53
-
54
- type PreviewTextOptions = {
55
- platform: Platform;
56
- maxChars?: number;
57
- maxLines?: number;
58
- };
59
-
60
- /**
61
- * Prepares the text for the preview.
62
- */
63
- export function preparePreviewText( text: string, options: PreviewTextOptions ): string {
64
- const { platform, maxChars, maxLines } = options;
65
-
66
- let result = stripHtmlTags( text );
67
-
68
- if ( maxChars && result.length > maxChars ) {
69
- result = result.substring( 0, maxChars );
70
- }
71
-
72
- if ( maxLines ) {
73
- const lines = result.split( '\n' );
74
-
75
- if ( lines.length > maxLines ) {
76
- result = lines.slice( 0, maxLines ).join( '\n' );
77
- }
78
- }
79
-
80
- // Convert URLs to hyperlinks.
81
- result = result.replace(
82
- // TODO: Use a better regex here to match the URLs without protocol.
83
- /(https?:\/\/\S+)/g,
84
- '<a href="$1" rel="noopener noreferrer" target="_blank">$1</a>'
85
- );
86
-
87
- let hashtagUrl;
88
-
89
- if ( 'twitter' === platform ) {
90
- hashtagUrl = 'https://twitter.com/hashtag/';
91
- } else if ( 'linkedin' === platform ) {
92
- hashtagUrl = 'https://www.linkedin.com/feed/hashtag/?keywords=';
93
- }
94
-
95
- if ( hashtagUrl ) {
96
- // Convert hashtags to hyperlinks.
97
- result = result.replace(
98
- /(^|\s)#(\w+)/g,
99
- '$1<a href="' + hashtagUrl + '$2" rel="noopener noreferrer" target="_blank">#$2</a>'
100
- );
101
- }
102
-
103
- // Convert newlines to <br> tags.
104
- result = result.replace( /\n/g, '<br/>' );
105
-
106
- return result;
107
- }