@calmlens/sdk 0.16.2 → 0.17.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 (112) hide show
  1. package/README.md +399 -162
  2. package/cjs/BrowserUpload-DZ0Vbmxi.js +10 -0
  3. package/cjs/BrowserUpload-uZjVFGfP.d.ts +11 -0
  4. package/cjs/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
  5. package/cjs/CalmLensAppClient-DBGmaDlG.js +89 -0
  6. package/cjs/CalmLensConnection-K1TAD1Z-.js +659 -0
  7. package/cjs/CalmLensServerClient-C-pxiz0C.js +645 -0
  8. package/cjs/CalmLensServerClient-JtP687a3.d.ts +235 -0
  9. package/cjs/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
  10. package/cjs/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
  11. package/cjs/CryptoUtils-B_x8lMIx-YBW1-bvL.js +42 -0
  12. package/cjs/FileIcons-Ob003MdS.js +175 -0
  13. package/cjs/Jurisdiction-FusEXb4U-zVs21tDv.js +91 -0
  14. package/cjs/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
  15. package/cjs/ModerationContextLimits-Dj1YAl3G.js +1311 -0
  16. package/cjs/ReactUpload-DxtFMr06.js +54 -0
  17. package/cjs/ReactUpload-nZahpmyg.d.ts +17 -0
  18. package/cjs/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
  19. package/cjs/TestTriggers-DcArt0Nu-CvoaONUB.js +1326 -0
  20. package/cjs/UploadController-BBkN4Ni6.js +618 -0
  21. package/{esm/index-C9Xw1aid.d.ts → cjs/WebhookPayload-2aL31v0J.d.ts} +131 -155
  22. package/cjs/app.d.ts +7 -44
  23. package/cjs/app.js +11 -89
  24. package/cjs/elements.d.ts +88 -0
  25. package/cjs/elements.js +555 -0
  26. package/cjs/file-icons.d.ts +67 -0
  27. package/cjs/file-icons.js +10 -0
  28. package/cjs/index-CI4BzN4W.d.ts +252 -0
  29. package/cjs/index.d.ts +6 -4
  30. package/cjs/index.js +9 -4
  31. package/cjs/react-native.d.ts +56 -0
  32. package/cjs/react-native.js +495 -0
  33. package/cjs/react.d.ts +30 -0
  34. package/cjs/react.js +370 -0
  35. package/cjs/server.d.ts +12 -191
  36. package/cjs/server.js +18 -378
  37. package/cjs/test-inputs.d.ts +2 -2
  38. package/cjs/test-inputs.js +9 -264
  39. package/cjs/testing.d.ts +285 -190
  40. package/cjs/testing.js +2393 -1203
  41. package/cjs/ui-CgZpgpNo.d.ts +526 -0
  42. package/cjs/ui-KceuoVCM.js +583 -0
  43. package/cjs/ui.d.ts +2 -0
  44. package/cjs/ui.js +27 -0
  45. package/cjs/vue.d.ts +490 -0
  46. package/cjs/vue.js +419 -0
  47. package/esm/BrowserUpload-D7-zNmc0.js +5 -0
  48. package/esm/BrowserUpload-uZjVFGfP.d.ts +11 -0
  49. package/esm/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
  50. package/esm/CalmLensAppClient-FVMwrHlH.js +84 -0
  51. package/esm/CalmLensConnection-iyNQHA8L.js +582 -0
  52. package/esm/CalmLensServerClient-JtP687a3.d.ts +235 -0
  53. package/esm/CalmLensServerClient-fQEYKLw4.js +586 -0
  54. package/esm/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
  55. package/esm/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
  56. package/esm/CryptoUtils-B_x8lMIx-DhuWGzqn.js +25 -0
  57. package/esm/FileIcons-M6dzjFxd.js +128 -0
  58. package/esm/Jurisdiction-FusEXb4U-1ov6m5yE.js +46 -0
  59. package/esm/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
  60. package/esm/ModerationContextLimits-D1x_WAtP.js +1114 -0
  61. package/esm/ReactUpload-D6yBCkcw.js +37 -0
  62. package/esm/ReactUpload-nZahpmyg.d.ts +17 -0
  63. package/esm/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
  64. package/esm/TestTriggers-DcArt0Nu-s0AQZuWE.js +1266 -0
  65. package/esm/UploadController-txp5NuzH.js +589 -0
  66. package/{cjs/index-C9Xw1aid.d.ts → esm/WebhookPayload-2aL31v0J.d.ts} +131 -155
  67. package/esm/app.d.ts +7 -44
  68. package/esm/app.js +3 -86
  69. package/esm/elements.d.ts +88 -0
  70. package/esm/elements.js +528 -0
  71. package/esm/file-icons.d.ts +67 -0
  72. package/esm/file-icons.js +1 -0
  73. package/esm/index-CI4BzN4W.d.ts +252 -0
  74. package/esm/index.d.ts +6 -4
  75. package/esm/index.js +1 -1
  76. package/esm/react-native.d.ts +56 -0
  77. package/esm/react-native.js +467 -0
  78. package/esm/react.d.ts +30 -0
  79. package/esm/react.js +343 -0
  80. package/esm/server.d.ts +12 -191
  81. package/esm/server.js +3 -369
  82. package/esm/styles.css +147 -0
  83. package/esm/svelte/CalmLensMedia.svelte +134 -0
  84. package/esm/svelte/CalmLensUploader.svelte +175 -0
  85. package/esm/svelte/Icon.svelte +7 -0
  86. package/esm/svelte/index.d.ts +37 -0
  87. package/esm/svelte/index.js +6 -0
  88. package/esm/test-inputs.d.ts +2 -2
  89. package/esm/test-inputs.js +1 -256
  90. package/esm/testing.d.ts +285 -190
  91. package/esm/testing.js +2329 -1122
  92. package/esm/ui-Ca_SpJXf.js +458 -0
  93. package/esm/ui-CgZpgpNo.d.ts +526 -0
  94. package/esm/ui.d.ts +2 -0
  95. package/esm/ui.js +3 -0
  96. package/esm/vue.d.ts +490 -0
  97. package/esm/vue.js +392 -0
  98. package/package.json +110 -11
  99. package/cjs/CalmLensConnection-5Hj3trGr.js +0 -234
  100. package/cjs/CalmLensUtils-BeIl1N6N.js +0 -699
  101. package/cjs/CalmLensVersion-BGpB9t4-.js +0 -480
  102. package/cjs/CalmLensWebhooks-CogUYk8-.js +0 -201
  103. package/cjs/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
  104. package/cjs/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
  105. package/cjs/WebhookPayload-CJoIkGBD.d.ts +0 -11753
  106. package/esm/CalmLensConnection-BAJdoZHy.js +0 -193
  107. package/esm/CalmLensUtils-DqniTKJ8.js +0 -574
  108. package/esm/CalmLensVersion-l_khh4nS.js +0 -415
  109. package/esm/CalmLensWebhooks-BtrKKLvg.js +0 -148
  110. package/esm/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
  111. package/esm/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
  112. package/esm/WebhookPayload-CJoIkGBD.d.ts +0 -11753
