@liveblocks/react-ui 2.7.2 → 2.8.0-beta2

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 (126) hide show
  1. package/dist/_private/index.d.mts +5 -3
  2. package/dist/_private/index.d.ts +5 -3
  3. package/dist/_private/index.js +4 -2
  4. package/dist/_private/index.js.map +1 -1
  5. package/dist/_private/index.mjs +2 -1
  6. package/dist/_private/index.mjs.map +1 -1
  7. package/dist/components/Comment.js +106 -3
  8. package/dist/components/Comment.js.map +1 -1
  9. package/dist/components/Comment.mjs +107 -5
  10. package/dist/components/Comment.mjs.map +1 -1
  11. package/dist/components/Composer.js +216 -103
  12. package/dist/components/Composer.js.map +1 -1
  13. package/dist/components/Composer.mjs +220 -107
  14. package/dist/components/Composer.mjs.map +1 -1
  15. package/dist/components/HistoryVersionSummary.js +5 -0
  16. package/dist/components/HistoryVersionSummary.js.map +1 -1
  17. package/dist/components/HistoryVersionSummary.mjs +5 -0
  18. package/dist/components/HistoryVersionSummary.mjs.map +1 -1
  19. package/dist/components/InboxNotification.js +20 -4
  20. package/dist/components/InboxNotification.js.map +1 -1
  21. package/dist/components/InboxNotification.mjs +20 -4
  22. package/dist/components/InboxNotification.mjs.map +1 -1
  23. package/dist/components/Thread.js +5 -0
  24. package/dist/components/Thread.js.map +1 -1
  25. package/dist/components/Thread.mjs +5 -0
  26. package/dist/components/Thread.mjs.map +1 -1
  27. package/dist/components/internal/Attachment.js +314 -0
  28. package/dist/components/internal/Attachment.js.map +1 -0
  29. package/dist/components/internal/Attachment.mjs +310 -0
  30. package/dist/components/internal/Attachment.mjs.map +1 -0
  31. package/dist/components/internal/InboxNotificationThread.js +12 -2
  32. package/dist/components/internal/InboxNotificationThread.js.map +1 -1
  33. package/dist/components/internal/InboxNotificationThread.mjs +13 -3
  34. package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
  35. package/dist/icons/Attachment.js +15 -0
  36. package/dist/icons/Attachment.js.map +1 -0
  37. package/dist/icons/Attachment.mjs +13 -0
  38. package/dist/icons/Attachment.mjs.map +1 -0
  39. package/dist/icons/Spinner.js +3 -9
  40. package/dist/icons/Spinner.js.map +1 -1
  41. package/dist/icons/Spinner.mjs +4 -10
  42. package/dist/icons/Spinner.mjs.map +1 -1
  43. package/dist/icons/{Missing.js → Warning.js} +3 -3
  44. package/dist/icons/{Missing.js.map → Warning.js.map} +1 -1
  45. package/dist/icons/{Missing.mjs → Warning.mjs} +3 -3
  46. package/dist/icons/{Missing.mjs.map → Warning.mjs.map} +1 -1
  47. package/dist/index.d.mts +73 -4
  48. package/dist/index.d.ts +73 -4
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.mjs.map +1 -1
  51. package/dist/overrides.js +5 -0
  52. package/dist/overrides.js.map +1 -1
  53. package/dist/overrides.mjs +5 -0
  54. package/dist/overrides.mjs.map +1 -1
  55. package/dist/primitives/Composer/contexts.js +17 -3
  56. package/dist/primitives/Composer/contexts.js.map +1 -1
  57. package/dist/primitives/Composer/contexts.mjs +15 -4
  58. package/dist/primitives/Composer/contexts.mjs.map +1 -1
  59. package/dist/primitives/Composer/index.js +207 -30
  60. package/dist/primitives/Composer/index.js.map +1 -1
  61. package/dist/primitives/Composer/index.mjs +210 -35
  62. package/dist/primitives/Composer/index.mjs.map +1 -1
  63. package/dist/primitives/Composer/utils.js +231 -0
  64. package/dist/primitives/Composer/utils.js.map +1 -1
  65. package/dist/primitives/Composer/utils.mjs +229 -1
  66. package/dist/primitives/Composer/utils.mjs.map +1 -1
  67. package/dist/primitives/EmojiPicker/utils.js +2 -2
  68. package/dist/primitives/EmojiPicker/utils.js.map +1 -1
  69. package/dist/primitives/EmojiPicker/utils.mjs +1 -1
  70. package/dist/primitives/EmojiPicker/utils.mjs.map +1 -1
  71. package/dist/primitives/FileSize.js +33 -0
  72. package/dist/primitives/FileSize.js.map +1 -0
  73. package/dist/primitives/FileSize.mjs +31 -0
  74. package/dist/primitives/FileSize.mjs.map +1 -0
  75. package/dist/primitives/index.d.mts +87 -3
  76. package/dist/primitives/index.d.ts +87 -3
  77. package/dist/primitives/index.js +4 -0
  78. package/dist/primitives/index.js.map +1 -1
  79. package/dist/primitives/index.mjs +2 -0
  80. package/dist/primitives/index.mjs.map +1 -1
  81. package/dist/slate/plugins/{paste-html.js → paste.js} +16 -5
  82. package/dist/slate/plugins/paste.js.map +1 -0
  83. package/dist/slate/plugins/{paste-html.mjs → paste.mjs} +16 -5
  84. package/dist/slate/plugins/paste.mjs.map +1 -0
  85. package/dist/utils/data-transfer.js +20 -0
  86. package/dist/utils/data-transfer.js.map +1 -0
  87. package/dist/utils/data-transfer.mjs +18 -0
  88. package/dist/utils/data-transfer.mjs.map +1 -0
  89. package/dist/utils/download.js +14 -0
  90. package/dist/utils/download.js.map +1 -0
  91. package/dist/utils/download.mjs +12 -0
  92. package/dist/utils/download.mjs.map +1 -0
  93. package/dist/utils/format-file-size.js +45 -0
  94. package/dist/utils/format-file-size.js.map +1 -0
  95. package/dist/utils/format-file-size.mjs +43 -0
  96. package/dist/utils/format-file-size.mjs.map +1 -0
  97. package/dist/utils/intl.js +6 -0
  98. package/dist/utils/intl.js.map +1 -1
  99. package/dist/utils/intl.mjs +6 -1
  100. package/dist/utils/intl.mjs.map +1 -1
  101. package/dist/utils/use-initial.js +2 -1
  102. package/dist/utils/use-initial.js.map +1 -1
  103. package/dist/utils/use-initial.mjs +3 -2
  104. package/dist/utils/use-initial.mjs.map +1 -1
  105. package/dist/utils/use-latest.js.map +1 -1
  106. package/dist/utils/use-latest.mjs.map +1 -1
  107. package/dist/version.js +1 -1
  108. package/dist/version.js.map +1 -1
  109. package/dist/version.mjs +1 -1
  110. package/dist/version.mjs.map +1 -1
  111. package/package.json +4 -4
  112. package/src/styles/dark/index.css +1 -0
  113. package/src/styles/index.css +343 -62
  114. package/src/styles/utils.css +44 -0
  115. package/styles/dark/attributes.css +1 -1
  116. package/styles/dark/attributes.css.map +1 -1
  117. package/styles/dark/media-query.css +1 -1
  118. package/styles/dark/media-query.css.map +1 -1
  119. package/styles.css +1 -1
  120. package/styles.css.map +1 -1
  121. package/dist/slate/plugins/paste-html.js.map +0 -1
  122. package/dist/slate/plugins/paste-html.mjs.map +0 -1
  123. package/dist/utils/chunk.js +0 -12
  124. package/dist/utils/chunk.js.map +0 -1
  125. package/dist/utils/chunk.mjs +0 -10
  126. package/dist/utils/chunk.mjs.map +0 -1
