@select-org/post-components 1.0.1 → 2.0.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.d.ts +40 -1
- package/dist/index.js +218 -15
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2 -0
- package/package.json +7 -5
package/dist/index.d.ts
CHANGED
|
@@ -50,6 +50,16 @@ interface PostCardProps {
|
|
|
50
50
|
isAdmin?: boolean;
|
|
51
51
|
isOwner?: boolean;
|
|
52
52
|
isPostPreview?: boolean;
|
|
53
|
+
isPrivate?: boolean;
|
|
54
|
+
membersCount?: number;
|
|
55
|
+
crossPostGroup?: {
|
|
56
|
+
name: string;
|
|
57
|
+
href?: string;
|
|
58
|
+
};
|
|
59
|
+
locale?: string;
|
|
60
|
+
translate?: (key: string, params?: {
|
|
61
|
+
count?: number;
|
|
62
|
+
}) => string;
|
|
53
63
|
onPostPress?: () => void;
|
|
54
64
|
onErasePress?: () => void;
|
|
55
65
|
onCancelPost?: () => void;
|
|
@@ -100,6 +110,16 @@ interface PostHeaderProps {
|
|
|
100
110
|
groupHref?: string;
|
|
101
111
|
postedAt: string;
|
|
102
112
|
postType: string;
|
|
113
|
+
isPrivate?: boolean;
|
|
114
|
+
membersCount?: number;
|
|
115
|
+
crossPostGroup?: {
|
|
116
|
+
name: string;
|
|
117
|
+
href?: string;
|
|
118
|
+
};
|
|
119
|
+
locale?: string;
|
|
120
|
+
translate?: (key: string, params?: {
|
|
121
|
+
count?: number;
|
|
122
|
+
}) => string;
|
|
103
123
|
isFeatured?: boolean;
|
|
104
124
|
isPostPreview?: boolean;
|
|
105
125
|
isAdmin?: boolean;
|
|
@@ -299,6 +319,25 @@ declare const AutoLink: {
|
|
|
299
319
|
truncate: (text: string, { truncate: len, truncateChars, truncateLocation }?: TruncateOptions) => string;
|
|
300
320
|
};
|
|
301
321
|
|
|
322
|
+
interface PostTypeHintContext {
|
|
323
|
+
isInGroup?: boolean;
|
|
324
|
+
isOwner?: boolean;
|
|
325
|
+
isPrivate?: boolean;
|
|
326
|
+
membersCount?: number;
|
|
327
|
+
/** Mirrors the web client's `isMetaDesc` branch (SEO/meta-description copy). */
|
|
328
|
+
isMetaDesc?: boolean;
|
|
329
|
+
}
|
|
330
|
+
interface PostTypeHint {
|
|
331
|
+
key: string;
|
|
332
|
+
params?: {
|
|
333
|
+
count?: number;
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
declare function getPostTypeHint(postType: string, ctx?: PostTypeHintContext): PostTypeHint;
|
|
337
|
+
declare const POST_TYPE_HINT_DEFAULTS: Record<string, (p?: {
|
|
338
|
+
count?: number;
|
|
339
|
+
}) => string>;
|
|
340
|
+
|
|
302
341
|
interface ReactionModalProps {
|
|
303
342
|
isOpen: boolean;
|
|
304
343
|
close: () => void;
|
|
@@ -318,4 +357,4 @@ interface Props {
|
|
|
318
357
|
}
|
|
319
358
|
declare const EraseConfirmModal: React.FC<Props>;
|
|
320
359
|
|
|
321
|
-
export { AutoLink, EmbedContent, EraseConfirmModal, ItemData, LinkItemMetaData, MediaUploadStatus, MediaUploadStatusOverlay, MentionData, PollItemData, PollResult, PostBody, PostCard, type PostCardProps, PostEmail, PostEmbedView, PostFooter, PostHeader, type PostHeaderProps, PostItemsView, PostLinkItem, PostMediaLayoutCore, PostPollView, PostSectionSourceInfoView, PostSectionsSummaryView, PostSectionsView, PostTextItem, PostUploadStrip, PrimaryContent, ReactionModal, ResolvedTextContent, SectionItem, TextItemContent, TipTapDocument };
|
|
360
|
+
export { AutoLink, EmbedContent, EraseConfirmModal, ItemData, LinkItemMetaData, MediaUploadStatus, MediaUploadStatusOverlay, MentionData, POST_TYPE_HINT_DEFAULTS, PollItemData, PollResult, PostBody, PostCard, type PostCardProps, PostEmail, PostEmbedView, PostFooter, PostHeader, type PostHeaderProps, PostItemsView, PostLinkItem, PostMediaLayoutCore, PostPollView, PostSectionSourceInfoView, PostSectionsSummaryView, PostSectionsView, PostTextItem, type PostTypeHint, type PostTypeHintContext, PostUploadStrip, PrimaryContent, ReactionModal, ResolvedTextContent, SectionItem, TextItemContent, TipTapDocument, getPostTypeHint };
|
package/dist/index.js
CHANGED
|
@@ -64,18 +64,169 @@ function AppIcon({ name, ...props }) {
|
|
|
64
64
|
return /* @__PURE__ */ jsx(Icon, { ...props });
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
// src/utils/postTypeHint.ts
|
|
68
|
+
var MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
69
|
+
"new:post:media",
|
|
70
|
+
"new:post:image",
|
|
71
|
+
"mediaItemToUpload"
|
|
72
|
+
]);
|
|
73
|
+
function getPostTypeHint(postType, ctx = {}) {
|
|
74
|
+
const {
|
|
75
|
+
isInGroup = false,
|
|
76
|
+
isOwner = false,
|
|
77
|
+
isPrivate = false,
|
|
78
|
+
membersCount = 0,
|
|
79
|
+
isMetaDesc = false
|
|
80
|
+
} = ctx;
|
|
81
|
+
const isMedia = MEDIA_TYPES.has(postType);
|
|
82
|
+
if (isInGroup) {
|
|
83
|
+
if (isMetaDesc) {
|
|
84
|
+
if (isMedia)
|
|
85
|
+
return { key: "post_detail_meta_description_type_image_post" };
|
|
86
|
+
switch (postType) {
|
|
87
|
+
case "new:post:link":
|
|
88
|
+
return { key: "post_detail_meta_description_type_link_post" };
|
|
89
|
+
case "new:post:poll":
|
|
90
|
+
return { key: "post_detail_meta_description_type_poll_post" };
|
|
91
|
+
case "new:post:thread":
|
|
92
|
+
return {
|
|
93
|
+
key: "post_detail_one_liner_receive_and_send_group_thread_post"
|
|
94
|
+
};
|
|
95
|
+
case "new:post:text":
|
|
96
|
+
default:
|
|
97
|
+
return { key: "post_detail_meta_description_type_message_post" };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (isMedia)
|
|
101
|
+
return { key: "post_detail_one_liner_receive_and_send_group_image_post" };
|
|
102
|
+
switch (postType) {
|
|
103
|
+
case "new:post:link":
|
|
104
|
+
return {
|
|
105
|
+
key: "post_detail_one_liner_receive_and_send_group_link_post"
|
|
106
|
+
};
|
|
107
|
+
case "new:post:poll":
|
|
108
|
+
return {
|
|
109
|
+
key: "post_detail_one_liner_receive_and_send_group_poll_post"
|
|
110
|
+
};
|
|
111
|
+
case "new:post:thread":
|
|
112
|
+
return {
|
|
113
|
+
key: "post_detail_one_liner_receive_and_send_group_thread_post"
|
|
114
|
+
};
|
|
115
|
+
case "new:post:text":
|
|
116
|
+
default:
|
|
117
|
+
return {
|
|
118
|
+
key: "post_detail_one_liner_receive_and_send_group_message_post"
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (isOwner) {
|
|
123
|
+
return membersCount > 1 ? sentPlural(postType, membersCount) : sentSingular(postType);
|
|
124
|
+
}
|
|
125
|
+
if (isPrivate) {
|
|
126
|
+
if (isMedia)
|
|
127
|
+
return { key: "post_detail_one_liner_receive_private_image_post" };
|
|
128
|
+
switch (postType) {
|
|
129
|
+
case "new:post:link":
|
|
130
|
+
return { key: "post_detail_one_liner_receive_private_link_post" };
|
|
131
|
+
case "new:post:poll":
|
|
132
|
+
return { key: "post_detail_one_liner_receive_private_poll_post" };
|
|
133
|
+
case "new:post:thread":
|
|
134
|
+
case "new:post:text":
|
|
135
|
+
default:
|
|
136
|
+
return { key: "post_detail_one_liner_receive_message_post" };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return membersCount > 1 ? sentPlural(postType, membersCount) : sentSingular(postType);
|
|
140
|
+
}
|
|
141
|
+
function sentPlural(postType, count) {
|
|
142
|
+
const params = { count };
|
|
143
|
+
if (MEDIA_TYPES.has(postType))
|
|
144
|
+
return { key: "post_detail_one_liner_send_private_image_post_plural", params };
|
|
145
|
+
switch (postType) {
|
|
146
|
+
case "new:post:link":
|
|
147
|
+
return {
|
|
148
|
+
key: "post_detail_one_liner_send_private_link_post_plural",
|
|
149
|
+
params
|
|
150
|
+
};
|
|
151
|
+
case "new:post:poll":
|
|
152
|
+
return {
|
|
153
|
+
key: "post_detail_one_liner_send_private_link_poll_plural",
|
|
154
|
+
params
|
|
155
|
+
};
|
|
156
|
+
case "new:post:thread":
|
|
157
|
+
case "new:post:text":
|
|
158
|
+
default:
|
|
159
|
+
return { key: "post_detail_one_liner_send_message_post_plural", params };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function sentSingular(postType) {
|
|
163
|
+
if (MEDIA_TYPES.has(postType))
|
|
164
|
+
return { key: "post_detail_one_liner_send_private_image_post_singular" };
|
|
165
|
+
switch (postType) {
|
|
166
|
+
case "new:post:link":
|
|
167
|
+
return { key: "post_detail_one_liner_send_private_link_post_singular" };
|
|
168
|
+
case "new:post:poll":
|
|
169
|
+
return { key: "post_detail_one_liner_send_private_link_poll_singular" };
|
|
170
|
+
case "new:post:thread":
|
|
171
|
+
case "new:post:text":
|
|
172
|
+
default:
|
|
173
|
+
return { key: "post_detail_one_liner_send_message_post_singular" };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
var POST_TYPE_HINT_DEFAULTS = {
|
|
177
|
+
// in-group (one-liner)
|
|
178
|
+
post_detail_one_liner_receive_and_send_group_image_post: () => "shared a media post in group",
|
|
179
|
+
post_detail_one_liner_receive_and_send_group_link_post: () => "shared a link post in group",
|
|
180
|
+
post_detail_one_liner_receive_and_send_group_poll_post: () => "shared a poll in group",
|
|
181
|
+
post_detail_one_liner_receive_and_send_group_thread_post: () => "shared a thread in group",
|
|
182
|
+
post_detail_one_liner_receive_and_send_group_message_post: () => "shared a post in group",
|
|
183
|
+
// in-group (meta description)
|
|
184
|
+
post_detail_meta_description_type_image_post: () => "A media post",
|
|
185
|
+
post_detail_meta_description_type_link_post: () => "A link post",
|
|
186
|
+
post_detail_meta_description_type_poll_post: () => "A poll",
|
|
187
|
+
post_detail_meta_description_type_message_post: () => "A post",
|
|
188
|
+
// owner / 1:M sent — plural
|
|
189
|
+
post_detail_one_liner_send_private_image_post_plural: (p) => `sent a media post to ${p?.count ?? 0} people`,
|
|
190
|
+
post_detail_one_liner_send_private_link_post_plural: (p) => `sent a link post to ${p?.count ?? 0} people`,
|
|
191
|
+
post_detail_one_liner_send_private_link_poll_plural: (p) => `sent a poll to ${p?.count ?? 0} people`,
|
|
192
|
+
post_detail_one_liner_send_message_post_plural: (p) => `sent a post to ${p?.count ?? 0} people`,
|
|
193
|
+
// owner / 1:M sent — singular
|
|
194
|
+
post_detail_one_liner_send_private_image_post_singular: () => "sent a media post",
|
|
195
|
+
post_detail_one_liner_send_private_link_post_singular: () => "sent a link post",
|
|
196
|
+
post_detail_one_liner_send_private_link_poll_singular: () => "sent a poll",
|
|
197
|
+
post_detail_one_liner_send_message_post_singular: () => "sent a post",
|
|
198
|
+
// private 1:1 received
|
|
199
|
+
post_detail_one_liner_receive_private_image_post: () => "sent you a media post",
|
|
200
|
+
post_detail_one_liner_receive_private_link_post: () => "sent you a link post",
|
|
201
|
+
post_detail_one_liner_receive_private_poll_post: () => "sent you a poll",
|
|
202
|
+
post_detail_one_liner_receive_message_post: () => "sent you a post"
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/utils/relativeTime.ts
|
|
206
|
+
var UNITS = [
|
|
207
|
+
["year", 31536e3],
|
|
208
|
+
["month", 2592e3],
|
|
209
|
+
["week", 604800],
|
|
210
|
+
["day", 86400],
|
|
211
|
+
["hour", 3600],
|
|
212
|
+
["minute", 60]
|
|
213
|
+
];
|
|
214
|
+
function formatRelativeTime(iso, locale = "en") {
|
|
215
|
+
const diffMs = Date.now() - new Date(iso).getTime();
|
|
216
|
+
const seconds = Math.round(diffMs / 1e3);
|
|
217
|
+
if (Math.abs(seconds) < 60) return "just now";
|
|
218
|
+
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
|
|
219
|
+
for (const [unit, secs] of UNITS) {
|
|
220
|
+
if (Math.abs(seconds) >= secs) {
|
|
221
|
+
const value = Math.round(seconds / secs);
|
|
222
|
+
return rtf.format(-value, unit);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return "just now";
|
|
226
|
+
}
|
|
227
|
+
|
|
67
228
|
// src/components/PostHeader.tsx
|
|
68
229
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
69
|
-
function formatRelativeTime(iso) {
|
|
70
|
-
const diff = Date.now() - new Date(iso).getTime();
|
|
71
|
-
const minutes = Math.floor(diff / 6e4);
|
|
72
|
-
if (minutes < 1) return "just now";
|
|
73
|
-
if (minutes < 60) return `${minutes}m`;
|
|
74
|
-
const hours = Math.floor(minutes / 60);
|
|
75
|
-
if (hours < 24) return `${hours}h`;
|
|
76
|
-
const days = Math.floor(hours / 24);
|
|
77
|
-
return `${days}d`;
|
|
78
|
-
}
|
|
79
230
|
var PostHeader = ({
|
|
80
231
|
author,
|
|
81
232
|
authorHref,
|
|
@@ -83,6 +234,11 @@ var PostHeader = ({
|
|
|
83
234
|
groupHref,
|
|
84
235
|
postedAt,
|
|
85
236
|
postType,
|
|
237
|
+
isPrivate = false,
|
|
238
|
+
membersCount,
|
|
239
|
+
crossPostGroup,
|
|
240
|
+
locale,
|
|
241
|
+
translate,
|
|
86
242
|
isFeatured = false,
|
|
87
243
|
isPostPreview = false,
|
|
88
244
|
isAdmin = false,
|
|
@@ -95,6 +251,13 @@ var PostHeader = ({
|
|
|
95
251
|
labels
|
|
96
252
|
}) => {
|
|
97
253
|
const cancelLabel = labels?.cancelPost ?? "Cancel";
|
|
254
|
+
const { key: hintKey, params: hintParams } = getPostTypeHint(postType, {
|
|
255
|
+
isInGroup: !!group,
|
|
256
|
+
isOwner,
|
|
257
|
+
isPrivate,
|
|
258
|
+
membersCount
|
|
259
|
+
});
|
|
260
|
+
const hintText = translate?.(hintKey, hintParams) ?? POST_TYPE_HINT_DEFAULTS[hintKey]?.(hintParams) ?? hintKey;
|
|
98
261
|
const badgeVariant = isOwner ? "owner" : isAdmin ? "admin" : void 0;
|
|
99
262
|
const authorNameNode = isPostPreview ? /* @__PURE__ */ jsx2("span", { className: "flex text-base font-semibold leading-[100%] text-foreground", children: author.name }) : LinkComponent ? /* @__PURE__ */ jsx2(
|
|
100
263
|
LinkComponent,
|
|
@@ -173,7 +336,7 @@ var PostHeader = ({
|
|
|
173
336
|
viewBox: "0 0 24 24",
|
|
174
337
|
width: 14,
|
|
175
338
|
height: 14,
|
|
176
|
-
className: "text-
|
|
339
|
+
className: "text-highlight fill-highlight shrink-0",
|
|
177
340
|
"aria-label": "Featured post",
|
|
178
341
|
children: /* @__PURE__ */ jsx2("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" })
|
|
179
342
|
}
|
|
@@ -186,16 +349,44 @@ var PostHeader = ({
|
|
|
186
349
|
title: postedAt,
|
|
187
350
|
className: "text-xs text-muted-foreground whitespace-nowrap shrink-0",
|
|
188
351
|
dateTime: postedAt,
|
|
189
|
-
children: formatRelativeTime(postedAt)
|
|
352
|
+
children: formatRelativeTime(postedAt, locale ?? "en")
|
|
190
353
|
}
|
|
191
354
|
)
|
|
192
355
|
] })
|
|
193
356
|
] }) }),
|
|
194
357
|
/* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground truncate mt-0.5", children: [
|
|
195
|
-
/* @__PURE__ */ jsx2("span", { children:
|
|
358
|
+
/* @__PURE__ */ jsx2("span", { children: hintText }),
|
|
196
359
|
groupLinkNode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
197
360
|
/* @__PURE__ */ jsx2("span", { className: "mx-1" }),
|
|
198
361
|
groupLinkNode
|
|
362
|
+
] }),
|
|
363
|
+
crossPostGroup && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
364
|
+
/* @__PURE__ */ jsx2("span", { className: "mx-1", children: "via" }),
|
|
365
|
+
LinkComponent && crossPostGroup.href ? /* @__PURE__ */ jsxs(
|
|
366
|
+
LinkComponent,
|
|
367
|
+
{
|
|
368
|
+
href: crossPostGroup.href,
|
|
369
|
+
className: "text-action-primary font-medium hover:underline no-underline",
|
|
370
|
+
children: [
|
|
371
|
+
"#",
|
|
372
|
+
crossPostGroup.name
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
) : crossPostGroup.href ? /* @__PURE__ */ jsxs(
|
|
376
|
+
"a",
|
|
377
|
+
{
|
|
378
|
+
href: crossPostGroup.href,
|
|
379
|
+
onClick: (e) => e.stopPropagation(),
|
|
380
|
+
className: "text-action-primary font-medium hover:underline no-underline",
|
|
381
|
+
children: [
|
|
382
|
+
"#",
|
|
383
|
+
crossPostGroup.name
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
) : /* @__PURE__ */ jsxs("span", { className: "text-action-primary font-medium", children: [
|
|
387
|
+
"#",
|
|
388
|
+
crossPostGroup.name
|
|
389
|
+
] })
|
|
199
390
|
] })
|
|
200
391
|
] })
|
|
201
392
|
] })
|
|
@@ -2568,6 +2759,11 @@ var PostCard = ({
|
|
|
2568
2759
|
isAdmin,
|
|
2569
2760
|
isOwner,
|
|
2570
2761
|
isPostPreview,
|
|
2762
|
+
isPrivate,
|
|
2763
|
+
membersCount,
|
|
2764
|
+
crossPostGroup,
|
|
2765
|
+
locale,
|
|
2766
|
+
translate,
|
|
2571
2767
|
onPostPress,
|
|
2572
2768
|
onErasePress,
|
|
2573
2769
|
onCancelPost,
|
|
@@ -2645,10 +2841,10 @@ var PostCard = ({
|
|
|
2645
2841
|
"article",
|
|
2646
2842
|
{
|
|
2647
2843
|
className: cn(
|
|
2648
|
-
"flex flex-col box-border bg-background",
|
|
2844
|
+
"w-full flex flex-col box-border bg-background",
|
|
2649
2845
|
!isPostDetail && "cursor-pointer sm:border border-border rounded-xl sm:rounded-2xl overflow-hidden shadow-sm hover:shadow-md transition-shadow duration-300 relative mt-6",
|
|
2650
2846
|
isPostDetail && "cursor-auto rounded-t-2xl w-full",
|
|
2651
|
-
post.isFeatured && !isPostDetail && "bg-surface
|
|
2847
|
+
post.isFeatured && !isPostDetail && "bg-highlight-surface border-highlight-border sm:border-t-4",
|
|
2652
2848
|
isPending && "cursor-default",
|
|
2653
2849
|
className
|
|
2654
2850
|
),
|
|
@@ -2697,6 +2893,11 @@ var PostCard = ({
|
|
|
2697
2893
|
isPostPreview,
|
|
2698
2894
|
isAdmin,
|
|
2699
2895
|
isOwner,
|
|
2896
|
+
isPrivate,
|
|
2897
|
+
membersCount,
|
|
2898
|
+
crossPostGroup,
|
|
2899
|
+
locale,
|
|
2900
|
+
translate,
|
|
2700
2901
|
onErasePress: onErasePress ? handleErasePress : void 0,
|
|
2701
2902
|
onCancelPost,
|
|
2702
2903
|
renderActionsMenu,
|
|
@@ -2900,6 +3101,7 @@ export {
|
|
|
2900
3101
|
AutoLink_default as AutoLink,
|
|
2901
3102
|
EraseConfirmModal_default as EraseConfirmModal,
|
|
2902
3103
|
MediaUploadStatusOverlay_default as MediaUploadStatusOverlay,
|
|
3104
|
+
POST_TYPE_HINT_DEFAULTS,
|
|
2903
3105
|
PostBody_default as PostBody,
|
|
2904
3106
|
PostCard_default as PostCard,
|
|
2905
3107
|
PostEmail_default as PostEmail,
|
|
@@ -2916,6 +3118,7 @@ export {
|
|
|
2916
3118
|
PostTextItem_default as PostTextItem,
|
|
2917
3119
|
PostUploadStrip_default as PostUploadStrip,
|
|
2918
3120
|
ReactionModal,
|
|
3121
|
+
getPostTypeHint,
|
|
2919
3122
|
hasMeaningfulHtml,
|
|
2920
3123
|
resolvePostContent
|
|
2921
3124
|
};
|