@pdfme/schemas 6.2.3-dev.6 → 6.2.3-dev.8
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/{builtins-Dtp1IM7M.js → builtins-Ch7UBNGU.js} +4 -4
- package/dist/{builtins-Dtp1IM7M.js.map → builtins-Ch7UBNGU.js.map} +1 -1
- package/dist/builtins.js +1 -1
- package/dist/dynamicLayout.js +1 -1
- package/dist/{dynamicTemplate-Zqt6kNsE.js → dynamicTemplate-Bnu4jVaz.js} +501 -51
- package/dist/dynamicTemplate-Bnu4jVaz.js.map +1 -0
- package/dist/graphics/imagehelper.d.ts +6 -1
- package/dist/index.js +906 -248
- package/dist/index.js.map +1 -1
- package/dist/tables/classes.d.ts +5 -3
- package/dist/tables/columnsWidget.d.ts +2 -0
- package/dist/tables/constants.d.ts +5 -0
- package/dist/tables/helper.d.ts +0 -12
- package/dist/tables/imageCell.d.ts +27 -0
- package/dist/tables/imageCellUi.d.ts +19 -0
- package/dist/tables/types.d.ts +28 -1
- package/dist/tables.js +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{utils-DvBaBoME.js → utils-BfzehhiZ.js} +2 -2
- package/dist/{utils-DvBaBoME.js.map → utils-BfzehhiZ.js.map} +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/dist/dynamicTemplate-Zqt6kNsE.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { D as getBoxContentArea, E as createBoxDimension, L as CODE_BACKGROUND_COLOR, V as DEFAULT_FONT_COLOR, X as PLACEHOLDER_FONT_COLOR, Z as SYNTHETIC_BOLD_CSS_TEXT_SHADOW, a as createListItemSplitRange, c as getListItemRange, g as getFontKitFont, i as TEXT_LINE_SPLIT_UNIT, it as VERTICAL_ALIGN_MIDDLE, l as getTableBodyRange, n as LIST_ITEM_SPLIT_UNIT, o as createTableBodySplitRange, r as TABLE_BODY_SPLIT_UNIT, s as createTextLineSplitRange, t as BUILT_IN_DYNAMIC_LAYOUT_SPLIT_UNITS, u as getTextLineRange, z as DEFAULT_ALIGNMENT } from "./splitRange-B6311Noc.js";
|
|
2
2
|
import { a as measureTextLines, f as resolveFontVariant, h as parseInlineMarkdown, u as isInlineMarkdownTextSchema } from "./measure-BarlRI1L.js";
|
|
3
|
-
import { a as mapVerticalAlignToFlex, c as Formatter, d as
|
|
4
|
-
import { a as getCellPropPanelSchema, c as
|
|
5
|
-
import { a as createSvgStr, d as rgbColorToCmykColor, f as rotatePoint, g as visitVariables, h as getVariableNames, i as createErrorElm, l as isEditable, m as countUniqueVariableNames, n as applyAlphaToOpacity, p as splitHexAlpha, r as convertForPdfLayoutProps, s as hex2PrintingColor, t as addAlphaToHex, u as readFile } from "./utils-
|
|
3
|
+
import { _ as embedAndGetFont, a as mapVerticalAlignToFlex, c as Formatter, d as TextAlignLeftIcon, f as TextAlignRightIcon, g as pdfRender$4, h as TextVerticalAlignTopIcon, i as makeElementPlainTextContentEditable, l as getExtraFormatterSchema, m as TextVerticalAlignMiddleIcon, n as textSchema, o as uiRender$4, p as TextVerticalAlignBottomIcon, r as buildStyledTextContainer, s as propPanel$3, t as builtInPlugins, u as TextAlignCenterIcon } from "./builtins-Ch7UBNGU.js";
|
|
4
|
+
import { C as hashImageDataUrl, S as normalizeImageOrientation, _ as TABLE_CELL_TYPES, a as getCellPropPanelSchema, b as TABLE_IMAGE_DATA_URL_PATTERN, c as HEX_COLOR_PATTERN, d as getTableImageObjectPosition, f as normalizeTableCellType, g as warnInvalidTableImageOnce, h as resolveImageDimension, i as getBodyWithSchemaRange, l as OPAQUE_HEX_COLOR_PATTERN, m as resolveFixedTableImageHeight, n as getDynamicLayoutForTable, o as getDefaultCellStyles, p as normalizeTableImageHeightMode, r as getBody, s as remapColumnStylesOnRemove, t as getDynamicHeightsForTable, u as createSingleTable, v as TABLE_IMAGE_HEIGHT_MODES, x as detectImageFormat, y as DEFAULT_TABLE_IMAGE_HEIGHT_MODE } from "./dynamicTemplate-Bnu4jVaz.js";
|
|
5
|
+
import { a as createSvgStr, d as rgbColorToCmykColor, f as rotatePoint, g as visitVariables, h as getVariableNames, i as createErrorElm, l as isEditable, m as countUniqueVariableNames, n as applyAlphaToOpacity, p as splitHexAlpha, r as convertForPdfLayoutProps, s as hex2PrintingColor, t as addAlphaToHex, u as readFile } from "./utils-BfzehhiZ.js";
|
|
6
6
|
import { a as normalizeListItems, c as LIST_STYLE_BULLET, i as normalizeListItemEntries, l as LIST_STYLE_ORDERED, n as calculateListLayout, o as serializeListItems, s as DEFAULT_LIST_STYLE, t as getDynamicLayoutForList } from "./dynamicTemplate-CcnCXHfM.js";
|
|
7
7
|
import { i as validateVariables, n as substituteVariables, r as substituteVariablesAsInlineMarkdownLiterals, t as resolveReadOnlyMultiVariableText } from "./helper-BR4_UZA5.js";
|
|
8
8
|
import "./tables.js";
|
|
9
9
|
import "./lists.js";
|
|
10
|
-
import { DEFAULT_FONT_NAME, ZOOM, b64toUint8Array, getDefaultFont, getFallbackFontName, getInternalLinkTarget, isHexValid, mm2pt, normalizeLinkHref, px2mm } from "@pdfme/common";
|
|
10
|
+
import { DEFAULT_FONT_NAME, ZOOM, b64toUint8Array, cloneDeep, getDefaultFont, getFallbackFontName, getInternalLinkTarget, isHexValid, mm2pt, normalizeLinkHref, px2mm } from "@pdfme/common";
|
|
11
11
|
import { Buffer as Buffer$1 } from "buffer";
|
|
12
12
|
import { popGraphicsState, pushGraphicsState, rotateDegrees, translate } from "@pdfme/pdf-lib";
|
|
13
13
|
import { Barcode, Calendar, CalendarClock, ChevronDown, Circle, CircleDot, Clock, Image, List, Minus, QrCode, Route, Square, SquareCheck, Table, Type } from "lucide";
|
|
14
|
-
import jpegJsModule from "jpeg-js";
|
|
15
|
-
import UPNGModule from "@pdf-lib/upng";
|
|
16
14
|
import DOMPurify from "dompurify";
|
|
17
15
|
import bwipjs from "bwip-js";
|
|
18
16
|
import AirDatepicker from "air-datepicker";
|
|
@@ -1412,210 +1410,6 @@ var listSchema = {
|
|
|
1412
1410
|
icon: createSvgStr(List)
|
|
1413
1411
|
};
|
|
1414
1412
|
//#endregion
|
|
1415
|
-
//#region src/graphics/orientation.ts
|
|
1416
|
-
var isJpegJsApi = (value) => !!value && typeof value === "object" && typeof value.decode === "function" && typeof value.encode === "function";
|
|
1417
|
-
var isUPNGApi = (value) => !!value && typeof value === "object" && typeof value.decode === "function" && typeof value.toRGBA8 === "function" && typeof value.encode === "function";
|
|
1418
|
-
var resolveExport = (value, guard, label) => {
|
|
1419
|
-
let current = value;
|
|
1420
|
-
while (current && typeof current === "object") {
|
|
1421
|
-
if (guard(current)) return current;
|
|
1422
|
-
current = current.default;
|
|
1423
|
-
}
|
|
1424
|
-
throw new TypeError(`Failed to resolve ${label} exports`);
|
|
1425
|
-
};
|
|
1426
|
-
var jpegJs = resolveExport(jpegJsModule, isJpegJsApi, "jpeg-js");
|
|
1427
|
-
var UPNG = resolveExport(UPNGModule, isUPNGApi, "@pdf-lib/upng");
|
|
1428
|
-
var JPEG_ENCODE_QUALITY = 90;
|
|
1429
|
-
var JPEG_MAX_MEMORY_MB = 512;
|
|
1430
|
-
var JPEG_SOI_0 = 255;
|
|
1431
|
-
var JPEG_SOI_1 = 216;
|
|
1432
|
-
var PNG_SIGNATURE = new Uint8Array([
|
|
1433
|
-
137,
|
|
1434
|
-
80,
|
|
1435
|
-
78,
|
|
1436
|
-
71,
|
|
1437
|
-
13,
|
|
1438
|
-
10,
|
|
1439
|
-
26,
|
|
1440
|
-
10
|
|
1441
|
-
]);
|
|
1442
|
-
var toArrayBuffer = (bytes) => {
|
|
1443
|
-
const copy = new Uint8Array(bytes.byteLength);
|
|
1444
|
-
copy.set(bytes);
|
|
1445
|
-
return copy.buffer;
|
|
1446
|
-
};
|
|
1447
|
-
var isPngSignature = (bytes) => {
|
|
1448
|
-
if (bytes.length < PNG_SIGNATURE.length) return false;
|
|
1449
|
-
for (let i = 0; i < PNG_SIGNATURE.length; i++) if (bytes[i] !== PNG_SIGNATURE[i]) return false;
|
|
1450
|
-
return true;
|
|
1451
|
-
};
|
|
1452
|
-
var detectImageFormat = (bytes) => {
|
|
1453
|
-
if (bytes.length >= 2 && bytes[0] === JPEG_SOI_0 && bytes[1] === JPEG_SOI_1) return "jpeg";
|
|
1454
|
-
if (isPngSignature(bytes)) return "png";
|
|
1455
|
-
return "other";
|
|
1456
|
-
};
|
|
1457
|
-
/** TIFF/IFD0: returns 1..8 or undefined. Never throws. */
|
|
1458
|
-
var parseTiffOrientation = (tiff) => {
|
|
1459
|
-
try {
|
|
1460
|
-
if (tiff.length < 8) return void 0;
|
|
1461
|
-
const le = tiff[0] === 73 && tiff[1] === 73;
|
|
1462
|
-
if (!le && !(tiff[0] === 77 && tiff[1] === 77)) return void 0;
|
|
1463
|
-
const view = new DataView(tiff.buffer, tiff.byteOffset, tiff.byteLength);
|
|
1464
|
-
if (view.getUint16(2, le) !== 42) return void 0;
|
|
1465
|
-
const ifd = view.getUint32(4, le);
|
|
1466
|
-
if (ifd + 2 > tiff.length) return void 0;
|
|
1467
|
-
const n = view.getUint16(ifd, le);
|
|
1468
|
-
for (let i = 0; i < n; i++) {
|
|
1469
|
-
const entry = ifd + 2 + i * 12;
|
|
1470
|
-
if (entry + 12 > tiff.length) return void 0;
|
|
1471
|
-
if (view.getUint16(entry, le) !== 274) continue;
|
|
1472
|
-
if (view.getUint16(entry + 2, le) !== 3) return void 0;
|
|
1473
|
-
if (view.getUint32(entry + 4, le) !== 1) return void 0;
|
|
1474
|
-
const val = view.getUint16(entry + 8, le);
|
|
1475
|
-
return val >= 1 && val <= 8 ? val : void 0;
|
|
1476
|
-
}
|
|
1477
|
-
return;
|
|
1478
|
-
} catch {
|
|
1479
|
-
return;
|
|
1480
|
-
}
|
|
1481
|
-
};
|
|
1482
|
-
var isExifApp1Payload = (segment) => segment.length >= 6 && segment[0] === 69 && segment[1] === 120 && segment[2] === 105 && segment[3] === 102 && segment[4] === 0 && segment[5] === 0;
|
|
1483
|
-
/** Standalone JPEG markers have no length field (TEM, RST0–7, SOI). */
|
|
1484
|
-
var isStandaloneJpegMarker = (marker) => marker === 1 || marker >= 208 && marker <= 216;
|
|
1485
|
-
/**
|
|
1486
|
-
* JPEG: scan APP1 'Exif\0\0' segments; stop at SOS/EOI.
|
|
1487
|
-
* Skips 0xFF fill/padding and standalone markers. If an Exif APP1 has no
|
|
1488
|
-
* valid Orientation, keep scanning for a later one.
|
|
1489
|
-
*/
|
|
1490
|
-
var getJpegOrientation = (bytes) => {
|
|
1491
|
-
if (bytes.length < 2 || bytes[0] !== JPEG_SOI_0 || bytes[1] !== JPEG_SOI_1) return void 0;
|
|
1492
|
-
let pos = 2;
|
|
1493
|
-
while (pos < bytes.length) {
|
|
1494
|
-
if (bytes[pos] !== 255) return void 0;
|
|
1495
|
-
while (pos < bytes.length && bytes[pos] === 255) pos++;
|
|
1496
|
-
if (pos >= bytes.length) return void 0;
|
|
1497
|
-
const marker = bytes[pos++];
|
|
1498
|
-
if (isStandaloneJpegMarker(marker)) continue;
|
|
1499
|
-
if (marker === 218 || marker === 217) return void 0;
|
|
1500
|
-
if (pos + 2 > bytes.length) return void 0;
|
|
1501
|
-
const size = bytes[pos] << 8 | bytes[pos + 1];
|
|
1502
|
-
if (size < 2 || pos + size > bytes.length) return void 0;
|
|
1503
|
-
if (marker === 225 && size >= 8) {
|
|
1504
|
-
const segment = bytes.subarray(pos + 2, pos + size);
|
|
1505
|
-
if (isExifApp1Payload(segment)) {
|
|
1506
|
-
const orientation = parseTiffOrientation(segment.subarray(6));
|
|
1507
|
-
if (orientation !== void 0) return orientation;
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
pos += size;
|
|
1511
|
-
}
|
|
1512
|
-
};
|
|
1513
|
-
/**
|
|
1514
|
-
* PNG: scan chunks for eXIf (raw TIFF payload). Skip IDAT and other
|
|
1515
|
-
* ancillary chunks; eXIf may appear after image data. Stop at IEND.
|
|
1516
|
-
*/
|
|
1517
|
-
var getPngOrientation = (bytes) => {
|
|
1518
|
-
if (!isPngSignature(bytes)) return void 0;
|
|
1519
|
-
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1520
|
-
let pos = 8;
|
|
1521
|
-
while (pos + 12 <= bytes.length) {
|
|
1522
|
-
const length = view.getUint32(pos);
|
|
1523
|
-
if (pos + 12 + length > bytes.length) return void 0;
|
|
1524
|
-
const type = String.fromCharCode(bytes[pos + 4], bytes[pos + 5], bytes[pos + 6], bytes[pos + 7]);
|
|
1525
|
-
if (type === "eXIf") return parseTiffOrientation(bytes.subarray(pos + 8, pos + 8 + length));
|
|
1526
|
-
if (type === "IEND") return void 0;
|
|
1527
|
-
pos += 12 + length;
|
|
1528
|
-
}
|
|
1529
|
-
};
|
|
1530
|
-
var orientationSwapsDimensions = (orientation) => orientation >= 5;
|
|
1531
|
-
/**
|
|
1532
|
-
* Map source (x, y) into destination (dx, dy) for EXIF orientations 2–8.
|
|
1533
|
-
* Orientations 5–8 swap width and height.
|
|
1534
|
-
*/
|
|
1535
|
-
var transformRgba = (src, width, height, orientation) => {
|
|
1536
|
-
const swap = orientationSwapsDimensions(orientation);
|
|
1537
|
-
const destWidth = swap ? height : width;
|
|
1538
|
-
const destHeight = swap ? width : height;
|
|
1539
|
-
const dest = new Uint8Array(destWidth * destHeight * 4);
|
|
1540
|
-
for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
|
|
1541
|
-
let dx = x;
|
|
1542
|
-
let dy = y;
|
|
1543
|
-
switch (orientation) {
|
|
1544
|
-
case 2:
|
|
1545
|
-
dx = width - 1 - x;
|
|
1546
|
-
dy = y;
|
|
1547
|
-
break;
|
|
1548
|
-
case 3:
|
|
1549
|
-
dx = width - 1 - x;
|
|
1550
|
-
dy = height - 1 - y;
|
|
1551
|
-
break;
|
|
1552
|
-
case 4:
|
|
1553
|
-
dx = x;
|
|
1554
|
-
dy = height - 1 - y;
|
|
1555
|
-
break;
|
|
1556
|
-
case 5:
|
|
1557
|
-
dx = y;
|
|
1558
|
-
dy = x;
|
|
1559
|
-
break;
|
|
1560
|
-
case 6:
|
|
1561
|
-
dx = height - 1 - y;
|
|
1562
|
-
dy = x;
|
|
1563
|
-
break;
|
|
1564
|
-
case 7:
|
|
1565
|
-
dx = height - 1 - y;
|
|
1566
|
-
dy = width - 1 - x;
|
|
1567
|
-
break;
|
|
1568
|
-
case 8:
|
|
1569
|
-
dx = y;
|
|
1570
|
-
dy = width - 1 - x;
|
|
1571
|
-
}
|
|
1572
|
-
const srcIndex = (y * width + x) * 4;
|
|
1573
|
-
const destIndex = (dy * destWidth + dx) * 4;
|
|
1574
|
-
dest[destIndex] = src[srcIndex];
|
|
1575
|
-
dest[destIndex + 1] = src[srcIndex + 1];
|
|
1576
|
-
dest[destIndex + 2] = src[srcIndex + 2];
|
|
1577
|
-
dest[destIndex + 3] = src[srcIndex + 3];
|
|
1578
|
-
}
|
|
1579
|
-
return {
|
|
1580
|
-
data: dest,
|
|
1581
|
-
width: destWidth,
|
|
1582
|
-
height: destHeight
|
|
1583
|
-
};
|
|
1584
|
-
};
|
|
1585
|
-
var bakeJpegOrientation = (bytes) => {
|
|
1586
|
-
const orientation = getJpegOrientation(bytes);
|
|
1587
|
-
if (!orientation || orientation === 1) return bytes;
|
|
1588
|
-
const raw = jpegJs.decode(bytes, {
|
|
1589
|
-
useTArray: true,
|
|
1590
|
-
formatAsRGBA: true,
|
|
1591
|
-
maxMemoryUsageInMB: JPEG_MAX_MEMORY_MB
|
|
1592
|
-
});
|
|
1593
|
-
const transformed = transformRgba(raw.data, raw.width, raw.height, orientation);
|
|
1594
|
-
return new Uint8Array(jpegJs.encode({
|
|
1595
|
-
data: transformed.data,
|
|
1596
|
-
width: transformed.width,
|
|
1597
|
-
height: transformed.height
|
|
1598
|
-
}, JPEG_ENCODE_QUALITY).data);
|
|
1599
|
-
};
|
|
1600
|
-
var bakePngOrientation = (bytes) => {
|
|
1601
|
-
const orientation = getPngOrientation(bytes);
|
|
1602
|
-
if (!orientation || orientation === 1) return bytes;
|
|
1603
|
-
const img = UPNG.decode(toArrayBuffer(bytes));
|
|
1604
|
-
const transformed = transformRgba(new Uint8Array(UPNG.toRGBA8(img)[0]), img.width, img.height, orientation);
|
|
1605
|
-
return new Uint8Array(UPNG.encode([toArrayBuffer(transformed.data)], transformed.width, transformed.height, 0));
|
|
1606
|
-
};
|
|
1607
|
-
/**
|
|
1608
|
-
* One normalize path for JPEG and PNG. Tag absent/1 is a byte-identical
|
|
1609
|
-
* passthrough. Tag 2–8 decodes, transforms pixels, and re-encodes without
|
|
1610
|
-
* an orientation tag. May throw on decode/encode failure — callers fall back.
|
|
1611
|
-
*/
|
|
1612
|
-
var normalizeImageOrientation = (bytes) => {
|
|
1613
|
-
const kind = detectImageFormat(bytes);
|
|
1614
|
-
if (kind === "jpeg") return bakeJpegOrientation(bytes);
|
|
1615
|
-
if (kind === "png") return bakePngOrientation(bytes);
|
|
1616
|
-
return bytes;
|
|
1617
|
-
};
|
|
1618
|
-
//#endregion
|
|
1619
1413
|
//#region src/graphics/image.ts
|
|
1620
1414
|
/**
|
|
1621
1415
|
* Build a short fingerprint for a potentially-large base64 image string.
|
|
@@ -1632,15 +1426,7 @@ var normalizeImageOrientation = (bytes) => {
|
|
|
1632
1426
|
* cost, without retaining any slice of the input as a Map key. Keys stay
|
|
1633
1427
|
* well under ~40 chars regardless of input size.
|
|
1634
1428
|
*/
|
|
1635
|
-
var getCacheKey = (schema, input) => {
|
|
1636
|
-
let hash = 2166136261;
|
|
1637
|
-
for (let i = 0; i < input.length; i++) {
|
|
1638
|
-
hash ^= input.charCodeAt(i);
|
|
1639
|
-
hash = Math.imul(hash, 16777619);
|
|
1640
|
-
}
|
|
1641
|
-
const hex = (hash >>> 0).toString(16).padStart(8, "0");
|
|
1642
|
-
return `${schema.type}:${input.length}:${hex}`;
|
|
1643
|
-
};
|
|
1429
|
+
var getCacheKey = (schema, input) => `${schema.type}:${input.length}:${hashImageDataUrl(input)}`;
|
|
1644
1430
|
var dataUrlToBytes = (value) => {
|
|
1645
1431
|
const idx = value.indexOf(";base64,");
|
|
1646
1432
|
const base64 = idx >= 0 ? value.slice(idx + 8) : value;
|
|
@@ -3000,7 +2786,154 @@ var lineSchema = {
|
|
|
3000
2786
|
icon: createSvgStr(Minus)
|
|
3001
2787
|
};
|
|
3002
2788
|
//#endregion
|
|
2789
|
+
//#region src/tables/imageCellUi.ts
|
|
2790
|
+
var buttonSize$1 = 18;
|
|
2791
|
+
var pendingImagePicker = null;
|
|
2792
|
+
var tableSchemaKey = (schema) => typeof schema.id === "string" && schema.id !== "" ? schema.id : schema.name;
|
|
2793
|
+
var noteRenderingTable = (schema) => {
|
|
2794
|
+
const schemaKey = tableSchemaKey(schema);
|
|
2795
|
+
if (pendingImagePicker && pendingImagePicker.schemaKey !== schemaKey) pendingImagePicker = null;
|
|
2796
|
+
};
|
|
2797
|
+
var clearImagePickerRequest = () => {
|
|
2798
|
+
pendingImagePicker = null;
|
|
2799
|
+
};
|
|
2800
|
+
var requestImagePicker = (request) => {
|
|
2801
|
+
pendingImagePicker = request;
|
|
2802
|
+
};
|
|
2803
|
+
var consumePendingImagePicker = (request) => {
|
|
2804
|
+
const pending = pendingImagePicker;
|
|
2805
|
+
if (!pending || pending.rowIndex !== request.rowIndex || pending.colIndex !== request.colIndex || pending.schemaKey !== request.schemaKey) return false;
|
|
2806
|
+
pendingImagePicker = null;
|
|
2807
|
+
return true;
|
|
2808
|
+
};
|
|
2809
|
+
var createImageButton = (options) => {
|
|
2810
|
+
const button = document.createElement("button");
|
|
2811
|
+
button.type = "button";
|
|
2812
|
+
button.innerText = options.text;
|
|
2813
|
+
button.setAttribute("aria-label", options.ariaLabel);
|
|
2814
|
+
button.title = options.ariaLabel;
|
|
2815
|
+
button.style.width = `${buttonSize$1}px`;
|
|
2816
|
+
button.style.height = `${buttonSize$1}px`;
|
|
2817
|
+
button.style.position = "absolute";
|
|
2818
|
+
button.style.top = "0px";
|
|
2819
|
+
button.style.right = options.right;
|
|
2820
|
+
button.style.display = "inline-flex";
|
|
2821
|
+
button.style.alignItems = "center";
|
|
2822
|
+
button.style.justifyContent = "center";
|
|
2823
|
+
button.style.padding = "0";
|
|
2824
|
+
button.style.border = "1px solid #d9d9d9";
|
|
2825
|
+
button.style.borderRadius = "3px";
|
|
2826
|
+
button.style.background = "#ffffff";
|
|
2827
|
+
button.style.color = "#333333";
|
|
2828
|
+
button.style.fontSize = "11px";
|
|
2829
|
+
button.style.lineHeight = "1";
|
|
2830
|
+
button.style.cursor = "pointer";
|
|
2831
|
+
button.style.zIndex = "20";
|
|
2832
|
+
button.addEventListener("mousedown", (event) => {
|
|
2833
|
+
event.preventDefault();
|
|
2834
|
+
});
|
|
2835
|
+
button.addEventListener("click", (event) => {
|
|
2836
|
+
event.preventDefault();
|
|
2837
|
+
event.stopPropagation();
|
|
2838
|
+
options.onClick();
|
|
2839
|
+
});
|
|
2840
|
+
return button;
|
|
2841
|
+
};
|
|
2842
|
+
var appendFrame = (schema) => {
|
|
2843
|
+
const contentArea = getBoxContentArea(schema);
|
|
2844
|
+
const frame = document.createElement("div");
|
|
2845
|
+
frame.style.position = "absolute";
|
|
2846
|
+
frame.style.zIndex = "1";
|
|
2847
|
+
frame.style.width = `${contentArea.width}mm`;
|
|
2848
|
+
frame.style.height = `${contentArea.height}mm`;
|
|
2849
|
+
frame.style.top = `${contentArea.topInset}mm`;
|
|
2850
|
+
frame.style.left = `${contentArea.leftInset}mm`;
|
|
2851
|
+
frame.style.boxSizing = "border-box";
|
|
2852
|
+
return frame;
|
|
2853
|
+
};
|
|
2854
|
+
var warnUnsupportedImage = (columnIndex) => {
|
|
2855
|
+
console.warn(`[@pdfme/schemas/table] unsupported image in column ${columnIndex ?? 0}; only PNG/JPEG data URL is supported`);
|
|
2856
|
+
};
|
|
2857
|
+
var renderTableImageCellUi = (arg) => {
|
|
2858
|
+
const { schema, rootElement, value, onChange, i18n, _cache } = arg;
|
|
2859
|
+
const dimension = value ? resolveImageDimension(value, _cache) : void 0;
|
|
2860
|
+
const frame = appendFrame(schema);
|
|
2861
|
+
if (dimension && value) {
|
|
2862
|
+
const img = document.createElement("img");
|
|
2863
|
+
img.alt = "";
|
|
2864
|
+
img.src = value;
|
|
2865
|
+
img.style.width = "100%";
|
|
2866
|
+
img.style.height = "100%";
|
|
2867
|
+
img.style.objectFit = "contain";
|
|
2868
|
+
img.style.objectPosition = getTableImageObjectPosition(schema.alignment, schema.verticalAlignment);
|
|
2869
|
+
frame.appendChild(img);
|
|
2870
|
+
} else {
|
|
2871
|
+
frame.textContent = i18n("schemas.table.imageCell.placeholder");
|
|
2872
|
+
frame.style.border = "1px dotted #999";
|
|
2873
|
+
frame.style.color = "#999";
|
|
2874
|
+
frame.style.fontSize = "10px";
|
|
2875
|
+
frame.style.display = "flex";
|
|
2876
|
+
frame.style.alignItems = "center";
|
|
2877
|
+
frame.style.justifyContent = "center";
|
|
2878
|
+
frame.style.textAlign = "center";
|
|
2879
|
+
frame.style.overflow = "hidden";
|
|
2880
|
+
frame.style.padding = "1mm";
|
|
2881
|
+
}
|
|
2882
|
+
rootElement.appendChild(frame);
|
|
2883
|
+
const input = document.createElement("input");
|
|
2884
|
+
input.type = "file";
|
|
2885
|
+
input.accept = "image/png, image/jpeg";
|
|
2886
|
+
input.tabIndex = -1;
|
|
2887
|
+
input.style.display = "none";
|
|
2888
|
+
input.addEventListener("click", (event) => {
|
|
2889
|
+
event.stopPropagation();
|
|
2890
|
+
});
|
|
2891
|
+
input.addEventListener("change", () => {
|
|
2892
|
+
if (!input.files || input.files.length === 0) return;
|
|
2893
|
+
readFile(input.files).then((result) => {
|
|
2894
|
+
if (typeof result === "string" && TABLE_IMAGE_DATA_URL_PATTERN.test(result) && resolveImageDimension(result, _cache)) {
|
|
2895
|
+
onChange?.({
|
|
2896
|
+
key: "content",
|
|
2897
|
+
value: result
|
|
2898
|
+
});
|
|
2899
|
+
return;
|
|
2900
|
+
}
|
|
2901
|
+
warnUnsupportedImage(schema.columnIndex);
|
|
2902
|
+
}).catch(() => {
|
|
2903
|
+
warnUnsupportedImage(schema.columnIndex);
|
|
2904
|
+
});
|
|
2905
|
+
});
|
|
2906
|
+
rootElement.appendChild(input);
|
|
2907
|
+
const hasValue = typeof value === "string" && value !== "";
|
|
2908
|
+
rootElement.appendChild(createImageButton({
|
|
2909
|
+
text: "▣",
|
|
2910
|
+
ariaLabel: i18n("schemas.table.imageCell.select"),
|
|
2911
|
+
right: hasValue ? `20px` : "0px",
|
|
2912
|
+
onClick: () => {
|
|
2913
|
+
input.click();
|
|
2914
|
+
}
|
|
2915
|
+
}));
|
|
2916
|
+
if (hasValue) rootElement.appendChild(createImageButton({
|
|
2917
|
+
text: "×",
|
|
2918
|
+
ariaLabel: i18n("schemas.table.imageCell.remove"),
|
|
2919
|
+
right: "0px",
|
|
2920
|
+
onClick: () => {
|
|
2921
|
+
onChange?.({
|
|
2922
|
+
key: "content",
|
|
2923
|
+
value: ""
|
|
2924
|
+
});
|
|
2925
|
+
}
|
|
2926
|
+
}));
|
|
2927
|
+
const { rowIndex, columnIndex, pickerSchemaKey } = schema;
|
|
2928
|
+
if (typeof rowIndex === "number" && typeof columnIndex === "number" && typeof pickerSchemaKey === "string" && consumePendingImagePicker({
|
|
2929
|
+
rowIndex,
|
|
2930
|
+
colIndex: columnIndex,
|
|
2931
|
+
schemaKey: pickerSchemaKey
|
|
2932
|
+
}) && !hasValue) input.click();
|
|
2933
|
+
};
|
|
2934
|
+
//#endregion
|
|
3003
2935
|
//#region src/tables/cell.ts
|
|
2936
|
+
var imagePdfRender = imageSchema.pdf;
|
|
3004
2937
|
var linePdfRender = lineSchema.pdf;
|
|
3005
2938
|
var rectanglePdfRender$1 = rectangle.pdf;
|
|
3006
2939
|
var renderLine = async (arg, schema, position, width, height) => linePdfRender({
|
|
@@ -3072,6 +3005,32 @@ var cellSchema = {
|
|
|
3072
3005
|
y: position.y
|
|
3073
3006
|
}, borderWidth.left, height)
|
|
3074
3007
|
]);
|
|
3008
|
+
if (schema.cellType === "image") {
|
|
3009
|
+
if (arg.value && resolveImageDimension(arg.value, arg._cache)) {
|
|
3010
|
+
const imageSchema = {
|
|
3011
|
+
name: schema.name,
|
|
3012
|
+
type: "image",
|
|
3013
|
+
content: arg.value,
|
|
3014
|
+
position: contentArea.position,
|
|
3015
|
+
width: contentArea.width,
|
|
3016
|
+
height: contentArea.height,
|
|
3017
|
+
rotate: 0,
|
|
3018
|
+
opacity: 1,
|
|
3019
|
+
objectFit: "contain",
|
|
3020
|
+
objectPosition: getTableImageObjectPosition(schema.alignment, schema.verticalAlignment)
|
|
3021
|
+
};
|
|
3022
|
+
try {
|
|
3023
|
+
await imagePdfRender({
|
|
3024
|
+
...arg,
|
|
3025
|
+
value: arg.value,
|
|
3026
|
+
schema: imageSchema
|
|
3027
|
+
});
|
|
3028
|
+
} catch {
|
|
3029
|
+
warnInvalidTableImageOnce(arg.value, schema.columnIndex ?? 0, arg._cache);
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
return;
|
|
3033
|
+
}
|
|
3075
3034
|
await pdfRender$4({
|
|
3076
3035
|
...arg,
|
|
3077
3036
|
schema: {
|
|
@@ -3091,19 +3050,35 @@ var cellSchema = {
|
|
|
3091
3050
|
const { schema, rootElement } = arg;
|
|
3092
3051
|
const { borderWidth, width, height, borderColor, backgroundColor } = schema;
|
|
3093
3052
|
rootElement.style.backgroundColor = backgroundColor;
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3053
|
+
if (schema.cellType === "image") {
|
|
3054
|
+
if (arg.mode === "designer") renderTableImageCellUi(arg);
|
|
3055
|
+
else if (arg.value ? resolveImageDimension(arg.value, arg._cache) : void 0) {
|
|
3056
|
+
const imageFrame = createTextDiv(schema);
|
|
3057
|
+
const img = document.createElement("img");
|
|
3058
|
+
img.alt = "";
|
|
3059
|
+
img.src = arg.value;
|
|
3060
|
+
img.style.width = "100%";
|
|
3061
|
+
img.style.height = "100%";
|
|
3062
|
+
img.style.objectFit = "contain";
|
|
3063
|
+
img.style.objectPosition = getTableImageObjectPosition(schema.alignment, schema.verticalAlignment);
|
|
3064
|
+
imageFrame.appendChild(img);
|
|
3065
|
+
rootElement.appendChild(imageFrame);
|
|
3066
|
+
}
|
|
3067
|
+
} else {
|
|
3068
|
+
const textDiv = createTextDiv(schema);
|
|
3069
|
+
await uiRender$4({
|
|
3070
|
+
...arg,
|
|
3071
|
+
schema: {
|
|
3072
|
+
...schema,
|
|
3073
|
+
backgroundColor: "",
|
|
3074
|
+
borderColor: "",
|
|
3075
|
+
borderWidth: createBoxDimension(0),
|
|
3076
|
+
padding: createBoxDimension(0)
|
|
3077
|
+
},
|
|
3078
|
+
rootElement: textDiv
|
|
3079
|
+
});
|
|
3080
|
+
rootElement.appendChild(textDiv);
|
|
3081
|
+
}
|
|
3107
3082
|
[
|
|
3108
3083
|
createLineDiv(`${width}mm`, `${borderWidth.top}mm`, "0mm", null, null, "0mm", borderColor),
|
|
3109
3084
|
createLineDiv(`${width}mm`, `${borderWidth.bottom}mm`, null, null, "0mm", "0mm", borderColor),
|
|
@@ -3143,7 +3118,7 @@ var cellSchema = {
|
|
|
3143
3118
|
//#region src/tables/pdfRender.ts
|
|
3144
3119
|
var rectanglePdfRender = rectangle.pdf;
|
|
3145
3120
|
var cellPdfRender = cellSchema.pdf;
|
|
3146
|
-
async function drawCell(arg, cell) {
|
|
3121
|
+
async function drawCell(arg, cell, columnIndex) {
|
|
3147
3122
|
await cellPdfRender({
|
|
3148
3123
|
...arg,
|
|
3149
3124
|
value: cell.raw,
|
|
@@ -3166,7 +3141,9 @@ async function drawCell(arg, cell) {
|
|
|
3166
3141
|
fontColor: cell.styles.textColor,
|
|
3167
3142
|
borderColor: cell.styles.lineColor,
|
|
3168
3143
|
borderWidth: cell.styles.lineWidth,
|
|
3169
|
-
padding: cell.styles.cellPadding
|
|
3144
|
+
padding: cell.styles.cellPadding,
|
|
3145
|
+
cellType: cell.isImage() ? "image" : "text",
|
|
3146
|
+
columnIndex
|
|
3170
3147
|
}
|
|
3171
3148
|
});
|
|
3172
3149
|
}
|
|
@@ -3180,7 +3157,7 @@ async function drawRow(arg, table, row, cursor, columns) {
|
|
|
3180
3157
|
}
|
|
3181
3158
|
cell.x = cursor.x;
|
|
3182
3159
|
cell.y = cursor.y;
|
|
3183
|
-
await drawCell(arg, cell);
|
|
3160
|
+
await drawCell(arg, cell, column.index);
|
|
3184
3161
|
cursor.x += column.width;
|
|
3185
3162
|
}
|
|
3186
3163
|
cursor.y += row.height;
|
|
@@ -3294,7 +3271,7 @@ var calcResizedHeadWidthPercentages = (arg) => {
|
|
|
3294
3271
|
var setBorder = (div, borderPosition, arg) => {
|
|
3295
3272
|
div.style[`border${borderPosition}`] = `${String(arg.schema.tableStyles.borderWidth)}mm solid ${arg.schema.tableStyles.borderColor}`;
|
|
3296
3273
|
};
|
|
3297
|
-
var drawBorder = (div, row, colIndex, rowIndex, rowsLength, arg) => {
|
|
3274
|
+
var drawBorder = (div, row, colIndex, rowIndex, rowsLength, arg, bodyLength) => {
|
|
3298
3275
|
const isFirstColumn = colIndex === 0;
|
|
3299
3276
|
const isLastColumn = colIndex === Object.values(row.cells).length - 1;
|
|
3300
3277
|
const isLastRow = rowIndex === rowsLength - 1;
|
|
@@ -3302,7 +3279,7 @@ var drawBorder = (div, row, colIndex, rowIndex, rowsLength, arg) => {
|
|
|
3302
3279
|
setBorder(div, "Top", arg);
|
|
3303
3280
|
if (isFirstColumn) setBorder(div, "Left", arg);
|
|
3304
3281
|
if (isLastColumn) setBorder(div, "Right", arg);
|
|
3305
|
-
if (
|
|
3282
|
+
if (bodyLength === 0) setBorder(div, "Bottom", arg);
|
|
3306
3283
|
} else if (row.section === "body") {
|
|
3307
3284
|
if (!arg.schema.showHead && rowIndex === 0) setBorder(div, "Top", arg);
|
|
3308
3285
|
if (isFirstColumn) setBorder(div, "Left", arg);
|
|
@@ -3325,20 +3302,28 @@ var renderRowUi = (args) => {
|
|
|
3325
3302
|
div.style.width = `${cell.width}mm`;
|
|
3326
3303
|
div.style.height = `${cell.height}mm`;
|
|
3327
3304
|
div.style.boxSizing = "border-box";
|
|
3328
|
-
drawBorder(div, row, colIndex, rowIndex, rows.length, arg);
|
|
3329
|
-
|
|
3305
|
+
drawBorder(div, row, colIndex, rowIndex, rows.length, arg, value.length);
|
|
3306
|
+
const imageCellEditable = arg.mode === "designer" || arg.mode === "form" && !arg.schema.readOnly;
|
|
3307
|
+
div.style.cursor = cell.isImage() ? imageCellEditable && section === "body" ? "pointer" : "default" : arg.mode === "designer" || arg.mode === "form" && section === "body" ? "text" : "default";
|
|
3330
3308
|
div.addEventListener("click", () => {
|
|
3331
3309
|
if (arg.mode === "viewer") return;
|
|
3310
|
+
const enteringEmptyImageCell = cell.isImage() && section === "body" && imageCellEditable && cell.raw === "" && (editingPosition.rowIndex !== rowIndex || editingPosition.colIndex !== colIndex);
|
|
3332
3311
|
onChangeEditingPosition({
|
|
3333
3312
|
rowIndex,
|
|
3334
3313
|
colIndex
|
|
3335
3314
|
});
|
|
3315
|
+
if (enteringEmptyImageCell) requestImagePicker({
|
|
3316
|
+
rowIndex,
|
|
3317
|
+
colIndex,
|
|
3318
|
+
schemaKey: tableSchemaKey(arg.schema)
|
|
3319
|
+
});
|
|
3336
3320
|
});
|
|
3337
3321
|
arg.rootElement.appendChild(div);
|
|
3338
3322
|
const isEditing = editingPosition.rowIndex === rowIndex && editingPosition.colIndex === colIndex;
|
|
3339
3323
|
let mode = "viewer";
|
|
3340
3324
|
if (arg.mode === "form") mode = section === "body" && isEditing && !arg.schema.readOnly ? "designer" : "viewer";
|
|
3341
3325
|
else if (arg.mode === "designer") mode = isEditing ? "designer" : "form";
|
|
3326
|
+
if (cell.isImage() && !isEditing) mode = "viewer";
|
|
3342
3327
|
cellUiRender({
|
|
3343
3328
|
...arg,
|
|
3344
3329
|
stopEditing: () => {
|
|
@@ -3377,7 +3362,11 @@ var renderRowUi = (args) => {
|
|
|
3377
3362
|
},
|
|
3378
3363
|
width: cell.width,
|
|
3379
3364
|
height: cell.height,
|
|
3380
|
-
...convertToCellStyle(cell.styles)
|
|
3365
|
+
...convertToCellStyle(cell.styles),
|
|
3366
|
+
cellType: cell.isImage() ? "image" : "text",
|
|
3367
|
+
columnIndex: colIndex,
|
|
3368
|
+
rowIndex,
|
|
3369
|
+
pickerSchemaKey: tableSchemaKey(arg.schema)
|
|
3381
3370
|
}
|
|
3382
3371
|
});
|
|
3383
3372
|
colOffsetX += cell.width;
|
|
@@ -3398,9 +3387,11 @@ var resetEditingPosition = () => {
|
|
|
3398
3387
|
headEditingPosition.colIndex = -1;
|
|
3399
3388
|
bodyEditingPosition.rowIndex = -1;
|
|
3400
3389
|
bodyEditingPosition.colIndex = -1;
|
|
3390
|
+
clearImagePickerRequest();
|
|
3401
3391
|
};
|
|
3402
3392
|
var uiRender = async (arg) => {
|
|
3403
3393
|
const { rootElement, onChange, schema, value, mode, scale } = arg;
|
|
3394
|
+
noteRenderingTable(schema);
|
|
3404
3395
|
const body = getBody(value);
|
|
3405
3396
|
const bodyRange = getTableBodyRange(schema);
|
|
3406
3397
|
const bodyWidthRange = getBodyWithSchemaRange(value, schema, bodyRange);
|
|
@@ -3608,15 +3599,678 @@ var uiRender = async (arg) => {
|
|
|
3608
3599
|
});
|
|
3609
3600
|
};
|
|
3610
3601
|
//#endregion
|
|
3602
|
+
//#region src/tables/columnsWidget.ts
|
|
3603
|
+
var cellTypeWarnCache = /* @__PURE__ */ new Map();
|
|
3604
|
+
/** More than this many columns, and each block can collapse. */
|
|
3605
|
+
var COLLAPSE_WHEN_MORE_THAN = 6;
|
|
3606
|
+
var expandedColumnBlocks = /* @__PURE__ */ new Set();
|
|
3607
|
+
var columnBlockKey = (schemaId, columnIndex) => `${schemaId}:${columnIndex}`;
|
|
3608
|
+
var themeRecord = (theme) => theme ?? void 0;
|
|
3609
|
+
var themeToken = (theme, key, fallback) => {
|
|
3610
|
+
const value = themeRecord(theme)?.[key];
|
|
3611
|
+
return typeof value === "string" && value.length > 0 ? value : fallback;
|
|
3612
|
+
};
|
|
3613
|
+
var themeNumber = (theme, key, fallback) => {
|
|
3614
|
+
const value = themeRecord(theme)?.[key];
|
|
3615
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
3616
|
+
};
|
|
3617
|
+
/** antd outlined Select / InputNumber metrics, read from the Designer token when present. */
|
|
3618
|
+
var panelControlMetrics = (theme) => {
|
|
3619
|
+
const lineWidth = themeNumber(theme, "lineWidth", 1);
|
|
3620
|
+
const controlHeight = themeNumber(theme, "controlHeight", 32);
|
|
3621
|
+
const paddingSm = themeNumber(theme, "paddingSM", 12);
|
|
3622
|
+
const controlHeightSm = themeNumber(theme, "controlHeightSM", 24);
|
|
3623
|
+
const fontSize = themeNumber(theme, "fontSize", 14);
|
|
3624
|
+
const outlineWidth = themeNumber(theme, "controlOutlineWidth", 2);
|
|
3625
|
+
return {
|
|
3626
|
+
lineWidth,
|
|
3627
|
+
controlHeight,
|
|
3628
|
+
borderRadius: themeNumber(theme, "borderRadius", 6),
|
|
3629
|
+
fontSize,
|
|
3630
|
+
paddingInline: Math.max(0, paddingSm - lineWidth),
|
|
3631
|
+
handleWidth: Math.max(0, controlHeightSm - lineWidth * 2),
|
|
3632
|
+
handleFontSize: fontSize / 2,
|
|
3633
|
+
outlineWidth,
|
|
3634
|
+
colorBorder: themeToken(theme, "colorBorder", "#d9d9d9"),
|
|
3635
|
+
colorBg: themeToken(theme, "colorBgContainer", "#ffffff"),
|
|
3636
|
+
colorText: themeToken(theme, "colorText", "rgba(0, 0, 0, 0.88)"),
|
|
3637
|
+
colorArrow: themeToken(theme, "colorTextQuaternary", "rgba(0, 0, 0, 0.25)"),
|
|
3638
|
+
colorIcon: themeToken(theme, "colorIcon", "rgba(0, 0, 0, 0.45)"),
|
|
3639
|
+
colorPrimary: themeToken(theme, "colorPrimary", "#1677ff"),
|
|
3640
|
+
colorPrimaryHover: themeToken(theme, "colorPrimaryHover", "#4096ff"),
|
|
3641
|
+
controlOutline: themeToken(theme, "controlOutline", "rgba(5, 145, 255, 0.1)"),
|
|
3642
|
+
motion: themeToken(theme, "motionDurationMid", "0.2s")
|
|
3643
|
+
};
|
|
3644
|
+
};
|
|
3645
|
+
var ANT_DOWN_PATH = "M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z";
|
|
3646
|
+
var ANT_UP_PATH = "M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z";
|
|
3647
|
+
var appendSvgIcon = (parent, path, size) => {
|
|
3648
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
3649
|
+
svg.setAttribute("viewBox", "64 64 896 896");
|
|
3650
|
+
svg.setAttribute("width", String(size));
|
|
3651
|
+
svg.setAttribute("height", String(size));
|
|
3652
|
+
svg.setAttribute("fill", "currentColor");
|
|
3653
|
+
svg.setAttribute("aria-hidden", "true");
|
|
3654
|
+
svg.setAttribute("focusable", "false");
|
|
3655
|
+
const shape = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
3656
|
+
shape.setAttribute("d", path);
|
|
3657
|
+
svg.appendChild(shape);
|
|
3658
|
+
parent.appendChild(svg);
|
|
3659
|
+
};
|
|
3660
|
+
var ensurePanelControlStyles = (rootElement, metrics) => {
|
|
3661
|
+
rootElement.style.setProperty("--pdfme-border", metrics.colorBorder);
|
|
3662
|
+
rootElement.style.setProperty("--pdfme-hover-border", metrics.colorPrimaryHover);
|
|
3663
|
+
rootElement.style.setProperty("--pdfme-active-border", metrics.colorPrimary);
|
|
3664
|
+
rootElement.style.setProperty("--pdfme-outline", metrics.controlOutline);
|
|
3665
|
+
rootElement.style.setProperty("--pdfme-outline-width", `${metrics.outlineWidth}px`);
|
|
3666
|
+
rootElement.style.setProperty("--pdfme-handle-width", `${metrics.handleWidth}px`);
|
|
3667
|
+
rootElement.style.setProperty("--pdfme-handle-hover", metrics.colorPrimary);
|
|
3668
|
+
rootElement.style.setProperty("--pdfme-padding-inline", `${metrics.paddingInline}px`);
|
|
3669
|
+
if (rootElement.querySelector("style[data-pdfme-column-controls]")) return;
|
|
3670
|
+
const style = document.createElement("style");
|
|
3671
|
+
style.dataset.pdfmeColumnControls = "true";
|
|
3672
|
+
style.textContent = `
|
|
3673
|
+
.pdfme-column-select,
|
|
3674
|
+
.pdfme-column-number {
|
|
3675
|
+
border-color: var(--pdfme-border);
|
|
3676
|
+
}
|
|
3677
|
+
.pdfme-column-select:hover,
|
|
3678
|
+
.pdfme-column-number:hover {
|
|
3679
|
+
border-color: var(--pdfme-hover-border);
|
|
3680
|
+
}
|
|
3681
|
+
.pdfme-column-select:focus-within,
|
|
3682
|
+
.pdfme-column-number:focus-within {
|
|
3683
|
+
border-color: var(--pdfme-active-border);
|
|
3684
|
+
box-shadow: 0 0 0 var(--pdfme-outline-width) var(--pdfme-outline);
|
|
3685
|
+
outline: 0;
|
|
3686
|
+
}
|
|
3687
|
+
.pdfme-column-select-input,
|
|
3688
|
+
.pdfme-column-number-input {
|
|
3689
|
+
outline: none;
|
|
3690
|
+
}
|
|
3691
|
+
.pdfme-column-select-input {
|
|
3692
|
+
appearance: none;
|
|
3693
|
+
-webkit-appearance: none;
|
|
3694
|
+
}
|
|
3695
|
+
.pdfme-column-number-input {
|
|
3696
|
+
appearance: textfield;
|
|
3697
|
+
-moz-appearance: textfield;
|
|
3698
|
+
padding-left: var(--pdfme-padding-inline);
|
|
3699
|
+
padding-right: var(--pdfme-padding-inline);
|
|
3700
|
+
}
|
|
3701
|
+
.pdfme-column-number:hover .pdfme-column-number-input,
|
|
3702
|
+
.pdfme-column-number:focus-within .pdfme-column-number-input {
|
|
3703
|
+
padding-right: calc(var(--pdfme-handle-width) + var(--pdfme-padding-inline));
|
|
3704
|
+
}
|
|
3705
|
+
.pdfme-column-number-input::-webkit-outer-spin-button,
|
|
3706
|
+
.pdfme-column-number-input::-webkit-inner-spin-button {
|
|
3707
|
+
-webkit-appearance: none;
|
|
3708
|
+
margin: 0;
|
|
3709
|
+
}
|
|
3710
|
+
.pdfme-column-number-handlers {
|
|
3711
|
+
opacity: 0;
|
|
3712
|
+
width: 0;
|
|
3713
|
+
}
|
|
3714
|
+
.pdfme-column-number:hover .pdfme-column-number-handlers,
|
|
3715
|
+
.pdfme-column-number:focus-within .pdfme-column-number-handlers {
|
|
3716
|
+
opacity: 1;
|
|
3717
|
+
width: var(--pdfme-handle-width);
|
|
3718
|
+
}
|
|
3719
|
+
.pdfme-column-number-handler:hover {
|
|
3720
|
+
color: var(--pdfme-handle-hover);
|
|
3721
|
+
height: 60%;
|
|
3722
|
+
}
|
|
3723
|
+
`;
|
|
3724
|
+
rootElement.appendChild(style);
|
|
3725
|
+
};
|
|
3726
|
+
var HORIZONTAL_ALIGNMENTS = [
|
|
3727
|
+
{
|
|
3728
|
+
value: "left",
|
|
3729
|
+
icon: TextAlignLeftIcon,
|
|
3730
|
+
labelKey: "schemas.left"
|
|
3731
|
+
},
|
|
3732
|
+
{
|
|
3733
|
+
value: "center",
|
|
3734
|
+
icon: TextAlignCenterIcon,
|
|
3735
|
+
labelKey: "schemas.center"
|
|
3736
|
+
},
|
|
3737
|
+
{
|
|
3738
|
+
value: "right",
|
|
3739
|
+
icon: TextAlignRightIcon,
|
|
3740
|
+
labelKey: "schemas.right"
|
|
3741
|
+
}
|
|
3742
|
+
];
|
|
3743
|
+
var VERTICAL_ALIGNMENTS = [
|
|
3744
|
+
{
|
|
3745
|
+
value: "top",
|
|
3746
|
+
icon: TextVerticalAlignTopIcon,
|
|
3747
|
+
labelKey: "schemas.top"
|
|
3748
|
+
},
|
|
3749
|
+
{
|
|
3750
|
+
value: "middle",
|
|
3751
|
+
icon: TextVerticalAlignMiddleIcon,
|
|
3752
|
+
labelKey: "schemas.middle"
|
|
3753
|
+
},
|
|
3754
|
+
{
|
|
3755
|
+
value: "bottom",
|
|
3756
|
+
icon: TextVerticalAlignBottomIcon,
|
|
3757
|
+
labelKey: "schemas.bottom"
|
|
3758
|
+
}
|
|
3759
|
+
];
|
|
3760
|
+
var isUnset = (value) => value == null;
|
|
3761
|
+
var clearColumnContent = (content, columnIndex) => {
|
|
3762
|
+
let rows;
|
|
3763
|
+
try {
|
|
3764
|
+
rows = JSON.parse(content ?? "[]");
|
|
3765
|
+
} catch {
|
|
3766
|
+
return content ?? "[]";
|
|
3767
|
+
}
|
|
3768
|
+
if (!Array.isArray(rows)) return content ?? "[]";
|
|
3769
|
+
const next = rows.map((row) => {
|
|
3770
|
+
if (!Array.isArray(row)) return row;
|
|
3771
|
+
const copy = row.slice();
|
|
3772
|
+
if (columnIndex < copy.length) copy[columnIndex] = "";
|
|
3773
|
+
return copy;
|
|
3774
|
+
});
|
|
3775
|
+
return JSON.stringify(next);
|
|
3776
|
+
};
|
|
3777
|
+
var dropColumnKey = (map, columnIndex) => {
|
|
3778
|
+
if (!map) return map;
|
|
3779
|
+
const next = { ...map };
|
|
3780
|
+
delete next[columnIndex];
|
|
3781
|
+
return Object.keys(next).length === 0 ? void 0 : next;
|
|
3782
|
+
};
|
|
3783
|
+
var columnLabel = (head, index, i18n) => {
|
|
3784
|
+
const label = head[index];
|
|
3785
|
+
return label ? label : `${i18n("schemas.table.columnLabel")} ${index + 1}`;
|
|
3786
|
+
};
|
|
3787
|
+
var commitStyles = (props, columnStyles, content) => {
|
|
3788
|
+
const schemaId = props.activeSchema.id;
|
|
3789
|
+
const changes = [{
|
|
3790
|
+
key: "columnStyles",
|
|
3791
|
+
value: columnStyles,
|
|
3792
|
+
schemaId
|
|
3793
|
+
}];
|
|
3794
|
+
if (content !== void 0) changes.push({
|
|
3795
|
+
key: "content",
|
|
3796
|
+
value: content,
|
|
3797
|
+
schemaId
|
|
3798
|
+
});
|
|
3799
|
+
props.changeSchemas(changes);
|
|
3800
|
+
};
|
|
3801
|
+
var setCellType = (props, table, columnIndex, nextType) => {
|
|
3802
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3803
|
+
if (nextType === "image") {
|
|
3804
|
+
next.cellType = {
|
|
3805
|
+
...next.cellType,
|
|
3806
|
+
[columnIndex]: "image"
|
|
3807
|
+
};
|
|
3808
|
+
if (isUnset(next.imageHeightMode?.[columnIndex])) next.imageHeightMode = {
|
|
3809
|
+
...next.imageHeightMode,
|
|
3810
|
+
[columnIndex]: DEFAULT_TABLE_IMAGE_HEIGHT_MODE
|
|
3811
|
+
};
|
|
3812
|
+
if (isUnset(next.imageHeight?.[columnIndex])) next.imageHeight = {
|
|
3813
|
+
...next.imageHeight,
|
|
3814
|
+
[columnIndex]: 20
|
|
3815
|
+
};
|
|
3816
|
+
if (isUnset(next.alignment?.[columnIndex])) next.alignment = {
|
|
3817
|
+
...next.alignment,
|
|
3818
|
+
[columnIndex]: "center"
|
|
3819
|
+
};
|
|
3820
|
+
} else {
|
|
3821
|
+
const cellType = dropColumnKey(next.cellType, columnIndex);
|
|
3822
|
+
const imageHeightMode = dropColumnKey(next.imageHeightMode, columnIndex);
|
|
3823
|
+
const imageHeight = dropColumnKey(next.imageHeight, columnIndex);
|
|
3824
|
+
if (cellType) next.cellType = cellType;
|
|
3825
|
+
else delete next.cellType;
|
|
3826
|
+
if (imageHeightMode) next.imageHeightMode = imageHeightMode;
|
|
3827
|
+
else delete next.imageHeightMode;
|
|
3828
|
+
if (imageHeight) next.imageHeight = imageHeight;
|
|
3829
|
+
else delete next.imageHeight;
|
|
3830
|
+
}
|
|
3831
|
+
commitStyles(props, next, clearColumnContent(table.content, columnIndex));
|
|
3832
|
+
};
|
|
3833
|
+
var setImageHeightMode = (props, table, columnIndex, mode) => {
|
|
3834
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3835
|
+
next.imageHeightMode = {
|
|
3836
|
+
...next.imageHeightMode,
|
|
3837
|
+
[columnIndex]: mode
|
|
3838
|
+
};
|
|
3839
|
+
commitStyles(props, next);
|
|
3840
|
+
};
|
|
3841
|
+
var setImageHeight = (props, table, columnIndex, height) => {
|
|
3842
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3843
|
+
next.imageHeight = {
|
|
3844
|
+
...next.imageHeight,
|
|
3845
|
+
[columnIndex]: height
|
|
3846
|
+
};
|
|
3847
|
+
commitStyles(props, next);
|
|
3848
|
+
};
|
|
3849
|
+
var setAlignment = (props, table, columnIndex, value) => {
|
|
3850
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3851
|
+
if (next.alignment?.[columnIndex] === value) return;
|
|
3852
|
+
next.alignment = {
|
|
3853
|
+
...next.alignment,
|
|
3854
|
+
[columnIndex]: value
|
|
3855
|
+
};
|
|
3856
|
+
commitStyles(props, next);
|
|
3857
|
+
};
|
|
3858
|
+
var setVerticalAlignment = (props, table, columnIndex, value) => {
|
|
3859
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3860
|
+
if (next.verticalAlignment?.[columnIndex] === value) return;
|
|
3861
|
+
next.verticalAlignment = {
|
|
3862
|
+
...next.verticalAlignment,
|
|
3863
|
+
[columnIndex]: value
|
|
3864
|
+
};
|
|
3865
|
+
commitStyles(props, next);
|
|
3866
|
+
};
|
|
3867
|
+
var iconSrc = (svg, color) => `data:image/svg+xml;utf8,${encodeURIComponent(svg.replace(/currentColor/g, color))}`;
|
|
3868
|
+
var appendIcon = (parent, svg, color, size = 17) => {
|
|
3869
|
+
const img = document.createElement("img");
|
|
3870
|
+
img.alt = "";
|
|
3871
|
+
img.width = size;
|
|
3872
|
+
img.height = size;
|
|
3873
|
+
img.src = iconSrc(svg, color);
|
|
3874
|
+
parent.appendChild(img);
|
|
3875
|
+
return img;
|
|
3876
|
+
};
|
|
3877
|
+
var appendSelect = (parent, options, value, control, columnIndex, metrics, layout, onChange) => {
|
|
3878
|
+
const shell = document.createElement("div");
|
|
3879
|
+
shell.className = "pdfme-column-select";
|
|
3880
|
+
shell.style.position = "relative";
|
|
3881
|
+
shell.style.display = "inline-flex";
|
|
3882
|
+
shell.style.alignItems = "center";
|
|
3883
|
+
shell.style.boxSizing = "border-box";
|
|
3884
|
+
shell.style.height = `${metrics.controlHeight}px`;
|
|
3885
|
+
shell.style.borderWidth = `${metrics.lineWidth}px`;
|
|
3886
|
+
shell.style.borderStyle = "solid";
|
|
3887
|
+
shell.style.borderRadius = `${metrics.borderRadius}px`;
|
|
3888
|
+
shell.style.background = metrics.colorBg;
|
|
3889
|
+
shell.style.overflow = "hidden";
|
|
3890
|
+
shell.style.transition = `all ${metrics.motion}`;
|
|
3891
|
+
shell.style.flexShrink = layout.flex ? "1" : "0";
|
|
3892
|
+
if (layout.width) shell.style.width = layout.width;
|
|
3893
|
+
if (layout.flex) {
|
|
3894
|
+
shell.style.flex = layout.flex;
|
|
3895
|
+
shell.style.minWidth = "0";
|
|
3896
|
+
}
|
|
3897
|
+
const select = document.createElement("select");
|
|
3898
|
+
select.className = "pdfme-column-select-input";
|
|
3899
|
+
select.dataset.control = control;
|
|
3900
|
+
select.dataset.columnIndex = String(columnIndex);
|
|
3901
|
+
select.style.width = "100%";
|
|
3902
|
+
select.style.height = "100%";
|
|
3903
|
+
select.style.boxSizing = "border-box";
|
|
3904
|
+
select.style.margin = "0";
|
|
3905
|
+
select.style.border = "0";
|
|
3906
|
+
select.style.borderRadius = `${metrics.borderRadius}px`;
|
|
3907
|
+
select.style.background = "transparent";
|
|
3908
|
+
select.style.padding = `0 ${metrics.paddingInline + 18}px 0 ${metrics.paddingInline}px`;
|
|
3909
|
+
select.style.font = "inherit";
|
|
3910
|
+
select.style.fontSize = `${metrics.fontSize}px`;
|
|
3911
|
+
select.style.lineHeight = `${metrics.controlHeight - metrics.lineWidth * 2}px`;
|
|
3912
|
+
select.style.color = metrics.colorText;
|
|
3913
|
+
select.style.cursor = "pointer";
|
|
3914
|
+
options.forEach((option) => {
|
|
3915
|
+
const element = document.createElement("option");
|
|
3916
|
+
element.value = option.value;
|
|
3917
|
+
element.textContent = option.label;
|
|
3918
|
+
select.appendChild(element);
|
|
3919
|
+
});
|
|
3920
|
+
select.value = value;
|
|
3921
|
+
select.addEventListener("change", () => {
|
|
3922
|
+
onChange(select.value);
|
|
3923
|
+
});
|
|
3924
|
+
const arrow = document.createElement("span");
|
|
3925
|
+
arrow.className = "pdfme-column-select-arrow";
|
|
3926
|
+
arrow.setAttribute("aria-hidden", "true");
|
|
3927
|
+
arrow.style.position = "absolute";
|
|
3928
|
+
arrow.style.top = "50%";
|
|
3929
|
+
arrow.style.right = `${metrics.paddingInline}px`;
|
|
3930
|
+
arrow.style.transform = "translateY(-50%)";
|
|
3931
|
+
arrow.style.display = "flex";
|
|
3932
|
+
arrow.style.width = "12px";
|
|
3933
|
+
arrow.style.height = "12px";
|
|
3934
|
+
arrow.style.color = metrics.colorArrow;
|
|
3935
|
+
arrow.style.fontSize = "12px";
|
|
3936
|
+
arrow.style.lineHeight = "1";
|
|
3937
|
+
arrow.style.pointerEvents = "none";
|
|
3938
|
+
appendSvgIcon(arrow, ANT_DOWN_PATH, 12);
|
|
3939
|
+
shell.appendChild(select);
|
|
3940
|
+
shell.appendChild(arrow);
|
|
3941
|
+
parent.appendChild(shell);
|
|
3942
|
+
return select;
|
|
3943
|
+
};
|
|
3944
|
+
var appendNumberInput = (parent, value, columnIndex, ariaLabel, metrics, onCommit) => {
|
|
3945
|
+
const shell = document.createElement("div");
|
|
3946
|
+
shell.className = "pdfme-column-number";
|
|
3947
|
+
shell.style.position = "relative";
|
|
3948
|
+
shell.style.display = "inline-flex";
|
|
3949
|
+
shell.style.alignItems = "center";
|
|
3950
|
+
shell.style.boxSizing = "border-box";
|
|
3951
|
+
shell.style.width = "72px";
|
|
3952
|
+
shell.style.height = `${metrics.controlHeight}px`;
|
|
3953
|
+
shell.style.flexShrink = "0";
|
|
3954
|
+
shell.style.borderWidth = `${metrics.lineWidth}px`;
|
|
3955
|
+
shell.style.borderStyle = "solid";
|
|
3956
|
+
shell.style.borderRadius = `${metrics.borderRadius}px`;
|
|
3957
|
+
shell.style.background = metrics.colorBg;
|
|
3958
|
+
shell.style.transition = `all ${metrics.motion}`;
|
|
3959
|
+
shell.style.overflow = "hidden";
|
|
3960
|
+
const input = document.createElement("input");
|
|
3961
|
+
input.type = "number";
|
|
3962
|
+
input.min = "1";
|
|
3963
|
+
input.step = "1";
|
|
3964
|
+
input.className = "pdfme-column-number-input";
|
|
3965
|
+
input.dataset.control = "imageHeight";
|
|
3966
|
+
input.dataset.columnIndex = String(columnIndex);
|
|
3967
|
+
input.setAttribute("aria-label", ariaLabel);
|
|
3968
|
+
input.style.width = "100%";
|
|
3969
|
+
input.style.height = "100%";
|
|
3970
|
+
input.style.boxSizing = "border-box";
|
|
3971
|
+
input.style.margin = "0";
|
|
3972
|
+
input.style.border = "0";
|
|
3973
|
+
input.style.borderRadius = "0";
|
|
3974
|
+
input.style.background = "transparent";
|
|
3975
|
+
input.style.font = "inherit";
|
|
3976
|
+
input.style.fontSize = `${metrics.fontSize}px`;
|
|
3977
|
+
input.style.lineHeight = "22px";
|
|
3978
|
+
input.style.color = metrics.colorText;
|
|
3979
|
+
input.value = value;
|
|
3980
|
+
input.addEventListener("change", () => {
|
|
3981
|
+
onCommit(input);
|
|
3982
|
+
});
|
|
3983
|
+
const handlers = document.createElement("div");
|
|
3984
|
+
handlers.className = "pdfme-column-number-handlers";
|
|
3985
|
+
handlers.style.position = "absolute";
|
|
3986
|
+
handlers.style.top = "0";
|
|
3987
|
+
handlers.style.right = "0";
|
|
3988
|
+
handlers.style.bottom = "0";
|
|
3989
|
+
handlers.style.display = "flex";
|
|
3990
|
+
handlers.style.flexDirection = "column";
|
|
3991
|
+
handlers.style.overflow = "hidden";
|
|
3992
|
+
handlers.style.background = metrics.colorBg;
|
|
3993
|
+
handlers.style.borderRadius = `0 ${metrics.borderRadius}px ${metrics.borderRadius}px 0`;
|
|
3994
|
+
handlers.style.transition = `all ${metrics.motion}`;
|
|
3995
|
+
const step = (delta) => {
|
|
3996
|
+
const current = Number(input.value);
|
|
3997
|
+
const base = Number.isFinite(current) ? current : Number(value);
|
|
3998
|
+
const next = Math.max(1, base + delta);
|
|
3999
|
+
if (next === base) return;
|
|
4000
|
+
input.value = String(next);
|
|
4001
|
+
input.dispatchEvent(new Event("change"));
|
|
4002
|
+
};
|
|
4003
|
+
const addHandler = (direction, path, label) => {
|
|
4004
|
+
const button = document.createElement("button");
|
|
4005
|
+
button.type = "button";
|
|
4006
|
+
button.className = "pdfme-column-number-handler";
|
|
4007
|
+
button.dataset.control = direction === "up" ? "imageHeightUp" : "imageHeightDown";
|
|
4008
|
+
button.setAttribute("aria-label", label);
|
|
4009
|
+
button.style.flex = "1 1 50%";
|
|
4010
|
+
button.style.display = "flex";
|
|
4011
|
+
button.style.alignItems = "center";
|
|
4012
|
+
button.style.justifyContent = "center";
|
|
4013
|
+
button.style.margin = "0";
|
|
4014
|
+
button.style.padding = "0";
|
|
4015
|
+
button.style.border = "0";
|
|
4016
|
+
button.style.borderLeft = `${metrics.lineWidth}px solid ${metrics.colorBorder}`;
|
|
4017
|
+
button.style.background = "transparent";
|
|
4018
|
+
button.style.color = metrics.colorIcon;
|
|
4019
|
+
button.style.cursor = "pointer";
|
|
4020
|
+
button.style.lineHeight = "0";
|
|
4021
|
+
if (direction === "down") button.style.borderTop = `${metrics.lineWidth}px solid ${metrics.colorBorder}`;
|
|
4022
|
+
button.addEventListener("mousedown", (event) => {
|
|
4023
|
+
event.preventDefault();
|
|
4024
|
+
});
|
|
4025
|
+
button.addEventListener("click", () => {
|
|
4026
|
+
step(direction === "up" ? 1 : -1);
|
|
4027
|
+
});
|
|
4028
|
+
appendSvgIcon(button, path, metrics.handleFontSize);
|
|
4029
|
+
handlers.appendChild(button);
|
|
4030
|
+
};
|
|
4031
|
+
addHandler("up", ANT_UP_PATH, "Increase Value");
|
|
4032
|
+
addHandler("down", ANT_DOWN_PATH, "Decrease Value");
|
|
4033
|
+
shell.appendChild(input);
|
|
4034
|
+
shell.appendChild(handlers);
|
|
4035
|
+
parent.appendChild(shell);
|
|
4036
|
+
return input;
|
|
4037
|
+
};
|
|
4038
|
+
var appendButtonGroup = (parent, control, buttons, current, columnIndex, colors, i18n, onSelect) => {
|
|
4039
|
+
const group = document.createElement("div");
|
|
4040
|
+
group.dataset.control = control;
|
|
4041
|
+
group.dataset.columnIndex = String(columnIndex);
|
|
4042
|
+
group.setAttribute("role", "group");
|
|
4043
|
+
group.style.display = "inline-flex";
|
|
4044
|
+
buttons.forEach((button, index) => {
|
|
4045
|
+
const element = document.createElement("button");
|
|
4046
|
+
element.type = "button";
|
|
4047
|
+
element.dataset.value = button.value;
|
|
4048
|
+
const label = i18n(button.labelKey);
|
|
4049
|
+
element.setAttribute("aria-label", label);
|
|
4050
|
+
element.title = label;
|
|
4051
|
+
const active = current === button.value;
|
|
4052
|
+
element.setAttribute("aria-pressed", active ? "true" : "false");
|
|
4053
|
+
element.style.padding = "7px";
|
|
4054
|
+
element.style.lineHeight = "0";
|
|
4055
|
+
element.style.background = "transparent";
|
|
4056
|
+
element.style.cursor = "pointer";
|
|
4057
|
+
element.style.border = `1px solid ${active ? colors.primary : colors.border}`;
|
|
4058
|
+
element.style.marginLeft = index === 0 ? "0" : "-1px";
|
|
4059
|
+
element.style.borderRadius = index === 0 ? "6px 0 0 6px" : index === buttons.length - 1 ? "0 6px 6px 0" : "0";
|
|
4060
|
+
element.style.position = "relative";
|
|
4061
|
+
element.style.zIndex = active ? "1" : "0";
|
|
4062
|
+
appendIcon(element, button.icon, active ? colors.primary : colors.text);
|
|
4063
|
+
element.addEventListener("click", () => {
|
|
4064
|
+
if (current === button.value) return;
|
|
4065
|
+
onSelect(button.value);
|
|
4066
|
+
});
|
|
4067
|
+
group.appendChild(element);
|
|
4068
|
+
});
|
|
4069
|
+
parent.appendChild(group);
|
|
4070
|
+
return group;
|
|
4071
|
+
};
|
|
4072
|
+
var ellipsis = (element) => {
|
|
4073
|
+
element.style.overflow = "hidden";
|
|
4074
|
+
element.style.textOverflow = "ellipsis";
|
|
4075
|
+
element.style.whiteSpace = "nowrap";
|
|
4076
|
+
element.style.minWidth = "0";
|
|
4077
|
+
};
|
|
4078
|
+
var TableColumns = (props) => {
|
|
4079
|
+
const { rootElement, activeSchema, i18n } = props;
|
|
4080
|
+
const table = activeSchema;
|
|
4081
|
+
const head = table.head || [];
|
|
4082
|
+
const columnStyles = table.columnStyles ?? {};
|
|
4083
|
+
const metrics = panelControlMetrics(props.theme);
|
|
4084
|
+
ensurePanelControlStyles(rootElement, metrics);
|
|
4085
|
+
const colors = {
|
|
4086
|
+
primary: themeToken(props.theme, "colorPrimary", "#1677ff"),
|
|
4087
|
+
border: themeToken(props.theme, "colorBorder", "#d9d9d9"),
|
|
4088
|
+
text: themeToken(props.theme, "colorText", "#000000"),
|
|
4089
|
+
split: themeToken(props.theme, "colorSplit", "#f0f0f0")
|
|
4090
|
+
};
|
|
4091
|
+
const collapsible = head.length > COLLAPSE_WHEN_MORE_THAN;
|
|
4092
|
+
head.forEach((_, index) => {
|
|
4093
|
+
const storedType = columnStyles.cellType?.[index];
|
|
4094
|
+
const cellType = normalizeTableCellType(storedType, index, cellTypeWarnCache) ?? "text";
|
|
4095
|
+
const label = columnLabel(head, index, i18n);
|
|
4096
|
+
const alignment = columnStyles.alignment?.[index];
|
|
4097
|
+
const verticalAlignment = columnStyles.verticalAlignment?.[index];
|
|
4098
|
+
const mode = cellType === "image" ? normalizeTableImageHeightMode(columnStyles.imageHeightMode?.[index]) ?? "fixed" : void 0;
|
|
4099
|
+
const block = document.createElement("div");
|
|
4100
|
+
block.dataset.columnIndex = String(index);
|
|
4101
|
+
block.style.marginBottom = index === head.length - 1 ? "0" : "10px";
|
|
4102
|
+
block.style.paddingBottom = index === head.length - 1 ? "0" : "10px";
|
|
4103
|
+
if (index !== head.length - 1) block.style.borderBottom = `1px solid ${colors.split}`;
|
|
4104
|
+
const body = document.createElement("div");
|
|
4105
|
+
body.dataset.control = "column-body";
|
|
4106
|
+
const expanded = collapsible && expandedColumnBlocks.has(columnBlockKey(activeSchema.id, index));
|
|
4107
|
+
if (collapsible) {
|
|
4108
|
+
const summary = document.createElement("button");
|
|
4109
|
+
summary.type = "button";
|
|
4110
|
+
summary.dataset.control = "summary";
|
|
4111
|
+
summary.setAttribute("aria-expanded", expanded ? "true" : "false");
|
|
4112
|
+
summary.setAttribute("aria-label", `Expand ${label}`);
|
|
4113
|
+
summary.title = label;
|
|
4114
|
+
summary.style.display = "flex";
|
|
4115
|
+
summary.style.alignItems = "center";
|
|
4116
|
+
summary.style.gap = "6px";
|
|
4117
|
+
summary.style.width = "100%";
|
|
4118
|
+
summary.style.padding = "0";
|
|
4119
|
+
summary.style.border = "none";
|
|
4120
|
+
summary.style.background = "transparent";
|
|
4121
|
+
summary.style.cursor = "pointer";
|
|
4122
|
+
summary.style.font = "inherit";
|
|
4123
|
+
summary.style.textAlign = "left";
|
|
4124
|
+
const name = document.createElement("span");
|
|
4125
|
+
name.dataset.control = "summary-name";
|
|
4126
|
+
name.textContent = label;
|
|
4127
|
+
name.style.fontWeight = "600";
|
|
4128
|
+
name.style.fontSize = "12px";
|
|
4129
|
+
name.style.flex = "1";
|
|
4130
|
+
ellipsis(name);
|
|
4131
|
+
summary.appendChild(name);
|
|
4132
|
+
const typeLabel = document.createElement("span");
|
|
4133
|
+
typeLabel.dataset.control = "summary-type";
|
|
4134
|
+
typeLabel.textContent = i18n(`schemas.table.cellType.${cellType}`);
|
|
4135
|
+
typeLabel.style.fontSize = "12px";
|
|
4136
|
+
typeLabel.style.flexShrink = "0";
|
|
4137
|
+
summary.appendChild(typeLabel);
|
|
4138
|
+
const alignmentIcon = HORIZONTAL_ALIGNMENTS.find((button) => button.value === alignment);
|
|
4139
|
+
if (alignmentIcon) {
|
|
4140
|
+
const icon = document.createElement("span");
|
|
4141
|
+
icon.dataset.control = "summary-alignment";
|
|
4142
|
+
icon.dataset.value = alignmentIcon.value;
|
|
4143
|
+
icon.style.lineHeight = "0";
|
|
4144
|
+
icon.style.flexShrink = "0";
|
|
4145
|
+
appendIcon(icon, alignmentIcon.icon, colors.text, 14);
|
|
4146
|
+
summary.appendChild(icon);
|
|
4147
|
+
}
|
|
4148
|
+
const verticalIcon = VERTICAL_ALIGNMENTS.find((button) => button.value === verticalAlignment);
|
|
4149
|
+
if (verticalIcon) {
|
|
4150
|
+
const icon = document.createElement("span");
|
|
4151
|
+
icon.dataset.control = "summary-vertical-alignment";
|
|
4152
|
+
icon.dataset.value = verticalIcon.value;
|
|
4153
|
+
icon.style.lineHeight = "0";
|
|
4154
|
+
icon.style.flexShrink = "0";
|
|
4155
|
+
appendIcon(icon, verticalIcon.icon, colors.text, 14);
|
|
4156
|
+
summary.appendChild(icon);
|
|
4157
|
+
}
|
|
4158
|
+
if (cellType === "image" && mode === "fixed") {
|
|
4159
|
+
const height = document.createElement("span");
|
|
4160
|
+
height.dataset.control = "summary-height";
|
|
4161
|
+
height.textContent = `${resolveFixedTableImageHeight(columnStyles.imageHeight?.[index])}mm`;
|
|
4162
|
+
height.style.fontSize = "12px";
|
|
4163
|
+
height.style.flexShrink = "0";
|
|
4164
|
+
summary.appendChild(height);
|
|
4165
|
+
}
|
|
4166
|
+
summary.addEventListener("click", () => {
|
|
4167
|
+
expandedColumnBlocks.add(columnBlockKey(activeSchema.id, index));
|
|
4168
|
+
summary.hidden = true;
|
|
4169
|
+
summary.setAttribute("aria-expanded", "true");
|
|
4170
|
+
body.hidden = false;
|
|
4171
|
+
});
|
|
4172
|
+
summary.hidden = expanded;
|
|
4173
|
+
body.hidden = !expanded;
|
|
4174
|
+
block.appendChild(summary);
|
|
4175
|
+
}
|
|
4176
|
+
const header = document.createElement("div");
|
|
4177
|
+
header.style.display = "flex";
|
|
4178
|
+
header.style.alignItems = "center";
|
|
4179
|
+
header.style.gap = "8px";
|
|
4180
|
+
if (collapsible) {
|
|
4181
|
+
const collapse = document.createElement("button");
|
|
4182
|
+
collapse.type = "button";
|
|
4183
|
+
collapse.dataset.control = "collapse";
|
|
4184
|
+
collapse.setAttribute("aria-expanded", "true");
|
|
4185
|
+
collapse.setAttribute("aria-label", `Collapse ${label}`);
|
|
4186
|
+
collapse.textContent = "▾";
|
|
4187
|
+
collapse.style.border = "none";
|
|
4188
|
+
collapse.style.background = "transparent";
|
|
4189
|
+
collapse.style.cursor = "pointer";
|
|
4190
|
+
collapse.style.padding = "0 2px 0 0";
|
|
4191
|
+
collapse.style.lineHeight = "1";
|
|
4192
|
+
collapse.addEventListener("click", () => {
|
|
4193
|
+
expandedColumnBlocks.delete(columnBlockKey(activeSchema.id, index));
|
|
4194
|
+
const summary = block.querySelector("[data-control=\"summary\"]");
|
|
4195
|
+
if (summary) {
|
|
4196
|
+
summary.hidden = false;
|
|
4197
|
+
summary.setAttribute("aria-expanded", "false");
|
|
4198
|
+
}
|
|
4199
|
+
body.hidden = true;
|
|
4200
|
+
});
|
|
4201
|
+
header.appendChild(collapse);
|
|
4202
|
+
}
|
|
4203
|
+
const title = document.createElement("div");
|
|
4204
|
+
title.dataset.control = "label";
|
|
4205
|
+
title.textContent = label;
|
|
4206
|
+
title.title = label;
|
|
4207
|
+
title.style.fontSize = "12px";
|
|
4208
|
+
title.style.fontWeight = "600";
|
|
4209
|
+
title.style.flex = "1";
|
|
4210
|
+
ellipsis(title);
|
|
4211
|
+
header.appendChild(title);
|
|
4212
|
+
appendSelect(header, TABLE_CELL_TYPES.map((type) => ({
|
|
4213
|
+
value: type,
|
|
4214
|
+
label: i18n(`schemas.table.cellType.${type}`)
|
|
4215
|
+
})), cellType, "cellType", index, metrics, { width: "110px" }, (value) => {
|
|
4216
|
+
if (value !== "text" && value !== "image") return;
|
|
4217
|
+
if (value === cellType) return;
|
|
4218
|
+
setCellType(props, table, index, value);
|
|
4219
|
+
});
|
|
4220
|
+
body.appendChild(header);
|
|
4221
|
+
const alignments = document.createElement("div");
|
|
4222
|
+
alignments.style.display = "flex";
|
|
4223
|
+
alignments.style.justifyContent = "space-between";
|
|
4224
|
+
alignments.style.alignItems = "center";
|
|
4225
|
+
alignments.style.marginTop = "8px";
|
|
4226
|
+
appendButtonGroup(alignments, "alignment", HORIZONTAL_ALIGNMENTS, alignment, index, colors, i18n, (value) => {
|
|
4227
|
+
if (value !== "left" && value !== "center" && value !== "right") return;
|
|
4228
|
+
setAlignment(props, table, index, value);
|
|
4229
|
+
});
|
|
4230
|
+
appendButtonGroup(alignments, "verticalAlignment", VERTICAL_ALIGNMENTS, verticalAlignment, index, colors, i18n, (value) => {
|
|
4231
|
+
if (value !== "top" && value !== "middle" && value !== "bottom") return;
|
|
4232
|
+
setVerticalAlignment(props, table, index, value);
|
|
4233
|
+
});
|
|
4234
|
+
body.appendChild(alignments);
|
|
4235
|
+
if (cellType === "image" && mode) {
|
|
4236
|
+
const imageRow = document.createElement("div");
|
|
4237
|
+
imageRow.style.display = "flex";
|
|
4238
|
+
imageRow.style.alignItems = "center";
|
|
4239
|
+
imageRow.style.gap = "8px";
|
|
4240
|
+
imageRow.style.marginTop = "8px";
|
|
4241
|
+
appendSelect(imageRow, TABLE_IMAGE_HEIGHT_MODES.map((heightMode) => ({
|
|
4242
|
+
value: heightMode,
|
|
4243
|
+
label: i18n(`schemas.table.imageHeightMode.${heightMode}`)
|
|
4244
|
+
})), mode, "imageHeightMode", index, metrics, { flex: "1" }, (value) => {
|
|
4245
|
+
if (value !== "fixed" && value !== "auto") return;
|
|
4246
|
+
if (value === mode) return;
|
|
4247
|
+
setImageHeightMode(props, table, index, value);
|
|
4248
|
+
});
|
|
4249
|
+
if (mode === "fixed") {
|
|
4250
|
+
const displayHeight = resolveFixedTableImageHeight(columnStyles.imageHeight?.[index]);
|
|
4251
|
+
appendNumberInput(imageRow, String(displayHeight), index, i18n("schemas.table.imageHeightMode.fixed"), metrics, (input) => {
|
|
4252
|
+
const parsed = Number(input.value);
|
|
4253
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
4254
|
+
input.value = String(displayHeight);
|
|
4255
|
+
return;
|
|
4256
|
+
}
|
|
4257
|
+
setImageHeight(props, table, index, parsed);
|
|
4258
|
+
});
|
|
4259
|
+
}
|
|
4260
|
+
body.appendChild(imageRow);
|
|
4261
|
+
}
|
|
4262
|
+
block.appendChild(body);
|
|
4263
|
+
rootElement.appendChild(block);
|
|
4264
|
+
});
|
|
4265
|
+
};
|
|
4266
|
+
//#endregion
|
|
3611
4267
|
//#region src/tables/index.ts
|
|
3612
4268
|
var tableSchema = {
|
|
3613
4269
|
pdf: pdfRender,
|
|
3614
4270
|
ui: uiRender,
|
|
3615
4271
|
propPanel: {
|
|
3616
4272
|
schema: ({ activeSchema, options, i18n }) => {
|
|
3617
|
-
const
|
|
3618
|
-
const head = tableSchema.head || [];
|
|
3619
|
-
const showHead = tableSchema.showHead || false;
|
|
4273
|
+
const showHead = activeSchema.showHead || false;
|
|
3620
4274
|
const font = options.font || { [DEFAULT_FONT_NAME]: {
|
|
3621
4275
|
data: "",
|
|
3622
4276
|
fallback: true
|
|
@@ -3691,18 +4345,22 @@ var tableSchema = {
|
|
|
3691
4345
|
isBody: true
|
|
3692
4346
|
})
|
|
3693
4347
|
},
|
|
3694
|
-
|
|
4348
|
+
tableColumns: {
|
|
3695
4349
|
title: i18n("schemas.table.columnStyle"),
|
|
3696
4350
|
type: "object",
|
|
3697
4351
|
widget: "Card",
|
|
4352
|
+
bind: false,
|
|
3698
4353
|
span: 24,
|
|
3699
|
-
properties:
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
4354
|
+
properties: { columns: {
|
|
4355
|
+
type: "void",
|
|
4356
|
+
widget: "TableColumns",
|
|
4357
|
+
bind: false,
|
|
4358
|
+
span: 24
|
|
4359
|
+
} }
|
|
3703
4360
|
}
|
|
3704
4361
|
};
|
|
3705
4362
|
},
|
|
4363
|
+
widgets: { TableColumns },
|
|
3706
4364
|
defaultSchema: {
|
|
3707
4365
|
name: "",
|
|
3708
4366
|
type: "table",
|