@@ -0,0 +1,310 @@
1
+ 'use client';
2
+ import { useIsInsideRoom, useAttachmentUrl } from '@liveblocks/react';
3
+ import React__default, { memo, useMemo, useCallback, useState } from 'react';
4
+ import { CrossIcon } from '../../icons/Cross.mjs';
5
+ import { SpinnerIcon } from '../../icons/Spinner.mjs';
6
+ import { WarningIcon } from '../../icons/Warning.mjs';
7
+ import { useOverrides } from '../../overrides.mjs';
8
+ import '../../primitives/Comment/index.mjs';
9
+ import '../../primitives/Composer/index.mjs';
10
+ import { useComposerAttachmentsContextOrNull } from '../../primitives/Composer/contexts.mjs';
11
+ import { AttachmentTooLargeError } from '../../primitives/Composer/utils.mjs';
12
+ import '../../primitives/EmojiPicker/index.mjs';
13
+ import '../../primitives/FileSize.mjs';
14
+ import '../../primitives/Timestamp.mjs';
15
+ import { classNames } from '../../utils/class-names.mjs';
16
+ import { formatFileSize } from '../../utils/format-file-size.mjs';
17
+ import { Tooltip } from './Tooltip.mjs';
18
+
19
+ const MAX_DISPLAYED_MEDIA_SIZE = 60 * 1024 * 1024;
20
+ const fileExtensionRegex = /^(.+?)(\.[^.]+)?$/;
21
+ function splitFileName(name) {
22
+ const match = name.match(fileExtensionRegex);
23
+ return { base: match?.[1] ?? name, extension: match?.[2] };
24
+ }
25
+ function getAttachmentIconGlyph(mimeType) {
26
+ if (mimeType === "application/zip" || mimeType === "application/gzip" || mimeType === "application/vnd.rar" || mimeType === "application/x-rar-compressed" || mimeType === "application/x-7z-compressed" || mimeType === "application/x-zip-compressed" || mimeType === "application/x-tar" || mimeType === "application/x-bzip" || mimeType === "application/x-bzip2") {
27
+ return /* @__PURE__ */ React__default.createElement("path", {
28
+ d: "M13 15h2v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1h1a.5.5 0 0 0 .5-.5V20h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 .5-.5V15a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2Z"
29
+ });
30
+ }
31
+ if (mimeType.startsWith("text/") || mimeType.startsWith("font/") || mimeType.startsWith("application/")) {
32
+ return /* @__PURE__ */ React__default.createElement("path", {
33
+ d: "M10 16a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1h-8a.5.5 0 0 1-.5-.5Z"
34
+ });
35
+ }
36
+ if (mimeType.startsWith("image/")) {
37
+ return /* @__PURE__ */ React__default.createElement("path", {
38
+ d: "M12 16h6a1 1 0 0 1 1 1v3l-1.293-1.293a1 1 0 0 0-1.414 0L14.09 20.91l-.464-.386a1 1 0 0 0-1.265-.013l-1.231.985A.995.995 0 0 1 11 21v-4a1 1 0 0 1 1-1Zm-2 1a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2v-4Zm3 2a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
39
+ });
40
+ }
41
+ if (mimeType.startsWith("video/")) {
42
+ return /* @__PURE__ */ React__default.createElement("path", {
43
+ d: "M12 15.71a1 1 0 0 1 1.49-.872l4.96 2.79a1 1 0 0 1 0 1.744l-4.96 2.79A1 1 0 0 1 12 21.29v-5.58Z"
44
+ });
45
+ }
46
+ if (mimeType.startsWith("audio/")) {
47
+ return /* @__PURE__ */ React__default.createElement("path", {
48
+ d: "M15 15a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 1 0v-7a.5.5 0 0 0-.5-.5Zm-2.5 2.5a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3Zm-2 1a.5.5 0 0 1 1 0v1a.5.5 0 0 1-1 0v-1Zm6-1a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3ZM19 16a.5.5 0 0 0-.5.5v5a.5.5 0 0 0 1 0v-5a.5.5 0 0 0-.5-.5Z"
49
+ });
50
+ }
51
+ return null;
52
+ }
53
+ const AttachmentFileIcon = memo(({ mimeType }) => {
54
+ const iconGlyph = useMemo(() => getAttachmentIconGlyph(mimeType), [mimeType]);
55
+ return /* @__PURE__ */ React__default.createElement("svg", {
56
+ className: "lb-attachment-icon",
57
+ width: 30,
58
+ height: 30,
59
+ viewBox: "0 0 30 30",
60
+ fill: "currentColor",
61
+ fillRule: "evenodd",
62
+ clipRule: "evenodd",
63
+ xmlns: "http://www.w3.org/2000/svg"
64
+ }, /* @__PURE__ */ React__default.createElement("path", {
65
+ d: "M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z",
66
+ className: "lb-attachment-icon-shadow"
67
+ }), /* @__PURE__ */ React__default.createElement("path", {
68
+ d: "M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z",
69
+ className: "lb-attachment-icon-background"
70
+ }), /* @__PURE__ */ React__default.createElement("path", {
71
+ d: "M14.382 3.037a4 4 0 0 1 2.29 1.135l6.156 6.157a4 4 0 0 1 1.136 2.289A2 2 0 0 0 22 11h-4a2 2 0 0 1-2-2V5a2 2 0 0 0-1.618-1.963Z",
72
+ className: "lb-attachment-icon-fold"
73
+ }), iconGlyph && /* @__PURE__ */ React__default.createElement("g", {
74
+ className: "lb-attachment-icon-glyph"
75
+ }, iconGlyph));
76
+ });
77
+ function AttachmentImagePreview({
78
+ attachment
79
+ }) {
80
+ const { url } = useAttachmentUrl(attachment.id);
81
+ const [isLoaded, setLoaded] = useState(false);
82
+ const handleLoad = useCallback(() => {
83
+ setLoaded(true);
84
+ }, []);
85
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, !isLoaded ? /* @__PURE__ */ React__default.createElement(SpinnerIcon, null) : null, url ? /* @__PURE__ */ React__default.createElement("div", {
86
+ className: "lb-attachment-preview-media",
87
+ "data-hidden": !isLoaded ? "" : void 0
88
+ }, /* @__PURE__ */ React__default.createElement("img", {
89
+ src: url,
90
+ loading: "lazy",
91
+ onLoad: handleLoad
92
+ })) : null);
93
+ }
94
+ function AttachmentVideoPreview({
95
+ attachment
96
+ }) {
97
+ const { url } = useAttachmentUrl(attachment.id);
98
+ const [isLoaded, setLoaded] = useState(false);
99
+ const handleLoad = useCallback(() => {
100
+ setLoaded(true);
101
+ }, []);
102
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, !isLoaded ? /* @__PURE__ */ React__default.createElement(SpinnerIcon, null) : null, url ? /* @__PURE__ */ React__default.createElement("div", {
103
+ className: "lb-attachment-preview-media",
104
+ "data-hidden": !isLoaded ? "" : void 0
105
+ }, /* @__PURE__ */ React__default.createElement("video", {
106
+ src: url,
107
+ onLoadedData: handleLoad
108
+ })) : null);
109
+ }
110
+ function AttachmentPreview({
111
+ attachment
112
+ }) {
113
+ const isInsideRoom = useIsInsideRoom();
114
+ const isUploaded = attachment.type === "attachment" || attachment.status === "uploaded";
115
+ if (isUploaded && isInsideRoom && attachment.size <= MAX_DISPLAYED_MEDIA_SIZE) {
116
+ if (attachment.mimeType.startsWith("image/")) {
117
+ return /* @__PURE__ */ React__default.createElement(AttachmentImagePreview, {
118
+ attachment
119
+ });
120
+ }
121
+ if (attachment.mimeType.startsWith("video/")) {
122
+ return /* @__PURE__ */ React__default.createElement(AttachmentVideoPreview, {
123
+ attachment
124
+ });
125
+ }
126
+ }
127
+ return /* @__PURE__ */ React__default.createElement(AttachmentFileIcon, {
128
+ mimeType: attachment.mimeType
129
+ });
130
+ }
131
+ function AttachmentName({
132
+ attachment
133
+ }) {
134
+ const { base: fileBaseName, extension: fileExtension } = useMemo(() => {
135
+ return splitFileName(attachment.name);
136
+ }, [attachment.name]);
137
+ return /* @__PURE__ */ React__default.createElement("span", {
138
+ className: "lb-attachment-name",
139
+ title: attachment.name
140
+ }, /* @__PURE__ */ React__default.createElement("span", {
141
+ className: "lb-attachment-name-base"
142
+ }, fileBaseName), fileExtension && /* @__PURE__ */ React__default.createElement("span", {
143
+ className: "lb-attachment-name-extension"
144
+ }, fileExtension));
145
+ }
146
+ function useClickOnKeyDown(onKeyDown) {
147
+ const handleKeyDown = useCallback(
148
+ (event) => {
149
+ onKeyDown?.(event);
150
+ if (event.isDefaultPrevented()) {
151
+ return;
152
+ }
153
+ if (event.key === "Enter" || event.key === " ") {
154
+ event.preventDefault();
155
+ const clickEvent = new MouseEvent("click", {
156
+ bubbles: true,
157
+ cancelable: true,
158
+ view: window
159
+ });
160
+ event.target.dispatchEvent(clickEvent);
161
+ }
162
+ },
163
+ [onKeyDown]
164
+ );
165
+ return handleKeyDown;
166
+ }
167
+ function useAttachmentContent(attachment, overrides) {
168
+ const $ = useOverrides(overrides);
169
+ const composerAttachmentsContext = useComposerAttachmentsContextOrNull();
170
+ const isInComposer = Boolean(composerAttachmentsContext);
171
+ const maxAttachmentSize = composerAttachmentsContext?.maxAttachmentSize;
172
+ const status = attachment.type === "localAttachment" ? attachment.status : void 0;
173
+ const isUploading = status === "uploading";
174
+ const isError = status === "error";
175
+ let description;
176
+ if (attachment.type === "localAttachment" && attachment.status === "error") {
177
+ if (attachment.error instanceof AttachmentTooLargeError) {
178
+ description = $.ATTACHMENT_TOO_LARGE(
179
+ maxAttachmentSize ? formatFileSize(maxAttachmentSize, $.locale) : void 0
180
+ );
181
+ } else {
182
+ description = $.ATTACHMENT_ERROR(attachment.error);
183
+ }
184
+ } else {
185
+ description = formatFileSize(attachment.size, $.locale);
186
+ }
187
+ const deleteLabel = isInComposer ? $.COMPOSER_REMOVE_ATTACHMENT : $.COMMENT_DELETE_ATTACHMENT;
188
+ return {
189
+ isUploading,
190
+ isError,
191
+ description,
192
+ deleteLabel
193
+ };
194
+ }
195
+ function MediaAttachment({
196
+ attachment,
197
+ overrides,
198
+ onClick,
199
+ onDeleteClick,
200
+ preventFocusOnDelete,
201
+ className,
202
+ onKeyDown,
203
+ ...props
204
+ }) {
205
+ const { isUploading, isError, description, deleteLabel } = useAttachmentContent(attachment, overrides);
206
+ const handleDeletePointerDown = useCallback(
207
+ (event) => {
208
+ if (preventFocusOnDelete) {
209
+ event.preventDefault();
210
+ }
211
+ },
212
+ [preventFocusOnDelete]
213
+ );
214
+ const handleKeyDown = useClickOnKeyDown(onKeyDown);
215
+ return /* @__PURE__ */ React__default.createElement("div", {
216
+ className: classNames("lb-attachment lb-media-attachment", className),
217
+ "data-error": isError ? "" : void 0,
218
+ ...props,
219
+ role: onClick ? "button" : void 0,
220
+ onClick,
221
+ tabIndex: onClick ? 0 : -1,
222
+ onKeyDown: onClick ? handleKeyDown : void 0
223
+ }, /* @__PURE__ */ React__default.createElement("div", {
224
+ className: "lb-attachment-preview"
225
+ }, isUploading ? /* @__PURE__ */ React__default.createElement(SpinnerIcon, null) : isError ? /* @__PURE__ */ React__default.createElement(WarningIcon, null) : /* @__PURE__ */ React__default.createElement(AttachmentPreview, {
226
+ attachment
227
+ })), /* @__PURE__ */ React__default.createElement("div", {
228
+ className: "lb-attachment-details"
229
+ }, /* @__PURE__ */ React__default.createElement(AttachmentName, {
230
+ attachment
231
+ }), /* @__PURE__ */ React__default.createElement("span", {
232
+ className: "lb-attachment-description",
233
+ title: description
234
+ }, description)), onDeleteClick && /* @__PURE__ */ React__default.createElement(Tooltip, {
235
+ content: deleteLabel
236
+ }, /* @__PURE__ */ React__default.createElement("button", {
237
+ type: "button",
238
+ className: "lb-attachment-delete",
239
+ onClick: onDeleteClick,
240
+ onPointerDown: handleDeletePointerDown,
241
+ "aria-label": deleteLabel
242
+ }, /* @__PURE__ */ React__default.createElement(CrossIcon, null))));
243
+ }
244
+ function FileAttachment({
245
+ attachment,
246
+ overrides,
247
+ onClick,
248
+ onDeleteClick,
249
+ preventFocusOnDelete,
250
+ className,
251
+ onKeyDown,
252
+ ...props
253
+ }) {
254
+ const { isUploading, isError, description, deleteLabel } = useAttachmentContent(attachment, overrides);
255
+ const handleDeletePointerDown = useCallback(
256
+ (event) => {
257
+ if (preventFocusOnDelete) {
258
+ event.preventDefault();
259
+ }
260
+ },
261
+ [preventFocusOnDelete]
262
+ );
263
+ const handleKeyDown = useClickOnKeyDown(onKeyDown);
264
+ return /* @__PURE__ */ React__default.createElement("div", {
265
+ className: classNames("lb-attachment lb-file-attachment", className),
266
+ "data-error": isError ? "" : void 0,
267
+ ...props,
268
+ role: onClick ? "button" : void 0,
269
+ onClick,
270
+ tabIndex: onClick ? 0 : -1,
271
+ onKeyDown: onClick ? handleKeyDown : void 0
272
+ }, /* @__PURE__ */ React__default.createElement("div", {
273
+ className: "lb-attachment-preview"
274
+ }, isUploading ? /* @__PURE__ */ React__default.createElement(SpinnerIcon, null) : isError ? /* @__PURE__ */ React__default.createElement(WarningIcon, null) : /* @__PURE__ */ React__default.createElement(AttachmentPreview, {
275
+ attachment
276
+ })), /* @__PURE__ */ React__default.createElement("div", {
277
+ className: "lb-attachment-details"
278
+ }, /* @__PURE__ */ React__default.createElement(AttachmentName, {
279
+ attachment
280
+ }), /* @__PURE__ */ React__default.createElement("span", {
281
+ className: "lb-attachment-description",
282
+ title: description
283
+ }, description)), onDeleteClick && /* @__PURE__ */ React__default.createElement(Tooltip, {
284
+ content: deleteLabel
285
+ }, /* @__PURE__ */ React__default.createElement("button", {
286
+ type: "button",
287
+ className: "lb-attachment-delete",
288
+ onClick: onDeleteClick,
289
+ onPointerDown: handleDeletePointerDown,
290
+ "aria-label": deleteLabel
291
+ }, /* @__PURE__ */ React__default.createElement(CrossIcon, null))));
292
+ }
293
+ function separateMediaAttachments(attachments) {
294
+ const mediaAttachments = [];
295
+ const fileAttachments = [];
296
+ for (const attachment of attachments) {
297
+ if ((attachment.mimeType.startsWith("image/") || attachment.mimeType.startsWith("video/")) && attachment.size <= MAX_DISPLAYED_MEDIA_SIZE) {
298
+ mediaAttachments.push(attachment);
299
+ } else {
300
+ fileAttachments.push(attachment);
301
+ }
302
+ }
303
+ return {
304
+ mediaAttachments,
305
+ fileAttachments
306
+ };
307
+ }
308
+
309
+ export { FileAttachment, MediaAttachment, separateMediaAttachments };
310
+ //# sourceMappingURL=Attachment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Attachment.mjs","sources":["../../../src/components/internal/Attachment.tsx"],"sourcesContent":["\"use client\";\n\nimport type { CommentMixedAttachment } from \"@liveblocks/core\";\nimport { useAttachmentUrl, useIsInsideRoom } from \"@liveblocks/react\";\nimport type {\n ComponentPropsWithoutRef,\n KeyboardEvent,\n MouseEventHandler,\n PointerEvent,\n} from \"react\";\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\n\nimport { CrossIcon } from \"../../icons/Cross\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport { WarningIcon } from \"../../icons/Warning\";\nimport type { Overrides } from \"../../overrides\";\nimport { useOverrides } from \"../../overrides\";\nimport { AttachmentTooLargeError } from \"../../primitives\";\nimport { useComposerAttachmentsContextOrNull } from \"../../primitives/Composer/contexts\";\nimport { classNames } from \"../../utils/class-names\";\nimport { formatFileSize } from \"../../utils/format-file-size\";\nimport { Tooltip } from \"./Tooltip\";\n\nconst MAX_DISPLAYED_MEDIA_SIZE = 60 * 1024 * 1024; // 60 MB\n\ninterface AttachmentProps extends ComponentPropsWithoutRef<\"div\"> {\n attachment: CommentMixedAttachment;\n onDeleteClick?: MouseEventHandler<HTMLButtonElement>;\n preventFocusOnDelete?: boolean;\n overrides?: Partial<Overrides>;\n}\n\nconst fileExtensionRegex = /^(.+?)(\\.[^.]+)?$/;\n\nfunction splitFileName(name: string) {\n const match = name.match(fileExtensionRegex);\n\n return { base: match?.[1] ?? name, extension: match?.[2] };\n}\n\nfunction getAttachmentIconGlyph(mimeType: string) {\n if (\n mimeType === \"application/zip\" ||\n mimeType === \"application/gzip\" ||\n mimeType === \"application/vnd.rar\" ||\n mimeType === \"application/x-rar-compressed\" ||\n mimeType === \"application/x-7z-compressed\" ||\n mimeType === \"application/x-zip-compressed\" ||\n mimeType === \"application/x-tar\" ||\n mimeType === \"application/x-bzip\" ||\n mimeType === \"application/x-bzip2\"\n ) {\n return (\n <path d=\"M13 15h2v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1H15v1h-1.5a.5.5 0 0 0 0 1h1a.5.5 0 0 0 .5-.5V20h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 0-1H15v-1h1.5a.5.5 0 0 0 .5-.5V15a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2Z\" />\n );\n }\n\n if (\n mimeType.startsWith(\"text/\") ||\n mimeType.startsWith(\"font/\") ||\n mimeType.startsWith(\"application/\")\n ) {\n return (\n <path d=\"M10 16a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1h-8a.5.5 0 0 1-.5-.5Z\" />\n );\n }\n\n if (mimeType.startsWith(\"image/\")) {\n return (\n <path d=\"M12 16h6a1 1 0 0 1 1 1v3l-1.293-1.293a1 1 0 0 0-1.414 0L14.09 20.91l-.464-.386a1 1 0 0 0-1.265-.013l-1.231.985A.995.995 0 0 1 11 21v-4a1 1 0 0 1 1-1Zm-2 1a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2v-4Zm3 2a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" />\n );\n }\n\n if (mimeType.startsWith(\"video/\")) {\n return (\n <path d=\"M12 15.71a1 1 0 0 1 1.49-.872l4.96 2.79a1 1 0 0 1 0 1.744l-4.96 2.79A1 1 0 0 1 12 21.29v-5.58Z\" />\n );\n }\n\n if (mimeType.startsWith(\"audio/\")) {\n return (\n <path d=\"M15 15a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 1 0v-7a.5.5 0 0 0-.5-.5Zm-2.5 2.5a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3Zm-2 1a.5.5 0 0 1 1 0v1a.5.5 0 0 1-1 0v-1Zm6-1a.5.5 0 0 1 1 0v3a.5.5 0 0 1-1 0v-3ZM19 16a.5.5 0 0 0-.5.5v5a.5.5 0 0 0 1 0v-5a.5.5 0 0 0-.5-.5Z\" />\n );\n }\n\n return null;\n}\n\nconst AttachmentFileIcon = memo(({ mimeType }: { mimeType: string }) => {\n const iconGlyph = useMemo(() => getAttachmentIconGlyph(mimeType), [mimeType]);\n\n return (\n <svg\n className=\"lb-attachment-icon\"\n width={30}\n height={30}\n viewBox=\"0 0 30 30\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z\"\n className=\"lb-attachment-icon-shadow\"\n />\n <path\n d=\"M6 5a2 2 0 0 1 2-2h5.843a4 4 0 0 1 2.829 1.172l6.156 6.156A4 4 0 0 1 24 13.157V25a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5Z\"\n className=\"lb-attachment-icon-background\"\n />\n <path\n d=\"M14.382 3.037a4 4 0 0 1 2.29 1.135l6.156 6.157a4 4 0 0 1 1.136 2.289A2 2 0 0 0 22 11h-4a2 2 0 0 1-2-2V5a2 2 0 0 0-1.618-1.963Z\"\n className=\"lb-attachment-icon-fold\"\n />\n\n {iconGlyph && <g className=\"lb-attachment-icon-glyph\">{iconGlyph}</g>}\n </svg>\n );\n});\n\nfunction AttachmentImagePreview({\n attachment,\n}: {\n attachment: CommentMixedAttachment;\n}) {\n const { url } = useAttachmentUrl(attachment.id);\n const [isLoaded, setLoaded] = useState(false);\n\n const handleLoad = useCallback(() => {\n setLoaded(true);\n }, []);\n\n return (\n <>\n {!isLoaded ? <SpinnerIcon /> : null}\n {url ? (\n <div\n className=\"lb-attachment-preview-media\"\n data-hidden={!isLoaded ? \"\" : undefined}\n >\n <img src={url} loading=\"lazy\" onLoad={handleLoad} />\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AttachmentVideoPreview({\n attachment,\n}: {\n attachment: CommentMixedAttachment;\n}) {\n const { url } = useAttachmentUrl(attachment.id);\n const [isLoaded, setLoaded] = useState(false);\n\n const handleLoad = useCallback(() => {\n setLoaded(true);\n }, []);\n\n return (\n <>\n {!isLoaded ? <SpinnerIcon /> : null}\n {url ? (\n <div\n className=\"lb-attachment-preview-media\"\n data-hidden={!isLoaded ? \"\" : undefined}\n >\n <video src={url} onLoadedData={handleLoad} />\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AttachmentPreview({\n attachment,\n}: {\n attachment: CommentMixedAttachment;\n}) {\n const isInsideRoom = useIsInsideRoom();\n const isUploaded =\n attachment.type === \"attachment\" || attachment.status === \"uploaded\";\n\n if (\n isUploaded &&\n isInsideRoom &&\n attachment.size <= MAX_DISPLAYED_MEDIA_SIZE\n ) {\n if (attachment.mimeType.startsWith(\"image/\")) {\n return <AttachmentImagePreview attachment={attachment} />;\n }\n\n if (attachment.mimeType.startsWith(\"video/\")) {\n return <AttachmentVideoPreview attachment={attachment} />;\n }\n }\n\n return <AttachmentFileIcon mimeType={attachment.mimeType} />;\n}\n\nfunction AttachmentName({\n attachment,\n}: {\n attachment: CommentMixedAttachment;\n}) {\n const { base: fileBaseName, extension: fileExtension } = useMemo(() => {\n return splitFileName(attachment.name);\n }, [attachment.name]);\n\n return (\n <span className=\"lb-attachment-name\" title={attachment.name}>\n <span className=\"lb-attachment-name-base\">{fileBaseName}</span>\n {fileExtension && (\n <span className=\"lb-attachment-name-extension\">{fileExtension}</span>\n )}\n </span>\n );\n}\n\nfunction useClickOnKeyDown(\n onKeyDown?: (event: KeyboardEvent<HTMLDivElement>) => void\n) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n // Simulate a click event on Enter or Space because it's a div\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n\n const clickEvent = new MouseEvent(\"click\", {\n bubbles: true,\n cancelable: true,\n view: window,\n });\n event.target.dispatchEvent(clickEvent);\n }\n },\n [onKeyDown]\n );\n\n return handleKeyDown;\n}\n\nfunction useAttachmentContent(\n attachment: CommentMixedAttachment,\n overrides?: Partial<Overrides>\n) {\n const $ = useOverrides(overrides);\n const composerAttachmentsContext = useComposerAttachmentsContextOrNull();\n const isInComposer = Boolean(composerAttachmentsContext);\n const maxAttachmentSize = composerAttachmentsContext?.maxAttachmentSize;\n\n const status =\n attachment.type === \"localAttachment\" ? attachment.status : undefined;\n const isUploading = status === \"uploading\";\n const isError = status === \"error\";\n\n let description: string;\n\n if (attachment.type === \"localAttachment\" && attachment.status === \"error\") {\n if (attachment.error instanceof AttachmentTooLargeError) {\n description = $.ATTACHMENT_TOO_LARGE(\n maxAttachmentSize\n ? formatFileSize(maxAttachmentSize, $.locale)\n : undefined\n );\n } else {\n description = $.ATTACHMENT_ERROR(attachment.error);\n }\n } else {\n description = formatFileSize(attachment.size, $.locale);\n }\n\n const deleteLabel = isInComposer\n ? $.COMPOSER_REMOVE_ATTACHMENT\n : $.COMMENT_DELETE_ATTACHMENT;\n\n return {\n isUploading,\n isError,\n description,\n deleteLabel,\n };\n}\n\nexport function MediaAttachment({\n attachment,\n overrides,\n onClick,\n onDeleteClick,\n preventFocusOnDelete,\n className,\n onKeyDown,\n ...props\n}: AttachmentProps) {\n const { isUploading, isError, description, deleteLabel } =\n useAttachmentContent(attachment, overrides);\n\n const handleDeletePointerDown = useCallback(\n (event: PointerEvent<HTMLButtonElement>) => {\n if (preventFocusOnDelete) {\n event.preventDefault();\n }\n },\n [preventFocusOnDelete]\n );\n\n const handleKeyDown = useClickOnKeyDown(onKeyDown);\n\n return (\n <div\n className={classNames(\"lb-attachment lb-media-attachment\", className)}\n data-error={isError ? \"\" : undefined}\n {...props}\n role={onClick ? \"button\" : undefined}\n onClick={onClick}\n tabIndex={onClick ? 0 : -1}\n onKeyDown={onClick ? handleKeyDown : undefined}\n >\n <div className=\"lb-attachment-preview\">\n {isUploading ? (\n <SpinnerIcon />\n ) : isError ? (\n <WarningIcon />\n ) : (\n <AttachmentPreview attachment={attachment} />\n )}\n </div>\n <div className=\"lb-attachment-details\">\n <AttachmentName attachment={attachment} />\n <span className=\"lb-attachment-description\" title={description}>\n {description}\n </span>\n </div>\n {onDeleteClick && (\n <Tooltip content={deleteLabel}>\n <button\n type=\"button\"\n className=\"lb-attachment-delete\"\n onClick={onDeleteClick}\n onPointerDown={handleDeletePointerDown}\n aria-label={deleteLabel}\n >\n <CrossIcon />\n </button>\n </Tooltip>\n )}\n </div>\n );\n}\n\nexport function FileAttachment({\n attachment,\n overrides,\n onClick,\n onDeleteClick,\n preventFocusOnDelete,\n className,\n onKeyDown,\n ...props\n}: AttachmentProps) {\n const { isUploading, isError, description, deleteLabel } =\n useAttachmentContent(attachment, overrides);\n\n const handleDeletePointerDown = useCallback(\n (event: PointerEvent<HTMLButtonElement>) => {\n if (preventFocusOnDelete) {\n event.preventDefault();\n }\n },\n [preventFocusOnDelete]\n );\n\n const handleKeyDown = useClickOnKeyDown(onKeyDown);\n\n return (\n <div\n className={classNames(\"lb-attachment lb-file-attachment\", className)}\n data-error={isError ? \"\" : undefined}\n {...props}\n role={onClick ? \"button\" : undefined}\n onClick={onClick}\n tabIndex={onClick ? 0 : -1}\n onKeyDown={onClick ? handleKeyDown : undefined}\n >\n <div className=\"lb-attachment-preview\">\n {isUploading ? (\n <SpinnerIcon />\n ) : isError ? (\n <WarningIcon />\n ) : (\n <AttachmentPreview attachment={attachment} />\n )}\n </div>\n <div className=\"lb-attachment-details\">\n <AttachmentName attachment={attachment} />\n <span className=\"lb-attachment-description\" title={description}>\n {description}\n </span>\n </div>\n {onDeleteClick && (\n <Tooltip content={deleteLabel}>\n <button\n type=\"button\"\n className=\"lb-attachment-delete\"\n onClick={onDeleteClick}\n onPointerDown={handleDeletePointerDown}\n aria-label={deleteLabel}\n >\n <CrossIcon />\n </button>\n </Tooltip>\n )}\n </div>\n );\n}\n\nexport function separateMediaAttachments<T extends CommentMixedAttachment>(\n attachments: T[]\n) {\n const mediaAttachments: T[] = [];\n const fileAttachments: T[] = [];\n\n for (const attachment of attachments) {\n if (\n (attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\")) &&\n attachment.size <= MAX_DISPLAYED_MEDIA_SIZE\n ) {\n mediaAttachments.push(attachment);\n } else {\n fileAttachments.push(attachment);\n }\n }\n\n return {\n mediaAttachments,\n fileAttachments,\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAuBA;AASA;AAEA;AACE;AAEA;AACF;AAEA;AACE;AAWE;AACG;AAAO;AAAoP;AAIhQ;AAKE;AACG;AAAO;AAAiP;AAI7P;AACE;AACG;AAAO;AAAiQ;AAI7Q;AACE;AACG;AAAO;AAAiG;AAI7G;AACE;AACG;AAAO;AAAyP;AAIrQ;AACF;AAEA;AACE;AAEA;AACG;AACW;AACH;AACC;AACA;AACH;AACI;AACA;AACH;AAEL;AACG;AACQ;AAEX;AACG;AACQ;AAEX;AACG;AACQ;AAGG;AAAY;AAGjC;AAEA;AAAgC;AAEhC;AAGE;AACA;AAEA;AACE;AAAc;AAGhB;AAIO;AACW;AACoB;AAE7B;AAAS;AAAa;AAAe;AAKhD;AAEA;AAAgC;AAEhC;AAGE;AACA;AAEA;AACE;AAAc;AAGhB;AAIO;AACW;AACoB;AAE7B;AAAW;AAAmB;AAKzC;AAEA;AAA2B;AAE3B;AAGE;AACA;AAGA;AAKE;AACE;AAAQ;AAAuB;AAAwB;AAGzD;AACE;AAAQ;AAAuB;AAAwB;AACzD;AAGF;AAAQ;AAAwC;AAClD;AAEA;AAAwB;AAExB;AAGE;AACE;AAAoC;AAGtC;AACG;AAAe;AAAuC;AACpD;AAAe;AAEb;AAAe;AAIxB;AAEA;AAGE;AAAsB;AAElB;AAEA;AACE;AAAA;AAIF;AACE;AAEA;AAA2C;AAChC;AACG;AACN;AAER;AAAqC;AACvC;AACF;AACU;AAGZ;AACF;AAEA;AAIE;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAEA;AACE;AACE;AAAgB;AAGV;AACN;AAEA;AAAiD;AACnD;AAEA;AAAsD;AAGxD;AAIA;AAAO;AACL;AACA;AACA;AACA;AAEJ;AAEO;AAAyB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AAGA;AAAgC;AAE5B;AACE;AAAqB;AACvB;AACF;AACqB;AAGvB;AAEA;AACG;AACqE;AACzC;AACvB;AACuB;AAC3B;AACwB;AACa;AAEpC;AAAc;AAMV;AAAkB;AAGtB;AAAc;AACZ;AAAe;AACf;AAAe;AAAmC;AAKlD;AAAiB;AACf;AACM;AACK;AACD;AACM;AACH;AAQxB;AAEO;AAAwB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AAGA;AAAgC;AAE5B;AACE;AAAqB;AACvB;AACF;AACqB;AAGvB;AAEA;AACG;AACoE;AACxC;AACvB;AACuB;AAC3B;AACwB;AACa;AAEpC;AAAc;AAMV;AAAkB;AAGtB;AAAc;AACZ;AAAe;AACf;AAAe;AAAmC;AAKlD;AAAiB;AACf;AACM;AACK;AACD;AACM;AACH;AAQxB;AAEO;AAGL;AACA;AAEA;AACE;AAKE;AAAgC;AAEhC;AAA+B;AACjC;AAGF;AAAO;AACL;AACA;AAEJ;;"}
@@ -12,6 +12,8 @@ const INBOX_NOTIFICATION_THREAD_MAX_COMMENTS = 3;
12
12
  function InboxNotificationComment({
13
13
  comment,
14
14
  showHeader = true,
15
+ showAttachments = true,
16
+ showReactions = true,
15
17
  overrides: overrides$1,
16
18
  className,
17
19
  ...props
@@ -37,14 +39,22 @@ function InboxNotificationComment({
37
39
  Mention: Comment.CommentMention,
38
40
  Link: Comment.CommentNonInteractiveLink
39
41
  }
40
- }), comment.reactions.length > 0 && /* @__PURE__ */ React.createElement("div", {
42
+ }), showReactions && comment.reactions.length > 0 && /* @__PURE__ */ React.createElement("div", {
41
43
  className: "lb-comment-reactions"
42
44
  }, comment.reactions.map((reaction) => /* @__PURE__ */ React.createElement(Comment.CommentNonInteractiveReaction, {
43
45
  key: reaction.emoji,
44
46
  reaction,
45
47
  overrides: overrides$1,
46
48
  disabled: true
47
- })))) : /* @__PURE__ */ React.createElement("div", {
49
+ }))), showAttachments && comment.attachments.length > 0 ? /* @__PURE__ */ React.createElement("div", {
50
+ className: "lb-comment-attachments"
51
+ }, /* @__PURE__ */ React.createElement("div", {
52
+ className: "lb-attachments"
53
+ }, comment.attachments.map((attachment) => /* @__PURE__ */ React.createElement(Comment.CommentNonInteractiveFileAttachment, {
54
+ key: attachment.id,
55
+ attachment,
56
+ overrides: overrides$1
57
+ })))) : null) : /* @__PURE__ */ React.createElement("div", {
48
58
  className: "lb-comment-body"
49
59
  }, /* @__PURE__ */ React.createElement("p", {
50
60
  className: "lb-comment-deleted"
@@ -1 +1 @@
1
- {"version":3,"file":"InboxNotificationThread.js","sources":["../../../src/components/internal/InboxNotificationThread.tsx"],"sourcesContent":["import type {\n BaseMetadata,\n CommentData,\n InboxNotificationThreadData,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { getMentionedIdsFromCommentBody } from \"@liveblocks/core\";\nimport type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport {\n type CommentOverrides,\n type GlobalOverrides,\n useOverrides,\n} from \"../../overrides\";\nimport * as CommentPrimitive from \"../../primitives/Comment\";\nimport { classNames } from \"../../utils/class-names\";\nimport {\n CommentMention,\n CommentNonInteractiveLink,\n CommentNonInteractiveReaction,\n} from \"../Comment\";\nimport { User } from \"./User\";\n\ntype InboxNotificationThreadCommentsContents = {\n type: \"comments\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\ntype InboxNotificationThreadMentionContents = {\n type: \"mention\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\nexport const INBOX_NOTIFICATION_THREAD_MAX_COMMENTS = 3;\n\ntype InboxNotificationThreadContents =\n | InboxNotificationThreadCommentsContents\n | InboxNotificationThreadMentionContents;\n\ninterface InboxNotificationCommentProps extends ComponentProps<\"div\"> {\n comment: CommentData;\n showHeader?: boolean;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\nexport function InboxNotificationComment({\n comment,\n showHeader = true,\n overrides,\n className,\n ...props\n}: InboxNotificationCommentProps) {\n const $ = useOverrides(overrides);\n\n return (\n <div\n className={classNames(\n \"lb-root lb-inbox-notification-comment lb-comment\",\n className\n )}\n {...props}\n >\n {showHeader && (\n <div className=\"lb-comment-header\">\n <User className=\"lb-comment-author\" userId={comment.userId} />\n </div>\n )}\n <div className=\"lb-comment-content\">\n {comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: CommentMention,\n Link: CommentNonInteractiveLink,\n }}\n />\n {comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentNonInteractiveReaction\n key={reaction.emoji}\n reaction={reaction}\n overrides={overrides}\n disabled\n />\n ))}\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Find the last comment with a mention for the given user ID,\n * unless the comment was created by the user themselves.\n */\nfunction findLastCommentWithMentionedId(\n comments: CommentData[],\n mentionedId: string\n) {\n for (let i = comments.length - 1; i >= 0; i--) {\n const comment = comments[i];\n\n if (comment.userId === mentionedId) {\n continue;\n }\n\n if (comment.body) {\n const mentionedIds = getMentionedIdsFromCommentBody(comment.body);\n\n if (mentionedIds.includes(mentionedId)) {\n return comment;\n }\n }\n }\n\n return;\n}\n\nfunction getUserIdsFromComments(comments: CommentData[]) {\n return Array.from(new Set(comments.map((comment) => comment.userId)));\n}\n\nexport function generateInboxNotificationThreadContents(\n inboxNotification: InboxNotificationThreadData,\n thread: ThreadData<BaseMetadata>,\n userId: string\n): InboxNotificationThreadContents {\n const unreadComments = thread.comments.filter((comment) => {\n if (!comment.body) {\n return false;\n }\n\n return inboxNotification.readAt\n ? comment.createdAt > inboxNotification.readAt &&\n comment.createdAt <= inboxNotification.notifiedAt\n : comment.createdAt <= inboxNotification.notifiedAt;\n });\n\n // If the thread is read, show the last comments.\n if (unreadComments.length === 0) {\n const lastComments = thread.comments\n .filter((comment) => comment.body)\n .slice(-INBOX_NOTIFICATION_THREAD_MAX_COMMENTS);\n\n return {\n type: \"comments\",\n unread: false,\n comments: lastComments,\n userIds: getUserIdsFromComments(lastComments),\n date: inboxNotification.notifiedAt,\n };\n }\n\n const commentWithMention = findLastCommentWithMentionedId(\n unreadComments,\n userId\n );\n\n // If the thread contains one or more mentions for the current user, show the last comment with a mention.\n if (commentWithMention) {\n return {\n type: \"mention\",\n unread: true,\n comments: [commentWithMention],\n userIds: [commentWithMention.userId],\n date: commentWithMention.createdAt,\n };\n }\n\n const lastUnreadComments = unreadComments.slice(\n -INBOX_NOTIFICATION_THREAD_MAX_COMMENTS\n );\n\n // Otherwise, show the last unread comments.\n return {\n type: \"comments\",\n unread: true,\n comments: lastUnreadComments,\n userIds: getUserIdsFromComments(unreadComments),\n date: inboxNotification.notifiedAt,\n };\n}\n"],"names":["overrides","useOverrides","classNames","User","CommentPrimitive.Body","CommentMention","CommentNonInteractiveLink","CommentNonInteractiveReaction","getMentionedIdsFromCommentBody"],"mappings":"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"}
1
+ {"version":3,"file":"InboxNotificationThread.js","sources":["../../../src/components/internal/InboxNotificationThread.tsx"],"sourcesContent":["import type {\n BaseMetadata,\n CommentData,\n InboxNotificationThreadData,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { getMentionedIdsFromCommentBody } from \"@liveblocks/core\";\nimport type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport {\n type CommentOverrides,\n type GlobalOverrides,\n useOverrides,\n} from \"../../overrides\";\nimport * as CommentPrimitive from \"../../primitives/Comment\";\nimport { classNames } from \"../../utils/class-names\";\nimport {\n CommentMention,\n CommentNonInteractiveFileAttachment,\n CommentNonInteractiveLink,\n CommentNonInteractiveReaction,\n} from \"../Comment\";\nimport { User } from \"./User\";\n\ntype InboxNotificationThreadCommentsContents = {\n type: \"comments\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\ntype InboxNotificationThreadMentionContents = {\n type: \"mention\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\nexport const INBOX_NOTIFICATION_THREAD_MAX_COMMENTS = 3;\n\ntype InboxNotificationThreadContents =\n | InboxNotificationThreadCommentsContents\n | InboxNotificationThreadMentionContents;\n\ninterface InboxNotificationCommentProps extends ComponentProps<\"div\"> {\n comment: CommentData;\n showHeader?: boolean;\n showAttachments?: boolean;\n showReactions?: boolean;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\nexport function InboxNotificationComment({\n comment,\n showHeader = true,\n showAttachments = true,\n showReactions = true,\n overrides,\n className,\n ...props\n}: InboxNotificationCommentProps) {\n const $ = useOverrides(overrides);\n\n return (\n <div\n className={classNames(\n \"lb-root lb-inbox-notification-comment lb-comment\",\n className\n )}\n {...props}\n >\n {showHeader && (\n <div className=\"lb-comment-header\">\n <User className=\"lb-comment-author\" userId={comment.userId} />\n </div>\n )}\n <div className=\"lb-comment-content\">\n {comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: CommentMention,\n Link: CommentNonInteractiveLink,\n }}\n />\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentNonInteractiveReaction\n key={reaction.emoji}\n reaction={reaction}\n overrides={overrides}\n disabled\n />\n ))}\n </div>\n )}\n {showAttachments && comment.attachments.length > 0 ? (\n <div className=\"lb-comment-attachments\">\n <div className=\"lb-attachments\">\n {comment.attachments.map((attachment) => (\n <CommentNonInteractiveFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n />\n ))}\n </div>\n </div>\n ) : null}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Find the last comment with a mention for the given user ID,\n * unless the comment was created by the user themselves.\n */\nfunction findLastCommentWithMentionedId(\n comments: CommentData[],\n mentionedId: string\n) {\n for (let i = comments.length - 1; i >= 0; i--) {\n const comment = comments[i];\n\n if (comment.userId === mentionedId) {\n continue;\n }\n\n if (comment.body) {\n const mentionedIds = getMentionedIdsFromCommentBody(comment.body);\n\n if (mentionedIds.includes(mentionedId)) {\n return comment;\n }\n }\n }\n\n return;\n}\n\nfunction getUserIdsFromComments(comments: CommentData[]) {\n return Array.from(new Set(comments.map((comment) => comment.userId)));\n}\n\nexport function generateInboxNotificationThreadContents(\n inboxNotification: InboxNotificationThreadData,\n thread: ThreadData<BaseMetadata>,\n userId: string\n): InboxNotificationThreadContents {\n const unreadComments = thread.comments.filter((comment) => {\n if (!comment.body) {\n return false;\n }\n\n return inboxNotification.readAt\n ? comment.createdAt > inboxNotification.readAt &&\n comment.createdAt <= inboxNotification.notifiedAt\n : comment.createdAt <= inboxNotification.notifiedAt;\n });\n\n // If the thread is read, show the last comments.\n if (unreadComments.length === 0) {\n const lastComments = thread.comments\n .filter((comment) => comment.body)\n .slice(-INBOX_NOTIFICATION_THREAD_MAX_COMMENTS);\n\n return {\n type: \"comments\",\n unread: false,\n comments: lastComments,\n userIds: getUserIdsFromComments(lastComments),\n date: inboxNotification.notifiedAt,\n };\n }\n\n const commentWithMention = findLastCommentWithMentionedId(\n unreadComments,\n userId\n );\n\n // If the thread contains one or more mentions for the current user, show the last comment with a mention.\n if (commentWithMention) {\n return {\n type: \"mention\",\n unread: true,\n comments: [commentWithMention],\n userIds: [commentWithMention.userId],\n date: commentWithMention.createdAt,\n };\n }\n\n const lastUnreadComments = unreadComments.slice(\n -INBOX_NOTIFICATION_THREAD_MAX_COMMENTS\n );\n\n // Otherwise, show the last unread comments.\n return {\n type: \"comments\",\n unread: true,\n comments: lastUnreadComments,\n userIds: getUserIdsFromComments(unreadComments),\n date: inboxNotification.notifiedAt,\n };\n}\n"],"names":["overrides","useOverrides","classNames","User","CommentPrimitive.Body","CommentMention","CommentNonInteractiveLink","CommentNonInteractiveReaction","CommentNonInteractiveFileAttachment","getMentionedIdsFromCommentBody"],"mappings":"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"}
@@ -3,13 +3,15 @@ import React__default from 'react';
3
3
  import { useOverrides } from '../../overrides.mjs';
4
4
  import { Body as CommentBody } from '../../primitives/Comment/index.mjs';
5
5
  import { classNames } from '../../utils/class-names.mjs';
6
- import { CommentMention, CommentNonInteractiveLink, CommentNonInteractiveReaction } from '../Comment.mjs';
6
+ import { CommentMention, CommentNonInteractiveLink, CommentNonInteractiveReaction, CommentNonInteractiveFileAttachment } from '../Comment.mjs';
7
7
  import { User } from './User.mjs';
8
8
 
9
9
  const INBOX_NOTIFICATION_THREAD_MAX_COMMENTS = 3;
10
10
  function InboxNotificationComment({
11
11
  comment,
12
12
  showHeader = true,
13
+ showAttachments = true,
14
+ showReactions = true,
13
15
  overrides,
14
16
  className,
15
17
  ...props
@@ -35,14 +37,22 @@ function InboxNotificationComment({
35
37
  Mention: CommentMention,
36
38
  Link: CommentNonInteractiveLink
37
39
  }
38
- }), comment.reactions.length > 0 && /* @__PURE__ */ React__default.createElement("div", {
40
+ }), showReactions && comment.reactions.length > 0 && /* @__PURE__ */ React__default.createElement("div", {
39
41
  className: "lb-comment-reactions"
40
42
  }, comment.reactions.map((reaction) => /* @__PURE__ */ React__default.createElement(CommentNonInteractiveReaction, {
41
43
  key: reaction.emoji,
42
44
  reaction,
43
45
  overrides,
44
46
  disabled: true
45
- })))) : /* @__PURE__ */ React__default.createElement("div", {
47
+ }))), showAttachments && comment.attachments.length > 0 ? /* @__PURE__ */ React__default.createElement("div", {
48
+ className: "lb-comment-attachments"
49
+ }, /* @__PURE__ */ React__default.createElement("div", {
50
+ className: "lb-attachments"
51
+ }, comment.attachments.map((attachment) => /* @__PURE__ */ React__default.createElement(CommentNonInteractiveFileAttachment, {
52
+ key: attachment.id,
53
+ attachment,
54
+ overrides
55
+ })))) : null) : /* @__PURE__ */ React__default.createElement("div", {
46
56
  className: "lb-comment-body"
47
57
  }, /* @__PURE__ */ React__default.createElement("p", {
48
58
  className: "lb-comment-deleted"
@@ -1 +1 @@
1
- {"version":3,"file":"InboxNotificationThread.mjs","sources":["../../../src/components/internal/InboxNotificationThread.tsx"],"sourcesContent":["import type {\n BaseMetadata,\n CommentData,\n InboxNotificationThreadData,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { getMentionedIdsFromCommentBody } from \"@liveblocks/core\";\nimport type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport {\n type CommentOverrides,\n type GlobalOverrides,\n useOverrides,\n} from \"../../overrides\";\nimport * as CommentPrimitive from \"../../primitives/Comment\";\nimport { classNames } from \"../../utils/class-names\";\nimport {\n CommentMention,\n CommentNonInteractiveLink,\n CommentNonInteractiveReaction,\n} from \"../Comment\";\nimport { User } from \"./User\";\n\ntype InboxNotificationThreadCommentsContents = {\n type: \"comments\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\ntype InboxNotificationThreadMentionContents = {\n type: \"mention\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\nexport const INBOX_NOTIFICATION_THREAD_MAX_COMMENTS = 3;\n\ntype InboxNotificationThreadContents =\n | InboxNotificationThreadCommentsContents\n | InboxNotificationThreadMentionContents;\n\ninterface InboxNotificationCommentProps extends ComponentProps<\"div\"> {\n comment: CommentData;\n showHeader?: boolean;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\nexport function InboxNotificationComment({\n comment,\n showHeader = true,\n overrides,\n className,\n ...props\n}: InboxNotificationCommentProps) {\n const $ = useOverrides(overrides);\n\n return (\n <div\n className={classNames(\n \"lb-root lb-inbox-notification-comment lb-comment\",\n className\n )}\n {...props}\n >\n {showHeader && (\n <div className=\"lb-comment-header\">\n <User className=\"lb-comment-author\" userId={comment.userId} />\n </div>\n )}\n <div className=\"lb-comment-content\">\n {comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: CommentMention,\n Link: CommentNonInteractiveLink,\n }}\n />\n {comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentNonInteractiveReaction\n key={reaction.emoji}\n reaction={reaction}\n overrides={overrides}\n disabled\n />\n ))}\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Find the last comment with a mention for the given user ID,\n * unless the comment was created by the user themselves.\n */\nfunction findLastCommentWithMentionedId(\n comments: CommentData[],\n mentionedId: string\n) {\n for (let i = comments.length - 1; i >= 0; i--) {\n const comment = comments[i];\n\n if (comment.userId === mentionedId) {\n continue;\n }\n\n if (comment.body) {\n const mentionedIds = getMentionedIdsFromCommentBody(comment.body);\n\n if (mentionedIds.includes(mentionedId)) {\n return comment;\n }\n }\n }\n\n return;\n}\n\nfunction getUserIdsFromComments(comments: CommentData[]) {\n return Array.from(new Set(comments.map((comment) => comment.userId)));\n}\n\nexport function generateInboxNotificationThreadContents(\n inboxNotification: InboxNotificationThreadData,\n thread: ThreadData<BaseMetadata>,\n userId: string\n): InboxNotificationThreadContents {\n const unreadComments = thread.comments.filter((comment) => {\n if (!comment.body) {\n return false;\n }\n\n return inboxNotification.readAt\n ? comment.createdAt > inboxNotification.readAt &&\n comment.createdAt <= inboxNotification.notifiedAt\n : comment.createdAt <= inboxNotification.notifiedAt;\n });\n\n // If the thread is read, show the last comments.\n if (unreadComments.length === 0) {\n const lastComments = thread.comments\n .filter((comment) => comment.body)\n .slice(-INBOX_NOTIFICATION_THREAD_MAX_COMMENTS);\n\n return {\n type: \"comments\",\n unread: false,\n comments: lastComments,\n userIds: getUserIdsFromComments(lastComments),\n date: inboxNotification.notifiedAt,\n };\n }\n\n const commentWithMention = findLastCommentWithMentionedId(\n unreadComments,\n userId\n );\n\n // If the thread contains one or more mentions for the current user, show the last comment with a mention.\n if (commentWithMention) {\n return {\n type: \"mention\",\n unread: true,\n comments: [commentWithMention],\n userIds: [commentWithMention.userId],\n date: commentWithMention.createdAt,\n };\n }\n\n const lastUnreadComments = unreadComments.slice(\n -INBOX_NOTIFICATION_THREAD_MAX_COMMENTS\n );\n\n // Otherwise, show the last unread comments.\n return {\n type: \"comments\",\n unread: true,\n comments: lastUnreadComments,\n userIds: getUserIdsFromComments(unreadComments),\n date: inboxNotification.notifiedAt,\n };\n}\n"],"names":["React","CommentPrimitive.Body"],"mappings":"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"}
1
+ {"version":3,"file":"InboxNotificationThread.mjs","sources":["../../../src/components/internal/InboxNotificationThread.tsx"],"sourcesContent":["import type {\n BaseMetadata,\n CommentData,\n InboxNotificationThreadData,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { getMentionedIdsFromCommentBody } from \"@liveblocks/core\";\nimport type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport {\n type CommentOverrides,\n type GlobalOverrides,\n useOverrides,\n} from \"../../overrides\";\nimport * as CommentPrimitive from \"../../primitives/Comment\";\nimport { classNames } from \"../../utils/class-names\";\nimport {\n CommentMention,\n CommentNonInteractiveFileAttachment,\n CommentNonInteractiveLink,\n CommentNonInteractiveReaction,\n} from \"../Comment\";\nimport { User } from \"./User\";\n\ntype InboxNotificationThreadCommentsContents = {\n type: \"comments\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\ntype InboxNotificationThreadMentionContents = {\n type: \"mention\";\n unread: boolean;\n comments: CommentData[];\n userIds: string[];\n date: Date;\n};\n\nexport const INBOX_NOTIFICATION_THREAD_MAX_COMMENTS = 3;\n\ntype InboxNotificationThreadContents =\n | InboxNotificationThreadCommentsContents\n | InboxNotificationThreadMentionContents;\n\ninterface InboxNotificationCommentProps extends ComponentProps<\"div\"> {\n comment: CommentData;\n showHeader?: boolean;\n showAttachments?: boolean;\n showReactions?: boolean;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\nexport function InboxNotificationComment({\n comment,\n showHeader = true,\n showAttachments = true,\n showReactions = true,\n overrides,\n className,\n ...props\n}: InboxNotificationCommentProps) {\n const $ = useOverrides(overrides);\n\n return (\n <div\n className={classNames(\n \"lb-root lb-inbox-notification-comment lb-comment\",\n className\n )}\n {...props}\n >\n {showHeader && (\n <div className=\"lb-comment-header\">\n <User className=\"lb-comment-author\" userId={comment.userId} />\n </div>\n )}\n <div className=\"lb-comment-content\">\n {comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: CommentMention,\n Link: CommentNonInteractiveLink,\n }}\n />\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentNonInteractiveReaction\n key={reaction.emoji}\n reaction={reaction}\n overrides={overrides}\n disabled\n />\n ))}\n </div>\n )}\n {showAttachments && comment.attachments.length > 0 ? (\n <div className=\"lb-comment-attachments\">\n <div className=\"lb-attachments\">\n {comment.attachments.map((attachment) => (\n <CommentNonInteractiveFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n />\n ))}\n </div>\n </div>\n ) : null}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Find the last comment with a mention for the given user ID,\n * unless the comment was created by the user themselves.\n */\nfunction findLastCommentWithMentionedId(\n comments: CommentData[],\n mentionedId: string\n) {\n for (let i = comments.length - 1; i >= 0; i--) {\n const comment = comments[i];\n\n if (comment.userId === mentionedId) {\n continue;\n }\n\n if (comment.body) {\n const mentionedIds = getMentionedIdsFromCommentBody(comment.body);\n\n if (mentionedIds.includes(mentionedId)) {\n return comment;\n }\n }\n }\n\n return;\n}\n\nfunction getUserIdsFromComments(comments: CommentData[]) {\n return Array.from(new Set(comments.map((comment) => comment.userId)));\n}\n\nexport function generateInboxNotificationThreadContents(\n inboxNotification: InboxNotificationThreadData,\n thread: ThreadData<BaseMetadata>,\n userId: string\n): InboxNotificationThreadContents {\n const unreadComments = thread.comments.filter((comment) => {\n if (!comment.body) {\n return false;\n }\n\n return inboxNotification.readAt\n ? comment.createdAt > inboxNotification.readAt &&\n comment.createdAt <= inboxNotification.notifiedAt\n : comment.createdAt <= inboxNotification.notifiedAt;\n });\n\n // If the thread is read, show the last comments.\n if (unreadComments.length === 0) {\n const lastComments = thread.comments\n .filter((comment) => comment.body)\n .slice(-INBOX_NOTIFICATION_THREAD_MAX_COMMENTS);\n\n return {\n type: \"comments\",\n unread: false,\n comments: lastComments,\n userIds: getUserIdsFromComments(lastComments),\n date: inboxNotification.notifiedAt,\n };\n }\n\n const commentWithMention = findLastCommentWithMentionedId(\n unreadComments,\n userId\n );\n\n // If the thread contains one or more mentions for the current user, show the last comment with a mention.\n if (commentWithMention) {\n return {\n type: \"mention\",\n unread: true,\n comments: [commentWithMention],\n userIds: [commentWithMention.userId],\n date: commentWithMention.createdAt,\n };\n }\n\n const lastUnreadComments = unreadComments.slice(\n -INBOX_NOTIFICATION_THREAD_MAX_COMMENTS\n );\n\n // Otherwise, show the last unread comments.\n return {\n type: \"comments\",\n unread: true,\n comments: lastUnreadComments,\n userIds: getUserIdsFromComments(unreadComments),\n date: inboxNotification.notifiedAt,\n };\n}\n"],"names":["React","CommentPrimitive.Body"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var Icon = require('../components/internal/Icon.js');
5
+
6
+ function AttachmentIcon(props) {
7
+ return /* @__PURE__ */ React.createElement(Icon.Icon, {
8
+ ...props
9
+ }, /* @__PURE__ */ React.createElement("path", {
10
+ d: "m14.077 11.737-3.723 3.62c-1.55 1.507-4.128 1.507-5.678 0-1.543-1.5-1.543-4.02 0-5.52l5.731-5.573c1.034-1.006 2.754-1.007 3.789-.003 1.03 1 1.032 2.682.003 3.684l-5.744 5.572a1.377 1.377 0 0 1-1.893 0 1.283 1.283 0 0 1-.392-.92c0-.345.14-.676.392-.92L10.348 8"
11
+ }));
12
+ }
13
+
14
+ exports.AttachmentIcon = AttachmentIcon;
15
+ //# sourceMappingURL=Attachment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Attachment.js","sources":["../../src/icons/Attachment.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function AttachmentIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"m14.077 11.737-3.723 3.62c-1.55 1.507-4.128 1.507-5.678 0-1.543-1.5-1.543-4.02 0-5.52l5.731-5.573c1.034-1.006 2.754-1.007 3.789-.003 1.03 1 1.032 2.682.003 3.684l-5.744 5.572a1.377 1.377 0 0 1-1.893 0 1.283 1.283 0 0 1-.392-.92c0-.345.14-.676.392-.92L10.348 8\" />\n </Icon>\n );\n}\n"],"names":["Icon"],"mappings":";;;;;AAKO,SAAS,eAAe,KAA8B,EAAA;AAC3D,EAAA,uBACG,KAAA,CAAA,aAAA,CAAAA,SAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,GAAA,kBACP,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,CAAE,EAAA,qQAAA;AAAA,GAAsQ,CAChR,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,13 @@
1
+ import React__default from 'react';
2
+ import { Icon } from '../components/internal/Icon.mjs';
3
+
4
+ function AttachmentIcon(props) {
5
+ return /* @__PURE__ */ React__default.createElement(Icon, {
6
+ ...props
7
+ }, /* @__PURE__ */ React__default.createElement("path", {
8
+ d: "m14.077 11.737-3.723 3.62c-1.55 1.507-4.128 1.507-5.678 0-1.543-1.5-1.543-4.02 0-5.52l5.731-5.573c1.034-1.006 2.754-1.007 3.789-.003 1.03 1 1.032 2.682.003 3.684l-5.744 5.572a1.377 1.377 0 0 1-1.893 0 1.283 1.283 0 0 1-.392-.92c0-.345.14-.676.392-.92L10.348 8"
9
+ }));
10
+ }
11
+
12
+ export { AttachmentIcon };
13
+ //# sourceMappingURL=Attachment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Attachment.mjs","sources":["../../src/icons/Attachment.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function AttachmentIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"m14.077 11.737-3.723 3.62c-1.55 1.507-4.128 1.507-5.678 0-1.543-1.5-1.543-4.02 0-5.52l5.731-5.573c1.034-1.006 2.754-1.007 3.789-.003 1.03 1 1.032 2.682.003 3.684l-5.744 5.572a1.377 1.377 0 0 1-1.893 0 1.283 1.283 0 0 1-.392-.92c0-.345.14-.676.392-.92L10.348 8\" />\n </Icon>\n );\n}\n"],"names":["React"],"mappings":";;;AAKO,SAAS,eAAe,KAA8B,EAAA;AAC3D,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,GAAA,kBACPA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,CAAE,EAAA,qQAAA;AAAA,GAAsQ,CAChR,CAAA,CAAA;AAEJ;;;;"}
@@ -7,15 +7,9 @@ function SpinnerIcon(props) {
7
7
  return /* @__PURE__ */ React.createElement(Icon.Icon, {
8
8
  ...props
9
9
  }, /* @__PURE__ */ React.createElement("path", {
10
- d: "M3 10a7 7 0 0 1 7-7"
11
- }, /* @__PURE__ */ React.createElement("animateTransform", {
12
- xmlns: "http://www.w3.org/2000/svg",
13
- attributeName: "transform",
14
- type: "rotate",
15
- dur: "0.75s",
16
- values: `0 ${Icon.ICON_WIDTH / 2} ${Icon.ICON_HEIGHT / 2};360 ${Icon.ICON_WIDTH / 2} ${Icon.ICON_HEIGHT / 2}`,
17
- repeatCount: "indefinite"
18
- })));
10
+ d: "M3 10a7 7 0 0 1 7-7",
11
+ className: "lb-icon-spinner"
12
+ }));
19
13
  }
20
14
 
21
15
  exports.SpinnerIcon = SpinnerIcon;
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.js","sources":["../../src/icons/Spinner.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport { Icon, ICON_HEIGHT, ICON_WIDTH } from \"../components/internal/Icon\";\n\nexport function SpinnerIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M3 10a7 7 0 0 1 7-7\">\n <animateTransform\n xmlns=\"http://www.w3.org/2000/svg\"\n attributeName=\"transform\"\n type=\"rotate\"\n dur=\"0.75s\"\n values={`0 ${ICON_WIDTH / 2} ${ICON_HEIGHT / 2};360 ${\n ICON_WIDTH / 2\n } ${ICON_HEIGHT / 2}`}\n repeatCount=\"indefinite\"\n />\n </path>\n </Icon>\n );\n}\n"],"names":["Icon","ICON_WIDTH","ICON_HEIGHT"],"mappings":";;;;;AAKO,SAAS,YAAY,KAA8B,EAAA;AACxD,EAAA,uBACG,KAAA,CAAA,aAAA,CAAAA,SAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,GAAA,kBACP,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,CAAE,EAAA,qBAAA;AAAA,GAAA,kBACL,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,IACC,KAAM,EAAA,4BAAA;AAAA,IACN,aAAc,EAAA,WAAA;AAAA,IACd,IAAK,EAAA,QAAA;AAAA,IACL,GAAI,EAAA,OAAA;AAAA,IACJ,MAAA,EAAQ,KAAKC,eAAa,GAAA,CAAA,CAAA,CAAA,EAAKC,mBAAc,CAC3C,CAAA,KAAA,EAAAD,eAAA,GAAa,KACXC,gBAAc,GAAA,CAAA,CAAA,CAAA;AAAA,IAClB,WAAY,EAAA,YAAA;AAAA,GACd,CACF,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Spinner.js","sources":["../../src/icons/Spinner.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function SpinnerIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M3 10a7 7 0 0 1 7-7\" className=\"lb-icon-spinner\" />\n </Icon>\n );\n}\n"],"names":["Icon"],"mappings":";;;;;AAKO,SAAS,YAAY,KAA8B,EAAA;AACxD,EAAA,uBACG,KAAA,CAAA,aAAA,CAAAA,SAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,GAAA,kBACP,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,CAAE,EAAA,qBAAA;AAAA,IAAsB,SAAU,EAAA,iBAAA;AAAA,GAAkB,CAC5D,CAAA,CAAA;AAEJ;;;;"}
@@ -1,19 +1,13 @@
1
1
  import React__default from 'react';
