@epam/ai-dial-attachment-input 0.0.0-dev.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/components/AttachmentCard/AttachmentCard.d.ts +4 -0
- package/components/AttachmentCard/AttachmentCard.d.ts.map +1 -0
- package/components/AttachmentTray/AttachmentTray.d.ts +4 -0
- package/components/AttachmentTray/AttachmentTray.d.ts.map +1 -0
- package/components/FileDndOverlay/FileDndOverlay.d.ts +4 -0
- package/components/FileDndOverlay/FileDndOverlay.d.ts.map +1 -0
- package/constants/upload.d.ts +2 -0
- package/constants/upload.d.ts.map +1 -0
- package/hooks/useClipboardPaste.d.ts +16 -0
- package/hooks/useClipboardPaste.d.ts.map +1 -0
- package/hooks/useLazyImageLoad.d.ts +21 -0
- package/hooks/useLazyImageLoad.d.ts.map +1 -0
- package/index.css +2 -0
- package/index.d.ts +16 -0
- package/index.d.ts.map +1 -0
- package/index.js +372 -0
- package/models/AttachmentCard.d.ts +53 -0
- package/models/AttachmentCard.d.ts.map +1 -0
- package/models/AttachmentTray.d.ts +25 -0
- package/models/AttachmentTray.d.ts.map +1 -0
- package/models/FileDndOverlay.d.ts +24 -0
- package/models/FileDndOverlay.d.ts.map +1 -0
- package/package.json +24 -0
- package/test-setup.d.ts +6 -0
- package/test-setup.d.ts.map +1 -0
- package/utils/attachment-mime.d.ts +20 -0
- package/utils/attachment-mime.d.ts.map +1 -0
- package/utils/generateAttachmentId.d.ts +6 -0
- package/utils/generateAttachmentId.d.ts.map +1 -0
- package/utils/getAttachmentCardState.d.ts +15 -0
- package/utils/getAttachmentCardState.d.ts.map +1 -0
- package/utils/getAttachmentIcon.d.ts +8 -0
- package/utils/getAttachmentIcon.d.ts.map +1 -0
- package/utils/getNameWithoutExtension.d.ts +5 -0
- package/utils/getNameWithoutExtension.d.ts.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AttachmentCard.d.ts","sourceRoot":"","sources":["../../../src/components/AttachmentCard/AttachmentCard.tsx"],"names":[],"mappings":"AAoBA,OAAO,EAAE,KAAK,EAAE,EAAgD,MAAM,OAAO,CAAC;AAK9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAKvE,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CA6TlD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AttachmentTray.d.ts","sourceRoot":"","sources":["../../../src/components/AttachmentTray/AttachmentTray.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGvE,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CA2ClD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileDndOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/FileDndOverlay/FileDndOverlay.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,EAAE,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAmDlD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/constants/upload.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,MAAM,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Attachment } from '@epam/ai-dial-chat-shared';
|
|
2
|
+
import { ClipboardEventHandler } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Returns a `handlePaste` handler for a textarea that intercepts clipboard
|
|
5
|
+
* events and converts image items or long plain-text strings into
|
|
6
|
+
* `Attachment` objects instead of inserting raw content.
|
|
7
|
+
*
|
|
8
|
+
* @param onAttachments - Called with the built attachments when a paste is
|
|
9
|
+
* intercepted.
|
|
10
|
+
* @param threshold - Plain-text pastes longer than this many characters are
|
|
11
|
+
* converted to a file attachment instead of being inserted inline.
|
|
12
|
+
*/
|
|
13
|
+
export declare const useClipboardPaste: (onAttachments: (attachments: Attachment[]) => void, threshold: number) => {
|
|
14
|
+
handlePaste: ClipboardEventHandler<HTMLTextAreaElement>;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=useClipboardPaste.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClipboardPaste.d.ts","sourceRoot":"","sources":["../../src/hooks/useClipboardPaste.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,qBAAqB,EAAe,MAAM,OAAO,CAAC;AAG3D;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAC5B,eAAe,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,IAAI,EAClD,WAAW,MAAM,KAChB;IAAE,WAAW,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAA;CA+D3D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
export declare enum LazyImageLoadStatus {
|
|
3
|
+
Idle = "idle",
|
|
4
|
+
Loading = "loading",
|
|
5
|
+
Loaded = "loaded",
|
|
6
|
+
Error = "error"
|
|
7
|
+
}
|
|
8
|
+
interface UseLazyImageLoadParams {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
src?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Tracks a lazily rendered image element so callers can keep a skeleton visible
|
|
14
|
+
* until the browser either loads the image or reports a load error.
|
|
15
|
+
*/
|
|
16
|
+
export declare const useLazyImageLoad: ({ enabled, src, }: UseLazyImageLoadParams) => {
|
|
17
|
+
imageRef: RefObject<HTMLImageElement | null>;
|
|
18
|
+
imageLoadStatus: LazyImageLoadStatus;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=useLazyImageLoad.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLazyImageLoad.d.ts","sourceRoot":"","sources":["../../src/hooks/useLazyImageLoad.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAEpE,oBAAY,mBAAmB;IAC7B,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,KAAK,UAAU;CAChB;AAED,UAAU,sBAAsB;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,mBAG9B,sBAAsB,KAAG;IAC1B,QAAQ,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC7C,eAAe,EAAE,mBAAmB,CAAC;CA0CtC,CAAC"}
|
package/index.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
._card_11tpd_1{border-color:var(--ci-card-border,var(--stroke-secondary,#d1dbea));background:var(--ci-card-bg,var(--bg-layer-0,#fcfcfc))}._cardError_11tpd_6{border-color:var(--ci-card-border-error,var(--stroke-error,#ae2f2f))}._cardSelected_11tpd_10{background:var(--ci-card-bg-selected,var(--bg-accent-primary-alpha,#7da4ff2e));border-color:var(--ci-card-border-selected,var(--stroke-accent-primary,#124ace))}._cardPrompt_11tpd_15:hover,._cardPasted_11tpd_16:hover{background:var(--ci-card-bg-hover,var(--controls-bg-neutral-hover,#d1dbea))}._name_11tpd_20{color:var(--ci-card-name,var(--text-primary,#161b2d))}._meta_11tpd_24{color:var(--ci-card-meta,var(--text-secondary,#575f73))}._loadingOverlay_11tpd_28{background:var(--ci-loading-overlay-bg,var(--bg-blackout,#0c101d4d))}._actionBtn_11tpd_32{color:var(--ci-card-action-color,var(--text-primary,#161b2d))}._actionBtn_11tpd_32:hover{background:var(--ci-card-remove-bg-hover,var(--bg-layer-3,#fcfcfc))}._card_11tpd_1:focus-within{outline-color:var(--ci-card-focus-outline,var(--controls-stroke-focus,#eef1f7))}._removeBtnImage_11tpd_43{background:var(--ci-card-remove-bg,var(--bg-layer-2,#eef1f7));color:var(--ci-card-remove-color,var(--text-primary,#161b2d))}._removeBtnImage_11tpd_43:hover{background:var(--ci-card-remove-bg-hover,var(--bg-layer-3,#fcfcfc))}
|
|
2
|
+
/*$vite$:1*/
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { AttachmentCard } from './components/AttachmentCard/AttachmentCard';
|
|
2
|
+
export { AttachmentTray } from './components/AttachmentTray/AttachmentTray';
|
|
3
|
+
export { FileDndOverlay } from './components/FileDndOverlay/FileDndOverlay';
|
|
4
|
+
export type { AttachmentCardProps, AttachmentCardColors, AttachmentCardTypography, } from './models/AttachmentCard';
|
|
5
|
+
export type { AttachmentTrayProps } from './models/AttachmentTray';
|
|
6
|
+
export type { FileDndOverlayProps } from './models/FileDndOverlay';
|
|
7
|
+
export { useClipboardPaste } from './hooks/useClipboardPaste';
|
|
8
|
+
export { useLazyImageLoad, LazyImageLoadStatus, } from './hooks/useLazyImageLoad';
|
|
9
|
+
export { generateAttachmentId } from './utils/generateAttachmentId';
|
|
10
|
+
export { getAttachmentCardState } from './utils/getAttachmentCardState';
|
|
11
|
+
export type { AttachmentCardState } from './utils/getAttachmentCardState';
|
|
12
|
+
export { getAttachmentIcon } from './utils/getAttachmentIcon';
|
|
13
|
+
export { getNameWithoutExtension } from './utils/getNameWithoutExtension';
|
|
14
|
+
export { mimeTypesToExtensionLabels, isMimeTypeAllowed, } from './utils/attachment-mime';
|
|
15
|
+
export { MAX_UPLOADS_PER_MINUTE } from './constants/upload';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAE5E,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EACL,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { AttachmentErrorReason as e, AttachmentType as t, MIME_TYPE_EXT_MAP as n, RequestStatus as r, buildCssVars as i, mergeClasses as a } from "@epam/ai-dial-chat-shared";
|
|
2
|
+
import { DIAL_ICON_SIZE as o, DialGhostIconButton as s, DialSkeleton as c, DialSkeletonVariant as l, DialSpinner as u, ElementSize as d } from "@epam/ai-dial-ui-kit";
|
|
3
|
+
import { IconClipboard as f, IconDownload as p, IconFile as m, IconFileDescription as h, IconFileTypeBmp as g, IconFileTypeCss as _, IconFileTypeCsv as v, IconFileTypeDoc as ee, IconFileTypeDocx as y, IconFileTypeHtml as b, IconFileTypeJpg as x, IconFileTypeJs as S, IconFileTypeJsx as C, IconFileTypePdf as w, IconFileTypePhp as T, IconFileTypePng as E, IconFileTypePpt as D, IconFileTypeRs as O, IconFileTypeSql as k, IconFileTypeSvg as A, IconFileTypeTs as j, IconFileTypeTsx as M, IconFileTypeTxt as N, IconFileTypeVue as P, IconFileTypeXls as F, IconFileTypeXml as I, IconFileTypeZip as te, IconFileX as L, IconMusic as R, IconPhoto as z, IconReload as ne, IconTerminal2 as B, IconVideo as V, IconX as re } from "@tabler/icons-react";
|
|
4
|
+
import { useCallback as H, useEffect as U, useMemo as ie, useRef as W, useState as G } from "react";
|
|
5
|
+
import { Fragment as K, jsx as q, jsxs as J } from "react/jsx-runtime";
|
|
6
|
+
//#region src/hooks/useLazyImageLoad.ts
|
|
7
|
+
var Y = /* @__PURE__ */ function(e) {
|
|
8
|
+
return e.Idle = "idle", e.Loading = "loading", e.Loaded = "loaded", e.Error = "error", e;
|
|
9
|
+
}({}), ae = ({ enabled: e, src: t }) => {
|
|
10
|
+
let n = W(null), [r, i] = G("idle");
|
|
11
|
+
return U(() => {
|
|
12
|
+
i(e && t ? "loading" : "idle");
|
|
13
|
+
}, [e, t]), U(() => {
|
|
14
|
+
let r = n.current;
|
|
15
|
+
if (!r || !e || !t) return;
|
|
16
|
+
let a = () => i("loaded"), o = () => i("error");
|
|
17
|
+
return r.addEventListener("load", a), r.addEventListener("error", o), r.complete && i(r.naturalWidth > 0 ? "loaded" : "error"), () => {
|
|
18
|
+
r.removeEventListener("load", a), r.removeEventListener("error", o);
|
|
19
|
+
};
|
|
20
|
+
}, [e, t]), {
|
|
21
|
+
imageRef: n,
|
|
22
|
+
imageLoadStatus: r
|
|
23
|
+
};
|
|
24
|
+
}, X = {
|
|
25
|
+
card: "_card_11tpd_1",
|
|
26
|
+
cardError: "_cardError_11tpd_6",
|
|
27
|
+
cardSelected: "_cardSelected_11tpd_10",
|
|
28
|
+
cardPrompt: "_cardPrompt_11tpd_15",
|
|
29
|
+
cardPasted: "_cardPasted_11tpd_16",
|
|
30
|
+
name: "_name_11tpd_20",
|
|
31
|
+
meta: "_meta_11tpd_24",
|
|
32
|
+
loadingOverlay: "_loadingOverlay_11tpd_28",
|
|
33
|
+
actionBtn: "_actionBtn_11tpd_32",
|
|
34
|
+
removeBtnImage: "_removeBtnImage_11tpd_43"
|
|
35
|
+
}, Z = (e) => {
|
|
36
|
+
if (!e) return m;
|
|
37
|
+
if (e.startsWith("image/")) switch (e) {
|
|
38
|
+
case "image/jpeg":
|
|
39
|
+
case "image/jpg": return x;
|
|
40
|
+
case "image/png": return E;
|
|
41
|
+
case "image/svg+xml": return A;
|
|
42
|
+
case "image/bmp": return g;
|
|
43
|
+
default: return z;
|
|
44
|
+
}
|
|
45
|
+
if (e.startsWith("video/")) return V;
|
|
46
|
+
if (e.startsWith("audio/")) return R;
|
|
47
|
+
switch (e) {
|
|
48
|
+
case "application/pdf": return w;
|
|
49
|
+
case "application/msword":
|
|
50
|
+
case "application/vnd.ms-word": return ee;
|
|
51
|
+
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": return y;
|
|
52
|
+
case "application/vnd.ms-powerpoint": return D;
|
|
53
|
+
case "application/vnd.openxmlformats-officedocument.presentationml.presentation": return D;
|
|
54
|
+
case "application/vnd.ms-excel": return F;
|
|
55
|
+
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": return F;
|
|
56
|
+
case "application/zip":
|
|
57
|
+
case "application/x-zip-compressed":
|
|
58
|
+
case "application/x-rar-compressed":
|
|
59
|
+
case "application/x-7z-compressed":
|
|
60
|
+
case "application/gzip":
|
|
61
|
+
case "application/x-tar": return te;
|
|
62
|
+
case "text/csv": return v;
|
|
63
|
+
case "text/plain": return N;
|
|
64
|
+
case "text/html":
|
|
65
|
+
case "application/xhtml+xml": return b;
|
|
66
|
+
case "text/xml":
|
|
67
|
+
case "application/xml": return I;
|
|
68
|
+
case "application/sql":
|
|
69
|
+
case "text/x-sql": return k;
|
|
70
|
+
case "text/javascript":
|
|
71
|
+
case "application/javascript": return S;
|
|
72
|
+
case "text/jsx": return C;
|
|
73
|
+
case "application/typescript":
|
|
74
|
+
case "text/typescript": return j;
|
|
75
|
+
case "text/tsx": return M;
|
|
76
|
+
case "text/css": return _;
|
|
77
|
+
case "text/x-php":
|
|
78
|
+
case "application/x-php": return T;
|
|
79
|
+
case "text/x-rustsrc":
|
|
80
|
+
case "application/x-rust": return O;
|
|
81
|
+
case "text/x-vue": return P;
|
|
82
|
+
default: return m;
|
|
83
|
+
}
|
|
84
|
+
}, Q = (e) => {
|
|
85
|
+
let { type: n, contentType: r } = e;
|
|
86
|
+
return n === t.Prompt ? B : n === t.Pasted ? f : n === t.Image ? z : Z(r ?? "");
|
|
87
|
+
}, oe = (e) => {
|
|
88
|
+
let t = e.toLowerCase().split(";")[0].trim(), r = n[t];
|
|
89
|
+
if (r) return r;
|
|
90
|
+
let i = t.split("/")[1];
|
|
91
|
+
if (i && !i.startsWith("vnd.") && !i.includes("+")) return i;
|
|
92
|
+
}, se = (e) => {
|
|
93
|
+
let { type: n, name: r, contentType: i } = e;
|
|
94
|
+
if (n === t.Prompt) return "Prompt";
|
|
95
|
+
if (n === t.Pasted) return "Pasted";
|
|
96
|
+
if (n === t.Image) return "Image";
|
|
97
|
+
if (i) {
|
|
98
|
+
let e = oe(i);
|
|
99
|
+
if (e) return `.${e}`;
|
|
100
|
+
}
|
|
101
|
+
let a = r.lastIndexOf(".");
|
|
102
|
+
return a > 0 && a < r.length - 1 ? `.${r.slice(a + 1).toLowerCase()}` : r;
|
|
103
|
+
}, ce = (e, n, i) => {
|
|
104
|
+
let { type: o, status: s, previewUrl: c, url: l } = e, u = s === r.Loading, d = s === r.Error, f = o === t.Image && !!(c ?? l) && !d, p = o === t.Audio && !d, m = a(X.card, d && X.cardError, n && X.cardSelected, !d && !n && o === t.Prompt && X.cardPrompt, !d && !n && o === t.Pasted && X.cardPasted);
|
|
105
|
+
return {
|
|
106
|
+
isLoading: u,
|
|
107
|
+
isError: d,
|
|
108
|
+
isImage: f,
|
|
109
|
+
isAudio: p,
|
|
110
|
+
areActionsVisible: d || i,
|
|
111
|
+
BottomIcon: Q(e),
|
|
112
|
+
typeLabel: se(e),
|
|
113
|
+
cardColorClass: m,
|
|
114
|
+
removeBtnClass: f ? X.removeBtnImage : X.actionBtn
|
|
115
|
+
};
|
|
116
|
+
}, le = (e) => {
|
|
117
|
+
let t = e.lastIndexOf(".");
|
|
118
|
+
return t > 0 ? e.slice(0, t) : e;
|
|
119
|
+
}, ue = ({ attachment: n, onRemove: r, onRetry: f, onExpand: m, onClick: h, isSelected: g, shouldAlwaysShowActions: _, removeLabel: v = "Remove attachment", retryLabel: ee = "Retry upload", clickLabel: y = "Open attachment", colors: b, typography: x, roundedClassName: S = "rounded", className: C }) => {
|
|
120
|
+
let { id: w, name: T } = n, E = n.previewUrl ?? n.url, D = n.type === t.Pasted, O = D && m !== void 0, k = h !== void 0 && !O, A = O || k, j = ie(() => D ? T : le(T), [D, T]), M = i({
|
|
121
|
+
"--ci-card-border": b?.border,
|
|
122
|
+
"--ci-card-bg": b?.background,
|
|
123
|
+
"--ci-card-name": b?.nameText,
|
|
124
|
+
"--ci-card-meta": b?.metaText
|
|
125
|
+
}), { isLoading: N, isError: P, isImage: F, isAudio: I, areActionsVisible: te, BottomIcon: L, typeLabel: R, cardColorClass: B, removeBtnClass: V } = ie(() => ce(n, g ?? !1, _ ?? !1), [
|
|
126
|
+
n,
|
|
127
|
+
g,
|
|
128
|
+
_
|
|
129
|
+
]), { imageRef: H, imageLoadStatus: U } = ae({
|
|
130
|
+
enabled: F,
|
|
131
|
+
src: E
|
|
132
|
+
}), W = () => {
|
|
133
|
+
O && m ? m(w) : k && h && h(w);
|
|
134
|
+
}, G = (e) => {
|
|
135
|
+
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), W());
|
|
136
|
+
};
|
|
137
|
+
if (I) return /* @__PURE__ */ J("div", {
|
|
138
|
+
style: M,
|
|
139
|
+
className: a("group flex w-full min-w-[280px] max-w-[300px] flex-col gap-2 border p-3", S, B, C),
|
|
140
|
+
children: [/* @__PURE__ */ J("div", {
|
|
141
|
+
className: "flex items-center justify-between gap-2",
|
|
142
|
+
children: [/* @__PURE__ */ q("span", {
|
|
143
|
+
title: n.name,
|
|
144
|
+
className: a(x?.fontClassName ?? "dial-tiny-text", "min-w-0 truncate", X.name),
|
|
145
|
+
children: n.name
|
|
146
|
+
}), h && /* @__PURE__ */ q(s, {
|
|
147
|
+
icon: /* @__PURE__ */ q(p, {
|
|
148
|
+
size: o.SM,
|
|
149
|
+
"aria-hidden": !0
|
|
150
|
+
}),
|
|
151
|
+
size: d.Small,
|
|
152
|
+
className: a("h-6 w-6 shrink-0 rounded", V),
|
|
153
|
+
"aria-label": y,
|
|
154
|
+
onClick: (e) => {
|
|
155
|
+
e.stopPropagation(), h(w);
|
|
156
|
+
}
|
|
157
|
+
})]
|
|
158
|
+
}), n.playUrl && /* @__PURE__ */ q("audio", {
|
|
159
|
+
controls: !0,
|
|
160
|
+
src: n.playUrl,
|
|
161
|
+
className: "w-full",
|
|
162
|
+
preload: "metadata"
|
|
163
|
+
})]
|
|
164
|
+
});
|
|
165
|
+
let Z = a("group relative flex h-[100px] w-[100px] flex-shrink-0 border focus-within:outline focus-within:outline-1 focus-within:outline-offset-1", S, B, !F && "flex-col gap-3 p-3", A && "cursor-pointer", C), Q = /* @__PURE__ */ J(K, { children: [
|
|
166
|
+
F ? /* @__PURE__ */ J("div", {
|
|
167
|
+
className: "relative h-full w-full overflow-hidden",
|
|
168
|
+
children: [U !== Y.Loaded && /* @__PURE__ */ q(c, {
|
|
169
|
+
variant: l.Rectangular,
|
|
170
|
+
width: "100%",
|
|
171
|
+
height: "100%",
|
|
172
|
+
active: U === Y.Loading,
|
|
173
|
+
overlay: /* @__PURE__ */ q(z, {
|
|
174
|
+
size: o.LG,
|
|
175
|
+
className: x?.placeholderIconClassName ?? "text-secondary",
|
|
176
|
+
"aria-hidden": !0
|
|
177
|
+
}),
|
|
178
|
+
className: a("absolute inset-0", S)
|
|
179
|
+
}), /* @__PURE__ */ q("img", {
|
|
180
|
+
ref: H,
|
|
181
|
+
src: E,
|
|
182
|
+
alt: T,
|
|
183
|
+
loading: "lazy",
|
|
184
|
+
decoding: "async",
|
|
185
|
+
className: a("h-full w-full object-cover transition-opacity duration-200", U === Y.Loaded ? "opacity-100" : "opacity-0", S)
|
|
186
|
+
})]
|
|
187
|
+
}) : P ? /* @__PURE__ */ J(K, { children: [/* @__PURE__ */ J("div", {
|
|
188
|
+
className: "flex flex-row items-center gap-1 overflow-hidden",
|
|
189
|
+
children: [/* @__PURE__ */ q(L, {
|
|
190
|
+
size: o.SM,
|
|
191
|
+
className: a("shrink-0", X.meta),
|
|
192
|
+
"aria-hidden": !0
|
|
193
|
+
}), /* @__PURE__ */ q("span", {
|
|
194
|
+
title: R,
|
|
195
|
+
className: a(x?.metaClassName ?? "dial-tiny-text", "min-w-0 truncate", X.meta),
|
|
196
|
+
children: R
|
|
197
|
+
})]
|
|
198
|
+
}), /* @__PURE__ */ q("div", {
|
|
199
|
+
className: "min-w-0 flex-1",
|
|
200
|
+
children: /* @__PURE__ */ q("div", {
|
|
201
|
+
title: j,
|
|
202
|
+
className: a(x?.fontClassName ?? "dial-tiny-text", "line-clamp-3 break-words", X.name),
|
|
203
|
+
children: j
|
|
204
|
+
})
|
|
205
|
+
})] }) : /* @__PURE__ */ J(K, { children: [/* @__PURE__ */ q("div", {
|
|
206
|
+
className: "min-w-0 flex-1",
|
|
207
|
+
children: /* @__PURE__ */ q("div", {
|
|
208
|
+
title: j,
|
|
209
|
+
className: a(x?.fontClassName ?? "dial-tiny-text", "line-clamp-3 break-words", X.name),
|
|
210
|
+
children: j
|
|
211
|
+
})
|
|
212
|
+
}), /* @__PURE__ */ J("div", {
|
|
213
|
+
className: "flex flex-row items-center gap-1 overflow-hidden",
|
|
214
|
+
children: [/* @__PURE__ */ q(L, {
|
|
215
|
+
size: o.SM,
|
|
216
|
+
className: a("shrink-0", X.meta),
|
|
217
|
+
"aria-hidden": !0
|
|
218
|
+
}), /* @__PURE__ */ q("span", {
|
|
219
|
+
title: R,
|
|
220
|
+
className: a(x?.metaClassName ?? "dial-tiny-text", "min-w-0 truncate", X.meta),
|
|
221
|
+
children: R
|
|
222
|
+
})]
|
|
223
|
+
})] }),
|
|
224
|
+
N && /* @__PURE__ */ q("span", {
|
|
225
|
+
className: a("absolute inset-0 flex items-center justify-center", S, X.loadingOverlay),
|
|
226
|
+
children: /* @__PURE__ */ q(u, {
|
|
227
|
+
size: 40,
|
|
228
|
+
ariaLabel: "Loading attachment",
|
|
229
|
+
className: "z-50"
|
|
230
|
+
})
|
|
231
|
+
}),
|
|
232
|
+
!N && /* @__PURE__ */ J("div", {
|
|
233
|
+
className: a("absolute end-1 top-1 flex gap-1 transition-opacity", te ? "opacity-100" : "opacity-0 group-focus-within:opacity-100 group-hover:opacity-100 mobile:opacity-100"),
|
|
234
|
+
children: [P && f && n.errorReason !== e.UnsupportedType && /* @__PURE__ */ q(s, {
|
|
235
|
+
icon: /* @__PURE__ */ q(ne, {
|
|
236
|
+
size: o.SM,
|
|
237
|
+
"aria-hidden": !0
|
|
238
|
+
}),
|
|
239
|
+
size: d.Small,
|
|
240
|
+
className: a("h-6 w-6 rounded", V),
|
|
241
|
+
"aria-label": ee,
|
|
242
|
+
onClick: (e) => {
|
|
243
|
+
e.stopPropagation(), f(w);
|
|
244
|
+
}
|
|
245
|
+
}), r && /* @__PURE__ */ q(s, {
|
|
246
|
+
icon: /* @__PURE__ */ q(re, {
|
|
247
|
+
size: o.SM,
|
|
248
|
+
"aria-hidden": !0
|
|
249
|
+
}),
|
|
250
|
+
size: d.Small,
|
|
251
|
+
className: a("h-6 w-6 rounded", V),
|
|
252
|
+
"aria-label": v,
|
|
253
|
+
onClick: (e) => {
|
|
254
|
+
e.stopPropagation(), r?.(w);
|
|
255
|
+
}
|
|
256
|
+
})]
|
|
257
|
+
})
|
|
258
|
+
] });
|
|
259
|
+
return A ? /* @__PURE__ */ q("div", {
|
|
260
|
+
style: M,
|
|
261
|
+
className: Z,
|
|
262
|
+
onClick: W,
|
|
263
|
+
onKeyDown: G,
|
|
264
|
+
tabIndex: 0,
|
|
265
|
+
role: "button",
|
|
266
|
+
"aria-label": k ? y : void 0,
|
|
267
|
+
children: Q
|
|
268
|
+
}) : /* @__PURE__ */ q("div", {
|
|
269
|
+
style: M,
|
|
270
|
+
className: Z,
|
|
271
|
+
children: Q
|
|
272
|
+
});
|
|
273
|
+
}, de = ({ attachments: e, onRemove: t, onRetry: n, onExpand: r, ariaLabel: i = "Attached files", removeLabel: o, retryLabel: s, onAttachmentClick: c, clickLabel: l, className: u }) => e.length === 0 ? null : /* @__PURE__ */ q("div", {
|
|
274
|
+
role: "list",
|
|
275
|
+
"aria-label": i,
|
|
276
|
+
className: a("flex w-full min-w-0 gap-2 overflow-x-auto", u),
|
|
277
|
+
children: e.map((e) => /* @__PURE__ */ q("div", {
|
|
278
|
+
role: "listitem",
|
|
279
|
+
children: /* @__PURE__ */ q(ue, {
|
|
280
|
+
attachment: e,
|
|
281
|
+
onRemove: t,
|
|
282
|
+
onRetry: n,
|
|
283
|
+
onExpand: r,
|
|
284
|
+
removeLabel: o,
|
|
285
|
+
retryLabel: s,
|
|
286
|
+
onClick: c ? () => c(e) : void 0,
|
|
287
|
+
clickLabel: l
|
|
288
|
+
})
|
|
289
|
+
}, e.id))
|
|
290
|
+
}), fe = ({ isVisible: e, isAttachmentsAllowed: t = !0, title: n, subtitle: r, iconClassName: i = "text-accent-primary", deniedIconClassName: o = "text-error", titleClassName: s = "heading-3 font-semibold", subtitleClassName: c = "dial-small-text" }) => {
|
|
291
|
+
if (!e) return null;
|
|
292
|
+
let l = n ?? (t ? "Attach files" : "No attachments allowed"), u = r ?? (t ? "Drop files here to attach them to message" : "Attachments can't be added to message"), d = t ? i : o, f = (e) => {
|
|
293
|
+
e.preventDefault();
|
|
294
|
+
}, p = t ? h : L;
|
|
295
|
+
return /* @__PURE__ */ q("div", {
|
|
296
|
+
className: a("fixed inset-0 z-[9999] flex items-center justify-center bg-blackout backdrop-blur-sm", t ? "pointer-events-none" : "pointer-events-auto cursor-not-allowed"),
|
|
297
|
+
onDragOver: t ? void 0 : f,
|
|
298
|
+
onDrop: t ? void 0 : f,
|
|
299
|
+
children: /* @__PURE__ */ J("div", {
|
|
300
|
+
className: "flex flex-col items-center text-center",
|
|
301
|
+
children: [
|
|
302
|
+
/* @__PURE__ */ q(p, {
|
|
303
|
+
size: 100,
|
|
304
|
+
className: d
|
|
305
|
+
}),
|
|
306
|
+
/* @__PURE__ */ q("span", {
|
|
307
|
+
className: a("mt-5", s),
|
|
308
|
+
children: l
|
|
309
|
+
}),
|
|
310
|
+
/* @__PURE__ */ q("span", {
|
|
311
|
+
className: a("mt-4", c),
|
|
312
|
+
children: u
|
|
313
|
+
})
|
|
314
|
+
]
|
|
315
|
+
})
|
|
316
|
+
});
|
|
317
|
+
}, $ = () => `${Date.now()}-${Math.random().toString(36).slice(2)}`, pe = (e, n) => ({ handlePaste: H((i) => {
|
|
318
|
+
if (!i.clipboardData) return;
|
|
319
|
+
let a = Array.from(i.clipboardData.items).filter((e) => e.kind === "file" && e.type.startsWith("image/")), o = i.clipboardData.getData("text/plain").length > 0;
|
|
320
|
+
if (a.length > 0 && !o) {
|
|
321
|
+
let n = [];
|
|
322
|
+
for (let e of a) {
|
|
323
|
+
let i = e.getAsFile();
|
|
324
|
+
if (!i) continue;
|
|
325
|
+
let a = new File([i], "Screenshot.png", { type: i.type }), o = {
|
|
326
|
+
id: $(),
|
|
327
|
+
name: "Screenshot.png",
|
|
328
|
+
contentType: i.type,
|
|
329
|
+
file: a,
|
|
330
|
+
type: t.Image,
|
|
331
|
+
status: r.Idle,
|
|
332
|
+
previewUrl: URL.createObjectURL(a)
|
|
333
|
+
};
|
|
334
|
+
n.push(o);
|
|
335
|
+
}
|
|
336
|
+
i.preventDefault(), e(n);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
let s = i.clipboardData.getData("text/plain");
|
|
340
|
+
if (s.length > n) {
|
|
341
|
+
let n = s.trim(), a = (n.length > 80 ? `${n.slice(0, 80).trimEnd()}…` : n) || "Pasted text", o = new File([s], a, { type: "text/plain" }), c = {
|
|
342
|
+
id: $(),
|
|
343
|
+
name: a,
|
|
344
|
+
contentType: "text/plain",
|
|
345
|
+
file: o,
|
|
346
|
+
type: t.Pasted,
|
|
347
|
+
status: r.Idle
|
|
348
|
+
};
|
|
349
|
+
i.preventDefault(), e([c]);
|
|
350
|
+
}
|
|
351
|
+
}, [e, n]) }), me = {
|
|
352
|
+
image: "Image files",
|
|
353
|
+
audio: "Audio files",
|
|
354
|
+
video: "Video files",
|
|
355
|
+
text: "Text files"
|
|
356
|
+
}, he = (e) => e.map((e) => {
|
|
357
|
+
if (e.endsWith("/*")) {
|
|
358
|
+
let t = e.slice(0, -2);
|
|
359
|
+
return me[t] ?? `${t} files`;
|
|
360
|
+
}
|
|
361
|
+
let t = e.split("/")[1];
|
|
362
|
+
return t == null ? e.toUpperCase() : t.toUpperCase();
|
|
363
|
+
}).join(", "), ge = (e, t) => t.length === 0 ? !1 : t.some((t) => {
|
|
364
|
+
if (t === "*" || t === "*/*") return !0;
|
|
365
|
+
if (t.endsWith("/*")) {
|
|
366
|
+
let n = t.slice(0, -2);
|
|
367
|
+
return e.startsWith(`${n}/`);
|
|
368
|
+
}
|
|
369
|
+
return e === t;
|
|
370
|
+
}), _e = 100;
|
|
371
|
+
//#endregion
|
|
372
|
+
export { ue as AttachmentCard, de as AttachmentTray, fe as FileDndOverlay, Y as LazyImageLoadStatus, _e as MAX_UPLOADS_PER_MINUTE, $ as generateAttachmentId, ce as getAttachmentCardState, Z as getAttachmentIcon, le as getNameWithoutExtension, ge as isMimeTypeAllowed, he as mimeTypesToExtensionLabels, pe as useClipboardPaste, ae as useLazyImageLoad };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { DisplayAttachment } from '@epam/ai-dial-chat-shared';
|
|
2
|
+
/** CSS custom-property overrides for the `AttachmentCard` component. */
|
|
3
|
+
export interface AttachmentCardColors {
|
|
4
|
+
/** Card border color in the default state. */
|
|
5
|
+
border?: string;
|
|
6
|
+
/** Card background color in the default state. */
|
|
7
|
+
background?: string;
|
|
8
|
+
/** File name text color. */
|
|
9
|
+
nameText?: string;
|
|
10
|
+
/** Meta (type / label) text color. */
|
|
11
|
+
metaText?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Typography overrides for the `AttachmentCard` component. */
|
|
14
|
+
export interface AttachmentCardTypography {
|
|
15
|
+
/** Utility class applied to the file name text. Defaults to `'dial-tiny-text'`. */
|
|
16
|
+
fontClassName?: string;
|
|
17
|
+
/** Utility class applied to the bottom meta label (file type / status). Defaults to `'dial-tiny-text'`. */
|
|
18
|
+
metaClassName?: string;
|
|
19
|
+
/** Utility class applied to the placeholder icon shown while the image is loading. Defaults to `'text-secondary'`. */
|
|
20
|
+
placeholderIconClassName?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Props accepted by the `AttachmentCard` component. */
|
|
23
|
+
export interface AttachmentCardProps {
|
|
24
|
+
/** The attachment data to display. */
|
|
25
|
+
attachment: DisplayAttachment;
|
|
26
|
+
/** Called when the user activates the remove button. */
|
|
27
|
+
onRemove?: (id: string) => void;
|
|
28
|
+
/** Called when the user activates the retry button (error state only). */
|
|
29
|
+
onRetry?: (id: string) => void;
|
|
30
|
+
/** Called when the user clicks or activates a pasted-text card to expand its content back into the input. */
|
|
31
|
+
onExpand?: (id: string) => void;
|
|
32
|
+
/** Renders the card in selected state (accent border + tinted background). */
|
|
33
|
+
isSelected?: boolean;
|
|
34
|
+
/** Forces action buttons to be always visible regardless of hover/focus state. */
|
|
35
|
+
shouldAlwaysShowActions?: boolean;
|
|
36
|
+
/** Accessible label for the remove button. */
|
|
37
|
+
removeLabel?: string;
|
|
38
|
+
/** Accessible label for the retry button (error state only). */
|
|
39
|
+
retryLabel?: string;
|
|
40
|
+
/** Called when the user clicks or keyboard-activates the card. Receives the attachment `id`. */
|
|
41
|
+
onClick?: (id: string) => void;
|
|
42
|
+
/** Accessible label applied to the card root when it is interactive via `onClick`. Defaults to `'Open attachment'`. */
|
|
43
|
+
clickLabel?: string;
|
|
44
|
+
/** Color overrides applied as CSS custom properties. */
|
|
45
|
+
colors?: AttachmentCardColors;
|
|
46
|
+
/** Typography overrides for text elements inside the card. */
|
|
47
|
+
typography?: AttachmentCardTypography;
|
|
48
|
+
/** Tailwind border-radius utility class applied to the card and its inner layers (e.g. `'rounded'`, `'rounded-lg'`). */
|
|
49
|
+
roundedClassName?: string;
|
|
50
|
+
/** Extra class name(s) merged onto the root element. */
|
|
51
|
+
className?: string;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=AttachmentCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AttachmentCard.d.ts","sourceRoot":"","sources":["../../src/models/AttachmentCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACnC,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,+DAA+D;AAC/D,MAAM,WAAW,wBAAwB;IACvC,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2GAA2G;IAC3G,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sHAAsH;IACtH,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,wDAAwD;IACxD,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,uHAAuH;IACvH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,wHAAwH;IACxH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DisplayAttachment } from '@epam/ai-dial-chat-shared';
|
|
2
|
+
/** Props accepted by the `AttachmentTray` component. */
|
|
3
|
+
export interface AttachmentTrayProps {
|
|
4
|
+
/** The list of attachments to display. */
|
|
5
|
+
attachments: DisplayAttachment[];
|
|
6
|
+
/** Called when the user removes an attachment card. */
|
|
7
|
+
onRemove?: (id: string) => void;
|
|
8
|
+
/** Called when the user retries a failed attachment upload. */
|
|
9
|
+
onRetry?: (id: string) => void;
|
|
10
|
+
/** Called when the user clicks a pasted-text card to expand its content back into the input. */
|
|
11
|
+
onExpand?: (id: string) => void;
|
|
12
|
+
/** Accessible label for the tray region. */
|
|
13
|
+
ariaLabel?: string;
|
|
14
|
+
/** Accessible label for each card's remove button. */
|
|
15
|
+
removeLabel?: string;
|
|
16
|
+
/** Accessible label for each card's retry button (error state only). */
|
|
17
|
+
retryLabel?: string;
|
|
18
|
+
/** Called when the user clicks or keyboard-activates an attachment card. Receives the full `DisplayAttachment` object. */
|
|
19
|
+
onAttachmentClick?: (attachment: DisplayAttachment) => void;
|
|
20
|
+
/** Accessible label forwarded to each card's root when it is interactive. When omitted, the card's own default (`'Open attachment'`) applies. */
|
|
21
|
+
clickLabel?: string;
|
|
22
|
+
/** Extra class name(s) merged onto the root element. */
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=AttachmentTray.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AttachmentTray.d.ts","sourceRoot":"","sources":["../../src/models/AttachmentTray.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,gGAAgG;IAChG,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0HAA0H;IAC1H,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5D,iJAAiJ;IACjJ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Props accepted by the `FileDndOverlay` component. */
|
|
2
|
+
export interface FileDndOverlayProps {
|
|
3
|
+
/** When `true`, the full-screen overlay is rendered. */
|
|
4
|
+
isVisible: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* When `false`, the overlay renders a denied state: `IconFileX` in error color,
|
|
7
|
+
* `cursor-not-allowed`, and drops are suppressed (not forwarded to the document).
|
|
8
|
+
* Defaults to `true`.
|
|
9
|
+
*/
|
|
10
|
+
isAttachmentsAllowed?: boolean;
|
|
11
|
+
/** Title text rendered below the icon. Defaults differ by state: `'Attach files'` when allowed, `'No attachments allowed'` when denied. */
|
|
12
|
+
title?: string;
|
|
13
|
+
/** Subtitle text rendered below the title. Defaults differ by state: `'Drop files here to attach them to message'` when allowed, `"Attachments can't be added to message"` when denied. */
|
|
14
|
+
subtitle?: string;
|
|
15
|
+
/** Tailwind class(es) applied to the icon in the allowed state. Defaults to `'text-accent-primary'`. */
|
|
16
|
+
iconClassName?: string;
|
|
17
|
+
/** Tailwind class(es) applied to the icon in the denied state (`isAttachmentsAllowed={false}`). Defaults to `'text-error'`. */
|
|
18
|
+
deniedIconClassName?: string;
|
|
19
|
+
/** Tailwind class(es) applied to the title. Defaults to `'heading-3'`. */
|
|
20
|
+
titleClassName?: string;
|
|
21
|
+
/** Tailwind class(es) applied to the subtitle. Defaults to `'dial-small-text'`. */
|
|
22
|
+
subtitleClassName?: string;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=FileDndOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileDndOverlay.d.ts","sourceRoot":"","sources":["../../src/models/FileDndOverlay.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,2IAA2I;IAC3I,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2LAA2L;IAC3L,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wGAAwG;IACxG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+HAA+H;IAC/H,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@epam/ai-dial-attachment-input",
|
|
3
|
+
"version": "0.0.0-dev.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"module": "./index.js",
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
"./package.json": "./package.json",
|
|
11
|
+
"./styles.css": "./style.css",
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"import": "./index.js",
|
|
15
|
+
"default": "./index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@epam/ai-dial-chat-shared": "0.0.0-dev.0",
|
|
20
|
+
"@epam/ai-dial-ui-kit": "0.12.0-dev.21",
|
|
21
|
+
"@tabler/icons-react": "^3.44.0",
|
|
22
|
+
"react": "^19.0.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/test-setup.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":"AAaA,cAAM,wBAAwB;IAC5B,OAAO;IACP,SAAS;IACT,UAAU;CACX"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an array of MIME type strings (including wildcards) into a
|
|
3
|
+
* comma-separated human-readable label string.
|
|
4
|
+
*
|
|
5
|
+
* Examples:
|
|
6
|
+
* `['application/pdf', 'image/jpeg']` → `'PDF, JPEG'`
|
|
7
|
+
* `['image/*', 'text/csv']` → `'Image files, CSV'`
|
|
8
|
+
*/
|
|
9
|
+
export declare const mimeTypesToExtensionLabels: (types: string[]) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Returns `true` when `mimeType` matches at least one entry in `allowedTypes`.
|
|
12
|
+
*
|
|
13
|
+
* Matching rules:
|
|
14
|
+
* - Exact match: `'application/pdf'` allows `'application/pdf'`.
|
|
15
|
+
* - Wildcard prefix: `'image/*'` allows any `'image/...'` MIME type.
|
|
16
|
+
*
|
|
17
|
+
* Returns `false` when `allowedTypes` is empty (no attachment types allowed).
|
|
18
|
+
*/
|
|
19
|
+
export declare const isMimeTypeAllowed: (mimeType: string, allowedTypes: string[]) => boolean;
|
|
20
|
+
//# sourceMappingURL=attachment-mime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-mime.d.ts","sourceRoot":"","sources":["../../src/utils/attachment-mime.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,MAAM,EAAE,KAAG,MAU5D,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,MAAM,EAChB,cAAc,MAAM,EAAE,KACrB,OAUF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateAttachmentId.d.ts","sourceRoot":"","sources":["../../src/utils/generateAttachmentId.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,QAAO,MACgB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DisplayAttachment } from '@epam/ai-dial-chat-shared';
|
|
2
|
+
import { Icon } from '@tabler/icons-react';
|
|
3
|
+
export interface AttachmentCardState {
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
isError: boolean;
|
|
6
|
+
isImage: boolean;
|
|
7
|
+
isAudio: boolean;
|
|
8
|
+
areActionsVisible: boolean;
|
|
9
|
+
BottomIcon: Icon;
|
|
10
|
+
typeLabel: string;
|
|
11
|
+
cardColorClass: string;
|
|
12
|
+
removeBtnClass: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const getAttachmentCardState: (attachment: DisplayAttachment, isSelected: boolean, shouldAlwaysShowActions: boolean) => AttachmentCardState;
|
|
15
|
+
//# sourceMappingURL=getAttachmentCardState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAttachmentCardState.d.ts","sourceRoot":"","sources":["../../src/utils/getAttachmentCardState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAOnE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAKhD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AA2CD,eAAO,MAAM,sBAAsB,GACjC,YAAY,iBAAiB,EAC7B,YAAY,OAAO,EACnB,yBAAyB,OAAO,KAC/B,mBAkCF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Icon } from '@tabler/icons-react';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the appropriate Tabler icon component for a given MIME content type.
|
|
4
|
+
* Broad category checks (`startsWith`) run first; then a specific MIME switch
|
|
5
|
+
* covers as many known file types as possible. Falls back to `IconFile`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const getAttachmentIcon: (contentType: string) => Icon;
|
|
8
|
+
//# sourceMappingURL=getAttachmentIcon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAttachmentIcon.d.ts","sourceRoot":"","sources":["../../src/utils/getAttachmentIcon.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,IA0FvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getNameWithoutExtension.d.ts","sourceRoot":"","sources":["../../src/utils/getNameWithoutExtension.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,KAAG,MAGtD,CAAC"}
|