@arbidocs/react 0.5.120 → 0.5.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PdfViewerImpl-ZVJZ4KNW.cjs +22 -0
- package/dist/PdfViewerImpl-ZVJZ4KNW.cjs.map +1 -0
- package/dist/{PdfViewerImpl.d-B28hLEuj.d.ts → PdfViewerImpl.d-CqnEzQO7.d.ts} +9 -1
- package/dist/ai/MessageArtifactCard.js +9 -1
- package/dist/ai/MessageArtifactCard.js.map +2 -2
- package/dist/annotations/freeze/index.d.ts +1 -1
- package/dist/artifacts/artifact-kind.js +1 -0
- package/dist/artifacts/artifact-kind.js.map +2 -2
- package/dist/artifacts/index.cjs +3 -2
- package/dist/artifacts/index.cjs.map +1 -1
- package/dist/artifacts/index.d.ts +3 -2
- package/dist/calls/livekit/index.cjs +51 -51
- package/dist/chat/chat-artifacts.js +0 -1
- package/dist/chat/chat-artifacts.js.map +2 -2
- package/dist/chat/open-document.js +3 -1
- package/dist/chat/open-document.js.map +2 -2
- package/dist/chat/turn-flush.js +16 -0
- package/dist/chat/turn-flush.js.map +7 -0
- package/dist/chat/useConversationActions.js +3 -0
- package/dist/chat/useConversationActions.js.map +2 -2
- package/dist/{chunk-QP3WQSAA.cjs → chunk-4B2GW3AY.cjs} +3 -3
- package/dist/{chunk-QP3WQSAA.cjs.map → chunk-4B2GW3AY.cjs.map} +1 -1
- package/dist/{chunk-YMB6XUR2.cjs → chunk-7L7QRIQ2.cjs} +11 -7
- package/dist/chunk-7L7QRIQ2.cjs.map +1 -0
- package/dist/{chunk-KDYYAZXP.cjs → chunk-DLEHM4IA.cjs} +227 -155
- package/dist/chunk-DLEHM4IA.cjs.map +1 -0
- package/dist/{chunk-5TRUFWKT.cjs → chunk-FAJLJDWS.cjs} +12 -12
- package/dist/{chunk-5TRUFWKT.cjs.map → chunk-FAJLJDWS.cjs.map} +1 -1
- package/dist/{PdfViewerImpl-QUSDLNNM.cjs → chunk-ICBT2XGF.cjs} +5 -2
- package/dist/chunk-ICBT2XGF.cjs.map +1 -0
- package/dist/{chunk-RLSBRZ6Z.cjs → chunk-IX4HOS5Z.cjs} +2 -3
- package/dist/chunk-IX4HOS5Z.cjs.map +1 -0
- package/dist/{chunk-AJRYZ3IC.cjs → chunk-K6ELFSG6.cjs} +3 -3
- package/dist/{chunk-AJRYZ3IC.cjs.map → chunk-K6ELFSG6.cjs.map} +1 -1
- package/dist/chunk-MAOGK7IC.cjs +61 -0
- package/dist/chunk-MAOGK7IC.cjs.map +1 -0
- package/dist/{chunk-C72FSQUE.cjs → chunk-WUYSVTKE.cjs} +14 -12
- package/dist/chunk-WUYSVTKE.cjs.map +1 -0
- package/dist/datasets/sources/documents.js +1 -1
- package/dist/datasets/sources/documents.js.map +2 -2
- package/dist/document-tools/core.cjs +80 -80
- package/dist/document-tools/images-to-pdf.js +43 -0
- package/dist/document-tools/images-to-pdf.js.map +7 -0
- package/dist/document-tools/index.cjs +184 -80
- package/dist/document-tools/index.cjs.map +1 -1
- package/dist/document-tools/index.d.ts +41 -1
- package/dist/document-tools/index.js +6 -1
- package/dist/document-tools/index.js.map +2 -2
- package/dist/document-tools/pdf-attachments.js +63 -0
- package/dist/document-tools/pdf-attachments.js.map +7 -0
- package/dist/entities/DocumentEntity.js +7 -2
- package/dist/entities/DocumentEntity.js.map +2 -2
- package/dist/entities/file-type.js +14 -2
- package/dist/entities/file-type.js.map +2 -2
- package/dist/entities/index.js +9 -1
- package/dist/entities/index.js.map +2 -2
- package/dist/icons/PresIcon.js +53 -0
- package/dist/icons/PresIcon.js.map +7 -0
- package/dist/icons/colors.js +2 -0
- package/dist/icons/colors.js.map +2 -2
- package/dist/icons/file-type.js +3 -0
- package/dist/icons/file-type.js.map +2 -2
- package/dist/icons/index.js +2 -0
- package/dist/icons/index.js.map +2 -2
- package/dist/index.cjs +964 -919
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-DYlUprG9.d.ts → index.d-D2puqWeN.d.ts} +17 -3
- package/dist/{index.d-oR5FKZpJ.d.ts → index.d-KbsNPTEN.d.ts} +7 -5
- package/dist/index.d.ts +46 -12
- package/dist/index.js +1 -0
- package/dist/index.js.map +2 -2
- package/dist/pdf-region-impl-ZG5G2OX2.cjs +98 -0
- package/dist/pdf-region-impl-ZG5G2OX2.cjs.map +1 -0
- package/dist/session/documents.js +9 -5
- package/dist/session/documents.js.map +2 -2
- package/dist/shell/index.cjs +54 -50
- package/dist/shell/index.d.ts +1 -1
- package/dist/ui/index.cjs +182 -170
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/slider.js +7 -1
- package/dist/ui/slider.js.map +2 -2
- package/dist/viewers/PdfViewer.cjs +3 -3
- package/dist/viewers/PdfViewer.d.ts +2 -2
- package/dist/viewers/PdfViewerImpl.js +4 -1
- package/dist/viewers/PdfViewerImpl.js.map +2 -2
- package/dist/viewers/index.cjs +28 -3
- package/dist/viewers/index.cjs.map +1 -1
- package/dist/viewers/index.d.ts +68 -2
- package/dist/viewers/index.js +14 -0
- package/dist/viewers/index.js.map +2 -2
- package/dist/viewers/pdf-region-impl.js +96 -0
- package/dist/viewers/pdf-region-impl.js.map +7 -0
- package/dist/viewers/pdf-region.js +57 -0
- package/dist/viewers/pdf-region.js.map +7 -0
- package/package.json +3 -3
- package/dist/PdfViewerImpl-QUSDLNNM.cjs.map +0 -1
- package/dist/chunk-C72FSQUE.cjs.map +0 -1
- package/dist/chunk-KDYYAZXP.cjs.map +0 -1
- package/dist/chunk-RLSBRZ6Z.cjs.map +0 -1
- package/dist/chunk-YMB6XUR2.cjs.map +0 -1
|
@@ -87,4 +87,44 @@ interface BuiltProduction {
|
|
|
87
87
|
*/
|
|
88
88
|
declare function buildProduction(client: DocumentToolsClient, documents: readonly ProductionSource[], choices: ProductionChoices, options: BuildProductionOptions): Promise<BuiltProduction>;
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Files attached to a PDF (the standard /EmbeddedFiles name tree, what a PDF reader lists under
|
|
92
|
+
* "Attachments"): read one by name, or put one in (replacing any of that name). Plain functions
|
|
93
|
+
* over bytes, for the browser and Node alike: a saved presentation is a PDF of its slides with its
|
|
94
|
+
* editable data attached (`arbi-presentation.json`), and anything that can read and write a PDF's
|
|
95
|
+
* attachments (these, pypdf / PyMuPDF on a server) can read and edit it. pdf-lib is loaded on use.
|
|
96
|
+
*/
|
|
97
|
+
interface PdfAttachment {
|
|
98
|
+
name: string;
|
|
99
|
+
data: Uint8Array;
|
|
100
|
+
mimeType: string;
|
|
101
|
+
description?: string;
|
|
102
|
+
}
|
|
103
|
+
type Bytes = Uint8Array | ArrayBuffer;
|
|
104
|
+
/** The attachment called `name`, or null when the PDF has none of that name. */
|
|
105
|
+
declare function readPdfAttachment(pdf: Bytes, name: string): Promise<Uint8Array | null>;
|
|
106
|
+
/** The PDF with `attachment` in it, replacing any attachment of the same name. */
|
|
107
|
+
declare function setPdfAttachment(pdf: Bytes, attachment: PdfAttachment): Promise<Uint8Array>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Page images to a PDF: one page per image, the image filling it, and the page's text laid on it
|
|
111
|
+
* invisibly so the PDF is searchable (a presentation's slides: what shows is exactly the image,
|
|
112
|
+
* redactions burnt in, while their titles and labels can still be found). pdf-lib is loaded on
|
|
113
|
+
* first use. Files can be attached to it (`meta.attachments`; see `pdf-attachments`).
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
interface PdfImagePage {
|
|
117
|
+
/** A JPEG or PNG. */
|
|
118
|
+
image: Blob;
|
|
119
|
+
/** The page size, in PDF points. */
|
|
120
|
+
width: number;
|
|
121
|
+
height: number;
|
|
122
|
+
/** Text on the page, laid on it invisibly for search. */
|
|
123
|
+
text?: readonly string[];
|
|
124
|
+
}
|
|
125
|
+
declare function imagesToPdf(pages: readonly PdfImagePage[], meta?: {
|
|
126
|
+
title?: string;
|
|
127
|
+
attachments?: readonly PdfAttachment[];
|
|
128
|
+
}): Promise<Blob>;
|
|
129
|
+
|
|
130
|
+
export { type BuildProductionOptions, type BuiltProduction, DocumentToolsClient, DocumentToolsEnvironment, PRODUCTIONS_FOLDER, type PdfAttachment, type PdfImagePage, type ProductionSource, type ProductionUpload, buildProduction, fetchProductionPdf, hasNoRendition, imagesToPdf, isPdfDocument, productionDocumentName, productionFileName, productionFolder, productionIndexCsv, productionTitle, readPdfAttachment, saveProductionFiles, setPdfAttachment };
|
|
@@ -12,17 +12,22 @@ import {
|
|
|
12
12
|
productionTitle,
|
|
13
13
|
saveProductionFiles
|
|
14
14
|
} from "./production.js";
|
|
15
|
+
import { imagesToPdf } from "./images-to-pdf.js";
|
|
16
|
+
import { readPdfAttachment, setPdfAttachment } from "./pdf-attachments.js";
|
|
15
17
|
export {
|
|
16
18
|
PRODUCTIONS_FOLDER,
|
|
17
19
|
buildProduction,
|
|
18
20
|
fetchProductionPdf,
|
|
19
21
|
hasNoRendition,
|
|
22
|
+
imagesToPdf,
|
|
20
23
|
isPdfDocument,
|
|
21
24
|
productionDocumentName,
|
|
22
25
|
productionFileName,
|
|
23
26
|
productionFolder,
|
|
24
27
|
productionIndexCsv,
|
|
25
28
|
productionTitle,
|
|
26
|
-
|
|
29
|
+
readPdfAttachment,
|
|
30
|
+
saveProductionFiles,
|
|
31
|
+
setPdfAttachment
|
|
27
32
|
};
|
|
28
33
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/document-tools/index.ts"],
|
|
4
|
-
"sourcesContent": ["/** Existing document-tools surface. PDF production is optional; lightweight consumers use /core. */\nexport * from './core'\nexport {\n PRODUCTIONS_FOLDER,\n buildProduction,\n fetchProductionPdf,\n hasNoRendition,\n isPdfDocument,\n productionDocumentName,\n productionFileName,\n productionFolder,\n productionIndexCsv,\n productionTitle,\n saveProductionFiles,\n type BuildProductionOptions,\n type BuiltProduction,\n type ProductionSource,\n type ProductionUpload,\n} from './production'\n"],
|
|
5
|
-
"mappings": "AACA,cAAc;AACd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;",
|
|
4
|
+
"sourcesContent": ["/** Existing document-tools surface. PDF production is optional; lightweight consumers use /core. */\nexport * from './core'\nexport {\n PRODUCTIONS_FOLDER,\n buildProduction,\n fetchProductionPdf,\n hasNoRendition,\n isPdfDocument,\n productionDocumentName,\n productionFileName,\n productionFolder,\n productionIndexCsv,\n productionTitle,\n saveProductionFiles,\n type BuildProductionOptions,\n type BuiltProduction,\n type ProductionSource,\n type ProductionUpload,\n} from './production'\nexport { imagesToPdf, type PdfImagePage } from './images-to-pdf'\nexport { readPdfAttachment, setPdfAttachment, type PdfAttachment } from './pdf-attachments'\n"],
|
|
5
|
+
"mappings": "AACA,cAAc;AACd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP,SAAS,mBAAsC;AAC/C,SAAS,mBAAmB,wBAA4C;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const asBytes = (bytes) => bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
2
|
+
async function readPdfAttachment(pdf, name) {
|
|
3
|
+
const lib = await import("pdf-lib");
|
|
4
|
+
const { PDFDocument, PDFName, PDFDict, PDFArray, PDFString, PDFHexString, decodePDFRawStream } = lib;
|
|
5
|
+
const doc = await PDFDocument.load(asBytes(pdf), { updateMetadata: false });
|
|
6
|
+
const names = doc.catalog.lookupMaybe(PDFName.of("Names"), PDFDict);
|
|
7
|
+
const root = names?.lookupMaybe(PDFName.of("EmbeddedFiles"), PDFDict);
|
|
8
|
+
if (!root) return null;
|
|
9
|
+
const find = (node) => {
|
|
10
|
+
const pairs = node.lookupMaybe(PDFName.of("Names"), PDFArray);
|
|
11
|
+
if (pairs) {
|
|
12
|
+
for (let i = 0; i + 1 < pairs.size(); i += 2) {
|
|
13
|
+
const key = pairs.lookup(i);
|
|
14
|
+
const text = key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : void 0;
|
|
15
|
+
if (text !== name) continue;
|
|
16
|
+
const spec = pairs.lookup(i + 1, PDFDict);
|
|
17
|
+
const files = spec.lookupMaybe(PDFName.of("EF"), PDFDict);
|
|
18
|
+
const stream = files?.lookup(PDFName.of("F"));
|
|
19
|
+
if (!stream || !(stream instanceof lib.PDFRawStream)) return null;
|
|
20
|
+
return decodePDFRawStream(stream).decode();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const kids = node.lookupMaybe(PDFName.of("Kids"), PDFArray);
|
|
24
|
+
for (let i = 0; kids && i < kids.size(); i++) {
|
|
25
|
+
const found = find(kids.lookup(i, PDFDict));
|
|
26
|
+
if (found) return found;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
return find(root);
|
|
31
|
+
}
|
|
32
|
+
function removeEntries(lib, doc, name) {
|
|
33
|
+
const { PDFName, PDFDict, PDFArray, PDFString, PDFHexString } = lib;
|
|
34
|
+
const root = doc.catalog.lookupMaybe(PDFName.of("Names"), PDFDict)?.lookupMaybe(PDFName.of("EmbeddedFiles"), PDFDict);
|
|
35
|
+
const pairs = root?.lookupMaybe(PDFName.of("Names"), PDFArray);
|
|
36
|
+
if (!pairs) return;
|
|
37
|
+
for (let i = pairs.size() - 2; i >= 0; i -= 2) {
|
|
38
|
+
const key = pairs.lookup(i);
|
|
39
|
+
const text = key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : void 0;
|
|
40
|
+
if (text === name) {
|
|
41
|
+
pairs.remove(i + 1);
|
|
42
|
+
pairs.remove(i);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function setPdfAttachment(pdf, attachment) {
|
|
47
|
+
const lib = await import("pdf-lib");
|
|
48
|
+
const doc = await lib.PDFDocument.load(asBytes(pdf), { updateMetadata: false });
|
|
49
|
+
removeEntries(lib, doc, attachment.name);
|
|
50
|
+
const now = /* @__PURE__ */ new Date();
|
|
51
|
+
await doc.attach(new Uint8Array(attachment.data), attachment.name, {
|
|
52
|
+
mimeType: attachment.mimeType,
|
|
53
|
+
description: attachment.description,
|
|
54
|
+
creationDate: now,
|
|
55
|
+
modificationDate: now
|
|
56
|
+
});
|
|
57
|
+
return doc.save();
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
readPdfAttachment,
|
|
61
|
+
setPdfAttachment
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=pdf-attachments.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/document-tools/pdf-attachments.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Files attached to a PDF (the standard /EmbeddedFiles name tree, what a PDF reader lists under\n * \"Attachments\"): read one by name, or put one in (replacing any of that name). Plain functions\n * over bytes, for the browser and Node alike: a saved presentation is a PDF of its slides with its\n * editable data attached (`arbi-presentation.json`), and anything that can read and write a PDF's\n * attachments (these, pypdf / PyMuPDF on a server) can read and edit it. pdf-lib is loaded on use.\n */\n\nimport type { PDFDict as PDFDictType, PDFDocument as PDFDocumentType } from 'pdf-lib'\n\nexport interface PdfAttachment {\n name: string\n data: Uint8Array\n mimeType: string\n description?: string\n}\n\ntype Bytes = Uint8Array | ArrayBuffer\nconst asBytes = (bytes: Bytes) => (bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes))\n\n/** The attachment called `name`, or null when the PDF has none of that name. */\nexport async function readPdfAttachment(pdf: Bytes, name: string): Promise<Uint8Array | null> {\n const lib = await import('pdf-lib')\n const { PDFDocument, PDFName, PDFDict, PDFArray, PDFString, PDFHexString, decodePDFRawStream } =\n lib\n const doc = await PDFDocument.load(asBytes(pdf), { updateMetadata: false })\n const names = doc.catalog.lookupMaybe(PDFName.of('Names'), PDFDict)\n const root = names?.lookupMaybe(PDFName.of('EmbeddedFiles'), PDFDict)\n if (!root) return null\n\n // A name tree: pairs [name, file spec] in /Names, or nested nodes under /Kids.\n const find = (node: PDFDictType): Uint8Array | null => {\n const pairs = node.lookupMaybe(PDFName.of('Names'), PDFArray)\n if (pairs) {\n for (let i = 0; i + 1 < pairs.size(); i += 2) {\n const key = pairs.lookup(i)\n const text =\n key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : undefined\n if (text !== name) continue\n const spec = pairs.lookup(i + 1, PDFDict)\n const files = spec.lookupMaybe(PDFName.of('EF'), PDFDict)\n const stream = files?.lookup(PDFName.of('F'))\n if (!stream || !(stream instanceof lib.PDFRawStream)) return null\n return decodePDFRawStream(stream).decode()\n }\n }\n const kids = node.lookupMaybe(PDFName.of('Kids'), PDFArray)\n for (let i = 0; kids && i < kids.size(); i++) {\n const found = find(kids.lookup(i, PDFDict))\n if (found) return found\n }\n return null\n }\n return find(root)\n}\n\n/** Remove the name-tree entries called `name` (flat /Names arrays; the shape pdf-lib writes). */\nfunction removeEntries(lib: typeof import('pdf-lib'), doc: PDFDocumentType, name: string) {\n const { PDFName, PDFDict, PDFArray, PDFString, PDFHexString } = lib\n const root = doc.catalog\n .lookupMaybe(PDFName.of('Names'), PDFDict)\n ?.lookupMaybe(PDFName.of('EmbeddedFiles'), PDFDict)\n const pairs = root?.lookupMaybe(PDFName.of('Names'), PDFArray)\n if (!pairs) return\n for (let i = pairs.size() - 2; i >= 0; i -= 2) {\n const key = pairs.lookup(i)\n const text =\n key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : undefined\n if (text === name) {\n pairs.remove(i + 1)\n pairs.remove(i)\n }\n }\n}\n\n/** The PDF with `attachment` in it, replacing any attachment of the same name. */\nexport async function setPdfAttachment(pdf: Bytes, attachment: PdfAttachment): Promise<Uint8Array> {\n const lib = await import('pdf-lib')\n const doc = await lib.PDFDocument.load(asBytes(pdf), { updateMetadata: false })\n removeEntries(lib, doc, attachment.name)\n const now = new Date()\n await doc.attach(new Uint8Array(attachment.data), attachment.name, {\n mimeType: attachment.mimeType,\n description: attachment.description,\n creationDate: now,\n modificationDate: now,\n })\n return doc.save()\n}\n"],
|
|
5
|
+
"mappings": "AAkBA,MAAM,UAAU,CAAC,UAAkB,iBAAiB,aAAa,QAAQ,IAAI,WAAW,KAAK;AAG7F,eAAsB,kBAAkB,KAAY,MAA0C;AAC5F,QAAM,MAAM,MAAM,OAAO,SAAS;AAClC,QAAM,EAAE,aAAa,SAAS,SAAS,UAAU,WAAW,cAAc,mBAAmB,IAC3F;AACF,QAAM,MAAM,MAAM,YAAY,KAAK,QAAQ,GAAG,GAAG,EAAE,gBAAgB,MAAM,CAAC;AAC1E,QAAM,QAAQ,IAAI,QAAQ,YAAY,QAAQ,GAAG,OAAO,GAAG,OAAO;AAClE,QAAM,OAAO,OAAO,YAAY,QAAQ,GAAG,eAAe,GAAG,OAAO;AACpE,MAAI,CAAC,KAAM,QAAO;AAGlB,QAAM,OAAO,CAAC,SAAyC;AACrD,UAAM,QAAQ,KAAK,YAAY,QAAQ,GAAG,OAAO,GAAG,QAAQ;AAC5D,QAAI,OAAO;AACT,eAAS,IAAI,GAAG,IAAI,IAAI,MAAM,KAAK,GAAG,KAAK,GAAG;AAC5C,cAAM,MAAM,MAAM,OAAO,CAAC;AAC1B,cAAM,OACJ,eAAe,aAAa,eAAe,eAAe,IAAI,WAAW,IAAI;AAC/E,YAAI,SAAS,KAAM;AACnB,cAAM,OAAO,MAAM,OAAO,IAAI,GAAG,OAAO;AACxC,cAAM,QAAQ,KAAK,YAAY,QAAQ,GAAG,IAAI,GAAG,OAAO;AACxD,cAAM,SAAS,OAAO,OAAO,QAAQ,GAAG,GAAG,CAAC;AAC5C,YAAI,CAAC,UAAU,EAAE,kBAAkB,IAAI,cAAe,QAAO;AAC7D,eAAO,mBAAmB,MAAM,EAAE,OAAO;AAAA,MAC3C;AAAA,IACF;AACA,UAAM,OAAO,KAAK,YAAY,QAAQ,GAAG,MAAM,GAAG,QAAQ;AAC1D,aAAS,IAAI,GAAG,QAAQ,IAAI,KAAK,KAAK,GAAG,KAAK;AAC5C,YAAM,QAAQ,KAAK,KAAK,OAAO,GAAG,OAAO,CAAC;AAC1C,UAAI,MAAO,QAAO;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI;AAClB;AAGA,SAAS,cAAc,KAA+B,KAAsB,MAAc;AACxF,QAAM,EAAE,SAAS,SAAS,UAAU,WAAW,aAAa,IAAI;AAChE,QAAM,OAAO,IAAI,QACd,YAAY,QAAQ,GAAG,OAAO,GAAG,OAAO,GACvC,YAAY,QAAQ,GAAG,eAAe,GAAG,OAAO;AACpD,QAAM,QAAQ,MAAM,YAAY,QAAQ,GAAG,OAAO,GAAG,QAAQ;AAC7D,MAAI,CAAC,MAAO;AACZ,WAAS,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG;AAC7C,UAAM,MAAM,MAAM,OAAO,CAAC;AAC1B,UAAM,OACJ,eAAe,aAAa,eAAe,eAAe,IAAI,WAAW,IAAI;AAC/E,QAAI,SAAS,MAAM;AACjB,YAAM,OAAO,IAAI,CAAC;AAClB,YAAM,OAAO,CAAC;AAAA,IAChB;AAAA,EACF;AACF;AAGA,eAAsB,iBAAiB,KAAY,YAAgD;AACjG,QAAM,MAAM,MAAM,OAAO,SAAS;AAClC,QAAM,MAAM,MAAM,IAAI,YAAY,KAAK,QAAQ,GAAG,GAAG,EAAE,gBAAgB,MAAM,CAAC;AAC9E,gBAAc,KAAK,KAAK,WAAW,IAAI;AACvC,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,IAAI,OAAO,IAAI,WAAW,WAAW,IAAI,GAAG,WAAW,MAAM;AAAA,IACjE,UAAU,WAAW;AAAA,IACrB,aAAa,WAAW;AAAA,IACxB,cAAc;AAAA,IACd,kBAAkB;AAAA,EACpB,CAAC;AACD,SAAO,IAAI,KAAK;AAClB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -7,10 +7,12 @@ import { EmlIcon } from "../icons/EmlIcon.js";
|
|
|
7
7
|
import { HtmlIcon } from "../icons/HtmlIcon.js";
|
|
8
8
|
import { ImgIcon } from "../icons/ImgIcon.js";
|
|
9
9
|
import { PdfIcon } from "../icons/PdfIcon.js";
|
|
10
|
+
import { PresIcon } from "../icons/PresIcon.js";
|
|
10
11
|
import { TxtIcon } from "../icons/TxtIcon.js";
|
|
11
12
|
import { VidIcon } from "../icons/VidIcon.js";
|
|
12
13
|
import { XlsIcon } from "../icons/XlsIcon.js";
|
|
13
14
|
import { cn } from "../lib/utils.js";
|
|
15
|
+
import { isPresentationFileName } from "./file-type.js";
|
|
14
16
|
function getDocumentTitle(document, defaultValue = "") {
|
|
15
17
|
if (!document) return defaultValue;
|
|
16
18
|
return document.doc_metadata?.title || document.file_name || defaultValue;
|
|
@@ -41,7 +43,10 @@ const TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
41
43
|
"yaml",
|
|
42
44
|
"yml"
|
|
43
45
|
]);
|
|
44
|
-
function getDocIcon(fileName, iconSize = 14) {
|
|
46
|
+
function getDocIcon(fileName, iconSize = 14, folder) {
|
|
47
|
+
if (isPresentationFileName(fileName, folder)) {
|
|
48
|
+
return /* @__PURE__ */ jsx(PresIcon, { size: iconSize, className: "flex-shrink-0" });
|
|
49
|
+
}
|
|
45
50
|
const ext = fileName?.split(".").pop()?.toLowerCase();
|
|
46
51
|
if (ext && VIDEO_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(VidIcon, { size: iconSize, className: "flex-shrink-0" });
|
|
47
52
|
if (ext && AUDIO_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(AudIcon, { size: iconSize, className: "flex-shrink-0" });
|
|
@@ -75,7 +80,7 @@ function DocumentEntity({
|
|
|
75
80
|
const ext = doc.file_name?.split(".").pop()?.toLowerCase();
|
|
76
81
|
const iconSize = size === "md" ? 16 : 14;
|
|
77
82
|
const eyeSizeClass = size === "md" ? "h-4 w-4" : "h-3.5 w-3.5";
|
|
78
|
-
const baseIcon = icon ?? getDocIcon(doc.file_name, iconSize);
|
|
83
|
+
const baseIcon = icon ?? getDocIcon(doc.file_name, iconSize, doc.folder);
|
|
79
84
|
const displayIcon = viewing || iconBadge ? /* @__PURE__ */ jsxs("span", { className: "relative inline-flex flex-shrink-0 items-center justify-center", children: [
|
|
80
85
|
viewing ? /* @__PURE__ */ jsx(Eye, { className: cn("text-primary-foreground", eyeSizeClass) }) : baseIcon,
|
|
81
86
|
iconBadge
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/entities/DocumentEntity.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * DocumentEntity Component\n *\n * Displays a document as a compact entity pill with file-type icon and name.\n * Promoted from the ARBI app and DECOUPLED from the app store/API: it renders\n * purely from the `doc` prop and optional `onClick`/`onIconClick` callbacks.\n */\n\nimport React from 'react'\nimport { Eye, FolderOpen } from 'lucide-react'\nimport { EntityPill, type EntitySize } from './EntityPill'\nimport { AudIcon } from '../icons/AudIcon'\nimport { DocIcon } from '../icons/DocIcon'\nimport { EmlIcon } from '../icons/EmlIcon'\nimport { HtmlIcon } from '../icons/HtmlIcon'\nimport { ImgIcon } from '../icons/ImgIcon'\nimport { PdfIcon } from '../icons/PdfIcon'\nimport { TxtIcon } from '../icons/TxtIcon'\nimport { VidIcon } from '../icons/VidIcon'\nimport { XlsIcon } from '../icons/XlsIcon'\nimport { cn } from '../lib/utils'\n\n/** Minimal, decoupled document shape the pill needs. Structurally compatible\n * with the SDK's `DocResponse` (from `useDocuments`), but no dependency on it \u2014\n * a consumer can pass any object with these fields. */\nexport interface DocumentLike {\n file_name?: string | null\n folder?: string | null\n doc_metadata?: { title?: string | null } | null\n}\n\n/** Title of a document: `doc_metadata.title`, falling back to `file_name`. */\nexport function getDocumentTitle(\n document: DocumentLike | null | undefined,\n defaultValue = ''\n): string {\n if (!document) return defaultValue\n return document.doc_metadata?.title || document.file_name || defaultValue\n}\n\nconst IMAGE_FILE_TYPES = new Set(['png', 'jpg', 'jpeg', 'gif', 'bmp', 'tiff', 'webp'])\n\n/**\n * Whether a document is an image (upload or AI-generated): pages and tokens are text-document\n * concepts, never meaningful for an image, whatever the stored value.\n */\nexport function isImageDocument(\n document: { file_type?: string | null } | null | undefined\n): boolean {\n return !!document?.file_type && IMAGE_FILE_TYPES.has(document.file_type.toLowerCase())\n}\n\n/** Hard cap on the pill's visible label. The full name still shows in the hover\n * tooltip; the pill stays compact so the trailing \u22EE menu never gets pushed. */\nconst MAX_LABEL_CHARS = 30\n\nfunction clampLabel(text: string): string {\n return text.length > MAX_LABEL_CHARS ? `${text.slice(0, MAX_LABEL_CHARS).trimEnd()}\u2026` : text\n}\n\nconst IMAGE_EXTENSIONS = new Set(['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tif', 'webp'])\nconst VIDEO_EXTENSIONS = new Set(['mp4', 'mpeg', 'mpg', 'webm', 'mov', 'avi', 'mkv'])\nconst AUDIO_EXTENSIONS = new Set(['mp3', 'wav', 'm4a', 'aac', 'ogg', 'flac'])\nconst EMAIL_EXTENSIONS = new Set(['eml', 'msg'])\nconst DOCX_EXTENSIONS = new Set(['doc', 'docx', 'odt', 'rtf'])\nconst XLSX_EXTENSIONS = new Set(['xls', 'xlsx', 'csv', 'ods'])\nconst HTML_EXTENSIONS = new Set(['html', 'htm', 'mhtml'])\nconst TEXT_EXTENSIONS = new Set([\n 'txt',\n 'text',\n 'md',\n 'markdown',\n 'log',\n 'json',\n 'xml',\n 'yaml',\n 'yml',\n])\n\n/**\n * The file-type glyph for a document, by extension.\n *\n * Exported because a document is recognisable by its icon before its name \u2014 any\n * surface that lists documents (the entity pill here, the workspace home's\n * Documents card) has to draw the same PDF/image/audio/video/email glyph, or\n * the same file looks like two different things in two places.\n */\nexport function getDocIcon(fileName?: string | null
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * DocumentEntity Component\n *\n * Displays a document as a compact entity pill with file-type icon and name.\n * Promoted from the ARBI app and DECOUPLED from the app store/API: it renders\n * purely from the `doc` prop and optional `onClick`/`onIconClick` callbacks.\n */\n\nimport React from 'react'\nimport { Eye, FolderOpen } from 'lucide-react'\nimport { EntityPill, type EntitySize } from './EntityPill'\nimport { AudIcon } from '../icons/AudIcon'\nimport { DocIcon } from '../icons/DocIcon'\nimport { EmlIcon } from '../icons/EmlIcon'\nimport { HtmlIcon } from '../icons/HtmlIcon'\nimport { ImgIcon } from '../icons/ImgIcon'\nimport { PdfIcon } from '../icons/PdfIcon'\nimport { PresIcon } from '../icons/PresIcon'\nimport { TxtIcon } from '../icons/TxtIcon'\nimport { VidIcon } from '../icons/VidIcon'\nimport { XlsIcon } from '../icons/XlsIcon'\nimport { cn } from '../lib/utils'\nimport { isPresentationFileName } from './file-type'\n\n/** Minimal, decoupled document shape the pill needs. Structurally compatible\n * with the SDK's `DocResponse` (from `useDocuments`), but no dependency on it \u2014\n * a consumer can pass any object with these fields. */\nexport interface DocumentLike {\n file_name?: string | null\n folder?: string | null\n doc_metadata?: { title?: string | null } | null\n}\n\n/** Title of a document: `doc_metadata.title`, falling back to `file_name`. */\nexport function getDocumentTitle(\n document: DocumentLike | null | undefined,\n defaultValue = ''\n): string {\n if (!document) return defaultValue\n return document.doc_metadata?.title || document.file_name || defaultValue\n}\n\nconst IMAGE_FILE_TYPES = new Set(['png', 'jpg', 'jpeg', 'gif', 'bmp', 'tiff', 'webp'])\n\n/**\n * Whether a document is an image (upload or AI-generated): pages and tokens are text-document\n * concepts, never meaningful for an image, whatever the stored value.\n */\nexport function isImageDocument(\n document: { file_type?: string | null } | null | undefined\n): boolean {\n return !!document?.file_type && IMAGE_FILE_TYPES.has(document.file_type.toLowerCase())\n}\n\n/** Hard cap on the pill's visible label. The full name still shows in the hover\n * tooltip; the pill stays compact so the trailing \u22EE menu never gets pushed. */\nconst MAX_LABEL_CHARS = 30\n\nfunction clampLabel(text: string): string {\n return text.length > MAX_LABEL_CHARS ? `${text.slice(0, MAX_LABEL_CHARS).trimEnd()}\u2026` : text\n}\n\nconst IMAGE_EXTENSIONS = new Set(['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tif', 'webp'])\nconst VIDEO_EXTENSIONS = new Set(['mp4', 'mpeg', 'mpg', 'webm', 'mov', 'avi', 'mkv'])\nconst AUDIO_EXTENSIONS = new Set(['mp3', 'wav', 'm4a', 'aac', 'ogg', 'flac'])\nconst EMAIL_EXTENSIONS = new Set(['eml', 'msg'])\nconst DOCX_EXTENSIONS = new Set(['doc', 'docx', 'odt', 'rtf'])\nconst XLSX_EXTENSIONS = new Set(['xls', 'xlsx', 'csv', 'ods'])\nconst HTML_EXTENSIONS = new Set(['html', 'htm', 'mhtml'])\nconst TEXT_EXTENSIONS = new Set([\n 'txt',\n 'text',\n 'md',\n 'markdown',\n 'log',\n 'json',\n 'xml',\n 'yaml',\n 'yml',\n])\n\n/**\n * The file-type glyph for a document, by extension.\n *\n * Exported because a document is recognisable by its icon before its name \u2014 any\n * surface that lists documents (the entity pill here, the workspace home's\n * Documents card) has to draw the same PDF/image/audio/video/email glyph, or\n * the same file looks like two different things in two places.\n */\nexport function getDocIcon(\n fileName?: string | null,\n iconSize = 14,\n /** The document's folder: a PDF in Presentations is a presentation. */\n folder?: string | null\n): React.ReactNode {\n if (isPresentationFileName(fileName, folder)) {\n return <PresIcon size={iconSize} className=\"flex-shrink-0\" />\n }\n const ext = fileName?.split('.').pop()?.toLowerCase()\n if (ext && VIDEO_EXTENSIONS.has(ext)) return <VidIcon size={iconSize} className=\"flex-shrink-0\" />\n if (ext && AUDIO_EXTENSIONS.has(ext)) return <AudIcon size={iconSize} className=\"flex-shrink-0\" />\n if (ext && IMAGE_EXTENSIONS.has(ext)) return <ImgIcon size={iconSize} className=\"flex-shrink-0\" />\n if (ext && EMAIL_EXTENSIONS.has(ext)) return <EmlIcon size={iconSize} className=\"flex-shrink-0\" />\n if (ext && DOCX_EXTENSIONS.has(ext)) return <DocIcon size={iconSize} className=\"flex-shrink-0\" />\n if (ext && XLSX_EXTENSIONS.has(ext)) return <XlsIcon size={iconSize} className=\"flex-shrink-0\" />\n if (ext && HTML_EXTENSIONS.has(ext)) return <HtmlIcon size={iconSize} className=\"flex-shrink-0\" />\n if (ext && TEXT_EXTENSIONS.has(ext)) return <TxtIcon size={iconSize} className=\"flex-shrink-0\" />\n // Unrecognised or missing extension (e.g. a display title): most uploads are PDFs.\n return <PdfIcon size={iconSize} className=\"flex-shrink-0\" />\n}\n\nexport interface DocumentEntityProps {\n doc: DocumentLike\n /** Override the default file-type icon */\n icon?: React.ReactNode\n /** `sm` (default) for inline/compact contexts, `md` for a larger pill (e.g. the documents\n * grid's primary name column). */\n size?: Extract<EntitySize, 'sm' | 'md'>\n /** Override default label max width */\n labelMaxWidth?: string\n /** Extra classes on the label text (e.g. a heavier weight on a card face). */\n labelClassName?: string\n /** Click handler for the whole pill */\n onClick?: (e: React.MouseEvent) => void\n /** Click handler for the icon only */\n onIconClick?: (e: React.MouseEvent) => void\n /** When true, the file-type icon is replaced by a pinned Eye \u2014 marks the\n * document that is currently open/being viewed. */\n viewing?: boolean\n /** Small overlay pinned to the icon's corner (e.g. an \"available offline\" pip). */\n iconBadge?: React.ReactNode\n /** Small content right after the name, inside the click area (e.g. a status glyph). */\n status?: React.ReactNode\n /** Trailing control rendered outside the click area (e.g. a \u22EF actions menu). */\n actions?: React.ReactNode\n /** When true, the pill fills the available width and the name truncates via\n * CSS so the trailing \u22EF menu pins to the right edge. */\n fullWidth?: boolean\n /** Render the WHOLE title (skip the 30-char `clampLabel` string cut) while\n * keeping the normal content-width layout \u2014 for callers that want the full\n * name to show/wrap (via a `labelClassName`) without `fullWidth`'s w-full.\n * `fullWidth` already implies this. */\n noClamp?: boolean\n /** Override the default folder/title hover tooltip. */\n tooltipContent?: React.ReactNode\n className?: string\n /** Forwarded to the pill so a surface can address this document's chip. */\n 'data-testid'?: string\n}\n\nexport function DocumentEntity({\n doc,\n icon,\n size = 'sm',\n labelMaxWidth,\n labelClassName,\n onClick,\n onIconClick,\n viewing,\n iconBadge,\n status,\n actions,\n tooltipContent,\n className,\n fullWidth,\n noClamp,\n 'data-testid': testId,\n}: DocumentEntityProps) {\n const title = getDocumentTitle(doc)\n const ext = doc.file_name?.split('.').pop()?.toLowerCase()\n const iconSize = size === 'md' ? 16 : 14\n const eyeSizeClass = size === 'md' ? 'h-4 w-4' : 'h-3.5 w-3.5'\n\n const baseIcon = icon ?? getDocIcon(doc.file_name, iconSize, doc.folder)\n const displayIcon =\n viewing || iconBadge ? (\n <span className=\"relative inline-flex flex-shrink-0 items-center justify-center\">\n {viewing ? <Eye className={cn('text-primary-foreground', eyeSizeClass)} /> : baseIcon}\n {iconBadge}\n </span>\n ) : (\n baseIcon\n )\n\n const defaultTooltip = (\n <div className=\"flex flex-col gap-1 text-xs max-w-[440px]\">\n {doc.folder && (\n // `flex-wrap` so a deep folder path wraps WITHIN the balloon instead of\n // spilling out of it (each path segment is atomic and wraps as a unit;\n // `min-w-0` + `break-all` lets a single over-long segment break too).\n <span className=\"flex flex-wrap items-center gap-0.5 text-muted-foreground\">\n <FolderOpen className=\"h-3 w-3 text-yellow-600 shrink-0\" />\n {doc.folder.split('/').map((part, i, arr) => (\n <span key={i} className=\"flex min-w-0 items-center gap-0.5\">\n {i > 0 && <span className=\"text-muted-foreground/50 mx-0.5\">/</span>}\n <span className={`break-all ${i < arr.length - 1 ? 'text-muted-foreground/70' : ''}`}>\n {part}\n </span>\n </span>\n ))}\n </span>\n )}\n <span className=\"font-medium break-words\">\n {title}\n {ext ? `.${ext}` : ''}\n </span>\n </div>\n )\n\n return (\n <EntityPill\n icon={displayIcon}\n size={size}\n label={fullWidth || noClamp ? title : clampLabel(title)}\n labelMaxWidth={labelMaxWidth ?? 'max-w-[140px]'}\n labelClassName={labelClassName}\n secondaryText={status}\n fullWidth={fullWidth}\n onClick={onClick}\n onIconClick={onIconClick}\n moreContent={actions}\n className={className}\n highlight={viewing}\n data-testid={testId}\n tooltipContent={tooltipContent ?? defaultTooltip}\n />\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -127,7 +127,16 @@ function extFromFileName(fileName) {
|
|
|
127
127
|
if (dot <= 0 || dot === fileName.length - 1) return void 0;
|
|
128
128
|
return fileName.slice(dot + 1);
|
|
129
129
|
}
|
|
130
|
-
|
|
130
|
+
const PRESENTATIONS_FOLDER = "Presentations";
|
|
131
|
+
const PRESENTATION_TEMPLATES_FOLDER = `${PRESENTATIONS_FOLDER}/Templates`;
|
|
132
|
+
function isPresentationFileName(fileName, folder) {
|
|
133
|
+
const name = (fileName ?? "").toLowerCase();
|
|
134
|
+
if (name.endsWith(".presentation.pdf") || name.endsWith(".presentation.json")) return true;
|
|
135
|
+
if (name.endsWith(".pptx")) return true;
|
|
136
|
+
return name.endsWith(".pdf") && (folder === PRESENTATIONS_FOLDER || folder === PRESENTATION_TEMPLATES_FOLDER);
|
|
137
|
+
}
|
|
138
|
+
function friendlyFileType(fileType, fileName, folder) {
|
|
139
|
+
if (isPresentationFileName(fileName, folder)) return "Presentation";
|
|
131
140
|
if (fileType) {
|
|
132
141
|
const trimmed = fileType.trim();
|
|
133
142
|
if (trimmed.includes("/")) {
|
|
@@ -146,6 +155,9 @@ function friendlyFileType(fileType, fileName) {
|
|
|
146
155
|
return "Other";
|
|
147
156
|
}
|
|
148
157
|
export {
|
|
149
|
-
|
|
158
|
+
PRESENTATIONS_FOLDER,
|
|
159
|
+
PRESENTATION_TEMPLATES_FOLDER,
|
|
160
|
+
friendlyFileType,
|
|
161
|
+
isPresentationFileName
|
|
150
162
|
};
|
|
151
163
|
//# sourceMappingURL=file-type.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/entities/file-type.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Friendly file-type label.\n *\n * `Doc.file_type` is populated from two unrelated upload paths in the\n * backend: sometimes it's a bare extension (``\"pdf\"``, ``\"docx\"``,\n * ``\"html\"``), sometimes it's a MIME type (``\"application/pdf\"``,\n * ``\"image/jpeg\"``). Showing the raw value as-is gives the grid a\n * mix of ``PDF`` and ``APPLICATION/PDF`` in the same column.\n *\n * This util normalises both shapes to a single short, capitalised\n * label. The classification is keyed off the MIME subtype (or the bare\n * extension) so adding a new entry only ever requires touching the\n * tables below.\n *\n * Falls back to the file name's extension when ``file_type`` is\n * missing or unrecognised, and finally to ``Other`` so the cell never\n * renders empty.\n */\n\n// Bare extension \u2192 friendly label. Lowercase keys, no leading dot.\nconst EXT_LABELS: Record<string, string> = {\n pdf: 'PDF',\n\n // Word / docs\n doc: 'Word',\n docx: 'Word',\n rtf: 'Word',\n odt: 'Word',\n\n // Spreadsheets\n xls: 'Excel',\n xlsx: 'Excel',\n ods: 'Excel',\n csv: 'CSV',\n tsv: 'CSV',\n\n // Slides\n ppt: 'PowerPoint',\n pptx: 'PowerPoint',\n odp: 'PowerPoint',\n\n // Plain text / markup\n txt: 'Text',\n log: 'Text',\n md: 'Markdown',\n markdown: 'Markdown',\n html: 'HTML',\n htm: 'HTML',\n xml: 'XML',\n json: 'JSON',\n yaml: 'YAML',\n yml: 'YAML',\n\n // Email\n eml: 'Email',\n msg: 'Email',\n mbox: 'Email',\n pst: 'Outlook',\n ost: 'Outlook',\n\n // Images\n jpg: 'Image',\n jpeg: 'Image',\n png: 'Image',\n gif: 'Image',\n bmp: 'Image',\n tif: 'Image',\n tiff: 'Image',\n webp: 'Image',\n svg: 'Image',\n heic: 'Image',\n heif: 'Image',\n\n // Audio\n mp3: 'Audio',\n wav: 'Audio',\n m4a: 'Audio',\n aac: 'Audio',\n ogg: 'Audio',\n flac: 'Audio',\n opus: 'Audio',\n\n // Video\n mp4: 'Video',\n webm: 'Video',\n mov: 'Video',\n avi: 'Video',\n mkv: 'Video',\n\n // Archives\n zip: 'Archive',\n tar: 'Archive',\n gz: 'Archive',\n rar: 'Archive',\n '7z': 'Archive',\n}\n\n// MIME subtype \u2192 friendly label. Keys are lowercase, no parameters\n// (i.e. anything after ``;`` is stripped before lookup). Used when\n// `file_type` looks like a MIME string (\"application/pdf\").\nconst MIME_SUBTYPE_LABELS: Record<string, string> = {\n // PDF\n pdf: 'PDF',\n 'x-pdf': 'PDF',\n\n // Word\n msword: 'Word',\n 'vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word',\n 'vnd.oasis.opendocument.text': 'Word',\n rtf: 'Word',\n\n // Excel\n 'vnd.ms-excel': 'Excel',\n 'vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel',\n 'vnd.oasis.opendocument.spreadsheet': 'Excel',\n csv: 'CSV',\n 'tab-separated-values': 'CSV',\n\n // PowerPoint\n 'vnd.ms-powerpoint': 'PowerPoint',\n 'vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint',\n 'vnd.oasis.opendocument.presentation': 'PowerPoint',\n\n // Plain text / markup\n plain: 'Text',\n html: 'HTML',\n xml: 'XML',\n json: 'JSON',\n markdown: 'Markdown',\n 'x-markdown': 'Markdown',\n yaml: 'YAML',\n 'x-yaml': 'YAML',\n\n // Email\n rfc822: 'Email',\n 'vnd.ms-outlook': 'Email',\n\n // Archives\n zip: 'Archive',\n 'x-zip-compressed': 'Archive',\n 'x-tar': 'Archive',\n gzip: 'Archive',\n 'x-7z-compressed': 'Archive',\n 'x-rar-compressed': 'Archive',\n}\n\n// Top-level MIME type \u2192 friendly label. Only used when neither the\n// extension table nor the subtype table matched, e.g. an unknown\n// image like ``image/avif``.\nconst MIME_TYPE_LABELS: Record<string, string> = {\n image: 'Image',\n audio: 'Audio',\n video: 'Video',\n text: 'Text',\n}\n\nfunction lookupExt(ext: string): string | undefined {\n return EXT_LABELS[ext.toLowerCase().replace(/^\\./, '')]\n}\n\nfunction lookupMime(mime: string): string | undefined {\n // Strip parameters: \"text/html; charset=utf-8\" \u2192 \"text/html\".\n const base = mime.toLowerCase().split(';')[0].trim()\n const slash = base.indexOf('/')\n if (slash <= 0) return undefined\n const top = base.slice(0, slash)\n const sub = base.slice(slash + 1)\n return MIME_SUBTYPE_LABELS[sub] ?? MIME_TYPE_LABELS[top]\n}\n\nfunction extFromFileName(fileName?: string | null): string | undefined {\n if (!fileName) return undefined\n const dot = fileName.lastIndexOf('.')\n if (dot <= 0 || dot === fileName.length - 1) return undefined\n return fileName.slice(dot + 1)\n}\n\n/**\n * Map a backend ``file_type`` value (extension OR MIME type) plus an\n * optional file name to a single short label suitable for a grid cell.\n *\n * Order:\n * 1. ``file_type`` looks like a MIME (\"a/b\") \u2192 MIME tables.\n * 2. ``file_type`` looks like a bare extension \u2192 extension table.\n * 3. ``file_name`` extension as a last-resort fallback.\n * 4. ``\"Other\"``.\n */\nexport function
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Friendly file-type label.\n *\n * `Doc.file_type` is populated from two unrelated upload paths in the\n * backend: sometimes it's a bare extension (``\"pdf\"``, ``\"docx\"``,\n * ``\"html\"``), sometimes it's a MIME type (``\"application/pdf\"``,\n * ``\"image/jpeg\"``). Showing the raw value as-is gives the grid a\n * mix of ``PDF`` and ``APPLICATION/PDF`` in the same column.\n *\n * This util normalises both shapes to a single short, capitalised\n * label. The classification is keyed off the MIME subtype (or the bare\n * extension) so adding a new entry only ever requires touching the\n * tables below.\n *\n * Falls back to the file name's extension when ``file_type`` is\n * missing or unrecognised, and finally to ``Other`` so the cell never\n * renders empty.\n */\n\n// Bare extension \u2192 friendly label. Lowercase keys, no leading dot.\nconst EXT_LABELS: Record<string, string> = {\n pdf: 'PDF',\n\n // Word / docs\n doc: 'Word',\n docx: 'Word',\n rtf: 'Word',\n odt: 'Word',\n\n // Spreadsheets\n xls: 'Excel',\n xlsx: 'Excel',\n ods: 'Excel',\n csv: 'CSV',\n tsv: 'CSV',\n\n // Slides\n ppt: 'PowerPoint',\n pptx: 'PowerPoint',\n odp: 'PowerPoint',\n\n // Plain text / markup\n txt: 'Text',\n log: 'Text',\n md: 'Markdown',\n markdown: 'Markdown',\n html: 'HTML',\n htm: 'HTML',\n xml: 'XML',\n json: 'JSON',\n yaml: 'YAML',\n yml: 'YAML',\n\n // Email\n eml: 'Email',\n msg: 'Email',\n mbox: 'Email',\n pst: 'Outlook',\n ost: 'Outlook',\n\n // Images\n jpg: 'Image',\n jpeg: 'Image',\n png: 'Image',\n gif: 'Image',\n bmp: 'Image',\n tif: 'Image',\n tiff: 'Image',\n webp: 'Image',\n svg: 'Image',\n heic: 'Image',\n heif: 'Image',\n\n // Audio\n mp3: 'Audio',\n wav: 'Audio',\n m4a: 'Audio',\n aac: 'Audio',\n ogg: 'Audio',\n flac: 'Audio',\n opus: 'Audio',\n\n // Video\n mp4: 'Video',\n webm: 'Video',\n mov: 'Video',\n avi: 'Video',\n mkv: 'Video',\n\n // Archives\n zip: 'Archive',\n tar: 'Archive',\n gz: 'Archive',\n rar: 'Archive',\n '7z': 'Archive',\n}\n\n// MIME subtype \u2192 friendly label. Keys are lowercase, no parameters\n// (i.e. anything after ``;`` is stripped before lookup). Used when\n// `file_type` looks like a MIME string (\"application/pdf\").\nconst MIME_SUBTYPE_LABELS: Record<string, string> = {\n // PDF\n pdf: 'PDF',\n 'x-pdf': 'PDF',\n\n // Word\n msword: 'Word',\n 'vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word',\n 'vnd.oasis.opendocument.text': 'Word',\n rtf: 'Word',\n\n // Excel\n 'vnd.ms-excel': 'Excel',\n 'vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel',\n 'vnd.oasis.opendocument.spreadsheet': 'Excel',\n csv: 'CSV',\n 'tab-separated-values': 'CSV',\n\n // PowerPoint\n 'vnd.ms-powerpoint': 'PowerPoint',\n 'vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint',\n 'vnd.oasis.opendocument.presentation': 'PowerPoint',\n\n // Plain text / markup\n plain: 'Text',\n html: 'HTML',\n xml: 'XML',\n json: 'JSON',\n markdown: 'Markdown',\n 'x-markdown': 'Markdown',\n yaml: 'YAML',\n 'x-yaml': 'YAML',\n\n // Email\n rfc822: 'Email',\n 'vnd.ms-outlook': 'Email',\n\n // Archives\n zip: 'Archive',\n 'x-zip-compressed': 'Archive',\n 'x-tar': 'Archive',\n gzip: 'Archive',\n 'x-7z-compressed': 'Archive',\n 'x-rar-compressed': 'Archive',\n}\n\n// Top-level MIME type \u2192 friendly label. Only used when neither the\n// extension table nor the subtype table matched, e.g. an unknown\n// image like ``image/avif``.\nconst MIME_TYPE_LABELS: Record<string, string> = {\n image: 'Image',\n audio: 'Audio',\n video: 'Video',\n text: 'Text',\n}\n\nfunction lookupExt(ext: string): string | undefined {\n return EXT_LABELS[ext.toLowerCase().replace(/^\\./, '')]\n}\n\nfunction lookupMime(mime: string): string | undefined {\n // Strip parameters: \"text/html; charset=utf-8\" \u2192 \"text/html\".\n const base = mime.toLowerCase().split(';')[0].trim()\n const slash = base.indexOf('/')\n if (slash <= 0) return undefined\n const top = base.slice(0, slash)\n const sub = base.slice(slash + 1)\n return MIME_SUBTYPE_LABELS[sub] ?? MIME_TYPE_LABELS[top]\n}\n\nfunction extFromFileName(fileName?: string | null): string | undefined {\n if (!fileName) return undefined\n const dot = fileName.lastIndexOf('.')\n if (dot <= 0 || dot === fileName.length - 1) return undefined\n return fileName.slice(dot + 1)\n}\n\n/**\n * Map a backend ``file_type`` value (extension OR MIME type) plus an\n * optional file name to a single short label suitable for a grid cell.\n *\n * Order:\n * 1. ``file_type`` looks like a MIME (\"a/b\") \u2192 MIME tables.\n * 2. ``file_type`` looks like a bare extension \u2192 extension table.\n * 3. ``file_name`` extension as a last-resort fallback.\n * 4. ``\"Other\"``.\n */\n/** Where presentations are saved (Files \u203A Presentations), and their templates. */\nexport const PRESENTATIONS_FOLDER = 'Presentations'\nexport const PRESENTATION_TEMPLATES_FOLDER = `${PRESENTATIONS_FOLDER}/Templates`\n\n/**\n * A presentation: a PowerPoint file (`.pptx`; one saved by ARBI carries its editable data inside).\n * Presentations saved before they were PowerPoint files are known too: a PDF kept in Files \u203A\n * Presentations or its Templates, `\u2026.presentation.pdf`, or `\u2026.presentation.json` (the data alone).\n */\nexport function isPresentationFileName(fileName?: string | null, folder?: string | null): boolean {\n const name = (fileName ?? '').toLowerCase()\n if (name.endsWith('.presentation.pdf') || name.endsWith('.presentation.json')) return true\n // A presentation is a PowerPoint file.\n if (name.endsWith('.pptx')) return true\n return (\n name.endsWith('.pdf') &&\n (folder === PRESENTATIONS_FOLDER || folder === PRESENTATION_TEMPLATES_FOLDER)\n )\n}\n\nexport function friendlyFileType(\n fileType?: string | null,\n fileName?: string | null,\n /** The document's folder: a PDF in Presentations is a presentation. */\n folder?: string | null\n): string {\n if (isPresentationFileName(fileName, folder)) return 'Presentation'\n if (fileType) {\n const trimmed = fileType.trim()\n if (trimmed.includes('/')) {\n const fromMime = lookupMime(trimmed)\n if (fromMime) return fromMime\n } else {\n const fromExt = lookupExt(trimmed)\n if (fromExt) return fromExt\n }\n }\n\n const fnExt = extFromFileName(fileName)\n if (fnExt) {\n const fromExt = lookupExt(fnExt)\n if (fromExt) return fromExt\n }\n\n return 'Other'\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/entities/index.js
CHANGED
|
@@ -53,7 +53,12 @@ import {
|
|
|
53
53
|
isVideoFile,
|
|
54
54
|
usesOriginalBytesForViewer
|
|
55
55
|
} from "./media-type.js";
|
|
56
|
-
import {
|
|
56
|
+
import {
|
|
57
|
+
friendlyFileType,
|
|
58
|
+
isPresentationFileName,
|
|
59
|
+
PRESENTATIONS_FOLDER,
|
|
60
|
+
PRESENTATION_TEMPLATES_FOLDER
|
|
61
|
+
} from "./file-type.js";
|
|
57
62
|
export {
|
|
58
63
|
AgentBadge,
|
|
59
64
|
BASE_COLORS,
|
|
@@ -63,6 +68,8 @@ export {
|
|
|
63
68
|
EntityPill,
|
|
64
69
|
NEUTRAL_GRAY,
|
|
65
70
|
PLACEHOLDER_COLOR,
|
|
71
|
+
PRESENTATIONS_FOLDER,
|
|
72
|
+
PRESENTATION_TEMPLATES_FOLDER,
|
|
66
73
|
PresenceLabel,
|
|
67
74
|
ProjectEntity,
|
|
68
75
|
SHARING_LABELS,
|
|
@@ -100,6 +107,7 @@ export {
|
|
|
100
107
|
isImageDocument,
|
|
101
108
|
isImageFile,
|
|
102
109
|
isMediaFile,
|
|
110
|
+
isPresentationFileName,
|
|
103
111
|
isVideoFile,
|
|
104
112
|
tagKindNouns,
|
|
105
113
|
tagKindTitle,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/entities/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { ThreadVisibilityIcon } from './ThreadVisibilityIcon'\nexport { EntityPill, type EntitySize } from './EntityPill'\nexport {\n DocumentEntity,\n getDocIcon,\n getDocumentTitle,\n isImageDocument,\n type DocumentEntityProps,\n type DocumentLike,\n} from './DocumentEntity'\nexport {\n SharingEntity,\n configureSharingMembers,\n SHARING_LABELS,\n type SharingEntityProps,\n} from './SharingEntity'\nexport { TagEntity, type TagEntityProps, type TagLike } from './TagEntity'\nexport { TAG_TYPE_ICONS, TAG_TYPE_LABELS, getTagTypeIcon, getTagTypeLabel } from './tag-types'\nexport { tagKindTitle, tagKindNouns } from './tag-kinds'\nexport { ProjectEntity, type ProjectEntityProps, type ProjectRelation } from './ProjectEntity'\nexport { UserEntity, type UserEntityProps, type PresenceDisplayStatus } from './UserEntity'\nexport { VerifiedBadge, type VerifiedBadgeProps } from './VerifiedBadge'\n// One agent stamp and one presence wording for every surface \u2014 see AgentMarkers.\nexport { AgentBadge, PresenceLabel } from './AgentMarkers'\n\n// Status pill + RAG dot \u2014 generic presentation, domain vocabulary INJECTED.\nexport {\n StatusPill,\n type StatusPillProps,\n type StatusVariant,\n type StatusBadgeProps,\n type StatusBadgeComponent,\n configureStatusRegistry,\n getStatusVariant,\n type Rag,\n configureRagLabels,\n} from './status'\n\n// Canonical entity registry \u2014 icons, names, and the deployment injection seam.\nexport {\n ENTITY_MAPPINGS,\n type EntityType,\n type EntityIconComponent,\n type EntityRegistryOverride,\n type EntityLabelForm,\n configureEntityRegistry,\n getEntityIcon,\n getEntityLabel,\n entityNoun,\n EntityIcon,\n VISIBILITY_ICONS,\n VisibilityIcon,\n} from './registry'\n\nexport { configureEntityVocabulary, type EntityNoun, type EntityVocabulary } from './vocabulary'\n\n// Entity colour system \u2014 deterministic id \u2192 colour derivation.\nexport {\n BASE_COLORS,\n PLACEHOLDER_COLOR,\n NEUTRAL_GRAY,\n getEntityColor,\n getEntityColorStyles,\n getWorkspaceColor,\n} from './colors'\n\n// Workspace square glyph (initial on a colour fill) and the outlined agent-avatar colours.\nexport { ShieldIcon, type ShieldIconProps } from './ShieldIcon'\nexport { agentAvatarColors } from './agent-avatar-colors'\n\n// What kind of file a document is: the viewer's choice of renderer and the short label of its type.\nexport {\n isAudioFile,\n isDownloadOnlyFile,\n isImageFile,\n isMediaFile,\n isVideoFile,\n usesOriginalBytesForViewer,\n} from './media-type'\nexport {
|
|
5
|
-
"mappings": "AAAA,SAAS,4BAA4B;AACrC,SAAS,kBAAmC;AAC5C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,iBAAoD;AAC7D,SAAS,gBAAgB,iBAAiB,gBAAgB,uBAAuB;AACjF,SAAS,cAAc,oBAAoB;AAC3C,SAAS,qBAAoE;AAC7E,SAAS,kBAAoE;AAC7E,SAAS,qBAA8C;AAEvD,SAAS,YAAY,qBAAqB;AAG1C;AAAA,EACE;AAAA,EAKA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,iCAAyE;AAGlF;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,kBAAwC;AACjD,SAAS,yBAAyB;AAGlC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,
|
|
4
|
+
"sourcesContent": ["export { ThreadVisibilityIcon } from './ThreadVisibilityIcon'\nexport { EntityPill, type EntitySize } from './EntityPill'\nexport {\n DocumentEntity,\n getDocIcon,\n getDocumentTitle,\n isImageDocument,\n type DocumentEntityProps,\n type DocumentLike,\n} from './DocumentEntity'\nexport {\n SharingEntity,\n configureSharingMembers,\n SHARING_LABELS,\n type SharingEntityProps,\n} from './SharingEntity'\nexport { TagEntity, type TagEntityProps, type TagLike } from './TagEntity'\nexport { TAG_TYPE_ICONS, TAG_TYPE_LABELS, getTagTypeIcon, getTagTypeLabel } from './tag-types'\nexport { tagKindTitle, tagKindNouns } from './tag-kinds'\nexport { ProjectEntity, type ProjectEntityProps, type ProjectRelation } from './ProjectEntity'\nexport { UserEntity, type UserEntityProps, type PresenceDisplayStatus } from './UserEntity'\nexport { VerifiedBadge, type VerifiedBadgeProps } from './VerifiedBadge'\n// One agent stamp and one presence wording for every surface \u2014 see AgentMarkers.\nexport { AgentBadge, PresenceLabel } from './AgentMarkers'\n\n// Status pill + RAG dot \u2014 generic presentation, domain vocabulary INJECTED.\nexport {\n StatusPill,\n type StatusPillProps,\n type StatusVariant,\n type StatusBadgeProps,\n type StatusBadgeComponent,\n configureStatusRegistry,\n getStatusVariant,\n type Rag,\n configureRagLabels,\n} from './status'\n\n// Canonical entity registry \u2014 icons, names, and the deployment injection seam.\nexport {\n ENTITY_MAPPINGS,\n type EntityType,\n type EntityIconComponent,\n type EntityRegistryOverride,\n type EntityLabelForm,\n configureEntityRegistry,\n getEntityIcon,\n getEntityLabel,\n entityNoun,\n EntityIcon,\n VISIBILITY_ICONS,\n VisibilityIcon,\n} from './registry'\n\nexport { configureEntityVocabulary, type EntityNoun, type EntityVocabulary } from './vocabulary'\n\n// Entity colour system \u2014 deterministic id \u2192 colour derivation.\nexport {\n BASE_COLORS,\n PLACEHOLDER_COLOR,\n NEUTRAL_GRAY,\n getEntityColor,\n getEntityColorStyles,\n getWorkspaceColor,\n} from './colors'\n\n// Workspace square glyph (initial on a colour fill) and the outlined agent-avatar colours.\nexport { ShieldIcon, type ShieldIconProps } from './ShieldIcon'\nexport { agentAvatarColors } from './agent-avatar-colors'\n\n// What kind of file a document is: the viewer's choice of renderer and the short label of its type.\nexport {\n isAudioFile,\n isDownloadOnlyFile,\n isImageFile,\n isMediaFile,\n isVideoFile,\n usesOriginalBytesForViewer,\n} from './media-type'\nexport {\n friendlyFileType,\n isPresentationFileName,\n PRESENTATIONS_FOLDER,\n PRESENTATION_TEMPLATES_FOLDER,\n} from './file-type'\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,4BAA4B;AACrC,SAAS,kBAAmC;AAC5C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,iBAAoD;AAC7D,SAAS,gBAAgB,iBAAiB,gBAAgB,uBAAuB;AACjF,SAAS,cAAc,oBAAoB;AAC3C,SAAS,qBAAoE;AAC7E,SAAS,kBAAoE;AAC7E,SAAS,qBAA8C;AAEvD,SAAS,YAAY,qBAAqB;AAG1C;AAAA,EACE;AAAA,EAKA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,iCAAyE;AAGlF;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,kBAAwC;AACjD,SAAS,yBAAyB;AAGlC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { FILE_TYPE_COLORS } from "./colors.js";
|
|
3
|
+
const PresIcon = ({ size = 16, className = "" }) => {
|
|
4
|
+
return /* @__PURE__ */ jsxs(
|
|
5
|
+
"svg",
|
|
6
|
+
{
|
|
7
|
+
width: size,
|
|
8
|
+
height: size,
|
|
9
|
+
viewBox: "0 0 24 24",
|
|
10
|
+
fill: "none",
|
|
11
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
12
|
+
className,
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsx(
|
|
15
|
+
"path",
|
|
16
|
+
{
|
|
17
|
+
d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z",
|
|
18
|
+
fill: FILE_TYPE_COLORS.pres,
|
|
19
|
+
stroke: FILE_TYPE_COLORS.pres,
|
|
20
|
+
strokeWidth: "1",
|
|
21
|
+
strokeLinecap: "round",
|
|
22
|
+
strokeLinejoin: "round"
|
|
23
|
+
}
|
|
24
|
+
),
|
|
25
|
+
/* @__PURE__ */ jsx(
|
|
26
|
+
"path",
|
|
27
|
+
{
|
|
28
|
+
d: "M14 2v6h6",
|
|
29
|
+
fill: "none",
|
|
30
|
+
stroke: FILE_TYPE_COLORS.white,
|
|
31
|
+
strokeWidth: "1",
|
|
32
|
+
strokeLinecap: "round",
|
|
33
|
+
strokeLinejoin: "round"
|
|
34
|
+
}
|
|
35
|
+
),
|
|
36
|
+
/* @__PURE__ */ jsx("rect", { x: "7", y: "11", width: "10", height: "6", rx: "0.75", fill: FILE_TYPE_COLORS.white }),
|
|
37
|
+
/* @__PURE__ */ jsx(
|
|
38
|
+
"path",
|
|
39
|
+
{
|
|
40
|
+
d: "M12 17v2.5",
|
|
41
|
+
stroke: FILE_TYPE_COLORS.white,
|
|
42
|
+
strokeWidth: "1.2",
|
|
43
|
+
strokeLinecap: "round"
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
export {
|
|
51
|
+
PresIcon
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=PresIcon.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/icons/PresIcon.tsx"],
|
|
4
|
+
"sourcesContent": ["/** Presentation file icon (fuchsia, a slide on it): a saved ARBI presentation, told apart from a PDF. */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface IconProps {\n size?: number\n className?: string\n}\n\nexport const PresIcon: React.FC<IconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.pres}\n stroke={FILE_TYPE_COLORS.pres}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n {/* A slide on a stand. */}\n <rect x=\"7\" y=\"11\" width=\"10\" height=\"6\" rx=\"0.75\" fill={FILE_TYPE_COLORS.white} />\n <path\n d=\"M12 17v2.5\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1.2\"\n strokeLinecap=\"round\"\n />\n </svg>\n )\n}\n"],
|
|
5
|
+
"mappings": "AAYI,SAQE,KARF;AATJ,SAAS,wBAAwB;AAO1B,MAAM,WAAgC,CAAC,EAAE,OAAO,IAAI,YAAY,GAAG,MAAM;AAC9E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN;AAAA,MAEA;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAM,iBAAiB;AAAA,YACvB,QAAQ,iBAAiB;AAAA,YACzB,aAAY;AAAA,YACZ,eAAc;AAAA,YACd,gBAAe;AAAA;AAAA,QACjB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA,YACL,QAAQ,iBAAiB;AAAA,YACzB,aAAY;AAAA,YACZ,eAAc;AAAA,YACd,gBAAe;AAAA;AAAA,QACjB;AAAA,QAEA,oBAAC,UAAK,GAAE,KAAI,GAAE,MAAK,OAAM,MAAK,QAAO,KAAI,IAAG,QAAO,MAAM,iBAAiB,OAAO;AAAA,QACjF;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,QAAQ,iBAAiB;AAAA,YACzB,aAAY;AAAA,YACZ,eAAc;AAAA;AAAA,QAChB;AAAA;AAAA;AAAA,EACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/icons/colors.js
CHANGED
package/dist/icons/colors.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/icons/colors.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * File-type icon colors \u2014 the subset of the app's FILE_TYPE_COLORS used by the\n * promoted file-type icons. Kept self-contained so the SDK icons render with the\n * same palette as the ARBI app without depending on the app's style constants.\n */\n\nconst NEUTRAL_GRAY = '#64748b' // slate-500\n\nexport const FILE_TYPE_COLORS = {\n pdf: '#ef4444', // red\n doc: '#3b82f6', // blue (Word docs)\n docx: '#3b82f6', // blue\n html: '#0284c7', // sky-600 (web files)\n img: '#8b5cf6', // violet-500 (images)\n vid: '#10b981', // emerald-500 (video)\n aud: '#f59e0b', // amber-500 (audio)\n xls: '#16a34a', // green-600 (Excel)\n eml: '#0d9488', // teal-600 (email)\n txt: NEUTRAL_GRAY, // gray (plain text)\n generic: NEUTRAL_GRAY, // gray (unknown)\n white: '#ffffff', // for strokes/text on colored backgrounds\n}\n"],
|
|
5
|
-
"mappings": "AAMA,MAAM,eAAe;AAEd,MAAM,mBAAmB;AAAA,EAC9B,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,MAAM;AAAA;AAAA,EACN,MAAM;AAAA;AAAA,EACN,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,SAAS;AAAA;AAAA,EACT,OAAO;AAAA;AACT;",
|
|
4
|
+
"sourcesContent": ["/**\n * File-type icon colors \u2014 the subset of the app's FILE_TYPE_COLORS used by the\n * promoted file-type icons. Kept self-contained so the SDK icons render with the\n * same palette as the ARBI app without depending on the app's style constants.\n */\n\nconst NEUTRAL_GRAY = '#64748b' // slate-500\n\nexport const FILE_TYPE_COLORS = {\n pdf: '#ef4444', // red\n doc: '#3b82f6', // blue (Word docs)\n docx: '#3b82f6', // blue\n html: '#0284c7', // sky-600 (web files)\n img: '#8b5cf6', // violet-500 (images)\n vid: '#10b981', // emerald-500 (video)\n aud: '#f59e0b', // amber-500 (audio)\n xls: '#16a34a', // green-600 (Excel)\n eml: '#0d9488', // teal-600 (email)\n pres: '#c026d3', // fuchsia-600 (presentations)\n txt: NEUTRAL_GRAY, // gray (plain text)\n generic: NEUTRAL_GRAY, // gray (unknown)\n white: '#ffffff', // for strokes/text on colored backgrounds\n}\n"],
|
|
5
|
+
"mappings": "AAMA,MAAM,eAAe;AAEd,MAAM,mBAAmB;AAAA,EAC9B,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,MAAM;AAAA;AAAA,EACN,MAAM;AAAA;AAAA,EACN,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,MAAM;AAAA;AAAA,EACN,KAAK;AAAA;AAAA,EACL,SAAS;AAAA;AAAA,EACT,OAAO;AAAA;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/icons/file-type.js
CHANGED
|
@@ -4,6 +4,8 @@ import { EmlIcon } from "./EmlIcon.js";
|
|
|
4
4
|
import { HtmlIcon } from "./HtmlIcon.js";
|
|
5
5
|
import { ImgIcon } from "./ImgIcon.js";
|
|
6
6
|
import { PdfIcon } from "./PdfIcon.js";
|
|
7
|
+
import { PresIcon } from "./PresIcon.js";
|
|
8
|
+
import { isPresentationFileName } from "../entities/file-type.js";
|
|
7
9
|
import { VidIcon } from "./VidIcon.js";
|
|
8
10
|
import { XlsIcon } from "./XlsIcon.js";
|
|
9
11
|
import { FileText } from "lucide-react";
|
|
@@ -95,6 +97,7 @@ function iconFromMime(mime) {
|
|
|
95
97
|
return null;
|
|
96
98
|
}
|
|
97
99
|
function getFileTypeIcon(fileName, opts) {
|
|
100
|
+
if (isPresentationFileName(fileName, opts?.folder)) return PresIcon;
|
|
98
101
|
return iconFromExtension(getFileExtension(fileName)) ?? (opts?.mime ? iconFromMime(opts.mime) : null) ?? (opts?.defaultToPdf ? PdfIcon : TextIcon);
|
|
99
102
|
}
|
|
100
103
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/icons/file-type.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Maps a file name (by extension) to the matching branded file-type icon\n * component. Single source of truth so the document grid, navigator, and the\n * file-explorer view all show identical icons.\n *\n * The icon components share a `{ size?, className? }` signature, so callers can\n * render the returned component at any size.\n */\n\nimport { AudIcon } from './AudIcon'\nimport { DocIcon } from './DocIcon'\nimport { EmlIcon } from './EmlIcon'\nimport { HtmlIcon } from './HtmlIcon'\nimport { ImgIcon } from './ImgIcon'\nimport { PdfIcon } from './PdfIcon'\nimport { VidIcon } from './VidIcon'\nimport { XlsIcon } from './XlsIcon'\nimport type { ComponentType } from 'react'\nimport { FileText } from 'lucide-react'\n\nexport type FileTypeIcon = ComponentType<{ size?: number; className?: string }>\n\n/**\n * Neutral document icon for plain-text files and anything otherwise\n * unrecognised. Inherits `currentColor`, so callers can tint it (e.g.\n * `text-muted-foreground`); a friendlier explorer fallback than a \"?\" glyph.\n */\nconst TextIcon: FileTypeIcon = FileText\n\nconst IMAGE_EXTENSIONS = new Set(['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tif', 'webp', 'svg'])\nconst VIDEO_EXTENSIONS = new Set(['mp4', 'mpeg', 'mpg', 'webm', 'mov', 'avi', 'mkv'])\nconst AUDIO_EXTENSIONS = new Set(['mp3', 'wav', 'm4a', 'aac', 'ogg', 'flac'])\nconst DOCX_EXTENSIONS = new Set(['doc', 'docx', 'odt', 'rtf'])\nconst XLSX_EXTENSIONS = new Set(['xls', 'xlsx', 'csv', 'ods'])\nconst EMAIL_EXTENSIONS = new Set(['eml', 'msg'])\nconst HTML_EXTENSIONS = new Set(['html', 'htm', 'mhtml'])\nconst PDF_EXTENSIONS = new Set(['pdf'])\nconst TEXT_EXTENSIONS = new Set([\n 'txt',\n 'text',\n 'md',\n 'markdown',\n 'log',\n 'json',\n 'xml',\n 'yaml',\n 'yml',\n])\n\n/** Lower-cased extension (without the dot), or '' when there is none. */\nexport function getFileExtension(fileName?: string | null): string {\n if (!fileName) return ''\n const dot = fileName.lastIndexOf('.')\n if (dot <= 0 || dot === fileName.length - 1) return ''\n return fileName.slice(dot + 1).toLowerCase()\n}\n\n/** Canonical extensions for the MIME types we expect from the backend. */\nconst MIME_TO_EXTENSION: Record<string, string> = {\n 'application/pdf': 'pdf',\n 'text/plain': 'txt',\n 'text/markdown': 'md',\n 'text/html': 'html',\n 'text/csv': 'csv',\n 'application/json': 'json',\n 'application/xml': 'xml',\n 'application/msword': 'doc',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',\n 'application/rtf': 'rtf',\n 'application/vnd.oasis.opendocument.text': 'odt',\n 'application/vnd.ms-excel': 'xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',\n 'application/vnd.oasis.opendocument.spreadsheet': 'ods',\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/gif': 'gif',\n 'image/webp': 'webp',\n 'image/svg+xml': 'svg',\n 'image/tiff': 'tiff',\n 'image/bmp': 'bmp',\n 'video/mp4': 'mp4',\n 'video/webm': 'webm',\n 'video/quicktime': 'mov',\n 'audio/mpeg': 'mp3',\n 'audio/wav': 'wav',\n 'audio/ogg': 'ogg',\n 'message/rfc822': 'eml',\n}\n\n/**\n * Best-effort file extension (no dot) for a MIME type, or '' when unknown.\n * Used to surface the real extension for documents stored with a display title\n * that has none.\n */\nexport function extensionFromMime(mime?: string | null): string {\n if (!mime) return ''\n return MIME_TO_EXTENSION[mime.toLowerCase()] ?? ''\n}\n\n/** Icon from a file extension, or null when the extension isn't recognised. */\nfunction iconFromExtension(ext: string): FileTypeIcon | null {\n if (VIDEO_EXTENSIONS.has(ext)) return VidIcon\n if (AUDIO_EXTENSIONS.has(ext)) return AudIcon\n if (IMAGE_EXTENSIONS.has(ext)) return ImgIcon\n if (DOCX_EXTENSIONS.has(ext)) return DocIcon\n if (XLSX_EXTENSIONS.has(ext)) return XlsIcon\n if (EMAIL_EXTENSIONS.has(ext)) return EmlIcon\n if (HTML_EXTENSIONS.has(ext)) return HtmlIcon\n if (PDF_EXTENSIONS.has(ext)) return PdfIcon\n if (TEXT_EXTENSIONS.has(ext)) return TextIcon\n return null\n}\n\n/**\n * Icon from a MIME type, or null when unrecognised. Used as a fallback for\n * documents whose stored `file_name` carries no extension (common when a\n * display title is used instead).\n */\nfunction iconFromMime(mime: string): FileTypeIcon | null {\n const m = mime.toLowerCase()\n if (m.startsWith('image/')) return ImgIcon\n if (m.startsWith('video/')) return VidIcon\n if (m.startsWith('audio/')) return AudIcon\n if (m === 'application/pdf') return PdfIcon\n if (m === 'text/html') return HtmlIcon\n if (m === 'message/rfc822' || m.includes('outlook')) return EmlIcon\n if (m.includes('word') || m === 'application/rtf' || m.includes('opendocument.text'))\n return DocIcon\n if (\n m.includes('sheet') ||\n m.includes('excel') ||\n m === 'text/csv' ||\n m.includes('opendocument.spreadsheet')\n )\n return XlsIcon\n if (m.startsWith('text/') || m === 'application/json' || m === 'application/xml') return TextIcon\n return null\n}\n\n/**\n * Returns the icon component for a document.\n *\n * Resolution order: file-name extension \u2192 MIME `file_type` \u2192 fallback. This\n * mirrors how documents are stored \u2014 many carry a display title without an\n * extension, so the MIME type is the reliable signal.\n *\n * @param fileName the document file name (uses its extension)\n * @param opts.mime the document `file_type` (MIME), used when the name has no\n * recognised extension\n * @param opts.defaultToPdf when true, an unresolved type falls back to the PDF\n * icon (preserves legacy grid/navigator behaviour). Defaults to the neutral\n * generic file icon.\n */\nexport function getFileTypeIcon(\n fileName?: string | null,\n opts?: { mime?: string | null; defaultToPdf?: boolean }\n): FileTypeIcon {\n return (\n iconFromExtension(getFileExtension(fileName)) ??\n (opts?.mime ? iconFromMime(opts.mime) : null) ??\n (opts?.defaultToPdf ? PdfIcon : TextIcon)\n )\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Maps a file name (by extension) to the matching branded file-type icon\n * component. Single source of truth so the document grid, navigator, and the\n * file-explorer view all show identical icons.\n *\n * The icon components share a `{ size?, className? }` signature, so callers can\n * render the returned component at any size.\n */\n\nimport { AudIcon } from './AudIcon'\nimport { DocIcon } from './DocIcon'\nimport { EmlIcon } from './EmlIcon'\nimport { HtmlIcon } from './HtmlIcon'\nimport { ImgIcon } from './ImgIcon'\nimport { PdfIcon } from './PdfIcon'\nimport { PresIcon } from './PresIcon'\nimport { isPresentationFileName } from '../entities/file-type'\nimport { VidIcon } from './VidIcon'\nimport { XlsIcon } from './XlsIcon'\nimport type { ComponentType } from 'react'\nimport { FileText } from 'lucide-react'\n\nexport type FileTypeIcon = ComponentType<{ size?: number; className?: string }>\n\n/**\n * Neutral document icon for plain-text files and anything otherwise\n * unrecognised. Inherits `currentColor`, so callers can tint it (e.g.\n * `text-muted-foreground`); a friendlier explorer fallback than a \"?\" glyph.\n */\nconst TextIcon: FileTypeIcon = FileText\n\nconst IMAGE_EXTENSIONS = new Set(['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tif', 'webp', 'svg'])\nconst VIDEO_EXTENSIONS = new Set(['mp4', 'mpeg', 'mpg', 'webm', 'mov', 'avi', 'mkv'])\nconst AUDIO_EXTENSIONS = new Set(['mp3', 'wav', 'm4a', 'aac', 'ogg', 'flac'])\nconst DOCX_EXTENSIONS = new Set(['doc', 'docx', 'odt', 'rtf'])\nconst XLSX_EXTENSIONS = new Set(['xls', 'xlsx', 'csv', 'ods'])\nconst EMAIL_EXTENSIONS = new Set(['eml', 'msg'])\nconst HTML_EXTENSIONS = new Set(['html', 'htm', 'mhtml'])\nconst PDF_EXTENSIONS = new Set(['pdf'])\nconst TEXT_EXTENSIONS = new Set([\n 'txt',\n 'text',\n 'md',\n 'markdown',\n 'log',\n 'json',\n 'xml',\n 'yaml',\n 'yml',\n])\n\n/** Lower-cased extension (without the dot), or '' when there is none. */\nexport function getFileExtension(fileName?: string | null): string {\n if (!fileName) return ''\n const dot = fileName.lastIndexOf('.')\n if (dot <= 0 || dot === fileName.length - 1) return ''\n return fileName.slice(dot + 1).toLowerCase()\n}\n\n/** Canonical extensions for the MIME types we expect from the backend. */\nconst MIME_TO_EXTENSION: Record<string, string> = {\n 'application/pdf': 'pdf',\n 'text/plain': 'txt',\n 'text/markdown': 'md',\n 'text/html': 'html',\n 'text/csv': 'csv',\n 'application/json': 'json',\n 'application/xml': 'xml',\n 'application/msword': 'doc',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',\n 'application/rtf': 'rtf',\n 'application/vnd.oasis.opendocument.text': 'odt',\n 'application/vnd.ms-excel': 'xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',\n 'application/vnd.oasis.opendocument.spreadsheet': 'ods',\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/gif': 'gif',\n 'image/webp': 'webp',\n 'image/svg+xml': 'svg',\n 'image/tiff': 'tiff',\n 'image/bmp': 'bmp',\n 'video/mp4': 'mp4',\n 'video/webm': 'webm',\n 'video/quicktime': 'mov',\n 'audio/mpeg': 'mp3',\n 'audio/wav': 'wav',\n 'audio/ogg': 'ogg',\n 'message/rfc822': 'eml',\n}\n\n/**\n * Best-effort file extension (no dot) for a MIME type, or '' when unknown.\n * Used to surface the real extension for documents stored with a display title\n * that has none.\n */\nexport function extensionFromMime(mime?: string | null): string {\n if (!mime) return ''\n return MIME_TO_EXTENSION[mime.toLowerCase()] ?? ''\n}\n\n/** Icon from a file extension, or null when the extension isn't recognised. */\nfunction iconFromExtension(ext: string): FileTypeIcon | null {\n if (VIDEO_EXTENSIONS.has(ext)) return VidIcon\n if (AUDIO_EXTENSIONS.has(ext)) return AudIcon\n if (IMAGE_EXTENSIONS.has(ext)) return ImgIcon\n if (DOCX_EXTENSIONS.has(ext)) return DocIcon\n if (XLSX_EXTENSIONS.has(ext)) return XlsIcon\n if (EMAIL_EXTENSIONS.has(ext)) return EmlIcon\n if (HTML_EXTENSIONS.has(ext)) return HtmlIcon\n if (PDF_EXTENSIONS.has(ext)) return PdfIcon\n if (TEXT_EXTENSIONS.has(ext)) return TextIcon\n return null\n}\n\n/**\n * Icon from a MIME type, or null when unrecognised. Used as a fallback for\n * documents whose stored `file_name` carries no extension (common when a\n * display title is used instead).\n */\nfunction iconFromMime(mime: string): FileTypeIcon | null {\n const m = mime.toLowerCase()\n if (m.startsWith('image/')) return ImgIcon\n if (m.startsWith('video/')) return VidIcon\n if (m.startsWith('audio/')) return AudIcon\n if (m === 'application/pdf') return PdfIcon\n if (m === 'text/html') return HtmlIcon\n if (m === 'message/rfc822' || m.includes('outlook')) return EmlIcon\n if (m.includes('word') || m === 'application/rtf' || m.includes('opendocument.text'))\n return DocIcon\n if (\n m.includes('sheet') ||\n m.includes('excel') ||\n m === 'text/csv' ||\n m.includes('opendocument.spreadsheet')\n )\n return XlsIcon\n if (m.startsWith('text/') || m === 'application/json' || m === 'application/xml') return TextIcon\n return null\n}\n\n/**\n * Returns the icon component for a document.\n *\n * Resolution order: file-name extension \u2192 MIME `file_type` \u2192 fallback. This\n * mirrors how documents are stored \u2014 many carry a display title without an\n * extension, so the MIME type is the reliable signal.\n *\n * @param fileName the document file name (uses its extension)\n * @param opts.mime the document `file_type` (MIME), used when the name has no\n * recognised extension\n * @param opts.defaultToPdf when true, an unresolved type falls back to the PDF\n * icon (preserves legacy grid/navigator behaviour). Defaults to the neutral\n * generic file icon.\n */\nexport function getFileTypeIcon(\n fileName?: string | null,\n opts?: { mime?: string | null; defaultToPdf?: boolean; folder?: string | null }\n): FileTypeIcon {\n // A saved presentation is a PDF by extension: its folder (or an older name) says what it is.\n if (isPresentationFileName(fileName, opts?.folder)) return PresIcon\n return (\n iconFromExtension(getFileExtension(fileName)) ??\n (opts?.mime ? iconFromMime(opts.mime) : null) ??\n (opts?.defaultToPdf ? PdfIcon : TextIcon)\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/icons/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PdfIcon } from "./PdfIcon.js";
|
|
2
|
+
import { PresIcon } from "./PresIcon.js";
|
|
2
3
|
import { DocIcon } from "./DocIcon.js";
|
|
3
4
|
import { HtmlIcon } from "./HtmlIcon.js";
|
|
4
5
|
import { TxtIcon } from "./TxtIcon.js";
|
|
@@ -44,6 +45,7 @@ export {
|
|
|
44
45
|
LinkedInIcon,
|
|
45
46
|
OpenAIIcon,
|
|
46
47
|
PdfIcon,
|
|
48
|
+
PresIcon,
|
|
47
49
|
ProviderIcon,
|
|
48
50
|
TxtIcon,
|
|
49
51
|
VidIcon,
|
package/dist/icons/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/icons/index.ts"],
|
|
4
|
-
"sourcesContent": ["// File-type icons\nexport { PdfIcon } from './PdfIcon'\nexport { DocIcon } from './DocIcon'\nexport { HtmlIcon } from './HtmlIcon'\nexport { TxtIcon } from './TxtIcon'\nexport { XlsIcon } from './XlsIcon'\nexport { AudIcon } from './AudIcon'\nexport { ImgIcon } from './ImgIcon'\nexport { VidIcon } from './VidIcon'\nexport { EmlIcon } from './EmlIcon'\nexport { FILE_TYPE_COLORS } from './colors'\nexport {\n getFileTypeIcon,\n getFileExtension,\n extensionFromMime,\n type FileTypeIcon,\n} from './file-type'\n\n// Brand / provider icons\nexport { AppleIcon } from './AppleIcon'\nexport { GoogleIcon } from './GoogleIcon'\nexport { GitHubIcon } from './GitHubIcon'\nexport { LinkedInIcon } from './LinkedInIcon'\nexport { OpenAIIcon } from './OpenAIIcon'\nexport { ClaudeIcon } from './ClaudeIcon'\nexport { GeminiIcon } from './GeminiIcon'\nexport { FireworksIcon } from './FireworksIcon'\nexport { ProviderIcon } from './ProviderIcon'\n\n// ARBI brand marks\nexport { ArbiIcon } from './ArbiIcon'\nexport { ARBI_MARK_SRC } from './arbi-mark'\nexport { ArbiBotHeadIcon } from './ArbiBotHeadIcon'\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAG7B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;",
|
|
4
|
+
"sourcesContent": ["// File-type icons\nexport { PdfIcon } from './PdfIcon'\nexport { PresIcon } from './PresIcon'\nexport { DocIcon } from './DocIcon'\nexport { HtmlIcon } from './HtmlIcon'\nexport { TxtIcon } from './TxtIcon'\nexport { XlsIcon } from './XlsIcon'\nexport { AudIcon } from './AudIcon'\nexport { ImgIcon } from './ImgIcon'\nexport { VidIcon } from './VidIcon'\nexport { EmlIcon } from './EmlIcon'\nexport { FILE_TYPE_COLORS } from './colors'\nexport {\n getFileTypeIcon,\n getFileExtension,\n extensionFromMime,\n type FileTypeIcon,\n} from './file-type'\n\n// Brand / provider icons\nexport { AppleIcon } from './AppleIcon'\nexport { GoogleIcon } from './GoogleIcon'\nexport { GitHubIcon } from './GitHubIcon'\nexport { LinkedInIcon } from './LinkedInIcon'\nexport { OpenAIIcon } from './OpenAIIcon'\nexport { ClaudeIcon } from './ClaudeIcon'\nexport { GeminiIcon } from './GeminiIcon'\nexport { FireworksIcon } from './FireworksIcon'\nexport { ProviderIcon } from './ProviderIcon'\n\n// ARBI brand marks\nexport { ArbiIcon } from './ArbiIcon'\nexport { ARBI_MARK_SRC } from './arbi-mark'\nexport { ArbiBotHeadIcon } from './ArbiBotHeadIcon'\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAG7B,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|