2
- import { Icon, ICON_WIDTH, ICON_HEIGHT } from '../components/internal/Icon.mjs';
2
+ import { Icon } from '../components/internal/Icon.mjs';
3
3
 
4
4
  function SpinnerIcon(props) {
5
5
  return /* @__PURE__ */ React__default.createElement(Icon, {
6
6
  ...props
7
7
  }, /* @__PURE__ */ React__default.createElement("path", {
8
- d: "M3 10a7 7 0 0 1 7-7"
9
- }, /* @__PURE__ */ React__default.createElement("animateTransform", {
10
- xmlns: "http://www.w3.org/2000/svg",
11
- attributeName: "transform",
12
- type: "rotate",
13
- dur: "0.75s",
14
- values: `0 ${ICON_WIDTH / 2} ${ICON_HEIGHT / 2};360 ${ICON_WIDTH / 2} ${ICON_HEIGHT / 2}`,
15
- repeatCount: "indefinite"
16
- })));
8
+ d: "M3 10a7 7 0 0 1 7-7",
9
+ className: "lb-icon-spinner"
10
+ }));
17
11
  }
18
12
 
19
13
  export { SpinnerIcon };
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.mjs","sources":["../../src/icons/Spinner.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport { Icon, ICON_HEIGHT, ICON_WIDTH } from \"../components/internal/Icon\";\n\nexport function SpinnerIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M3 10a7 7 0 0 1 7-7\">\n <animateTransform\n xmlns=\"http://www.w3.org/2000/svg\"\n attributeName=\"transform\"\n type=\"rotate\"\n dur=\"0.75s\"\n values={`0 ${ICON_WIDTH / 2} ${ICON_HEIGHT / 2};360 ${\n ICON_WIDTH / 2\n } ${ICON_HEIGHT / 2}`}\n repeatCount=\"indefinite\"\n />\n </path>\n </Icon>\n );\n}\n"],"names":["React"],"mappings":";;;AAKO,SAAS,YAAY,KAA8B,EAAA;AACxD,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,GAAA,kBACPA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,CAAE,EAAA,qBAAA;AAAA,GAAA,kBACLA,cAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,IACC,KAAM,EAAA,4BAAA;AAAA,IACN,aAAc,EAAA,WAAA;AAAA,IACd,IAAK,EAAA,QAAA;AAAA,IACL,GAAI,EAAA,OAAA;AAAA,IACJ,MAAA,EAAQ,KAAK,UAAa,GAAA,CAAA,CAAA,CAAA,EAAK,cAAc,CAC3C,CAAA,KAAA,EAAA,UAAA,GAAa,KACX,WAAc,GAAA,CAAA,CAAA,CAAA;AAAA,IAClB,WAAY,EAAA,YAAA;AAAA,GACd,CACF,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Spinner.mjs","sources":["../../src/icons/Spinner.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport React from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function SpinnerIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M3 10a7 7 0 0 1 7-7\" className=\"lb-icon-spinner\" />\n </Icon>\n );\n}\n"],"names":["React"],"mappings":";;;AAKO,SAAS,YAAY,KAA8B,EAAA;AACxD,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,GAAA,kBACPA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,CAAE,EAAA,qBAAA;AAAA,IAAsB,SAAU,EAAA,iBAAA;AAAA,GAAkB,CAC5D,CAAA,CAAA;AAEJ;;;;"}