@@ -0,0 +1,467 @@
1
+ import { _ as getMediaState, a as getMediaAspectRatio, b as ICONS, c as describeUploadItem, d as formatMessage, f as getDropzoneHint, g as resolveMessages, h as getUploadItemOutcome, i as resolveTheme, l as describeUploader, m as getUploadItemMessage, o as getMediaLoadKey, p as getMediaUnavailableMessage, r as CALMLENS_THEME, s as DEFAULT_MESSAGES, t as CALMLENS_STYLES, u as formatBytes, v as pickMediaSource, x as ICON_ATTRIBUTES, y as resolveMediaProps } from "./ui-Ca_SpJXf.js";
2
+ import { i as createProgressFetch, n as createUploadController, r as isFileAccepted, t as UploadController } from "./UploadController-txp5NuzH.js";
3
+ import { a as getFileIcon, o as getFileIconLabel, t as FILE_ICON_COLORS } from "./FileIcons-M6dzjFxd.js";
4
+ import { n as useOwnController, r as useUploadSnapshot, t as useCalmLensUpload } from "./ReactUpload-D6yBCkcw.js";
5
+ import { useMemo, useState } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Image, PixelRatio, Pressable, StyleSheet, Text, View } from "react-native";
8
+ // src/react-native.tsx
9
+ const createUploaderStyles = (theme) => StyleSheet.create({
10
+ uploader: { gap: 12 },
11
+ picker: {
12
+ alignItems: "center",
13
+ gap: 12,
14
+ paddingVertical: 28,
15
+ paddingHorizontal: 20,
16
+ borderWidth: 1.5,
17
+ borderStyle: "dashed",
18
+ borderColor: theme.border,
19
+ borderRadius: theme.radius,
20
+ backgroundColor: theme.surface
21
+ },
22
+ hint: {
23
+ fontSize: 13,
24
+ color: theme.muted
25
+ },
26
+ button: {
27
+ paddingVertical: 8,
28
+ paddingHorizontal: 14,
29
+ borderRadius: 8,
30
+ borderWidth: 1,
31
+ borderColor: theme.accent,
32
+ backgroundColor: theme.accent
33
+ },
34
+ buttonText: {
35
+ fontSize: 14,
36
+ fontWeight: "500",
37
+ color: theme.accentText
38
+ },
39
+ outlineButton: {
40
+ backgroundColor: "transparent",
41
+ borderColor: theme.border
42
+ },
43
+ outlineButtonText: { color: theme.text },
44
+ smallButton: {
45
+ paddingVertical: 4,
46
+ paddingHorizontal: 10
47
+ },
48
+ disabledButton: {
49
+ backgroundColor: "transparent",
50
+ borderStyle: "dashed",
51
+ borderColor: theme.border
52
+ },
53
+ disabledButtonText: { color: theme.muted },
54
+ uploads: { gap: 8 },
55
+ upload: {
56
+ flexDirection: "row",
57
+ alignItems: "center",
58
+ gap: 12,
59
+ padding: 12,
60
+ borderWidth: 1,
61
+ borderColor: theme.border,
62
+ borderRadius: theme.radius,
63
+ backgroundColor: theme.background
64
+ },
65
+ messageRow: {
66
+ flexDirection: "row",
67
+ alignItems: "center",
68
+ gap: 8
69
+ },
70
+ outcomeDot: {
71
+ width: 8,
72
+ height: 8,
73
+ borderRadius: 4
74
+ },
75
+ accepted: { backgroundColor: theme.success },
76
+ restricted: { backgroundColor: theme.warning },
77
+ rejected: { backgroundColor: theme.danger },
78
+ thumb: {
79
+ width: 40,
80
+ height: 40,
81
+ borderRadius: 8,
82
+ overflow: "hidden"
83
+ },
84
+ fileIcon: {
85
+ alignItems: "center",
86
+ justifyContent: "center",
87
+ borderWidth: 1.5
88
+ },
89
+ fileIconLabel: {
90
+ fontSize: 9,
91
+ fontWeight: "700",
92
+ fontFamily: "monospace"
93
+ },
94
+ body: {
95
+ flex: 1,
96
+ minWidth: 0,
97
+ gap: 4
98
+ },
99
+ name: {
100
+ fontWeight: "500",
101
+ color: theme.text
102
+ },
103
+ size: {
104
+ fontSize: 13,
105
+ color: theme.muted
106
+ },
107
+ message: {
108
+ fontSize: 13,
109
+ color: theme.text
110
+ },
111
+ progress: {
112
+ height: 4,
113
+ borderRadius: 2,
114
+ overflow: "hidden",
115
+ backgroundColor: theme.border
116
+ },
117
+ progressBar: {
118
+ height: "100%",
119
+ borderRadius: 2,
120
+ backgroundColor: theme.accent
121
+ },
122
+ actions: {
123
+ flexDirection: "row",
124
+ alignItems: "center",
125
+ gap: 8
126
+ },
127
+ iconButton: {
128
+ width: 30,
129
+ height: 30,
130
+ alignItems: "center",
131
+ justifyContent: "center",
132
+ borderRadius: 8
133
+ },
134
+ iconButtonText: {
135
+ fontSize: 16,
136
+ color: theme.text
137
+ }
138
+ });
139
+ /** The `testID` of the uploader's pick buttons, for end-to-end tests such as Detox or Maestro. */
140
+ const CHOOSE_TEST_ID = "calmlens-choose";
141
+ const Button = ({ label, onPress, disabled, variant, size, styles, testID }) => /* @__PURE__ */ jsx(Pressable, {
142
+ role: "button",
143
+ "aria-label": label,
144
+ testID,
145
+ disabled,
146
+ onPress,
147
+ style: [
148
+ styles.button,
149
+ variant === "outline" && styles.outlineButton,
150
+ size === "small" && styles.smallButton,
151
+ disabled && styles.disabledButton
152
+ ],
153
+ children: /* @__PURE__ */ jsx(Text, {
154
+ style: [
155
+ styles.buttonText,
156
+ variant === "outline" && styles.outlineButtonText,
157
+ disabled && styles.disabledButtonText
158
+ ],
159
+ children: label
160
+ })
161
+ });
162
+ /** The file-type tile shown for files without an image preview, in the family's colour. */
163
+ const FileIcon = ({ file, styles }) => {
164
+ const { family, extension } = getFileIcon(file);
165
+ const tint = FILE_ICON_COLORS[family];
166
+ return /* @__PURE__ */ jsx(View, {
167
+ "aria-hidden": true,
168
+ style: [
169
+ styles.thumb,
170
+ styles.fileIcon,
171
+ { borderColor: tint }
172
+ ],
173
+ children: /* @__PURE__ */ jsx(Text, {
174
+ style: [styles.fileIconLabel, { color: tint }],
175
+ children: getFileIconLabel(extension).text
176
+ })
177
+ });
178
+ };
179
+ const UploadRow = ({ item, view, messages, styles, showChooseAnother, disabled, onChooseAnother, onRetry, onRemove }) => /* @__PURE__ */ jsxs(View, {
180
+ style: styles.upload,
181
+ children: [
182
+ item.previewUrl ? /* @__PURE__ */ jsx(Image, {
183
+ source: { uri: item.previewUrl },
184
+ "aria-hidden": true,
185
+ blurRadius: view.outcome === "rejected" ? 6 : void 0,
186
+ style: styles.thumb
187
+ }) : /* @__PURE__ */ jsx(FileIcon, {
188
+ file: item.file,
189
+ styles
190
+ }),
191
+ /* @__PURE__ */ jsxs(View, {
192
+ style: styles.body,
193
+ children: [
194
+ /* @__PURE__ */ jsx(Text, {
195
+ style: styles.name,
196
+ numberOfLines: 1,
197
+ children: item.file.name
198
+ }),
199
+ /* @__PURE__ */ jsx(Text, {
200
+ style: styles.size,
201
+ children: view.size
202
+ }),
203
+ view.busy && /* @__PURE__ */ jsx(View, {
204
+ role: "progressbar",
205
+ "aria-label": view.message,
206
+ "aria-valuemin": 0,
207
+ "aria-valuemax": 100,
208
+ "aria-valuenow": view.progressPercent,
209
+ style: styles.progress,
210
+ children: /* @__PURE__ */ jsx(View, { style: [styles.progressBar, { width: `${view.progressPercent ?? 100}%` }] })
211
+ }),
212
+ view.message ? /* @__PURE__ */ jsxs(View, {
213
+ style: styles.messageRow,
214
+ children: [view.outcome && /* @__PURE__ */ jsx(View, {
215
+ "aria-hidden": true,
216
+ style: [styles.outcomeDot, styles[view.outcome]]
217
+ }), /* @__PURE__ */ jsx(Text, {
218
+ role: "status",
219
+ style: styles.message,
220
+ children: view.message
221
+ })]
222
+ }) : null
223
+ ]
224
+ }),
225
+ /* @__PURE__ */ jsxs(View, {
226
+ style: styles.actions,
227
+ children: [
228
+ showChooseAnother && /* @__PURE__ */ jsx(Button, {
229
+ label: messages.chooseAnother,
230
+ testID: "calmlens-choose",
231
+ variant: "outline",
232
+ size: "small",
233
+ disabled,
234
+ onPress: onChooseAnother,
235
+ styles
236
+ }),
237
+ view.canRetry && /* @__PURE__ */ jsx(Pressable, {
238
+ role: "button",
239
+ "aria-label": messages.retry,
240
+ onPress: onRetry,
241
+ style: styles.iconButton,
242
+ children: /* @__PURE__ */ jsx(Text, {
243
+ "aria-hidden": true,
244
+ style: styles.iconButtonText,
245
+ children: "↻"
246
+ })
247
+ }),
248
+ /* @__PURE__ */ jsx(Pressable, {
249
+ role: "button",
250
+ "aria-label": view.removeLabel,
251
+ onPress: onRemove,
252
+ style: styles.iconButton,
253
+ children: /* @__PURE__ */ jsx(Text, {
254
+ "aria-hidden": true,
255
+ style: styles.iconButtonText,
256
+ children: "✕"
257
+ })
258
+ })
259
+ ]
260
+ })
261
+ ]
262
+ });
263
+ /**
264
+ * A pick button and file list that uploads through an upload preset, shows each file's progress
265
+ * and moderation decision, and reports finished uploads to `onUploaded`. `pick` opens your app's
266
+ * picker, such as `expo-image-picker`.
267
+ */
268
+ function CalmLensUploader({ pick, disabled, messages: overrides, controller: external, theme: themeOverrides, style, ...options }) {
269
+ const own = useOwnController(options, !external);
270
+ const upload = useUploadSnapshot(external ?? own);
271
+ const { accept, multiple = false } = upload.controller.options;
272
+ const messages = useMemo(() => resolveMessages(overrides), [overrides]);
273
+ const styles = useMemo(() => createUploaderStyles(resolveTheme(themeOverrides)), [themeOverrides]);
274
+ const view = describeUploader(upload, upload.controller.options, messages);
275
+ const openPicker = async () => {
276
+ if (disabled) return;
277
+ const files = await pick({
278
+ multiple,
279
+ accept
280
+ });
281
+ if (files?.length) upload.addFiles(files);
282
+ };
283
+ return /* @__PURE__ */ jsxs(View, {
284
+ style: [styles.uploader, style],
285
+ children: [view.showDropzone && /* @__PURE__ */ jsxs(View, {
286
+ style: styles.picker,
287
+ children: [/* @__PURE__ */ jsx(Button, {
288
+ label: view.chooseLabel,
289
+ testID: "calmlens-choose",
290
+ variant: "outline",
291
+ disabled,
292
+ onPress: () => void openPicker(),
293
+ styles
294
+ }), view.hint && /* @__PURE__ */ jsx(Text, {
295
+ style: styles.hint,
296
+ children: view.hint
297
+ })]
298
+ }), upload.items.length > 0 && /* @__PURE__ */ jsx(View, {
299
+ style: styles.uploads,
300
+ children: upload.items.map((item) => /* @__PURE__ */ jsx(UploadRow, {
301
+ item,
302
+ view: describeUploadItem(item, messages),
303
+ messages,
304
+ styles,
305
+ showChooseAnother: !view.showDropzone,
306
+ disabled,
307
+ onChooseAnother: () => void openPicker(),
308
+ onRetry: () => upload.retry(item.key),
309
+ onRemove: () => upload.remove(item.key)
310
+ }, item.key))
311
+ })]
312
+ });
313
+ }
314
+ const mediaStyles = StyleSheet.create({
315
+ media: {
316
+ position: "relative",
317
+ overflow: "hidden",
318
+ minHeight: 160
319
+ },
320
+ sized: { minHeight: 0 },
321
+ fill: { ...StyleSheet.absoluteFill },
322
+ notice: {
323
+ ...StyleSheet.absoluteFill,
324
+ alignItems: "center",
325
+ justifyContent: "center",
326
+ gap: 6,
327
+ padding: 12,
328
+ backgroundColor: "rgba(0, 0, 0, 0.45)"
329
+ },
330
+ noticeTitle: {
331
+ fontWeight: "600",
332
+ color: "#fff",
333
+ textAlign: "center"
334
+ },
335
+ noticeText: {
336
+ color: "#fff",
337
+ textAlign: "center"
338
+ },
339
+ revealButton: {
340
+ marginTop: 4,
341
+ paddingVertical: 7,
342
+ paddingHorizontal: 14,
343
+ borderRadius: 8,
344
+ backgroundColor: "#fff"
345
+ },
346
+ revealText: {
347
+ fontSize: 14,
348
+ fontWeight: "500",
349
+ color: "#111"
350
+ }
351
+ });
352
+ /**
353
+ * Shows an asset from the CalmLens CDN, at the width in `widths` that covers its measured size,
354
+ * with a blurred placeholder while it loads. Age-restricted assets stay behind the placeholder and
355
+ * a reveal button until `ageConfirmed` is set; blocked and purged assets show an unavailable notice.
356
+ */
357
+ function CalmLensMedia(input) {
358
+ const { asset: _asset, projectId, assetId, status, contentRemoved, type, resource, lens, transform, widths, url, placeholder, placeholderHash, placeholderUrl: customPlaceholderUrl, cdnBaseUrl, viewerClaims, alt = "", aspectRatio, width, height, averageColor, fit = "cover", messages: overrides, theme: themeOverrides, onReveal, renderPlayer, style } = resolveMediaProps(input);
359
+ const messages = useMemo(() => resolveMessages(overrides), [overrides]);
360
+ const theme = useMemo(() => resolveTheme(themeOverrides), [themeOverrides]);
361
+ const state = getMediaState({
362
+ asset: _asset,
363
+ projectId,
364
+ assetId,
365
+ status,
366
+ contentRemoved,
367
+ type,
368
+ resource,
369
+ lens,
370
+ transform,
371
+ widths,
372
+ url,
373
+ placeholder,
374
+ placeholderHash,
375
+ placeholderUrl: customPlaceholderUrl,
376
+ cdnBaseUrl,
377
+ viewerClaims
378
+ });
379
+ const [layoutWidth, setLayoutWidth] = useState();
380
+ const src = state.kind === "image" ? pickMediaSource(state, layoutWidth) : void 0;
381
+ const loadKey = src ?? getMediaLoadKey(state);
382
+ const [load, setLoad] = useState({
383
+ key: loadKey,
384
+ state: "loading"
385
+ });
386
+ const current = load.key === loadKey ? load.state : "loading";
387
+ const ratio = getMediaAspectRatio({
388
+ aspectRatio,
389
+ width,
390
+ height
391
+ });
392
+ const unavailable = state.kind === "unavailable" || current === "error";
393
+ const placeholderUrl = state.kind === "audio" || state.kind === "unavailable" ? void 0 : state.placeholderUrl;
394
+ const showPlaceholder = placeholderUrl && !unavailable && (state.kind !== "image" || current !== "loaded") && !(state.kind === "video" && renderPlayer);
395
+ const player = (state.kind === "video" || state.kind === "audio") && !unavailable ? renderPlayer?.({
396
+ kind: state.kind,
397
+ src: state.src,
398
+ alt
399
+ }) : void 0;
400
+ return /* @__PURE__ */ jsxs(View, {
401
+ onLayout: (event) => {
402
+ setLayoutWidth(PixelRatio.getPixelSizeForLayoutSize(event.nativeEvent.layout.width));
403
+ },
404
+ style: [
405
+ mediaStyles.media,
406
+ ratio !== void 0 && [mediaStyles.sized, { aspectRatio: ratio }],
407
+ { backgroundColor: averageColor ?? theme.surface },
408
+ style
409
+ ],
410
+ children: [
411
+ showPlaceholder && /* @__PURE__ */ jsx(Image, {
412
+ source: { uri: placeholderUrl },
413
+ "aria-hidden": true,
414
+ blurRadius: 12,
415
+ resizeMode: fit,
416
+ style: mediaStyles.fill
417
+ }),
418
+ src && !unavailable && /* @__PURE__ */ jsx(Image, {
419
+ source: { uri: src },
420
+ "aria-label": alt || void 0,
421
+ accessible: Boolean(alt),
422
+ resizeMode: fit,
423
+ onLoad: () => setLoad({
424
+ key: loadKey,
425
+ state: "loaded"
426
+ }),
427
+ onError: () => setLoad({
428
+ key: loadKey,
429
+ state: "error"
430
+ }),
431
+ style: [mediaStyles.fill, { opacity: current === "loaded" ? 1 : 0 }]
432
+ }, loadKey),
433
+ player,
434
+ state.kind === "gated" && /* @__PURE__ */ jsxs(View, {
435
+ style: mediaStyles.notice,
436
+ children: [
437
+ /* @__PURE__ */ jsx(Text, {
438
+ style: mediaStyles.noticeTitle,
439
+ children: messages.sensitiveTitle
440
+ }),
441
+ /* @__PURE__ */ jsx(Text, {
442
+ style: mediaStyles.noticeText,
443
+ children: messages.sensitiveBody
444
+ }),
445
+ onReveal && /* @__PURE__ */ jsx(Pressable, {
446
+ role: "button",
447
+ "aria-label": messages.reveal,
448
+ onPress: onReveal,
449
+ style: mediaStyles.revealButton,
450
+ children: /* @__PURE__ */ jsx(Text, {
451
+ style: mediaStyles.revealText,
452
+ children: messages.reveal
453
+ })
454
+ })
455
+ ]
456
+ }),
457
+ unavailable && /* @__PURE__ */ jsx(View, {
458
+ style: [mediaStyles.notice, { backgroundColor: theme.surface }],
459
+ children: /* @__PURE__ */ jsx(Text, {
460
+ style: { color: theme.text },
461
+ children: getMediaUnavailableMessage(state, messages)
462
+ })
463
+ })
464
+ ]
465
+ });
466
+ }
467
+ export { CALMLENS_STYLES, CALMLENS_THEME, CHOOSE_TEST_ID, CalmLensMedia, CalmLensUploader, DEFAULT_MESSAGES, ICONS, ICON_ATTRIBUTES, UploadController, createProgressFetch, createUploadController, describeUploadItem, describeUploader, formatBytes, formatMessage, getDropzoneHint, getMediaAspectRatio, getMediaLoadKey, getMediaState, getMediaUnavailableMessage, getUploadItemMessage, getUploadItemOutcome, isFileAccepted, pickMediaSource, resolveMediaProps, resolveMessages, resolveTheme, useCalmLensUpload };
package/esm/react.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { A as CustomUploadResult, B as MediaAsset, C as getDropzoneHint, D as resolveMessages, E as getUploadItemOutcome, G as MediaState, H as MediaOptions, J as resolveMediaProps, K as getMediaState, L as UploadStage, M as UploadController, P as UploadFile, S as formatMessage, T as getUploadItemMessage, U as MediaSettings, V as MediaImageSource, W as MediaSource, _ as UploadItemView, a as createProgressFetch, b as describeUploader, c as IconName, d as UploaderDisplayOptions, g as DEFAULT_MESSAGES, h as CalmLensMessages, i as CALMLENS_STYLES, j as UploadClient, k as CustomUploadContext, l as MediaDisplayOptions, m as getMediaLoadKey, n as CalmLensTheme, o as ICONS, p as getMediaAspectRatio, q as pickMediaSource, r as resolveTheme, s as ICON_ATTRIBUTES, t as CALMLENS_THEME, u as MediaProps, v as UploaderView, w as getMediaUnavailableMessage, x as formatBytes, y as describeUploadItem, z as isFileAccepted } from "./ui-CgZpgpNo.js";
2
+ import { a as UploaderProps, i as UploadSnapshot, n as UploadControllerOptions, o as UseCalmLensUploadResult, r as UploadItem, s as createUploadController, t as CalmLensUpload } from "./BrowserUpload-uZjVFGfP.js";
3
+ import { CSSProperties, HTMLAttributes } from "react";
4
+ /**
5
+ * Uploads files through an upload preset and re-renders as each one uploads and is checked. Use
6
+ * it to build your own upload UI; `CalmLensUploader` is built on it. Uploads still running when
7
+ * the component unmounts are cancelled.
8
+ */
9
+ export declare const useCalmLensUpload: <F extends UploadFile = File>(options: UploadControllerOptions<F>) => UseCalmLensUploadResult<F>;
10
+ /** Leaves out the stylesheet the components render, so you can style the `calmlens-*` classes. */
11
+ type StyleOptions = {
12
+ unstyled?: boolean;
13
+ };
14
+ export type CalmLensUploaderProps = UploaderProps & StyleOptions & {
15
+ className?: string;
16
+ style?: CSSProperties;
17
+ };
18
+ /**
19
+ * A drop zone and file list that uploads through an upload preset, shows each file's progress
20
+ * and moderation decision, and reports finished uploads to `onUploaded`.
21
+ */
22
+ export declare function CalmLensUploader({ disabled, capture, messages: overrides, unstyled, controller: external, className, style, ...options }: CalmLensUploaderProps): import("react").JSX.Element;
23
+ export type CalmLensMediaProps = MediaProps & StyleOptions & Omit<HTMLAttributes<HTMLElement>, "children" | "placeholder">;
24
+ /**
25
+ * Shows an asset from the CalmLens CDN with responsive widths and a blurred placeholder while
26
+ * it loads. Age-restricted assets stay behind the placeholder and a reveal button until
27
+ * `ageConfirmed` is set; blocked and purged assets show an unavailable notice.
28
+ */
29
+ export declare function CalmLensMedia(input: CalmLensMediaProps): import("react").JSX.Element;
30
+ export { CALMLENS_STYLES, CALMLENS_THEME, type CalmLensMessages, type CalmLensTheme, type CalmLensUpload, type CustomUploadContext, type CustomUploadResult, DEFAULT_MESSAGES, ICONS, ICON_ATTRIBUTES, type IconName, type MediaAsset, type MediaDisplayOptions, type MediaImageSource, type MediaOptions, type MediaProps, type MediaSettings, type MediaSource, type MediaState, type UploadClient, UploadController, type UploadControllerOptions, type UploadFile, type UploadItem, type UploadItemView, type UploadSnapshot, type UploadStage, type UploaderDisplayOptions, type UploaderProps, type UploaderView, type UseCalmLensUploadResult, createProgressFetch, createUploadController, describeUploadItem, describeUploader, formatBytes, formatMessage, getDropzoneHint, getMediaAspectRatio, getMediaLoadKey, getMediaState, getMediaUnavailableMessage, getUploadItemMessage, getUploadItemOutcome, isFileAccepted, pickMediaSource, resolveMediaProps, resolveMessages, resolveTheme };