@calmlens/sdk 0.16.3 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +425 -181
- package/bin/calmlens.js +16016 -0
- package/bin/package.json +1 -0
- package/cjs/BrowserUpload-BT091eOB.d.ts +11 -0
- package/cjs/BrowserUpload-CQwXEGFv.js +10 -0
- package/cjs/CalmLensAppClient-CHQGu-Do.js +89 -0
- package/cjs/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
- package/cjs/CalmLensConnection-B8Bu2j3y.js +659 -0
- package/cjs/CalmLensServerClient-C5o2A8MW.js +645 -0
- package/cjs/CalmLensServerClient-JtP687a3.d.ts +235 -0
- package/cjs/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
- package/cjs/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
- package/cjs/CryptoUtils-B_x8lMIx-YBW1-bvL.js +42 -0
- package/cjs/FileIcons-Ob003MdS.js +175 -0
- package/cjs/Jurisdiction-FusEXb4U-zVs21tDv.js +91 -0
- package/cjs/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
- package/cjs/ModerationContextLimits-DelWfmiJ.js +1311 -0
- package/cjs/ReactUpload-CAyCsyG6.d.ts +17 -0
- package/cjs/ReactUpload-Cfg5JYUq.js +54 -0
- package/cjs/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
- package/cjs/TestTriggers-DTc_iMJF-BjMPq4_3.js +1327 -0
- package/cjs/UploadController-BGO1eyzb.js +618 -0
- package/{esm/index-C9Xw1aid.d.ts → cjs/WebhookPayload-2aL31v0J.d.ts} +131 -155
- package/cjs/app.d.ts +7 -44
- package/cjs/app.js +11 -89
- package/cjs/elements.d.ts +88 -0
- package/cjs/elements.js +555 -0
- package/cjs/file-icons.d.ts +67 -0
- package/cjs/file-icons.js +10 -0
- package/cjs/index-CI4BzN4W.d.ts +252 -0
- package/cjs/index.d.ts +6 -4
- package/cjs/index.js +9 -4
- package/cjs/react-native.d.ts +56 -0
- package/cjs/react-native.js +495 -0
- package/cjs/react.d.ts +30 -0
- package/cjs/react.js +370 -0
- package/cjs/server.d.ts +12 -191
- package/cjs/server.js +18 -378
- package/cjs/test-inputs.d.ts +2 -2
- package/cjs/test-inputs.js +9 -264
- package/cjs/testing.d.ts +285 -190
- package/cjs/testing.js +2393 -1203
- package/cjs/ui-CC1GOoMg.js +583 -0
- package/cjs/ui-wIiMfqMB.d.ts +526 -0
- package/cjs/ui.d.ts +2 -0
- package/cjs/ui.js +27 -0
- package/cjs/vue.d.ts +490 -0
- package/cjs/vue.js +419 -0
- package/esm/BrowserUpload-BT091eOB.d.ts +11 -0
- package/esm/BrowserUpload-D2xBWqhm.js +5 -0
- package/esm/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
- package/esm/CalmLensAppClient-DuFas_dW.js +84 -0
- package/esm/CalmLensConnection-MxwwLXdl.js +582 -0
- package/esm/CalmLensServerClient-D80_mKpW.js +586 -0
- package/esm/CalmLensServerClient-JtP687a3.d.ts +235 -0
- package/esm/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
- package/esm/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
- package/esm/CryptoUtils-B_x8lMIx-DhuWGzqn.js +25 -0
- package/esm/FileIcons-M6dzjFxd.js +128 -0
- package/esm/Jurisdiction-FusEXb4U-1ov6m5yE.js +46 -0
- package/esm/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
- package/esm/ModerationContextLimits-BaX2QnU8.js +1114 -0
- package/esm/ReactUpload-CAyCsyG6.d.ts +17 -0
- package/esm/ReactUpload-CL2XC8WS.js +37 -0
- package/esm/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
- package/esm/TestTriggers-DTc_iMJF-HfB533Gx.js +1267 -0
- package/esm/UploadController-qjoYGCwx.js +589 -0
- package/{cjs/index-C9Xw1aid.d.ts → esm/WebhookPayload-2aL31v0J.d.ts} +131 -155
- package/esm/app.d.ts +7 -44
- package/esm/app.js +3 -86
- package/esm/elements.d.ts +88 -0
- package/esm/elements.js +528 -0
- package/esm/file-icons.d.ts +67 -0
- package/esm/file-icons.js +1 -0
- package/esm/index-CI4BzN4W.d.ts +252 -0
- package/esm/index.d.ts +6 -4
- package/esm/index.js +1 -1
- package/esm/react-native.d.ts +56 -0
- package/esm/react-native.js +467 -0
- package/esm/react.d.ts +30 -0
- package/esm/react.js +343 -0
- package/esm/server.d.ts +12 -191
- package/esm/server.js +3 -369
- package/esm/styles.css +147 -0
- package/esm/svelte/CalmLensMedia.svelte +134 -0
- package/esm/svelte/CalmLensUploader.svelte +175 -0
- package/esm/svelte/Icon.svelte +7 -0
- package/esm/svelte/index.d.ts +37 -0
- package/esm/svelte/index.js +6 -0
- package/esm/test-inputs.d.ts +2 -2
- package/esm/test-inputs.js +1 -256
- package/esm/testing.d.ts +285 -190
- package/esm/testing.js +2329 -1122
- package/esm/ui-CCY3yXFn.js +458 -0
- package/esm/ui-wIiMfqMB.d.ts +526 -0
- package/esm/ui.d.ts +2 -0
- package/esm/ui.js +3 -0
- package/esm/vue.d.ts +490 -0
- package/esm/vue.js +392 -0
- package/package.json +118 -13
- package/cjs/CalmLensConnection-BNUHp_AQ.js +0 -234
- package/cjs/CalmLensUtils-o171ownK.js +0 -699
- package/cjs/CalmLensVersion-DwhgxQK5.js +0 -480
- package/cjs/CalmLensWebhooks-BKrq30Yp.js +0 -201
- package/cjs/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
- package/cjs/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
- package/cjs/WebhookPayload-CJoIkGBD.d.ts +0 -11753
- package/esm/CalmLensConnection-XTqmlwzG.js +0 -193
- package/esm/CalmLensUtils-DsF8Aa_x.js +0 -574
- package/esm/CalmLensVersion-DcifRKsx.js +0 -415
- package/esm/CalmLensWebhooks-BvGyk5d3.js +0 -148
- package/esm/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
- package/esm/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
- package/esm/WebhookPayload-CJoIkGBD.d.ts +0 -11753
|
@@ -0,0 +1,88 @@
|
|
|
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-wIiMfqMB.js";
|
|
2
|
+
import { a as UploaderProps, i as UploadSnapshot, n as UploadControllerOptions, r as UploadItem, s as createUploadController, t as CalmLensUpload } from "./BrowserUpload-BT091eOB.js";
|
|
3
|
+
/** The `detail` of each event the elements dispatch. */
|
|
4
|
+
export interface CalmLensElementEvents {
|
|
5
|
+
"calmlens-uploaded": CalmLensUpload;
|
|
6
|
+
"calmlens-rejected": UploadItem;
|
|
7
|
+
"calmlens-failed": UploadItem;
|
|
8
|
+
"calmlens-removed": UploadItem;
|
|
9
|
+
"calmlens-change": UploadSnapshot;
|
|
10
|
+
"calmlens-reveal": undefined;
|
|
11
|
+
}
|
|
12
|
+
declare const BaseElement: typeof HTMLElement;
|
|
13
|
+
/**
|
|
14
|
+
* `<calmlens-uploader upload-preset-id="…" token-url="/api/upload-token">` uploads through an
|
|
15
|
+
* upload preset and dispatches `calmlens-uploaded` with `{ assetId, status, file }` for each
|
|
16
|
+
* finished upload. Attributes: `upload-preset-id`, `token-url`, `accept`, `max-file-size`
|
|
17
|
+
* (bytes), `no-auto-upload`, `multiple`, `max-files`, `disabled`, `capture` and `base-url`. Set
|
|
18
|
+
* the `token`, `upload`, `checkStatus`, `messages` and `controller` properties from script for
|
|
19
|
+
* anything an attribute can't hold.
|
|
20
|
+
*/
|
|
21
|
+
export declare class CalmLensUploaderElement extends BaseElement {
|
|
22
|
+
#private;
|
|
23
|
+
static observedAttributes: string[];
|
|
24
|
+
/** The upload token, or a function returning one per file, instead of `token-url`. */
|
|
25
|
+
get token(): UploadControllerOptions["token"];
|
|
26
|
+
set token(value: UploadControllerOptions["token"]);
|
|
27
|
+
/** Uploads each file your own way instead of through `upload-preset-id`. */
|
|
28
|
+
get upload(): UploadControllerOptions["upload"];
|
|
29
|
+
set upload(value: UploadControllerOptions["upload"]);
|
|
30
|
+
/** Checks a pending upload made with `upload`. */
|
|
31
|
+
get checkStatus(): UploadControllerOptions["checkStatus"];
|
|
32
|
+
set checkStatus(value: UploadControllerOptions["checkStatus"]);
|
|
33
|
+
/** Creates the client for each upload, for example a `MockCalmLensAppClient` in tests. */
|
|
34
|
+
get createClient(): UploadControllerOptions["createClient"];
|
|
35
|
+
set createClient(value: UploadControllerOptions["createClient"]);
|
|
36
|
+
get messages(): Partial<CalmLensMessages> | undefined;
|
|
37
|
+
set messages(value: Partial<CalmLensMessages> | undefined);
|
|
38
|
+
/**
|
|
39
|
+
* The upload queue, for reading items or calling `start`, `retry`, `remove` and `clear`. Set it
|
|
40
|
+
* to show a queue your script created; its own options then apply instead of the attributes.
|
|
41
|
+
*/
|
|
42
|
+
get controller(): UploadController<File>;
|
|
43
|
+
set controller(value: UploadController<File>);
|
|
44
|
+
connectedCallback(): void;
|
|
45
|
+
disconnectedCallback(): void;
|
|
46
|
+
attributeChangedCallback(): void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `<calmlens-media project-id="…" asset-id="…" status="allowed" alt="…">` shows an asset from the
|
|
50
|
+
* CalmLens CDN with a blurred placeholder while it loads. Age-restricted assets show the
|
|
51
|
+
* placeholder and a reveal button, which dispatches `calmlens-reveal`, until `age-confirmed` is set.
|
|
52
|
+
* Attributes: `project-id`, `asset-id`, `status`, `age-confirmed`, `type`, `resource`, `lens`,
|
|
53
|
+
* `transform`, `widths` (comma-separated), `url`, `no-placeholder`, `placeholder-hash`,
|
|
54
|
+
* `placeholder-url`, `average-color`, `cdn-base-url`, `alt`, `aspect-ratio`, `width`, `height`,
|
|
55
|
+
* `sizes`, `fit`, `position`, `eager`, `fetch-priority` and `no-controls`. Set the
|
|
56
|
+
* `asset` property to an API asset instead of `project-id` and `asset-id`.
|
|
57
|
+
*/
|
|
58
|
+
export declare class CalmLensMediaElement extends BaseElement {
|
|
59
|
+
#private;
|
|
60
|
+
static observedAttributes: string[];
|
|
61
|
+
get messages(): Partial<CalmLensMessages> | undefined;
|
|
62
|
+
set messages(value: Partial<CalmLensMessages> | undefined);
|
|
63
|
+
/**
|
|
64
|
+
* An asset from the API, in place of `project-id` and `asset-id`. It supplies the status, type
|
|
65
|
+
* and preview too; attributes you set win over it.
|
|
66
|
+
*/
|
|
67
|
+
get asset(): MediaAsset | undefined;
|
|
68
|
+
set asset(value: MediaAsset | undefined);
|
|
69
|
+
connectedCallback(): void;
|
|
70
|
+
attributeChangedCallback(): void;
|
|
71
|
+
}
|
|
72
|
+
/** Defines `<calmlens-uploader>` and `<calmlens-media>`, if they aren't defined yet. */
|
|
73
|
+
export declare const defineCalmLensElements: () => void;
|
|
74
|
+
declare global {
|
|
75
|
+
interface HTMLElementTagNameMap {
|
|
76
|
+
"calmlens-uploader": CalmLensUploaderElement;
|
|
77
|
+
"calmlens-media": CalmLensMediaElement;
|
|
78
|
+
}
|
|
79
|
+
interface HTMLElementEventMap {
|
|
80
|
+
"calmlens-uploaded": CustomEvent<CalmLensUpload>;
|
|
81
|
+
"calmlens-rejected": CustomEvent<UploadItem>;
|
|
82
|
+
"calmlens-failed": CustomEvent<UploadItem>;
|
|
83
|
+
"calmlens-removed": CustomEvent<UploadItem>;
|
|
84
|
+
"calmlens-change": CustomEvent<UploadSnapshot>;
|
|
85
|
+
"calmlens-reveal": CustomEvent<undefined>;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
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, createProgressFetch, createUploadController, describeUploadItem, describeUploader, formatBytes, formatMessage, getDropzoneHint, getMediaAspectRatio, getMediaLoadKey, getMediaState, getMediaUnavailableMessage, getUploadItemMessage, getUploadItemOutcome, isFileAccepted, pickMediaSource, resolveMediaProps, resolveMessages, resolveTheme };
|
package/esm/elements.js
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
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-CCY3yXFn.js";
|
|
2
|
+
import { i as createProgressFetch, n as createUploadController$1, r as isFileAccepted, t as UploadController } from "./UploadController-qjoYGCwx.js";
|
|
3
|
+
import { t as createUploadController } from "./BrowserUpload-D2xBWqhm.js";
|
|
4
|
+
// src/elements.ts
|
|
5
|
+
const el = (tag, attributes = {}, children = []) => {
|
|
6
|
+
const node = document.createElement(tag);
|
|
7
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
8
|
+
if (value === void 0 || value === false) continue;
|
|
9
|
+
node.setAttribute(name, value === true ? "" : String(value));
|
|
10
|
+
}
|
|
11
|
+
for (const child of children) if (child) node.append(child);
|
|
12
|
+
return node;
|
|
13
|
+
};
|
|
14
|
+
const icon = (name) => {
|
|
15
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
16
|
+
for (const [attribute, value] of Object.entries(ICON_ATTRIBUTES)) svg.setAttribute(attribute, value);
|
|
17
|
+
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
18
|
+
path.setAttribute("d", ICONS[name]);
|
|
19
|
+
svg.append(path);
|
|
20
|
+
return svg;
|
|
21
|
+
};
|
|
22
|
+
/** A row's file-type icon, from the SDK's own SVG markup. */
|
|
23
|
+
const fileThumbnail = (svg) => {
|
|
24
|
+
const thumbnail = el("span", {
|
|
25
|
+
class: "calmlens-upload__thumb",
|
|
26
|
+
"data-kind": "file",
|
|
27
|
+
"aria-hidden": "true"
|
|
28
|
+
});
|
|
29
|
+
thumbnail.innerHTML = svg;
|
|
30
|
+
return thumbnail;
|
|
31
|
+
};
|
|
32
|
+
const numberAttribute = (element, name) => {
|
|
33
|
+
const value = element.getAttribute(name);
|
|
34
|
+
return value === null || value === "" ? void 0 : Number(value);
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Moves properties set on an element before it was defined onto its setters. Until then they're
|
|
38
|
+
* plain own properties, which would hide the class's accessors.
|
|
39
|
+
*/
|
|
40
|
+
const upgradeProperties = (element, names) => {
|
|
41
|
+
const record = element;
|
|
42
|
+
for (const name of names) {
|
|
43
|
+
if (!Object.hasOwn(element, name)) continue;
|
|
44
|
+
const value = record[name];
|
|
45
|
+
delete record[name];
|
|
46
|
+
record[name] = value;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const BaseElement = typeof HTMLElement === "undefined" ? class {} : HTMLElement;
|
|
50
|
+
/**
|
|
51
|
+
* `<calmlens-uploader upload-preset-id="…" token-url="/api/upload-token">` uploads through an
|
|
52
|
+
* upload preset and dispatches `calmlens-uploaded` with `{ assetId, status, file }` for each
|
|
53
|
+
* finished upload. Attributes: `upload-preset-id`, `token-url`, `accept`, `max-file-size`
|
|
54
|
+
* (bytes), `no-auto-upload`, `multiple`, `max-files`, `disabled`, `capture` and `base-url`. Set
|
|
55
|
+
* the `token`, `upload`, `checkStatus`, `messages` and `controller` properties from script for
|
|
56
|
+
* anything an attribute can't hold.
|
|
57
|
+
*/
|
|
58
|
+
var CalmLensUploaderElement = class extends BaseElement {
|
|
59
|
+
static {
|
|
60
|
+
this.observedAttributes = [
|
|
61
|
+
"upload-preset-id",
|
|
62
|
+
"token-url",
|
|
63
|
+
"accept",
|
|
64
|
+
"max-file-size",
|
|
65
|
+
"no-auto-upload",
|
|
66
|
+
"multiple",
|
|
67
|
+
"max-files",
|
|
68
|
+
"disabled",
|
|
69
|
+
"capture",
|
|
70
|
+
"base-url"
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
#token;
|
|
74
|
+
#upload;
|
|
75
|
+
#checkStatus;
|
|
76
|
+
#createClient;
|
|
77
|
+
#messages;
|
|
78
|
+
#controller;
|
|
79
|
+
/** Whether `controller` was set from script, so its options and uploads aren't this element's. */
|
|
80
|
+
#external = false;
|
|
81
|
+
#unsubscribe;
|
|
82
|
+
#dragging = false;
|
|
83
|
+
#input;
|
|
84
|
+
/** The upload token, or a function returning one per file, instead of `token-url`. */
|
|
85
|
+
get token() {
|
|
86
|
+
return this.#token;
|
|
87
|
+
}
|
|
88
|
+
set token(value) {
|
|
89
|
+
this.#token = value;
|
|
90
|
+
this.#updateOptions();
|
|
91
|
+
}
|
|
92
|
+
/** Uploads each file your own way instead of through `upload-preset-id`. */
|
|
93
|
+
get upload() {
|
|
94
|
+
return this.#upload;
|
|
95
|
+
}
|
|
96
|
+
set upload(value) {
|
|
97
|
+
this.#upload = value;
|
|
98
|
+
this.#updateOptions();
|
|
99
|
+
}
|
|
100
|
+
/** Checks a pending upload made with `upload`. */
|
|
101
|
+
get checkStatus() {
|
|
102
|
+
return this.#checkStatus;
|
|
103
|
+
}
|
|
104
|
+
set checkStatus(value) {
|
|
105
|
+
this.#checkStatus = value;
|
|
106
|
+
this.#updateOptions();
|
|
107
|
+
}
|
|
108
|
+
/** Creates the client for each upload, for example a `MockCalmLensAppClient` in tests. */
|
|
109
|
+
get createClient() {
|
|
110
|
+
return this.#createClient;
|
|
111
|
+
}
|
|
112
|
+
set createClient(value) {
|
|
113
|
+
this.#createClient = value;
|
|
114
|
+
this.#updateOptions();
|
|
115
|
+
}
|
|
116
|
+
get messages() {
|
|
117
|
+
return this.#messages;
|
|
118
|
+
}
|
|
119
|
+
set messages(value) {
|
|
120
|
+
this.#messages = value;
|
|
121
|
+
this.#render();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The upload queue, for reading items or calling `start`, `retry`, `remove` and `clear`. Set it
|
|
125
|
+
* to show a queue your script created; its own options then apply instead of the attributes.
|
|
126
|
+
*/
|
|
127
|
+
get controller() {
|
|
128
|
+
this.#controller ??= createUploadController$1(this.#options());
|
|
129
|
+
return this.#controller;
|
|
130
|
+
}
|
|
131
|
+
set controller(value) {
|
|
132
|
+
if (value === this.#controller) return;
|
|
133
|
+
this.#unsubscribe?.();
|
|
134
|
+
if (!this.#external) this.#controller?.clear();
|
|
135
|
+
this.#controller = value;
|
|
136
|
+
this.#external = true;
|
|
137
|
+
if (this.isConnected) {
|
|
138
|
+
this.#subscribe();
|
|
139
|
+
this.#render();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
#updateOptions() {
|
|
143
|
+
if (!this.#external) this.#controller?.setOptions(this.#options());
|
|
144
|
+
}
|
|
145
|
+
#subscribe() {
|
|
146
|
+
this.#unsubscribe = this.controller.subscribe((snapshot) => {
|
|
147
|
+
this.#renderItems();
|
|
148
|
+
this.dispatchEvent(new CustomEvent("calmlens-change", { detail: snapshot }));
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
#options() {
|
|
152
|
+
const emit = (type, detail) => this.dispatchEvent(new CustomEvent(type, {
|
|
153
|
+
detail,
|
|
154
|
+
bubbles: true
|
|
155
|
+
}));
|
|
156
|
+
return {
|
|
157
|
+
uploadPresetId: this.getAttribute("upload-preset-id") ?? void 0,
|
|
158
|
+
upload: this.upload,
|
|
159
|
+
checkStatus: this.checkStatus,
|
|
160
|
+
createClient: this.createClient,
|
|
161
|
+
token: this.token,
|
|
162
|
+
tokenUrl: this.getAttribute("token-url") ?? void 0,
|
|
163
|
+
accept: this.getAttribute("accept") ?? void 0,
|
|
164
|
+
maxFileSize: numberAttribute(this, "max-file-size"),
|
|
165
|
+
autoUpload: !this.hasAttribute("no-auto-upload"),
|
|
166
|
+
multiple: this.hasAttribute("multiple"),
|
|
167
|
+
maxFiles: numberAttribute(this, "max-files"),
|
|
168
|
+
baseUrl: this.getAttribute("base-url") ?? void 0,
|
|
169
|
+
onUploaded: (upload) => emit("calmlens-uploaded", upload),
|
|
170
|
+
onRejected: (item) => emit("calmlens-rejected", item),
|
|
171
|
+
onFailed: (item) => emit("calmlens-failed", item),
|
|
172
|
+
onRemoved: (item) => emit("calmlens-removed", item)
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
connectedCallback() {
|
|
176
|
+
upgradeProperties(this, [
|
|
177
|
+
"token",
|
|
178
|
+
"upload",
|
|
179
|
+
"checkStatus",
|
|
180
|
+
"createClient",
|
|
181
|
+
"messages",
|
|
182
|
+
"controller"
|
|
183
|
+
]);
|
|
184
|
+
this.classList.add("calmlens-uploader");
|
|
185
|
+
this.#subscribe();
|
|
186
|
+
this.#render();
|
|
187
|
+
}
|
|
188
|
+
disconnectedCallback() {
|
|
189
|
+
this.#unsubscribe?.();
|
|
190
|
+
if (!this.#external) this.controller.clear();
|
|
191
|
+
}
|
|
192
|
+
attributeChangedCallback() {
|
|
193
|
+
this.#updateOptions();
|
|
194
|
+
if (this.isConnected) this.#render();
|
|
195
|
+
}
|
|
196
|
+
#render() {
|
|
197
|
+
if (!this.isConnected) return;
|
|
198
|
+
this.#updateOptions();
|
|
199
|
+
const { accept, multiple } = this.controller.options;
|
|
200
|
+
const messages = resolveMessages(this.#messages);
|
|
201
|
+
const disabled = this.hasAttribute("disabled");
|
|
202
|
+
const view = describeUploader(this.controller.getSnapshot(), this.controller.options, messages);
|
|
203
|
+
const input = el("input", {
|
|
204
|
+
type: "file",
|
|
205
|
+
hidden: true,
|
|
206
|
+
accept,
|
|
207
|
+
multiple,
|
|
208
|
+
capture: this.getAttribute("capture") ?? void 0,
|
|
209
|
+
disabled
|
|
210
|
+
});
|
|
211
|
+
this.#input = input;
|
|
212
|
+
input.addEventListener("change", () => {
|
|
213
|
+
if (input.files) this.controller.addFiles(input.files);
|
|
214
|
+
input.value = "";
|
|
215
|
+
});
|
|
216
|
+
const button = el("button", {
|
|
217
|
+
type: "button",
|
|
218
|
+
class: "calmlens-button",
|
|
219
|
+
"data-variant": "outline",
|
|
220
|
+
disabled
|
|
221
|
+
}, [view.chooseLabel]);
|
|
222
|
+
button.addEventListener("click", (event) => {
|
|
223
|
+
event.stopPropagation();
|
|
224
|
+
this.#openPicker();
|
|
225
|
+
});
|
|
226
|
+
const title = el("p", { class: "calmlens-dropzone__title" }, [messages.dropzoneTitle]);
|
|
227
|
+
const zone = el("div", {
|
|
228
|
+
class: "calmlens-dropzone",
|
|
229
|
+
"data-disabled": disabled
|
|
230
|
+
}, [
|
|
231
|
+
el("span", { class: "calmlens-dropzone__icon" }, [icon("upload")]),
|
|
232
|
+
el("div", { class: "calmlens-dropzone__text" }, [title, view.hint && el("p", { class: "calmlens-dropzone__hint" }, [view.hint])]),
|
|
233
|
+
button
|
|
234
|
+
]);
|
|
235
|
+
const setDragging = (dragging) => {
|
|
236
|
+
this.#dragging = dragging;
|
|
237
|
+
zone.toggleAttribute("data-dragging", dragging);
|
|
238
|
+
title.textContent = dragging ? messages.dropzoneTitleDragging : messages.dropzoneTitle;
|
|
239
|
+
};
|
|
240
|
+
const onDragOver = (event) => {
|
|
241
|
+
event.preventDefault();
|
|
242
|
+
if (!this.hasAttribute("disabled") && !this.#dragging) setDragging(true);
|
|
243
|
+
};
|
|
244
|
+
zone.addEventListener("click", () => this.#openPicker());
|
|
245
|
+
zone.addEventListener("dragover", onDragOver);
|
|
246
|
+
zone.addEventListener("dragenter", onDragOver);
|
|
247
|
+
zone.addEventListener("dragleave", (event) => {
|
|
248
|
+
if (!zone.contains(event.relatedTarget)) setDragging(false);
|
|
249
|
+
});
|
|
250
|
+
zone.addEventListener("drop", (event) => {
|
|
251
|
+
event.preventDefault();
|
|
252
|
+
setDragging(false);
|
|
253
|
+
if (!this.hasAttribute("disabled") && event.dataTransfer) this.controller.addFiles(event.dataTransfer.files);
|
|
254
|
+
});
|
|
255
|
+
zone.addEventListener("paste", (event) => {
|
|
256
|
+
const files = event.clipboardData?.files;
|
|
257
|
+
if (!this.hasAttribute("disabled") && files?.length) this.controller.addFiles(files);
|
|
258
|
+
});
|
|
259
|
+
this.replaceChildren(zone, input, el("ul", {
|
|
260
|
+
class: "calmlens-uploads",
|
|
261
|
+
hidden: true
|
|
262
|
+
}));
|
|
263
|
+
this.#renderItems();
|
|
264
|
+
}
|
|
265
|
+
#openPicker() {
|
|
266
|
+
if (!this.hasAttribute("disabled")) this.#input?.click();
|
|
267
|
+
}
|
|
268
|
+
#renderItems() {
|
|
269
|
+
const list = this.querySelector(":scope > .calmlens-uploads");
|
|
270
|
+
const zone = this.querySelector(":scope > .calmlens-dropzone");
|
|
271
|
+
if (!list || !zone) return;
|
|
272
|
+
const messages = resolveMessages(this.#messages);
|
|
273
|
+
const snapshot = this.controller.getSnapshot();
|
|
274
|
+
const { items } = snapshot;
|
|
275
|
+
const view = describeUploader(snapshot, this.controller.options, messages);
|
|
276
|
+
zone.hidden = !view.showDropzone;
|
|
277
|
+
list.hidden = items.length === 0;
|
|
278
|
+
const thumbnails = new Map([...list.querySelectorAll(".calmlens-upload")].map((row) => [row.dataset.key, row.querySelector(".calmlens-upload__thumb")]));
|
|
279
|
+
const disabled = this.hasAttribute("disabled");
|
|
280
|
+
list.replaceChildren(...items.map((item) => {
|
|
281
|
+
const itemView = describeUploadItem(item, messages);
|
|
282
|
+
const thumbnail = thumbnails.get(item.key) ?? (item.previewUrl ? el("img", {
|
|
283
|
+
class: "calmlens-upload__thumb",
|
|
284
|
+
src: item.previewUrl,
|
|
285
|
+
alt: ""
|
|
286
|
+
}) : fileThumbnail(itemView.fileIcon));
|
|
287
|
+
const bar = el("div", { class: "calmlens-progress__bar" });
|
|
288
|
+
if (itemView.progressPercent !== void 0) bar.style.width = `${itemView.progressPercent}%`;
|
|
289
|
+
const chooseAnother = !view.showDropzone && el("button", {
|
|
290
|
+
type: "button",
|
|
291
|
+
class: "calmlens-button",
|
|
292
|
+
"data-variant": "outline",
|
|
293
|
+
"data-size": "small",
|
|
294
|
+
disabled
|
|
295
|
+
}, [messages.chooseAnother]);
|
|
296
|
+
if (chooseAnother) chooseAnother.addEventListener("click", () => this.#openPicker());
|
|
297
|
+
const retry = itemView.canRetry && el("button", {
|
|
298
|
+
type: "button",
|
|
299
|
+
class: "calmlens-icon-button",
|
|
300
|
+
"aria-label": messages.retry,
|
|
301
|
+
title: messages.retry
|
|
302
|
+
}, [icon("retry")]);
|
|
303
|
+
if (retry) retry.addEventListener("click", () => this.controller.retry(item.key));
|
|
304
|
+
const remove = el("button", {
|
|
305
|
+
type: "button",
|
|
306
|
+
class: "calmlens-icon-button",
|
|
307
|
+
"aria-label": itemView.removeLabel,
|
|
308
|
+
title: itemView.removeLabel
|
|
309
|
+
}, [icon("remove")]);
|
|
310
|
+
remove.addEventListener("click", () => this.controller.remove(item.key));
|
|
311
|
+
const row = el("li", {
|
|
312
|
+
class: "calmlens-upload",
|
|
313
|
+
"data-stage": item.stage,
|
|
314
|
+
"data-outcome": itemView.outcome
|
|
315
|
+
}, [
|
|
316
|
+
thumbnail,
|
|
317
|
+
el("div", { class: "calmlens-upload__body" }, [
|
|
318
|
+
el("span", { class: "calmlens-upload__name" }, [item.file.name]),
|
|
319
|
+
el("span", { class: "calmlens-upload__size" }, [itemView.size]),
|
|
320
|
+
itemView.busy && el("div", {
|
|
321
|
+
class: "calmlens-progress",
|
|
322
|
+
role: "progressbar",
|
|
323
|
+
"aria-label": itemView.message,
|
|
324
|
+
"aria-valuemin": 0,
|
|
325
|
+
"aria-valuemax": 100,
|
|
326
|
+
"aria-valuenow": itemView.progressPercent
|
|
327
|
+
}, [bar]),
|
|
328
|
+
itemView.message && el("p", {
|
|
329
|
+
class: "calmlens-upload__message",
|
|
330
|
+
role: "status"
|
|
331
|
+
}, [itemView.message])
|
|
332
|
+
]),
|
|
333
|
+
el("div", { class: "calmlens-upload__actions" }, [
|
|
334
|
+
chooseAnother,
|
|
335
|
+
retry,
|
|
336
|
+
remove
|
|
337
|
+
])
|
|
338
|
+
]);
|
|
339
|
+
row.dataset.key = item.key;
|
|
340
|
+
return row;
|
|
341
|
+
}));
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* `<calmlens-media project-id="…" asset-id="…" status="allowed" alt="…">` shows an asset from the
|
|
346
|
+
* CalmLens CDN with a blurred placeholder while it loads. Age-restricted assets show the
|
|
347
|
+
* placeholder and a reveal button, which dispatches `calmlens-reveal`, until `age-confirmed` is set.
|
|
348
|
+
* Attributes: `project-id`, `asset-id`, `status`, `age-confirmed`, `type`, `resource`, `lens`,
|
|
349
|
+
* `transform`, `widths` (comma-separated), `url`, `no-placeholder`, `placeholder-hash`,
|
|
350
|
+
* `placeholder-url`, `average-color`, `cdn-base-url`, `alt`, `aspect-ratio`, `width`, `height`,
|
|
351
|
+
* `sizes`, `fit`, `position`, `eager`, `fetch-priority` and `no-controls`. Set the
|
|
352
|
+
* `asset` property to an API asset instead of `project-id` and `asset-id`.
|
|
353
|
+
*/
|
|
354
|
+
var CalmLensMediaElement = class extends BaseElement {
|
|
355
|
+
static {
|
|
356
|
+
this.observedAttributes = [
|
|
357
|
+
"project-id",
|
|
358
|
+
"asset-id",
|
|
359
|
+
"status",
|
|
360
|
+
"content-removed",
|
|
361
|
+
"type",
|
|
362
|
+
"resource",
|
|
363
|
+
"lens",
|
|
364
|
+
"transform",
|
|
365
|
+
"widths",
|
|
366
|
+
"url",
|
|
367
|
+
"no-placeholder",
|
|
368
|
+
"placeholder-hash",
|
|
369
|
+
"placeholder-url",
|
|
370
|
+
"average-color",
|
|
371
|
+
"cdn-base-url",
|
|
372
|
+
"viewer-claims",
|
|
373
|
+
"alt",
|
|
374
|
+
"aspect-ratio",
|
|
375
|
+
"width",
|
|
376
|
+
"height",
|
|
377
|
+
"sizes",
|
|
378
|
+
"fit",
|
|
379
|
+
"position",
|
|
380
|
+
"eager",
|
|
381
|
+
"fetch-priority",
|
|
382
|
+
"no-controls"
|
|
383
|
+
];
|
|
384
|
+
}
|
|
385
|
+
#messages;
|
|
386
|
+
#asset;
|
|
387
|
+
#loadKey;
|
|
388
|
+
get messages() {
|
|
389
|
+
return this.#messages;
|
|
390
|
+
}
|
|
391
|
+
set messages(value) {
|
|
392
|
+
this.#messages = value;
|
|
393
|
+
this.#loadKey = void 0;
|
|
394
|
+
this.#render();
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* An asset from the API, in place of `project-id` and `asset-id`. It supplies the status, type
|
|
398
|
+
* and preview too; attributes you set win over it.
|
|
399
|
+
*/
|
|
400
|
+
get asset() {
|
|
401
|
+
return this.#asset;
|
|
402
|
+
}
|
|
403
|
+
set asset(value) {
|
|
404
|
+
this.#asset = value;
|
|
405
|
+
this.#render();
|
|
406
|
+
}
|
|
407
|
+
connectedCallback() {
|
|
408
|
+
upgradeProperties(this, ["messages", "asset"]);
|
|
409
|
+
this.classList.add("calmlens-media");
|
|
410
|
+
this.setAttribute("role", "figure");
|
|
411
|
+
this.#render();
|
|
412
|
+
}
|
|
413
|
+
attributeChangedCallback() {
|
|
414
|
+
this.#render();
|
|
415
|
+
}
|
|
416
|
+
#mediaOptions() {
|
|
417
|
+
const list = (name) => this.getAttribute(name)?.split(",").map((value) => value.trim()).filter(Boolean);
|
|
418
|
+
return resolveMediaProps({
|
|
419
|
+
asset: this.#asset,
|
|
420
|
+
projectId: this.getAttribute("project-id") ?? void 0,
|
|
421
|
+
assetId: this.getAttribute("asset-id") ?? void 0,
|
|
422
|
+
status: this.getAttribute("status") ?? void 0,
|
|
423
|
+
contentRemoved: this.hasAttribute("content-removed") ? true : void 0,
|
|
424
|
+
type: this.getAttribute("type") ?? void 0,
|
|
425
|
+
resource: this.getAttribute("resource") ?? void 0,
|
|
426
|
+
lens: this.getAttribute("lens") ?? void 0,
|
|
427
|
+
transform: this.getAttribute("transform") ?? void 0,
|
|
428
|
+
widths: list("widths")?.map(Number),
|
|
429
|
+
url: this.getAttribute("url") ?? void 0,
|
|
430
|
+
placeholder: !this.hasAttribute("no-placeholder"),
|
|
431
|
+
placeholderHash: this.getAttribute("placeholder-hash") ?? void 0,
|
|
432
|
+
placeholderUrl: this.getAttribute("placeholder-url") ?? void 0,
|
|
433
|
+
viewerClaims: this.hasAttribute("viewer-claims") ? JSON.parse(this.getAttribute("viewer-claims")) : void 0,
|
|
434
|
+
cdnBaseUrl: this.getAttribute("cdn-base-url") ?? void 0,
|
|
435
|
+
width: numberAttribute(this, "width"),
|
|
436
|
+
height: numberAttribute(this, "height"),
|
|
437
|
+
averageColor: this.getAttribute("average-color") ?? void 0
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
#render() {
|
|
441
|
+
if (!this.isConnected) return;
|
|
442
|
+
const options = this.#mediaOptions();
|
|
443
|
+
if (!options.projectId || !options.assetId) return;
|
|
444
|
+
const state = getMediaState(options);
|
|
445
|
+
const loadKey = `${getMediaLoadKey(state)} ${this.getAttribute("alt")} ${this.getAttribute("sizes")} ${options.viewerClaims?.ageConfirmed}`;
|
|
446
|
+
const ratio = getMediaAspectRatio({
|
|
447
|
+
aspectRatio: numberAttribute(this, "aspect-ratio"),
|
|
448
|
+
width: options.width,
|
|
449
|
+
height: options.height
|
|
450
|
+
});
|
|
451
|
+
this.style.aspectRatio = ratio ? String(ratio) : "";
|
|
452
|
+
this.toggleAttribute("data-sized", Boolean(ratio));
|
|
453
|
+
this.style.backgroundColor = options.averageColor ?? "";
|
|
454
|
+
this.style.setProperty("--calmlens-fit", this.getAttribute("fit"));
|
|
455
|
+
this.style.setProperty("--calmlens-position", this.getAttribute("position"));
|
|
456
|
+
this.dataset.kind = state.kind;
|
|
457
|
+
if (loadKey === this.#loadKey) return;
|
|
458
|
+
this.#loadKey = loadKey;
|
|
459
|
+
this.dataset.state = "loading";
|
|
460
|
+
const messages = resolveMessages(this.#messages);
|
|
461
|
+
const alt = this.getAttribute("alt") ?? "";
|
|
462
|
+
const sizes = this.getAttribute("sizes") ?? void 0;
|
|
463
|
+
const placeholder = state.kind !== "audio" && state.kind !== "unavailable" && state.placeholderUrl ? el("img", {
|
|
464
|
+
class: "calmlens-media__placeholder",
|
|
465
|
+
src: state.placeholderUrl,
|
|
466
|
+
alt: "",
|
|
467
|
+
"aria-hidden": "true"
|
|
468
|
+
}) : void 0;
|
|
469
|
+
const notice = (children) => el("div", { class: "calmlens-media__notice" }, children);
|
|
470
|
+
const unavailable = () => notice([el("p", {}, [icon("unavailable"), el("span", { class: "calmlens-media__label" }, [getMediaUnavailableMessage(state, messages)])])]);
|
|
471
|
+
const fail = () => {
|
|
472
|
+
this.dataset.state = "error";
|
|
473
|
+
this.replaceChildren(unavailable());
|
|
474
|
+
};
|
|
475
|
+
const controls = !this.hasAttribute("no-controls");
|
|
476
|
+
if (state.kind === "unavailable") this.replaceChildren(unavailable());
|
|
477
|
+
else if (state.kind === "gated") {
|
|
478
|
+
const reveal = el("button", {
|
|
479
|
+
type: "button",
|
|
480
|
+
class: "calmlens-button"
|
|
481
|
+
}, [messages.reveal]);
|
|
482
|
+
reveal.addEventListener("click", () => this.dispatchEvent(new CustomEvent("calmlens-reveal", { bubbles: true })));
|
|
483
|
+
this.replaceChildren(...[placeholder].filter((node) => node !== void 0), notice([
|
|
484
|
+
el("strong", {}, [messages.sensitiveTitle]),
|
|
485
|
+
el("p", {}, [messages.sensitiveBody]),
|
|
486
|
+
reveal
|
|
487
|
+
]));
|
|
488
|
+
} else if (state.kind === "image") {
|
|
489
|
+
const image = el("img", {
|
|
490
|
+
class: "calmlens-media__content",
|
|
491
|
+
src: state.src,
|
|
492
|
+
srcset: state.srcSet,
|
|
493
|
+
sizes,
|
|
494
|
+
alt,
|
|
495
|
+
width: options.width,
|
|
496
|
+
height: options.height,
|
|
497
|
+
loading: this.hasAttribute("eager") ? void 0 : "lazy",
|
|
498
|
+
decoding: "async",
|
|
499
|
+
fetchpriority: this.getAttribute("fetch-priority") ?? void 0
|
|
500
|
+
});
|
|
501
|
+
image.addEventListener("load", () => {
|
|
502
|
+
this.dataset.state = "loaded";
|
|
503
|
+
placeholder?.remove();
|
|
504
|
+
});
|
|
505
|
+
image.addEventListener("error", fail);
|
|
506
|
+
this.replaceChildren(...[placeholder, image].filter((node) => node !== void 0));
|
|
507
|
+
} else {
|
|
508
|
+
const media = el(state.kind, {
|
|
509
|
+
class: "calmlens-media__content",
|
|
510
|
+
src: state.src,
|
|
511
|
+
controls,
|
|
512
|
+
playsinline: state.kind === "video",
|
|
513
|
+
preload: "metadata",
|
|
514
|
+
"aria-label": alt || void 0
|
|
515
|
+
});
|
|
516
|
+
media.addEventListener("error", fail);
|
|
517
|
+
this.replaceChildren(media);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
/** Defines `<calmlens-uploader>` and `<calmlens-media>`, if they aren't defined yet. */
|
|
522
|
+
const defineCalmLensElements = () => {
|
|
523
|
+
if (typeof customElements === "undefined") return;
|
|
524
|
+
if (!customElements.get("calmlens-uploader")) customElements.define("calmlens-uploader", CalmLensUploaderElement);
|
|
525
|
+
if (!customElements.get("calmlens-media")) customElements.define("calmlens-media", CalmLensMediaElement);
|
|
526
|
+
};
|
|
527
|
+
defineCalmLensElements();
|
|
528
|
+
export { CALMLENS_STYLES, CALMLENS_THEME, CalmLensMediaElement, CalmLensUploaderElement, DEFAULT_MESSAGES, ICONS, ICON_ATTRIBUTES, UploadController, createProgressFetch, createUploadController, defineCalmLensElements, describeUploadItem, describeUploader, formatBytes, formatMessage, getDropzoneHint, getMediaAspectRatio, getMediaLoadKey, getMediaState, getMediaUnavailableMessage, getUploadItemMessage, getUploadItemOutcome, isFileAccepted, pickMediaSource, resolveMediaProps, resolveMessages, resolveTheme };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-type icons for files without an image preview: a file outline in the family's colour with
|
|
3
|
+
* the family's symbol and an extension label, drawn the same way by every framework. The symbols are
|
|
4
|
+
* Tabler icons (MIT) as 24×24 stroke paths.
|
|
5
|
+
*/
|
|
6
|
+
type FileIconFamily = "documents" | "spreadsheets" | "presentations" | "images" | "audio" | "video" | "archives" | "code" | "data" | "design" | "applications" | "fonts" | "maps" | "games" | "system" | "security" | "unknown";
|
|
7
|
+
/** The families `getFileIcon` finds from a file's name and MIME type. */
|
|
8
|
+
type UploadFileIconFamily = Exclude<FileIconFamily, "applications" | "maps" | "games" | "system" | "security" | "unknown">;
|
|
9
|
+
/** The file outline every family's icon is drawn on. */
|
|
10
|
+
export declare const FILE_ICON_OUTLINE = "M14 3v4a1 1 0 0 0 1 1h4 M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2";
|
|
11
|
+
/** The symbols of the families `getFileIcon` finds, which the upload widget draws. */
|
|
12
|
+
export declare const FILE_ICON_SYMBOLS: Record<UploadFileIconFamily, string>;
|
|
13
|
+
/**
|
|
14
|
+
* The symbols of the families only an app's own file detection finds, kept apart so the upload
|
|
15
|
+
* widget doesn't bundle them.
|
|
16
|
+
*/
|
|
17
|
+
export declare const MORE_FILE_ICON_SYMBOLS: Record<Exclude<FileIconFamily, UploadFileIconFamily | "unknown">, string>;
|
|
18
|
+
export declare const FILE_ICON_COLORS: Record<FileIconFamily, string>;
|
|
19
|
+
/** A file's icon family and the extension its label shows, such as `pdf`. */
|
|
20
|
+
export declare const getFileIcon: (file: {
|
|
21
|
+
name: string;
|
|
22
|
+
type: string;
|
|
23
|
+
}) => {
|
|
24
|
+
family: UploadFileIconFamily;
|
|
25
|
+
extension: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Where each part of the icon goes in its 24×24 box: the symbol inside the outline, above a band
|
|
29
|
+
* holding the extension. Icons 32 pixels or smaller leave the band out and centre the symbol.
|
|
30
|
+
*/
|
|
31
|
+
export declare const getFileIconLayout: (size: number) => {
|
|
32
|
+
compact: boolean;
|
|
33
|
+
symbol: {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
};
|
|
39
|
+
outlineStroke: number;
|
|
40
|
+
/** The band and its label, in a half-scale group: `transform="scale(0.5)"`. */
|
|
41
|
+
band: {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
rx: number;
|
|
47
|
+
};
|
|
48
|
+
label: {
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
/** The label's font size, and a squeezed width for long extensions. */
|
|
54
|
+
export declare const getFileIconLabel: (extension: string) => {
|
|
55
|
+
text: string;
|
|
56
|
+
fontSize: number;
|
|
57
|
+
textLength: number | undefined;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* The icon as SVG markup, for the components to insert as it is. `extension` must come from
|
|
61
|
+
* `getFileIcon`, which keeps only letters and digits.
|
|
62
|
+
*/
|
|
63
|
+
export declare const renderFileIconSvg: ({ family, extension }: {
|
|
64
|
+
family: UploadFileIconFamily | "unknown";
|
|
65
|
+
extension: string;
|
|
66
|
+
}, size: number) => string;
|
|
67
|
+
export type { FileIconFamily, UploadFileIconFamily };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as FILE_ICON_COLORS, n as FILE_ICON_OUTLINE, r as FILE_ICON_SYMBOLS, i as MORE_FILE_ICON_SYMBOLS, a as getFileIcon, o as getFileIconLabel, s as getFileIconLayout, c as renderFileIconSvg } from "./FileIcons-M6dzjFxd.js";
|