@pdfme/schemas 6.2.3 → 6.2.4-dev.2
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/barcodes/constants.d.ts +1 -0
- package/dist/barcodes/helper.d.ts +34 -3
- package/dist/{builtins-BFhn3tdm.js → builtins-Ch7UBNGU.js} +4 -4
- package/dist/{builtins-BFhn3tdm.js.map → builtins-Ch7UBNGU.js.map} +1 -1
- package/dist/builtins.js +1 -1
- package/dist/dynamicLayout.js +1 -1
- package/dist/{dynamicTemplate-1cxsTQIG.js → dynamicTemplate-Bnu4jVaz.js} +532 -51
- package/dist/dynamicTemplate-Bnu4jVaz.js.map +1 -0
- package/dist/graphics/imagehelper.d.ts +6 -1
- package/dist/index.js +1055 -261
- 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 +1 -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-DL6a4DC2.js → utils-BfzehhiZ.js} +2 -2
- package/dist/{utils-DL6a4DC2.js.map → utils-BfzehhiZ.js.map} +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -2
- package/dist/dynamicTemplate-1cxsTQIG.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 HEX_COLOR_PATTERN, i as getBodyWithSchemaRange, l as OPAQUE_HEX_COLOR_PATTERN, n as getDynamicLayoutForTable, o 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;
|
|
@@ -2408,6 +2194,11 @@ var BARCODE_TYPES = [
|
|
|
2408
2194
|
];
|
|
2409
2195
|
var DEFAULT_BARCODE_BG_COLOR = "#ffffff";
|
|
2410
2196
|
var DEFAULT_BARCODE_COLOR = "#000000";
|
|
2197
|
+
var ASPECT_RATIO_LOCKED_BARCODE_TYPES = [
|
|
2198
|
+
"qrcode",
|
|
2199
|
+
"gs1datamatrix",
|
|
2200
|
+
"pdf417"
|
|
2201
|
+
];
|
|
2411
2202
|
//#endregion
|
|
2412
2203
|
//#region src/barcodes/helper.ts
|
|
2413
2204
|
var validateCheckDigit = (input, checkDigitPos) => {
|
|
@@ -2510,17 +2301,67 @@ var renderBarcodeToNodeBuffer = async (options) => {
|
|
|
2510
2301
|
if (typeof toBuffer !== "function") throw new Error("[@pdfme/schemas] bwip-js toBuffer() is not available in this environment.");
|
|
2511
2302
|
return toBuffer(options);
|
|
2512
2303
|
};
|
|
2304
|
+
var aspectRatioLockedTypes = ASPECT_RATIO_LOCKED_BARCODE_TYPES;
|
|
2305
|
+
var isAspectRatioLockedBarcodeType = (type) => aspectRatioLockedTypes.includes(type);
|
|
2306
|
+
var SQUARE_BARCODE_TYPES = ["qrcode", "gs1datamatrix"];
|
|
2307
|
+
var isSquareBarcodeType = (type) => SQUARE_BARCODE_TYPES.includes(type);
|
|
2308
|
+
var SVG_VIEW_BOX_PATTERN = /viewBox="\s*(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)\s*"/;
|
|
2309
|
+
var positiveSize = (value) => {
|
|
2310
|
+
const size = Number(value);
|
|
2311
|
+
return Number.isFinite(size) && size > 0 ? size : void 0;
|
|
2312
|
+
};
|
|
2313
|
+
/** Root `viewBox` width/height, then `width`/`height` attributes. `undefined` when neither parses. */
|
|
2314
|
+
var getSvgViewBoxSize = (svg) => {
|
|
2315
|
+
const viewBox = svg.match(SVG_VIEW_BOX_PATTERN);
|
|
2316
|
+
if (viewBox) {
|
|
2317
|
+
const width = positiveSize(viewBox[3]);
|
|
2318
|
+
const height = positiveSize(viewBox[4]);
|
|
2319
|
+
if (width !== void 0 && height !== void 0) return {
|
|
2320
|
+
width,
|
|
2321
|
+
height
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
const openTag = svg.match(/<svg\b[^>]*>/)?.[0];
|
|
2325
|
+
if (!openTag) return void 0;
|
|
2326
|
+
const width = positiveSize(openTag.match(/\bwidth="([^"]+)"/)?.[1]);
|
|
2327
|
+
const height = positiveSize(openTag.match(/\bheight="([^"]+)"/)?.[1]);
|
|
2328
|
+
if (width === void 0 || height === void 0) return void 0;
|
|
2329
|
+
return {
|
|
2330
|
+
width,
|
|
2331
|
+
height
|
|
2332
|
+
};
|
|
2333
|
+
};
|
|
2334
|
+
/** Centered contain rect for a natural size; the full box when the natural size is unknown. */
|
|
2335
|
+
var getBarcodeFitLayout = ({ boxWidth, boxHeight, naturalWidth, naturalHeight }) => {
|
|
2336
|
+
const stretch = {
|
|
2337
|
+
width: boxWidth,
|
|
2338
|
+
height: boxHeight,
|
|
2339
|
+
offsetX: 0,
|
|
2340
|
+
offsetY: 0
|
|
2341
|
+
};
|
|
2342
|
+
if (naturalWidth === void 0 || naturalHeight === void 0 || naturalWidth <= 0 || naturalHeight <= 0) return stretch;
|
|
2343
|
+
const ratio = naturalWidth / naturalHeight;
|
|
2344
|
+
const widthLimited = boxWidth / boxHeight <= ratio;
|
|
2345
|
+
const width = widthLimited ? boxWidth : boxHeight * ratio;
|
|
2346
|
+
const height = widthLimited ? boxWidth / ratio : boxHeight;
|
|
2347
|
+
return {
|
|
2348
|
+
width,
|
|
2349
|
+
height,
|
|
2350
|
+
offsetX: (boxWidth - width) / 2,
|
|
2351
|
+
offsetY: (boxHeight - height) / 2
|
|
2352
|
+
};
|
|
2353
|
+
};
|
|
2513
2354
|
var createBwipJsRenderOptions = (arg) => {
|
|
2514
2355
|
const { type, input, width, height, backgroundColor, barColor, textColor, includetext = true } = arg;
|
|
2515
2356
|
const bwipjsArg = {
|
|
2516
2357
|
bcid: barCodeType2Bcid(type),
|
|
2517
2358
|
text: input,
|
|
2518
|
-
width,
|
|
2519
|
-
height,
|
|
2520
2359
|
scale: 5,
|
|
2521
2360
|
includetext,
|
|
2522
2361
|
textxalign: "center"
|
|
2523
2362
|
};
|
|
2363
|
+
if (width !== void 0) bwipjsArg.width = width;
|
|
2364
|
+
if (height !== void 0) bwipjsArg.height = height;
|
|
2524
2365
|
if (backgroundColor) bwipjsArg.backgroundcolor = mapHexColorForBwipJsLib(backgroundColor);
|
|
2525
2366
|
if (barColor) bwipjsArg.barcolor = mapHexColorForBwipJsLib(barColor);
|
|
2526
2367
|
if (textColor) bwipjsArg.textcolor = mapHexColorForBwipJsLib(textColor);
|
|
@@ -2534,6 +2375,39 @@ var createBarCodeSvg = (arg) => {
|
|
|
2534
2375
|
if (/<image\b/i.test(svg)) throw new Error(`[@pdfme/schemas] bwip-js emitted an embedded image for ${arg.type}; vector barcode PDF rendering requires path-based SVG.`);
|
|
2535
2376
|
return svg;
|
|
2536
2377
|
};
|
|
2378
|
+
/** Natural (unscaled) symbol size from bwip-js, in SVG user units. */
|
|
2379
|
+
var getNaturalBarcodeSize = (schema, input) => getSvgViewBoxSize(createBarCodeSvg({
|
|
2380
|
+
...schema,
|
|
2381
|
+
width: void 0,
|
|
2382
|
+
height: void 0,
|
|
2383
|
+
backgroundColor: void 0,
|
|
2384
|
+
input
|
|
2385
|
+
}));
|
|
2386
|
+
var contentAspectRatioMemo = /* @__PURE__ */ new Map();
|
|
2387
|
+
var CONTENT_ASPECT_RATIO_MEMO_LIMIT = 200;
|
|
2388
|
+
/**
|
|
2389
|
+
* Natural width / height of a locked symbology; undefined for 1D types. Square types
|
|
2390
|
+
* return 1 even for empty content. The Designer calls this on every width/height/content
|
|
2391
|
+
* commit, so content-dependent ratios are memoized.
|
|
2392
|
+
*/
|
|
2393
|
+
var getBarcodeAspectRatio = (schema) => {
|
|
2394
|
+
if (!isAspectRatioLockedBarcodeType(schema.type)) return void 0;
|
|
2395
|
+
if (isSquareBarcodeType(schema.type)) return 1;
|
|
2396
|
+
const input = schema.content ?? "";
|
|
2397
|
+
if (!validateBarcodeInput(schema.type, input)) return void 0;
|
|
2398
|
+
const key = `${schema.type}:${input}`;
|
|
2399
|
+
if (contentAspectRatioMemo.has(key)) return contentAspectRatioMemo.get(key);
|
|
2400
|
+
let ratio;
|
|
2401
|
+
try {
|
|
2402
|
+
const size = getNaturalBarcodeSize(schema, input);
|
|
2403
|
+
ratio = size ? size.width / size.height : void 0;
|
|
2404
|
+
} catch {
|
|
2405
|
+
ratio = void 0;
|
|
2406
|
+
}
|
|
2407
|
+
if (contentAspectRatioMemo.size >= CONTENT_ASPECT_RATIO_MEMO_LIMIT) contentAspectRatioMemo.clear();
|
|
2408
|
+
contentAspectRatioMemo.set(key, ratio);
|
|
2409
|
+
return ratio;
|
|
2410
|
+
};
|
|
2537
2411
|
var createBarCode = async (arg) => {
|
|
2538
2412
|
const bwipjsArg = createBwipJsRenderOptions(arg);
|
|
2539
2413
|
const runtime = resolveBarcodeRenderRuntime();
|
|
@@ -2543,8 +2417,20 @@ var createBarCode = async (arg) => {
|
|
|
2543
2417
|
};
|
|
2544
2418
|
//#endregion
|
|
2545
2419
|
//#region src/barcodes/pdfRender.ts
|
|
2546
|
-
var getBarcodeCacheKey = (schema, value) => {
|
|
2547
|
-
return `svg:${schema.type}:${
|
|
2420
|
+
var getBarcodeCacheKey = (schema, size, value) => {
|
|
2421
|
+
return `svg:${schema.type}:${size.width}:${size.height}:${schema.barColor}:${schema.textColor}:${schema.includetext}:${value}`;
|
|
2422
|
+
};
|
|
2423
|
+
var getNaturalSize = (schema, value, cache) => {
|
|
2424
|
+
if (!isAspectRatioLockedBarcodeType(schema.type)) return void 0;
|
|
2425
|
+
if (isSquareBarcodeType(schema.type)) return {
|
|
2426
|
+
width: 1,
|
|
2427
|
+
height: 1
|
|
2428
|
+
};
|
|
2429
|
+
const key = `svg-natural:${schema.type}:${value}`;
|
|
2430
|
+
if (cache.has(key)) return cache.get(key);
|
|
2431
|
+
const size = getNaturalBarcodeSize(schema, value);
|
|
2432
|
+
cache.set(key, size);
|
|
2433
|
+
return size;
|
|
2548
2434
|
};
|
|
2549
2435
|
var addSvgOpacity = (svg, opacity) => {
|
|
2550
2436
|
return opacity === void 0 ? svg : svg.replace(/<svg\b/, `<svg opacity="${opacity}"`);
|
|
@@ -2558,11 +2444,20 @@ var getSvgColorMapper = (colorType = "") => {
|
|
|
2558
2444
|
var pdfRender$1 = async (arg) => {
|
|
2559
2445
|
const { value, schema, page, options, _cache } = arg;
|
|
2560
2446
|
if (!validateBarcodeInput(schema.type, value)) return;
|
|
2561
|
-
const
|
|
2447
|
+
const natural = getNaturalSize(schema, value, _cache);
|
|
2448
|
+
const fitted = getBarcodeFitLayout({
|
|
2449
|
+
boxWidth: schema.width,
|
|
2450
|
+
boxHeight: schema.height,
|
|
2451
|
+
naturalWidth: natural?.width,
|
|
2452
|
+
naturalHeight: natural?.height
|
|
2453
|
+
});
|
|
2454
|
+
const inputBarcodeCacheKey = getBarcodeCacheKey(schema, fitted, value);
|
|
2562
2455
|
let svg = _cache.get(inputBarcodeCacheKey);
|
|
2563
2456
|
if (!svg) {
|
|
2564
2457
|
svg = createBarCodeSvg({
|
|
2565
2458
|
...schema,
|
|
2459
|
+
width: fitted.width,
|
|
2460
|
+
height: fitted.height,
|
|
2566
2461
|
backgroundColor: void 0,
|
|
2567
2462
|
type: schema.type,
|
|
2568
2463
|
input: value
|
|
@@ -2596,11 +2491,17 @@ var pdfRender$1 = async (arg) => {
|
|
|
2596
2491
|
opacity: applyAlphaToOpacity(opacity, alpha)
|
|
2597
2492
|
});
|
|
2598
2493
|
}
|
|
2494
|
+
const layout = getBarcodeFitLayout({
|
|
2495
|
+
boxWidth: width,
|
|
2496
|
+
boxHeight: height,
|
|
2497
|
+
naturalWidth: natural?.width,
|
|
2498
|
+
naturalHeight: natural?.height
|
|
2499
|
+
});
|
|
2599
2500
|
await page.drawSvg(addSvgOpacity(svg, opacity), {
|
|
2600
|
-
x,
|
|
2601
|
-
y: y + height,
|
|
2602
|
-
width,
|
|
2603
|
-
height,
|
|
2501
|
+
x: x + layout.offsetX,
|
|
2502
|
+
y: y + height - layout.offsetY,
|
|
2503
|
+
width: layout.width,
|
|
2504
|
+
height: layout.height,
|
|
2604
2505
|
mapColor: getSvgColorMapper(options.colorType)
|
|
2605
2506
|
});
|
|
2606
2507
|
} finally {
|
|
@@ -2764,7 +2665,7 @@ var barcodeDefaults = [
|
|
|
2764
2665
|
position,
|
|
2765
2666
|
...defaultColors,
|
|
2766
2667
|
width: 40,
|
|
2767
|
-
height:
|
|
2668
|
+
height: 11.65,
|
|
2768
2669
|
rotate: 0,
|
|
2769
2670
|
opacity: 1
|
|
2770
2671
|
} }
|
|
@@ -2836,9 +2737,25 @@ var createBarcodeImage = async (schema, value) => {
|
|
|
2836
2737
|
return await blobToDataURL(new Blob([new Uint8Array(imageBuf)], { type: "image/png" }));
|
|
2837
2738
|
};
|
|
2838
2739
|
var createBarcodeImageElm = async (schema, value) => {
|
|
2839
|
-
const barcodeDataURL = await createBarcodeImage(schema, value);
|
|
2840
2740
|
const img = document.createElement("img");
|
|
2841
|
-
|
|
2741
|
+
if (isAspectRatioLockedBarcodeType(schema.type)) {
|
|
2742
|
+
const svg = createBarCodeSvg({
|
|
2743
|
+
...schema,
|
|
2744
|
+
width: void 0,
|
|
2745
|
+
height: void 0,
|
|
2746
|
+
backgroundColor: void 0,
|
|
2747
|
+
input: value
|
|
2748
|
+
});
|
|
2749
|
+
img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
2750
|
+
const imgStyle = {
|
|
2751
|
+
...fullSize,
|
|
2752
|
+
objectFit: "contain",
|
|
2753
|
+
borderRadius: 0
|
|
2754
|
+
};
|
|
2755
|
+
Object.assign(img.style, imgStyle);
|
|
2756
|
+
return img;
|
|
2757
|
+
}
|
|
2758
|
+
img.src = await createBarcodeImage(schema, value);
|
|
2842
2759
|
const imgStyle = {
|
|
2843
2760
|
...fullSize,
|
|
2844
2761
|
borderRadius: 0
|
|
@@ -2909,7 +2826,8 @@ var barcodes = BARCODE_TYPES.reduce((acc, type) => Object.assign(acc, { [type]:
|
|
|
2909
2826
|
pdf: pdfRender$1,
|
|
2910
2827
|
ui: uiRender$1,
|
|
2911
2828
|
propPanel: getPropPanelByBarcodeType(type),
|
|
2912
|
-
icon: createSvgStr(type == "qrcode" ? QrCode : Barcode)
|
|
2829
|
+
icon: createSvgStr(type == "qrcode" ? QrCode : Barcode),
|
|
2830
|
+
...isAspectRatioLockedBarcodeType(type) ? { getAspectRatio: getBarcodeAspectRatio } : {}
|
|
2913
2831
|
} }), {});
|
|
2914
2832
|
//#endregion
|
|
2915
2833
|
//#region src/shapes/line.ts
|
|
@@ -3000,7 +2918,154 @@ var lineSchema = {
|
|
|
3000
2918
|
icon: createSvgStr(Minus)
|
|
3001
2919
|
};
|
|
3002
2920
|
//#endregion
|
|
2921
|
+
//#region src/tables/imageCellUi.ts
|
|
2922
|
+
var buttonSize$1 = 18;
|
|
2923
|
+
var pendingImagePicker = null;
|
|
2924
|
+
var tableSchemaKey = (schema) => typeof schema.id === "string" && schema.id !== "" ? schema.id : schema.name;
|
|
2925
|
+
var noteRenderingTable = (schema) => {
|
|
2926
|
+
const schemaKey = tableSchemaKey(schema);
|
|
2927
|
+
if (pendingImagePicker && pendingImagePicker.schemaKey !== schemaKey) pendingImagePicker = null;
|
|
2928
|
+
};
|
|
2929
|
+
var clearImagePickerRequest = () => {
|
|
2930
|
+
pendingImagePicker = null;
|
|
2931
|
+
};
|
|
2932
|
+
var requestImagePicker = (request) => {
|
|
2933
|
+
pendingImagePicker = request;
|
|
2934
|
+
};
|
|
2935
|
+
var consumePendingImagePicker = (request) => {
|
|
2936
|
+
const pending = pendingImagePicker;
|
|
2937
|
+
if (!pending || pending.rowIndex !== request.rowIndex || pending.colIndex !== request.colIndex || pending.schemaKey !== request.schemaKey) return false;
|
|
2938
|
+
pendingImagePicker = null;
|
|
2939
|
+
return true;
|
|
2940
|
+
};
|
|
2941
|
+
var createImageButton = (options) => {
|
|
2942
|
+
const button = document.createElement("button");
|
|
2943
|
+
button.type = "button";
|
|
2944
|
+
button.innerText = options.text;
|
|
2945
|
+
button.setAttribute("aria-label", options.ariaLabel);
|
|
2946
|
+
button.title = options.ariaLabel;
|
|
2947
|
+
button.style.width = `${buttonSize$1}px`;
|
|
2948
|
+
button.style.height = `${buttonSize$1}px`;
|
|
2949
|
+
button.style.position = "absolute";
|
|
2950
|
+
button.style.top = "0px";
|
|
2951
|
+
button.style.right = options.right;
|
|
2952
|
+
button.style.display = "inline-flex";
|
|
2953
|
+
button.style.alignItems = "center";
|
|
2954
|
+
button.style.justifyContent = "center";
|
|
2955
|
+
button.style.padding = "0";
|
|
2956
|
+
button.style.border = "1px solid #d9d9d9";
|
|
2957
|
+
button.style.borderRadius = "3px";
|
|
2958
|
+
button.style.background = "#ffffff";
|
|
2959
|
+
button.style.color = "#333333";
|
|
2960
|
+
button.style.fontSize = "11px";
|
|
2961
|
+
button.style.lineHeight = "1";
|
|
2962
|
+
button.style.cursor = "pointer";
|
|
2963
|
+
button.style.zIndex = "20";
|
|
2964
|
+
button.addEventListener("mousedown", (event) => {
|
|
2965
|
+
event.preventDefault();
|
|
2966
|
+
});
|
|
2967
|
+
button.addEventListener("click", (event) => {
|
|
2968
|
+
event.preventDefault();
|
|
2969
|
+
event.stopPropagation();
|
|
2970
|
+
options.onClick();
|
|
2971
|
+
});
|
|
2972
|
+
return button;
|
|
2973
|
+
};
|
|
2974
|
+
var appendFrame = (schema) => {
|
|
2975
|
+
const contentArea = getBoxContentArea(schema);
|
|
2976
|
+
const frame = document.createElement("div");
|
|
2977
|
+
frame.style.position = "absolute";
|
|
2978
|
+
frame.style.zIndex = "1";
|
|
2979
|
+
frame.style.width = `${contentArea.width}mm`;
|
|
2980
|
+
frame.style.height = `${contentArea.height}mm`;
|
|
2981
|
+
frame.style.top = `${contentArea.topInset}mm`;
|
|
2982
|
+
frame.style.left = `${contentArea.leftInset}mm`;
|
|
2983
|
+
frame.style.boxSizing = "border-box";
|
|
2984
|
+
return frame;
|
|
2985
|
+
};
|
|
2986
|
+
var warnUnsupportedImage = (columnIndex) => {
|
|
2987
|
+
console.warn(`[@pdfme/schemas/table] unsupported image in column ${columnIndex ?? 0}; only PNG/JPEG data URL is supported`);
|
|
2988
|
+
};
|
|
2989
|
+
var renderTableImageCellUi = (arg) => {
|
|
2990
|
+
const { schema, rootElement, value, onChange, i18n, _cache } = arg;
|
|
2991
|
+
const dimension = value ? resolveImageDimension(value, _cache) : void 0;
|
|
2992
|
+
const frame = appendFrame(schema);
|
|
2993
|
+
if (dimension && value) {
|
|
2994
|
+
const img = document.createElement("img");
|
|
2995
|
+
img.alt = "";
|
|
2996
|
+
img.src = value;
|
|
2997
|
+
img.style.width = "100%";
|
|
2998
|
+
img.style.height = "100%";
|
|
2999
|
+
img.style.objectFit = "contain";
|
|
3000
|
+
img.style.objectPosition = getTableImageObjectPosition(schema.alignment, schema.verticalAlignment);
|
|
3001
|
+
frame.appendChild(img);
|
|
3002
|
+
} else {
|
|
3003
|
+
frame.textContent = i18n("schemas.table.imageCell.placeholder");
|
|
3004
|
+
frame.style.border = "1px dotted #999";
|
|
3005
|
+
frame.style.color = "#999";
|
|
3006
|
+
frame.style.fontSize = "10px";
|
|
3007
|
+
frame.style.display = "flex";
|
|
3008
|
+
frame.style.alignItems = "center";
|
|
3009
|
+
frame.style.justifyContent = "center";
|
|
3010
|
+
frame.style.textAlign = "center";
|
|
3011
|
+
frame.style.overflow = "hidden";
|
|
3012
|
+
frame.style.padding = "1mm";
|
|
3013
|
+
}
|
|
3014
|
+
rootElement.appendChild(frame);
|
|
3015
|
+
const input = document.createElement("input");
|
|
3016
|
+
input.type = "file";
|
|
3017
|
+
input.accept = "image/png, image/jpeg";
|
|
3018
|
+
input.tabIndex = -1;
|
|
3019
|
+
input.style.display = "none";
|
|
3020
|
+
input.addEventListener("click", (event) => {
|
|
3021
|
+
event.stopPropagation();
|
|
3022
|
+
});
|
|
3023
|
+
input.addEventListener("change", () => {
|
|
3024
|
+
if (!input.files || input.files.length === 0) return;
|
|
3025
|
+
readFile(input.files).then((result) => {
|
|
3026
|
+
if (typeof result === "string" && TABLE_IMAGE_DATA_URL_PATTERN.test(result) && resolveImageDimension(result, _cache)) {
|
|
3027
|
+
onChange?.({
|
|
3028
|
+
key: "content",
|
|
3029
|
+
value: result
|
|
3030
|
+
});
|
|
3031
|
+
return;
|
|
3032
|
+
}
|
|
3033
|
+
warnUnsupportedImage(schema.columnIndex);
|
|
3034
|
+
}).catch(() => {
|
|
3035
|
+
warnUnsupportedImage(schema.columnIndex);
|
|
3036
|
+
});
|
|
3037
|
+
});
|
|
3038
|
+
rootElement.appendChild(input);
|
|
3039
|
+
const hasValue = typeof value === "string" && value !== "";
|
|
3040
|
+
rootElement.appendChild(createImageButton({
|
|
3041
|
+
text: "▣",
|
|
3042
|
+
ariaLabel: i18n("schemas.table.imageCell.select"),
|
|
3043
|
+
right: hasValue ? `20px` : "0px",
|
|
3044
|
+
onClick: () => {
|
|
3045
|
+
input.click();
|
|
3046
|
+
}
|
|
3047
|
+
}));
|
|
3048
|
+
if (hasValue) rootElement.appendChild(createImageButton({
|
|
3049
|
+
text: "×",
|
|
3050
|
+
ariaLabel: i18n("schemas.table.imageCell.remove"),
|
|
3051
|
+
right: "0px",
|
|
3052
|
+
onClick: () => {
|
|
3053
|
+
onChange?.({
|
|
3054
|
+
key: "content",
|
|
3055
|
+
value: ""
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
}));
|
|
3059
|
+
const { rowIndex, columnIndex, pickerSchemaKey } = schema;
|
|
3060
|
+
if (typeof rowIndex === "number" && typeof columnIndex === "number" && typeof pickerSchemaKey === "string" && consumePendingImagePicker({
|
|
3061
|
+
rowIndex,
|
|
3062
|
+
colIndex: columnIndex,
|
|
3063
|
+
schemaKey: pickerSchemaKey
|
|
3064
|
+
}) && !hasValue) input.click();
|
|
3065
|
+
};
|
|
3066
|
+
//#endregion
|
|
3003
3067
|
//#region src/tables/cell.ts
|
|
3068
|
+
var imagePdfRender = imageSchema.pdf;
|
|
3004
3069
|
var linePdfRender = lineSchema.pdf;
|
|
3005
3070
|
var rectanglePdfRender$1 = rectangle.pdf;
|
|
3006
3071
|
var renderLine = async (arg, schema, position, width, height) => linePdfRender({
|
|
@@ -3072,6 +3137,32 @@ var cellSchema = {
|
|
|
3072
3137
|
y: position.y
|
|
3073
3138
|
}, borderWidth.left, height)
|
|
3074
3139
|
]);
|
|
3140
|
+
if (schema.cellType === "image") {
|
|
3141
|
+
if (arg.value && resolveImageDimension(arg.value, arg._cache)) {
|
|
3142
|
+
const imageSchema = {
|
|
3143
|
+
name: schema.name,
|
|
3144
|
+
type: "image",
|
|
3145
|
+
content: arg.value,
|
|
3146
|
+
position: contentArea.position,
|
|
3147
|
+
width: contentArea.width,
|
|
3148
|
+
height: contentArea.height,
|
|
3149
|
+
rotate: 0,
|
|
3150
|
+
opacity: 1,
|
|
3151
|
+
objectFit: "contain",
|
|
3152
|
+
objectPosition: getTableImageObjectPosition(schema.alignment, schema.verticalAlignment)
|
|
3153
|
+
};
|
|
3154
|
+
try {
|
|
3155
|
+
await imagePdfRender({
|
|
3156
|
+
...arg,
|
|
3157
|
+
value: arg.value,
|
|
3158
|
+
schema: imageSchema
|
|
3159
|
+
});
|
|
3160
|
+
} catch {
|
|
3161
|
+
warnInvalidTableImageOnce(arg.value, schema.columnIndex ?? 0, arg._cache);
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
return;
|
|
3165
|
+
}
|
|
3075
3166
|
await pdfRender$4({
|
|
3076
3167
|
...arg,
|
|
3077
3168
|
schema: {
|
|
@@ -3091,19 +3182,35 @@ var cellSchema = {
|
|
|
3091
3182
|
const { schema, rootElement } = arg;
|
|
3092
3183
|
const { borderWidth, width, height, borderColor, backgroundColor } = schema;
|
|
3093
3184
|
rootElement.style.backgroundColor = backgroundColor;
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3185
|
+
if (schema.cellType === "image") {
|
|
3186
|
+
if (arg.mode === "designer") renderTableImageCellUi(arg);
|
|
3187
|
+
else if (arg.value ? resolveImageDimension(arg.value, arg._cache) : void 0) {
|
|
3188
|
+
const imageFrame = createTextDiv(schema);
|
|
3189
|
+
const img = document.createElement("img");
|
|
3190
|
+
img.alt = "";
|
|
3191
|
+
img.src = arg.value;
|
|
3192
|
+
img.style.width = "100%";
|
|
3193
|
+
img.style.height = "100%";
|
|
3194
|
+
img.style.objectFit = "contain";
|
|
3195
|
+
img.style.objectPosition = getTableImageObjectPosition(schema.alignment, schema.verticalAlignment);
|
|
3196
|
+
imageFrame.appendChild(img);
|
|
3197
|
+
rootElement.appendChild(imageFrame);
|
|
3198
|
+
}
|
|
3199
|
+
} else {
|
|
3200
|
+
const textDiv = createTextDiv(schema);
|
|
3201
|
+
await uiRender$4({
|
|
3202
|
+
...arg,
|
|
3203
|
+
schema: {
|
|
3204
|
+
...schema,
|
|
3205
|
+
backgroundColor: "",
|
|
3206
|
+
borderColor: "",
|
|
3207
|
+
borderWidth: createBoxDimension(0),
|
|
3208
|
+
padding: createBoxDimension(0)
|
|
3209
|
+
},
|
|
3210
|
+
rootElement: textDiv
|
|
3211
|
+
});
|
|
3212
|
+
rootElement.appendChild(textDiv);
|
|
3213
|
+
}
|
|
3107
3214
|
[
|
|
3108
3215
|
createLineDiv(`${width}mm`, `${borderWidth.top}mm`, "0mm", null, null, "0mm", borderColor),
|
|
3109
3216
|
createLineDiv(`${width}mm`, `${borderWidth.bottom}mm`, null, null, "0mm", "0mm", borderColor),
|
|
@@ -3143,7 +3250,7 @@ var cellSchema = {
|
|
|
3143
3250
|
//#region src/tables/pdfRender.ts
|
|
3144
3251
|
var rectanglePdfRender = rectangle.pdf;
|
|
3145
3252
|
var cellPdfRender = cellSchema.pdf;
|
|
3146
|
-
async function drawCell(arg, cell) {
|
|
3253
|
+
async function drawCell(arg, cell, columnIndex) {
|
|
3147
3254
|
await cellPdfRender({
|
|
3148
3255
|
...arg,
|
|
3149
3256
|
value: cell.raw,
|
|
@@ -3166,7 +3273,9 @@ async function drawCell(arg, cell) {
|
|
|
3166
3273
|
fontColor: cell.styles.textColor,
|
|
3167
3274
|
borderColor: cell.styles.lineColor,
|
|
3168
3275
|
borderWidth: cell.styles.lineWidth,
|
|
3169
|
-
padding: cell.styles.cellPadding
|
|
3276
|
+
padding: cell.styles.cellPadding,
|
|
3277
|
+
cellType: cell.isImage() ? "image" : "text",
|
|
3278
|
+
columnIndex
|
|
3170
3279
|
}
|
|
3171
3280
|
});
|
|
3172
3281
|
}
|
|
@@ -3180,7 +3289,7 @@ async function drawRow(arg, table, row, cursor, columns) {
|
|
|
3180
3289
|
}
|
|
3181
3290
|
cell.x = cursor.x;
|
|
3182
3291
|
cell.y = cursor.y;
|
|
3183
|
-
await drawCell(arg, cell);
|
|
3292
|
+
await drawCell(arg, cell, column.index);
|
|
3184
3293
|
cursor.x += column.width;
|
|
3185
3294
|
}
|
|
3186
3295
|
cursor.y += row.height;
|
|
@@ -3294,7 +3403,7 @@ var calcResizedHeadWidthPercentages = (arg) => {
|
|
|
3294
3403
|
var setBorder = (div, borderPosition, arg) => {
|
|
3295
3404
|
div.style[`border${borderPosition}`] = `${String(arg.schema.tableStyles.borderWidth)}mm solid ${arg.schema.tableStyles.borderColor}`;
|
|
3296
3405
|
};
|
|
3297
|
-
var drawBorder = (div, row, colIndex, rowIndex, rowsLength, arg) => {
|
|
3406
|
+
var drawBorder = (div, row, colIndex, rowIndex, rowsLength, arg, bodyLength) => {
|
|
3298
3407
|
const isFirstColumn = colIndex === 0;
|
|
3299
3408
|
const isLastColumn = colIndex === Object.values(row.cells).length - 1;
|
|
3300
3409
|
const isLastRow = rowIndex === rowsLength - 1;
|
|
@@ -3302,7 +3411,7 @@ var drawBorder = (div, row, colIndex, rowIndex, rowsLength, arg) => {
|
|
|
3302
3411
|
setBorder(div, "Top", arg);
|
|
3303
3412
|
if (isFirstColumn) setBorder(div, "Left", arg);
|
|
3304
3413
|
if (isLastColumn) setBorder(div, "Right", arg);
|
|
3305
|
-
if (
|
|
3414
|
+
if (bodyLength === 0) setBorder(div, "Bottom", arg);
|
|
3306
3415
|
} else if (row.section === "body") {
|
|
3307
3416
|
if (!arg.schema.showHead && rowIndex === 0) setBorder(div, "Top", arg);
|
|
3308
3417
|
if (isFirstColumn) setBorder(div, "Left", arg);
|
|
@@ -3325,20 +3434,28 @@ var renderRowUi = (args) => {
|
|
|
3325
3434
|
div.style.width = `${cell.width}mm`;
|
|
3326
3435
|
div.style.height = `${cell.height}mm`;
|
|
3327
3436
|
div.style.boxSizing = "border-box";
|
|
3328
|
-
drawBorder(div, row, colIndex, rowIndex, rows.length, arg);
|
|
3329
|
-
|
|
3437
|
+
drawBorder(div, row, colIndex, rowIndex, rows.length, arg, value.length);
|
|
3438
|
+
const imageCellEditable = arg.mode === "designer" || arg.mode === "form" && !arg.schema.readOnly;
|
|
3439
|
+
div.style.cursor = cell.isImage() ? imageCellEditable && section === "body" ? "pointer" : "default" : arg.mode === "designer" || arg.mode === "form" && section === "body" ? "text" : "default";
|
|
3330
3440
|
div.addEventListener("click", () => {
|
|
3331
3441
|
if (arg.mode === "viewer") return;
|
|
3442
|
+
const enteringEmptyImageCell = cell.isImage() && section === "body" && imageCellEditable && cell.raw === "" && (editingPosition.rowIndex !== rowIndex || editingPosition.colIndex !== colIndex);
|
|
3332
3443
|
onChangeEditingPosition({
|
|
3333
3444
|
rowIndex,
|
|
3334
3445
|
colIndex
|
|
3335
3446
|
});
|
|
3447
|
+
if (enteringEmptyImageCell) requestImagePicker({
|
|
3448
|
+
rowIndex,
|
|
3449
|
+
colIndex,
|
|
3450
|
+
schemaKey: tableSchemaKey(arg.schema)
|
|
3451
|
+
});
|
|
3336
3452
|
});
|
|
3337
3453
|
arg.rootElement.appendChild(div);
|
|
3338
3454
|
const isEditing = editingPosition.rowIndex === rowIndex && editingPosition.colIndex === colIndex;
|
|
3339
3455
|
let mode = "viewer";
|
|
3340
3456
|
if (arg.mode === "form") mode = section === "body" && isEditing && !arg.schema.readOnly ? "designer" : "viewer";
|
|
3341
3457
|
else if (arg.mode === "designer") mode = isEditing ? "designer" : "form";
|
|
3458
|
+
if (cell.isImage() && !isEditing) mode = "viewer";
|
|
3342
3459
|
cellUiRender({
|
|
3343
3460
|
...arg,
|
|
3344
3461
|
stopEditing: () => {
|
|
@@ -3377,7 +3494,11 @@ var renderRowUi = (args) => {
|
|
|
3377
3494
|
},
|
|
3378
3495
|
width: cell.width,
|
|
3379
3496
|
height: cell.height,
|
|
3380
|
-
...convertToCellStyle(cell.styles)
|
|
3497
|
+
...convertToCellStyle(cell.styles),
|
|
3498
|
+
cellType: cell.isImage() ? "image" : "text",
|
|
3499
|
+
columnIndex: colIndex,
|
|
3500
|
+
rowIndex,
|
|
3501
|
+
pickerSchemaKey: tableSchemaKey(arg.schema)
|
|
3381
3502
|
}
|
|
3382
3503
|
});
|
|
3383
3504
|
colOffsetX += cell.width;
|
|
@@ -3398,9 +3519,11 @@ var resetEditingPosition = () => {
|
|
|
3398
3519
|
headEditingPosition.colIndex = -1;
|
|
3399
3520
|
bodyEditingPosition.rowIndex = -1;
|
|
3400
3521
|
bodyEditingPosition.colIndex = -1;
|
|
3522
|
+
clearImagePickerRequest();
|
|
3401
3523
|
};
|
|
3402
3524
|
var uiRender = async (arg) => {
|
|
3403
3525
|
const { rootElement, onChange, schema, value, mode, scale } = arg;
|
|
3526
|
+
noteRenderingTable(schema);
|
|
3404
3527
|
const body = getBody(value);
|
|
3405
3528
|
const bodyRange = getTableBodyRange(schema);
|
|
3406
3529
|
const bodyWidthRange = getBodyWithSchemaRange(value, schema, bodyRange);
|
|
@@ -3526,6 +3649,10 @@ var uiRender = async (arg) => {
|
|
|
3526
3649
|
{
|
|
3527
3650
|
key: "content",
|
|
3528
3651
|
value: JSON.stringify(bodyWidthRange.map((row) => row.filter((_, j) => j !== i)))
|
|
3652
|
+
},
|
|
3653
|
+
{
|
|
3654
|
+
key: "columnStyles",
|
|
3655
|
+
value: remapColumnStylesOnRemove(schema.columnStyles ?? {}, i)
|
|
3529
3656
|
}
|
|
3530
3657
|
]);
|
|
3531
3658
|
}
|
|
@@ -3604,15 +3731,678 @@ var uiRender = async (arg) => {
|
|
|
3604
3731
|
});
|
|
3605
3732
|
};
|
|
3606
3733
|
//#endregion
|
|
3734
|
+
//#region src/tables/columnsWidget.ts
|
|
3735
|
+
var cellTypeWarnCache = /* @__PURE__ */ new Map();
|
|
3736
|
+
/** More than this many columns, and each block can collapse. */
|
|
3737
|
+
var COLLAPSE_WHEN_MORE_THAN = 6;
|
|
3738
|
+
var expandedColumnBlocks = /* @__PURE__ */ new Set();
|
|
3739
|
+
var columnBlockKey = (schemaId, columnIndex) => `${schemaId}:${columnIndex}`;
|
|
3740
|
+
var themeRecord = (theme) => theme ?? void 0;
|
|
3741
|
+
var themeToken = (theme, key, fallback) => {
|
|
3742
|
+
const value = themeRecord(theme)?.[key];
|
|
3743
|
+
return typeof value === "string" && value.length > 0 ? value : fallback;
|
|
3744
|
+
};
|
|
3745
|
+
var themeNumber = (theme, key, fallback) => {
|
|
3746
|
+
const value = themeRecord(theme)?.[key];
|
|
3747
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
3748
|
+
};
|
|
3749
|
+
/** antd outlined Select / InputNumber metrics, read from the Designer token when present. */
|
|
3750
|
+
var panelControlMetrics = (theme) => {
|
|
3751
|
+
const lineWidth = themeNumber(theme, "lineWidth", 1);
|
|
3752
|
+
const controlHeight = themeNumber(theme, "controlHeight", 32);
|
|
3753
|
+
const paddingSm = themeNumber(theme, "paddingSM", 12);
|
|
3754
|
+
const controlHeightSm = themeNumber(theme, "controlHeightSM", 24);
|
|
3755
|
+
const fontSize = themeNumber(theme, "fontSize", 14);
|
|
3756
|
+
const outlineWidth = themeNumber(theme, "controlOutlineWidth", 2);
|
|
3757
|
+
return {
|
|
3758
|
+
lineWidth,
|
|
3759
|
+
controlHeight,
|
|
3760
|
+
borderRadius: themeNumber(theme, "borderRadius", 6),
|
|
3761
|
+
fontSize,
|
|
3762
|
+
paddingInline: Math.max(0, paddingSm - lineWidth),
|
|
3763
|
+
handleWidth: Math.max(0, controlHeightSm - lineWidth * 2),
|
|
3764
|
+
handleFontSize: fontSize / 2,
|
|
3765
|
+
outlineWidth,
|
|
3766
|
+
colorBorder: themeToken(theme, "colorBorder", "#d9d9d9"),
|
|
3767
|
+
colorBg: themeToken(theme, "colorBgContainer", "#ffffff"),
|
|
3768
|
+
colorText: themeToken(theme, "colorText", "rgba(0, 0, 0, 0.88)"),
|
|
3769
|
+
colorArrow: themeToken(theme, "colorTextQuaternary", "rgba(0, 0, 0, 0.25)"),
|
|
3770
|
+
colorIcon: themeToken(theme, "colorIcon", "rgba(0, 0, 0, 0.45)"),
|
|
3771
|
+
colorPrimary: themeToken(theme, "colorPrimary", "#1677ff"),
|
|
3772
|
+
colorPrimaryHover: themeToken(theme, "colorPrimaryHover", "#4096ff"),
|
|
3773
|
+
controlOutline: themeToken(theme, "controlOutline", "rgba(5, 145, 255, 0.1)"),
|
|
3774
|
+
motion: themeToken(theme, "motionDurationMid", "0.2s")
|
|
3775
|
+
};
|
|
3776
|
+
};
|
|
3777
|
+
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";
|
|
3778
|
+
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";
|
|
3779
|
+
var appendSvgIcon = (parent, path, size) => {
|
|
3780
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
3781
|
+
svg.setAttribute("viewBox", "64 64 896 896");
|
|
3782
|
+
svg.setAttribute("width", String(size));
|
|
3783
|
+
svg.setAttribute("height", String(size));
|
|
3784
|
+
svg.setAttribute("fill", "currentColor");
|
|
3785
|
+
svg.setAttribute("aria-hidden", "true");
|
|
3786
|
+
svg.setAttribute("focusable", "false");
|
|
3787
|
+
const shape = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
3788
|
+
shape.setAttribute("d", path);
|
|
3789
|
+
svg.appendChild(shape);
|
|
3790
|
+
parent.appendChild(svg);
|
|
3791
|
+
};
|
|
3792
|
+
var ensurePanelControlStyles = (rootElement, metrics) => {
|
|
3793
|
+
rootElement.style.setProperty("--pdfme-border", metrics.colorBorder);
|
|
3794
|
+
rootElement.style.setProperty("--pdfme-hover-border", metrics.colorPrimaryHover);
|
|
3795
|
+
rootElement.style.setProperty("--pdfme-active-border", metrics.colorPrimary);
|
|
3796
|
+
rootElement.style.setProperty("--pdfme-outline", metrics.controlOutline);
|
|
3797
|
+
rootElement.style.setProperty("--pdfme-outline-width", `${metrics.outlineWidth}px`);
|
|
3798
|
+
rootElement.style.setProperty("--pdfme-handle-width", `${metrics.handleWidth}px`);
|
|
3799
|
+
rootElement.style.setProperty("--pdfme-handle-hover", metrics.colorPrimary);
|
|
3800
|
+
rootElement.style.setProperty("--pdfme-padding-inline", `${metrics.paddingInline}px`);
|
|
3801
|
+
if (rootElement.querySelector("style[data-pdfme-column-controls]")) return;
|
|
3802
|
+
const style = document.createElement("style");
|
|
3803
|
+
style.dataset.pdfmeColumnControls = "true";
|
|
3804
|
+
style.textContent = `
|
|
3805
|
+
.pdfme-column-select,
|
|
3806
|
+
.pdfme-column-number {
|
|
3807
|
+
border-color: var(--pdfme-border);
|
|
3808
|
+
}
|
|
3809
|
+
.pdfme-column-select:hover,
|
|
3810
|
+
.pdfme-column-number:hover {
|
|
3811
|
+
border-color: var(--pdfme-hover-border);
|
|
3812
|
+
}
|
|
3813
|
+
.pdfme-column-select:focus-within,
|
|
3814
|
+
.pdfme-column-number:focus-within {
|
|
3815
|
+
border-color: var(--pdfme-active-border);
|
|
3816
|
+
box-shadow: 0 0 0 var(--pdfme-outline-width) var(--pdfme-outline);
|
|
3817
|
+
outline: 0;
|
|
3818
|
+
}
|
|
3819
|
+
.pdfme-column-select-input,
|
|
3820
|
+
.pdfme-column-number-input {
|
|
3821
|
+
outline: none;
|
|
3822
|
+
}
|
|
3823
|
+
.pdfme-column-select-input {
|
|
3824
|
+
appearance: none;
|
|
3825
|
+
-webkit-appearance: none;
|
|
3826
|
+
}
|
|
3827
|
+
.pdfme-column-number-input {
|
|
3828
|
+
appearance: textfield;
|
|
3829
|
+
-moz-appearance: textfield;
|
|
3830
|
+
padding-left: var(--pdfme-padding-inline);
|
|
3831
|
+
padding-right: var(--pdfme-padding-inline);
|
|
3832
|
+
}
|
|
3833
|
+
.pdfme-column-number:hover .pdfme-column-number-input,
|
|
3834
|
+
.pdfme-column-number:focus-within .pdfme-column-number-input {
|
|
3835
|
+
padding-right: calc(var(--pdfme-handle-width) + var(--pdfme-padding-inline));
|
|
3836
|
+
}
|
|
3837
|
+
.pdfme-column-number-input::-webkit-outer-spin-button,
|
|
3838
|
+
.pdfme-column-number-input::-webkit-inner-spin-button {
|
|
3839
|
+
-webkit-appearance: none;
|
|
3840
|
+
margin: 0;
|
|
3841
|
+
}
|
|
3842
|
+
.pdfme-column-number-handlers {
|
|
3843
|
+
opacity: 0;
|
|
3844
|
+
width: 0;
|
|
3845
|
+
}
|
|
3846
|
+
.pdfme-column-number:hover .pdfme-column-number-handlers,
|
|
3847
|
+
.pdfme-column-number:focus-within .pdfme-column-number-handlers {
|
|
3848
|
+
opacity: 1;
|
|
3849
|
+
width: var(--pdfme-handle-width);
|
|
3850
|
+
}
|
|
3851
|
+
.pdfme-column-number-handler:hover {
|
|
3852
|
+
color: var(--pdfme-handle-hover);
|
|
3853
|
+
height: 60%;
|
|
3854
|
+
}
|
|
3855
|
+
`;
|
|
3856
|
+
rootElement.appendChild(style);
|
|
3857
|
+
};
|
|
3858
|
+
var HORIZONTAL_ALIGNMENTS = [
|
|
3859
|
+
{
|
|
3860
|
+
value: "left",
|
|
3861
|
+
icon: TextAlignLeftIcon,
|
|
3862
|
+
labelKey: "schemas.left"
|
|
3863
|
+
},
|
|
3864
|
+
{
|
|
3865
|
+
value: "center",
|
|
3866
|
+
icon: TextAlignCenterIcon,
|
|
3867
|
+
labelKey: "schemas.center"
|
|
3868
|
+
},
|
|
3869
|
+
{
|
|
3870
|
+
value: "right",
|
|
3871
|
+
icon: TextAlignRightIcon,
|
|
3872
|
+
labelKey: "schemas.right"
|
|
3873
|
+
}
|
|
3874
|
+
];
|
|
3875
|
+
var VERTICAL_ALIGNMENTS = [
|
|
3876
|
+
{
|
|
3877
|
+
value: "top",
|
|
3878
|
+
icon: TextVerticalAlignTopIcon,
|
|
3879
|
+
labelKey: "schemas.top"
|
|
3880
|
+
},
|
|
3881
|
+
{
|
|
3882
|
+
value: "middle",
|
|
3883
|
+
icon: TextVerticalAlignMiddleIcon,
|
|
3884
|
+
labelKey: "schemas.middle"
|
|
3885
|
+
},
|
|
3886
|
+
{
|
|
3887
|
+
value: "bottom",
|
|
3888
|
+
icon: TextVerticalAlignBottomIcon,
|
|
3889
|
+
labelKey: "schemas.bottom"
|
|
3890
|
+
}
|
|
3891
|
+
];
|
|
3892
|
+
var isUnset = (value) => value == null;
|
|
3893
|
+
var clearColumnContent = (content, columnIndex) => {
|
|
3894
|
+
let rows;
|
|
3895
|
+
try {
|
|
3896
|
+
rows = JSON.parse(content ?? "[]");
|
|
3897
|
+
} catch {
|
|
3898
|
+
return content ?? "[]";
|
|
3899
|
+
}
|
|
3900
|
+
if (!Array.isArray(rows)) return content ?? "[]";
|
|
3901
|
+
const next = rows.map((row) => {
|
|
3902
|
+
if (!Array.isArray(row)) return row;
|
|
3903
|
+
const copy = row.slice();
|
|
3904
|
+
if (columnIndex < copy.length) copy[columnIndex] = "";
|
|
3905
|
+
return copy;
|
|
3906
|
+
});
|
|
3907
|
+
return JSON.stringify(next);
|
|
3908
|
+
};
|
|
3909
|
+
var dropColumnKey = (map, columnIndex) => {
|
|
3910
|
+
if (!map) return map;
|
|
3911
|
+
const next = { ...map };
|
|
3912
|
+
delete next[columnIndex];
|
|
3913
|
+
return Object.keys(next).length === 0 ? void 0 : next;
|
|
3914
|
+
};
|
|
3915
|
+
var columnLabel = (head, index, i18n) => {
|
|
3916
|
+
const label = head[index];
|
|
3917
|
+
return label ? label : `${i18n("schemas.table.columnLabel")} ${index + 1}`;
|
|
3918
|
+
};
|
|
3919
|
+
var commitStyles = (props, columnStyles, content) => {
|
|
3920
|
+
const schemaId = props.activeSchema.id;
|
|
3921
|
+
const changes = [{
|
|
3922
|
+
key: "columnStyles",
|
|
3923
|
+
value: columnStyles,
|
|
3924
|
+
schemaId
|
|
3925
|
+
}];
|
|
3926
|
+
if (content !== void 0) changes.push({
|
|
3927
|
+
key: "content",
|
|
3928
|
+
value: content,
|
|
3929
|
+
schemaId
|
|
3930
|
+
});
|
|
3931
|
+
props.changeSchemas(changes);
|
|
3932
|
+
};
|
|
3933
|
+
var setCellType = (props, table, columnIndex, nextType) => {
|
|
3934
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3935
|
+
if (nextType === "image") {
|
|
3936
|
+
next.cellType = {
|
|
3937
|
+
...next.cellType,
|
|
3938
|
+
[columnIndex]: "image"
|
|
3939
|
+
};
|
|
3940
|
+
if (isUnset(next.imageHeightMode?.[columnIndex])) next.imageHeightMode = {
|
|
3941
|
+
...next.imageHeightMode,
|
|
3942
|
+
[columnIndex]: DEFAULT_TABLE_IMAGE_HEIGHT_MODE
|
|
3943
|
+
};
|
|
3944
|
+
if (isUnset(next.imageHeight?.[columnIndex])) next.imageHeight = {
|
|
3945
|
+
...next.imageHeight,
|
|
3946
|
+
[columnIndex]: 20
|
|
3947
|
+
};
|
|
3948
|
+
if (isUnset(next.alignment?.[columnIndex])) next.alignment = {
|
|
3949
|
+
...next.alignment,
|
|
3950
|
+
[columnIndex]: "center"
|
|
3951
|
+
};
|
|
3952
|
+
} else {
|
|
3953
|
+
const cellType = dropColumnKey(next.cellType, columnIndex);
|
|
3954
|
+
const imageHeightMode = dropColumnKey(next.imageHeightMode, columnIndex);
|
|
3955
|
+
const imageHeight = dropColumnKey(next.imageHeight, columnIndex);
|
|
3956
|
+
if (cellType) next.cellType = cellType;
|
|
3957
|
+
else delete next.cellType;
|
|
3958
|
+
if (imageHeightMode) next.imageHeightMode = imageHeightMode;
|
|
3959
|
+
else delete next.imageHeightMode;
|
|
3960
|
+
if (imageHeight) next.imageHeight = imageHeight;
|
|
3961
|
+
else delete next.imageHeight;
|
|
3962
|
+
}
|
|
3963
|
+
commitStyles(props, next, clearColumnContent(table.content, columnIndex));
|
|
3964
|
+
};
|
|
3965
|
+
var setImageHeightMode = (props, table, columnIndex, mode) => {
|
|
3966
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3967
|
+
next.imageHeightMode = {
|
|
3968
|
+
...next.imageHeightMode,
|
|
3969
|
+
[columnIndex]: mode
|
|
3970
|
+
};
|
|
3971
|
+
commitStyles(props, next);
|
|
3972
|
+
};
|
|
3973
|
+
var setImageHeight = (props, table, columnIndex, height) => {
|
|
3974
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3975
|
+
next.imageHeight = {
|
|
3976
|
+
...next.imageHeight,
|
|
3977
|
+
[columnIndex]: height
|
|
3978
|
+
};
|
|
3979
|
+
commitStyles(props, next);
|
|
3980
|
+
};
|
|
3981
|
+
var setAlignment = (props, table, columnIndex, value) => {
|
|
3982
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3983
|
+
if (next.alignment?.[columnIndex] === value) return;
|
|
3984
|
+
next.alignment = {
|
|
3985
|
+
...next.alignment,
|
|
3986
|
+
[columnIndex]: value
|
|
3987
|
+
};
|
|
3988
|
+
commitStyles(props, next);
|
|
3989
|
+
};
|
|
3990
|
+
var setVerticalAlignment = (props, table, columnIndex, value) => {
|
|
3991
|
+
const next = cloneDeep(table.columnStyles ?? {});
|
|
3992
|
+
if (next.verticalAlignment?.[columnIndex] === value) return;
|
|
3993
|
+
next.verticalAlignment = {
|
|
3994
|
+
...next.verticalAlignment,
|
|
3995
|
+
[columnIndex]: value
|
|
3996
|
+
};
|
|
3997
|
+
commitStyles(props, next);
|
|
3998
|
+
};
|
|
3999
|
+
var iconSrc = (svg, color) => `data:image/svg+xml;utf8,${encodeURIComponent(svg.replace(/currentColor/g, color))}`;
|
|
4000
|
+
var appendIcon = (parent, svg, color, size = 17) => {
|
|
4001
|
+
const img = document.createElement("img");
|
|
4002
|
+
img.alt = "";
|
|
4003
|
+
img.width = size;
|
|
4004
|
+
img.height = size;
|
|
4005
|
+
img.src = iconSrc(svg, color);
|
|
4006
|
+
parent.appendChild(img);
|
|
4007
|
+
return img;
|
|
4008
|
+
};
|
|
4009
|
+
var appendSelect = (parent, options, value, control, columnIndex, metrics, layout, onChange) => {
|
|
4010
|
+
const shell = document.createElement("div");
|
|
4011
|
+
shell.className = "pdfme-column-select";
|
|
4012
|
+
shell.style.position = "relative";
|
|
4013
|
+
shell.style.display = "inline-flex";
|
|
4014
|
+
shell.style.alignItems = "center";
|
|
4015
|
+
shell.style.boxSizing = "border-box";
|
|
4016
|
+
shell.style.height = `${metrics.controlHeight}px`;
|
|
4017
|
+
shell.style.borderWidth = `${metrics.lineWidth}px`;
|
|
4018
|
+
shell.style.borderStyle = "solid";
|
|
4019
|
+
shell.style.borderRadius = `${metrics.borderRadius}px`;
|
|
4020
|
+
shell.style.background = metrics.colorBg;
|
|
4021
|
+
shell.style.overflow = "hidden";
|
|
4022
|
+
shell.style.transition = `all ${metrics.motion}`;
|
|
4023
|
+
shell.style.flexShrink = layout.flex ? "1" : "0";
|
|
4024
|
+
if (layout.width) shell.style.width = layout.width;
|
|
4025
|
+
if (layout.flex) {
|
|
4026
|
+
shell.style.flex = layout.flex;
|
|
4027
|
+
shell.style.minWidth = "0";
|
|
4028
|
+
}
|
|
4029
|
+
const select = document.createElement("select");
|
|
4030
|
+
select.className = "pdfme-column-select-input";
|
|
4031
|
+
select.dataset.control = control;
|
|
4032
|
+
select.dataset.columnIndex = String(columnIndex);
|
|
4033
|
+
select.style.width = "100%";
|
|
4034
|
+
select.style.height = "100%";
|
|
4035
|
+
select.style.boxSizing = "border-box";
|
|
4036
|
+
select.style.margin = "0";
|
|
4037
|
+
select.style.border = "0";
|
|
4038
|
+
select.style.borderRadius = `${metrics.borderRadius}px`;
|
|
4039
|
+
select.style.background = "transparent";
|
|
4040
|
+
select.style.padding = `0 ${metrics.paddingInline + 18}px 0 ${metrics.paddingInline}px`;
|
|
4041
|
+
select.style.font = "inherit";
|
|
4042
|
+
select.style.fontSize = `${metrics.fontSize}px`;
|
|
4043
|
+
select.style.lineHeight = `${metrics.controlHeight - metrics.lineWidth * 2}px`;
|
|
4044
|
+
select.style.color = metrics.colorText;
|
|
4045
|
+
select.style.cursor = "pointer";
|
|
4046
|
+
options.forEach((option) => {
|
|
4047
|
+
const element = document.createElement("option");
|
|
4048
|
+
element.value = option.value;
|
|
4049
|
+
element.textContent = option.label;
|
|
4050
|
+
select.appendChild(element);
|
|
4051
|
+
});
|
|
4052
|
+
select.value = value;
|
|
4053
|
+
select.addEventListener("change", () => {
|
|
4054
|
+
onChange(select.value);
|
|
4055
|
+
});
|
|
4056
|
+
const arrow = document.createElement("span");
|
|
4057
|
+
arrow.className = "pdfme-column-select-arrow";
|
|
4058
|
+
arrow.setAttribute("aria-hidden", "true");
|
|
4059
|
+
arrow.style.position = "absolute";
|
|
4060
|
+
arrow.style.top = "50%";
|
|
4061
|
+
arrow.style.right = `${metrics.paddingInline}px`;
|
|
4062
|
+
arrow.style.transform = "translateY(-50%)";
|
|
4063
|
+
arrow.style.display = "flex";
|
|
4064
|
+
arrow.style.width = "12px";
|
|
4065
|
+
arrow.style.height = "12px";
|
|
4066
|
+
arrow.style.color = metrics.colorArrow;
|
|
4067
|
+
arrow.style.fontSize = "12px";
|
|
4068
|
+
arrow.style.lineHeight = "1";
|
|
4069
|
+
arrow.style.pointerEvents = "none";
|
|
4070
|
+
appendSvgIcon(arrow, ANT_DOWN_PATH, 12);
|
|
4071
|
+
shell.appendChild(select);
|
|
4072
|
+
shell.appendChild(arrow);
|
|
4073
|
+
parent.appendChild(shell);
|
|
4074
|
+
return select;
|
|
4075
|
+
};
|
|
4076
|
+
var appendNumberInput = (parent, value, columnIndex, ariaLabel, metrics, onCommit) => {
|
|
4077
|
+
const shell = document.createElement("div");
|
|
4078
|
+
shell.className = "pdfme-column-number";
|
|
4079
|
+
shell.style.position = "relative";
|
|
4080
|
+
shell.style.display = "inline-flex";
|
|
4081
|
+
shell.style.alignItems = "center";
|
|
4082
|
+
shell.style.boxSizing = "border-box";
|
|
4083
|
+
shell.style.width = "72px";
|
|
4084
|
+
shell.style.height = `${metrics.controlHeight}px`;
|
|
4085
|
+
shell.style.flexShrink = "0";
|
|
4086
|
+
shell.style.borderWidth = `${metrics.lineWidth}px`;
|
|
4087
|
+
shell.style.borderStyle = "solid";
|
|
4088
|
+
shell.style.borderRadius = `${metrics.borderRadius}px`;
|
|
4089
|
+
shell.style.background = metrics.colorBg;
|
|
4090
|
+
shell.style.transition = `all ${metrics.motion}`;
|
|
4091
|
+
shell.style.overflow = "hidden";
|
|
4092
|
+
const input = document.createElement("input");
|
|
4093
|
+
input.type = "number";
|
|
4094
|
+
input.min = "1";
|
|
4095
|
+
input.step = "1";
|
|
4096
|
+
input.className = "pdfme-column-number-input";
|
|
4097
|
+
input.dataset.control = "imageHeight";
|
|
4098
|
+
input.dataset.columnIndex = String(columnIndex);
|
|
4099
|
+
input.setAttribute("aria-label", ariaLabel);
|
|
4100
|
+
input.style.width = "100%";
|
|
4101
|
+
input.style.height = "100%";
|
|
4102
|
+
input.style.boxSizing = "border-box";
|
|
4103
|
+
input.style.margin = "0";
|
|
4104
|
+
input.style.border = "0";
|
|
4105
|
+
input.style.borderRadius = "0";
|
|
4106
|
+
input.style.background = "transparent";
|
|
4107
|
+
input.style.font = "inherit";
|
|
4108
|
+
input.style.fontSize = `${metrics.fontSize}px`;
|
|
4109
|
+
input.style.lineHeight = "22px";
|
|
4110
|
+
input.style.color = metrics.colorText;
|
|
4111
|
+
input.value = value;
|
|
4112
|
+
input.addEventListener("change", () => {
|
|
4113
|
+
onCommit(input);
|
|
4114
|
+
});
|
|
4115
|
+
const handlers = document.createElement("div");
|
|
4116
|
+
handlers.className = "pdfme-column-number-handlers";
|
|
4117
|
+
handlers.style.position = "absolute";
|
|
4118
|
+
handlers.style.top = "0";
|
|
4119
|
+
handlers.style.right = "0";
|
|
4120
|
+
handlers.style.bottom = "0";
|
|
4121
|
+
handlers.style.display = "flex";
|
|
4122
|
+
handlers.style.flexDirection = "column";
|
|
4123
|
+
handlers.style.overflow = "hidden";
|
|
4124
|
+
handlers.style.background = metrics.colorBg;
|
|
4125
|
+
handlers.style.borderRadius = `0 ${metrics.borderRadius}px ${metrics.borderRadius}px 0`;
|
|
4126
|
+
handlers.style.transition = `all ${metrics.motion}`;
|
|
4127
|
+
const step = (delta) => {
|
|
4128
|
+
const current = Number(input.value);
|
|
4129
|
+
const base = Number.isFinite(current) ? current : Number(value);
|
|
4130
|
+
const next = Math.max(1, base + delta);
|
|
4131
|
+
if (next === base) return;
|
|
4132
|
+
input.value = String(next);
|
|
4133
|
+
input.dispatchEvent(new Event("change"));
|
|
4134
|
+
};
|
|
4135
|
+
const addHandler = (direction, path, label) => {
|
|
4136
|
+
const button = document.createElement("button");
|
|
4137
|
+
button.type = "button";
|
|
4138
|
+
button.className = "pdfme-column-number-handler";
|
|
4139
|
+
button.dataset.control = direction === "up" ? "imageHeightUp" : "imageHeightDown";
|
|
4140
|
+
button.setAttribute("aria-label", label);
|
|
4141
|
+
button.style.flex = "1 1 50%";
|
|
4142
|
+
button.style.display = "flex";
|
|
4143
|
+
button.style.alignItems = "center";
|
|
4144
|
+
button.style.justifyContent = "center";
|
|
4145
|
+
button.style.margin = "0";
|
|
4146
|
+
button.style.padding = "0";
|
|
4147
|
+
button.style.border = "0";
|
|
4148
|
+
button.style.borderLeft = `${metrics.lineWidth}px solid ${metrics.colorBorder}`;
|
|
4149
|
+
button.style.background = "transparent";
|
|
4150
|
+
button.style.color = metrics.colorIcon;
|
|
4151
|
+
button.style.cursor = "pointer";
|
|
4152
|
+
button.style.lineHeight = "0";
|
|
4153
|
+
if (direction === "down") button.style.borderTop = `${metrics.lineWidth}px solid ${metrics.colorBorder}`;
|
|
4154
|
+
button.addEventListener("mousedown", (event) => {
|
|
4155
|
+
event.preventDefault();
|
|
4156
|
+
});
|
|
4157
|
+
button.addEventListener("click", () => {
|
|
4158
|
+
step(direction === "up" ? 1 : -1);
|
|
4159
|
+
});
|
|
4160
|
+
appendSvgIcon(button, path, metrics.handleFontSize);
|
|
4161
|
+
handlers.appendChild(button);
|
|
4162
|
+
};
|
|
4163
|
+
addHandler("up", ANT_UP_PATH, "Increase Value");
|
|
4164
|
+
addHandler("down", ANT_DOWN_PATH, "Decrease Value");
|
|
4165
|
+
shell.appendChild(input);
|
|
4166
|
+
shell.appendChild(handlers);
|
|
4167
|
+
parent.appendChild(shell);
|
|
4168
|
+
return input;
|
|
4169
|
+
};
|
|
4170
|
+
var appendButtonGroup = (parent, control, buttons, current, columnIndex, colors, i18n, onSelect) => {
|
|
4171
|
+
const group = document.createElement("div");
|
|
4172
|
+
group.dataset.control = control;
|
|
4173
|
+
group.dataset.columnIndex = String(columnIndex);
|
|
4174
|
+
group.setAttribute("role", "group");
|
|
4175
|
+
group.style.display = "inline-flex";
|
|
4176
|
+
buttons.forEach((button, index) => {
|
|
4177
|
+
const element = document.createElement("button");
|
|
4178
|
+
element.type = "button";
|
|
4179
|
+
element.dataset.value = button.value;
|
|
4180
|
+
const label = i18n(button.labelKey);
|
|
4181
|
+
element.setAttribute("aria-label", label);
|
|
4182
|
+
element.title = label;
|
|
4183
|
+
const active = current === button.value;
|
|
4184
|
+
element.setAttribute("aria-pressed", active ? "true" : "false");
|
|
4185
|
+
element.style.padding = "7px";
|
|
4186
|
+
element.style.lineHeight = "0";
|
|
4187
|
+
element.style.background = "transparent";
|
|
4188
|
+
element.style.cursor = "pointer";
|
|
4189
|
+
element.style.border = `1px solid ${active ? colors.primary : colors.border}`;
|
|
4190
|
+
element.style.marginLeft = index === 0 ? "0" : "-1px";
|
|
4191
|
+
element.style.borderRadius = index === 0 ? "6px 0 0 6px" : index === buttons.length - 1 ? "0 6px 6px 0" : "0";
|
|
4192
|
+
element.style.position = "relative";
|
|
4193
|
+
element.style.zIndex = active ? "1" : "0";
|
|
4194
|
+
appendIcon(element, button.icon, active ? colors.primary : colors.text);
|
|
4195
|
+
element.addEventListener("click", () => {
|
|
4196
|
+
if (current === button.value) return;
|
|
4197
|
+
onSelect(button.value);
|
|
4198
|
+
});
|
|
4199
|
+
group.appendChild(element);
|
|
4200
|
+
});
|
|
4201
|
+
parent.appendChild(group);
|
|
4202
|
+
return group;
|
|
4203
|
+
};
|
|
4204
|
+
var ellipsis = (element) => {
|
|
4205
|
+
element.style.overflow = "hidden";
|
|
4206
|
+
element.style.textOverflow = "ellipsis";
|
|
4207
|
+
element.style.whiteSpace = "nowrap";
|
|
4208
|
+
element.style.minWidth = "0";
|
|
4209
|
+
};
|
|
4210
|
+
var TableColumns = (props) => {
|
|
4211
|
+
const { rootElement, activeSchema, i18n } = props;
|
|
4212
|
+
const table = activeSchema;
|
|
4213
|
+
const head = table.head || [];
|
|
4214
|
+
const columnStyles = table.columnStyles ?? {};
|
|
4215
|
+
const metrics = panelControlMetrics(props.theme);
|
|
4216
|
+
ensurePanelControlStyles(rootElement, metrics);
|
|
4217
|
+
const colors = {
|
|
4218
|
+
primary: themeToken(props.theme, "colorPrimary", "#1677ff"),
|
|
4219
|
+
border: themeToken(props.theme, "colorBorder", "#d9d9d9"),
|
|
4220
|
+
text: themeToken(props.theme, "colorText", "#000000"),
|
|
4221
|
+
split: themeToken(props.theme, "colorSplit", "#f0f0f0")
|
|
4222
|
+
};
|
|
4223
|
+
const collapsible = head.length > COLLAPSE_WHEN_MORE_THAN;
|
|
4224
|
+
head.forEach((_, index) => {
|
|
4225
|
+
const storedType = columnStyles.cellType?.[index];
|
|
4226
|
+
const cellType = normalizeTableCellType(storedType, index, cellTypeWarnCache) ?? "text";
|
|
4227
|
+
const label = columnLabel(head, index, i18n);
|
|
4228
|
+
const alignment = columnStyles.alignment?.[index];
|
|
4229
|
+
const verticalAlignment = columnStyles.verticalAlignment?.[index];
|
|
4230
|
+
const mode = cellType === "image" ? normalizeTableImageHeightMode(columnStyles.imageHeightMode?.[index]) ?? "fixed" : void 0;
|
|
4231
|
+
const block = document.createElement("div");
|
|
4232
|
+
block.dataset.columnIndex = String(index);
|
|
4233
|
+
block.style.marginBottom = index === head.length - 1 ? "0" : "10px";
|
|
4234
|
+
block.style.paddingBottom = index === head.length - 1 ? "0" : "10px";
|
|
4235
|
+
if (index !== head.length - 1) block.style.borderBottom = `1px solid ${colors.split}`;
|
|
4236
|
+
const body = document.createElement("div");
|
|
4237
|
+
body.dataset.control = "column-body";
|
|
4238
|
+
const expanded = collapsible && expandedColumnBlocks.has(columnBlockKey(activeSchema.id, index));
|
|
4239
|
+
if (collapsible) {
|
|
4240
|
+
const summary = document.createElement("button");
|
|
4241
|
+
summary.type = "button";
|
|
4242
|
+
summary.dataset.control = "summary";
|
|
4243
|
+
summary.setAttribute("aria-expanded", expanded ? "true" : "false");
|
|
4244
|
+
summary.setAttribute("aria-label", `Expand ${label}`);
|
|
4245
|
+
summary.title = label;
|
|
4246
|
+
summary.style.display = "flex";
|
|
4247
|
+
summary.style.alignItems = "center";
|
|
4248
|
+
summary.style.gap = "6px";
|
|
4249
|
+
summary.style.width = "100%";
|
|
4250
|
+
summary.style.padding = "0";
|
|
4251
|
+
summary.style.border = "none";
|
|
4252
|
+
summary.style.background = "transparent";
|
|
4253
|
+
summary.style.cursor = "pointer";
|
|
4254
|
+
summary.style.font = "inherit";
|
|
4255
|
+
summary.style.textAlign = "left";
|
|
4256
|
+
const name = document.createElement("span");
|
|
4257
|
+
name.dataset.control = "summary-name";
|
|
4258
|
+
name.textContent = label;
|
|
4259
|
+
name.style.fontWeight = "600";
|
|
4260
|
+
name.style.fontSize = "12px";
|
|
4261
|
+
name.style.flex = "1";
|
|
4262
|
+
ellipsis(name);
|
|
4263
|
+
summary.appendChild(name);
|
|
4264
|
+
const typeLabel = document.createElement("span");
|
|
4265
|
+
typeLabel.dataset.control = "summary-type";
|
|
4266
|
+
typeLabel.textContent = i18n(`schemas.table.cellType.${cellType}`);
|
|
4267
|
+
typeLabel.style.fontSize = "12px";
|
|
4268
|
+
typeLabel.style.flexShrink = "0";
|
|
4269
|
+
summary.appendChild(typeLabel);
|
|
4270
|
+
const alignmentIcon = HORIZONTAL_ALIGNMENTS.find((button) => button.value === alignment);
|
|
4271
|
+
if (alignmentIcon) {
|
|
4272
|
+
const icon = document.createElement("span");
|
|
4273
|
+
icon.dataset.control = "summary-alignment";
|
|
4274
|
+
icon.dataset.value = alignmentIcon.value;
|
|
4275
|
+
icon.style.lineHeight = "0";
|
|
4276
|
+
icon.style.flexShrink = "0";
|
|
4277
|
+
appendIcon(icon, alignmentIcon.icon, colors.text, 14);
|
|
4278
|
+
summary.appendChild(icon);
|
|
4279
|
+
}
|
|
4280
|
+
const verticalIcon = VERTICAL_ALIGNMENTS.find((button) => button.value === verticalAlignment);
|
|
4281
|
+
if (verticalIcon) {
|
|
4282
|
+
const icon = document.createElement("span");
|
|
4283
|
+
icon.dataset.control = "summary-vertical-alignment";
|
|
4284
|
+
icon.dataset.value = verticalIcon.value;
|
|
4285
|
+
icon.style.lineHeight = "0";
|
|
4286
|
+
icon.style.flexShrink = "0";
|
|
4287
|
+
appendIcon(icon, verticalIcon.icon, colors.text, 14);
|
|
4288
|
+
summary.appendChild(icon);
|
|
4289
|
+
}
|
|
4290
|
+
if (cellType === "image" && mode === "fixed") {
|
|
4291
|
+
const height = document.createElement("span");
|
|
4292
|
+
height.dataset.control = "summary-height";
|
|
4293
|
+
height.textContent = `${resolveFixedTableImageHeight(columnStyles.imageHeight?.[index])}mm`;
|
|
4294
|
+
height.style.fontSize = "12px";
|
|
4295
|
+
height.style.flexShrink = "0";
|
|
4296
|
+
summary.appendChild(height);
|
|
4297
|
+
}
|
|
4298
|
+
summary.addEventListener("click", () => {
|
|
4299
|
+
expandedColumnBlocks.add(columnBlockKey(activeSchema.id, index));
|
|
4300
|
+
summary.hidden = true;
|
|
4301
|
+
summary.setAttribute("aria-expanded", "true");
|
|
4302
|
+
body.hidden = false;
|
|
4303
|
+
});
|
|
4304
|
+
summary.hidden = expanded;
|
|
4305
|
+
body.hidden = !expanded;
|
|
4306
|
+
block.appendChild(summary);
|
|
4307
|
+
}
|
|
4308
|
+
const header = document.createElement("div");
|
|
4309
|
+
header.style.display = "flex";
|
|
4310
|
+
header.style.alignItems = "center";
|
|
4311
|
+
header.style.gap = "8px";
|
|
4312
|
+
if (collapsible) {
|
|
4313
|
+
const collapse = document.createElement("button");
|
|
4314
|
+
collapse.type = "button";
|
|
4315
|
+
collapse.dataset.control = "collapse";
|
|
4316
|
+
collapse.setAttribute("aria-expanded", "true");
|
|
4317
|
+
collapse.setAttribute("aria-label", `Collapse ${label}`);
|
|
4318
|
+
collapse.textContent = "▾";
|
|
4319
|
+
collapse.style.border = "none";
|
|
4320
|
+
collapse.style.background = "transparent";
|
|
4321
|
+
collapse.style.cursor = "pointer";
|
|
4322
|
+
collapse.style.padding = "0 2px 0 0";
|
|
4323
|
+
collapse.style.lineHeight = "1";
|
|
4324
|
+
collapse.addEventListener("click", () => {
|
|
4325
|
+
expandedColumnBlocks.delete(columnBlockKey(activeSchema.id, index));
|
|
4326
|
+
const summary = block.querySelector("[data-control=\"summary\"]");
|
|
4327
|
+
if (summary) {
|
|
4328
|
+
summary.hidden = false;
|
|
4329
|
+
summary.setAttribute("aria-expanded", "false");
|
|
4330
|
+
}
|
|
4331
|
+
body.hidden = true;
|
|
4332
|
+
});
|
|
4333
|
+
header.appendChild(collapse);
|
|
4334
|
+
}
|
|
4335
|
+
const title = document.createElement("div");
|
|
4336
|
+
title.dataset.control = "label";
|
|
4337
|
+
title.textContent = label;
|
|
4338
|
+
title.title = label;
|
|
4339
|
+
title.style.fontSize = "12px";
|
|
4340
|
+
title.style.fontWeight = "600";
|
|
4341
|
+
title.style.flex = "1";
|
|
4342
|
+
ellipsis(title);
|
|
4343
|
+
header.appendChild(title);
|
|
4344
|
+
appendSelect(header, TABLE_CELL_TYPES.map((type) => ({
|
|
4345
|
+
value: type,
|
|
4346
|
+
label: i18n(`schemas.table.cellType.${type}`)
|
|
4347
|
+
})), cellType, "cellType", index, metrics, { width: "110px" }, (value) => {
|
|
4348
|
+
if (value !== "text" && value !== "image") return;
|
|
4349
|
+
if (value === cellType) return;
|
|
4350
|
+
setCellType(props, table, index, value);
|
|
4351
|
+
});
|
|
4352
|
+
body.appendChild(header);
|
|
4353
|
+
const alignments = document.createElement("div");
|
|
4354
|
+
alignments.style.display = "flex";
|
|
4355
|
+
alignments.style.justifyContent = "space-between";
|
|
4356
|
+
alignments.style.alignItems = "center";
|
|
4357
|
+
alignments.style.marginTop = "8px";
|
|
4358
|
+
appendButtonGroup(alignments, "alignment", HORIZONTAL_ALIGNMENTS, alignment, index, colors, i18n, (value) => {
|
|
4359
|
+
if (value !== "left" && value !== "center" && value !== "right") return;
|
|
4360
|
+
setAlignment(props, table, index, value);
|
|
4361
|
+
});
|
|
4362
|
+
appendButtonGroup(alignments, "verticalAlignment", VERTICAL_ALIGNMENTS, verticalAlignment, index, colors, i18n, (value) => {
|
|
4363
|
+
if (value !== "top" && value !== "middle" && value !== "bottom") return;
|
|
4364
|
+
setVerticalAlignment(props, table, index, value);
|
|
4365
|
+
});
|
|
4366
|
+
body.appendChild(alignments);
|
|
4367
|
+
if (cellType === "image" && mode) {
|
|
4368
|
+
const imageRow = document.createElement("div");
|
|
4369
|
+
imageRow.style.display = "flex";
|
|
4370
|
+
imageRow.style.alignItems = "center";
|
|
4371
|
+
imageRow.style.gap = "8px";
|
|
4372
|
+
imageRow.style.marginTop = "8px";
|
|
4373
|
+
appendSelect(imageRow, TABLE_IMAGE_HEIGHT_MODES.map((heightMode) => ({
|
|
4374
|
+
value: heightMode,
|
|
4375
|
+
label: i18n(`schemas.table.imageHeightMode.${heightMode}`)
|
|
4376
|
+
})), mode, "imageHeightMode", index, metrics, { flex: "1" }, (value) => {
|
|
4377
|
+
if (value !== "fixed" && value !== "auto") return;
|
|
4378
|
+
if (value === mode) return;
|
|
4379
|
+
setImageHeightMode(props, table, index, value);
|
|
4380
|
+
});
|
|
4381
|
+
if (mode === "fixed") {
|
|
4382
|
+
const displayHeight = resolveFixedTableImageHeight(columnStyles.imageHeight?.[index]);
|
|
4383
|
+
appendNumberInput(imageRow, String(displayHeight), index, i18n("schemas.table.imageHeightMode.fixed"), metrics, (input) => {
|
|
4384
|
+
const parsed = Number(input.value);
|
|
4385
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
4386
|
+
input.value = String(displayHeight);
|
|
4387
|
+
return;
|
|
4388
|
+
}
|
|
4389
|
+
setImageHeight(props, table, index, parsed);
|
|
4390
|
+
});
|
|
4391
|
+
}
|
|
4392
|
+
body.appendChild(imageRow);
|
|
4393
|
+
}
|
|
4394
|
+
block.appendChild(body);
|
|
4395
|
+
rootElement.appendChild(block);
|
|
4396
|
+
});
|
|
4397
|
+
};
|
|
4398
|
+
//#endregion
|
|
3607
4399
|
//#region src/tables/index.ts
|
|
3608
4400
|
var tableSchema = {
|
|
3609
4401
|
pdf: pdfRender,
|
|
3610
4402
|
ui: uiRender,
|
|
3611
4403
|
propPanel: {
|
|
3612
4404
|
schema: ({ activeSchema, options, i18n }) => {
|
|
3613
|
-
const
|
|
3614
|
-
const head = tableSchema.head || [];
|
|
3615
|
-
const showHead = tableSchema.showHead || false;
|
|
4405
|
+
const showHead = activeSchema.showHead || false;
|
|
3616
4406
|
const font = options.font || { [DEFAULT_FONT_NAME]: {
|
|
3617
4407
|
data: "",
|
|
3618
4408
|
fallback: true
|
|
@@ -3687,18 +4477,22 @@ var tableSchema = {
|
|
|
3687
4477
|
isBody: true
|
|
3688
4478
|
})
|
|
3689
4479
|
},
|
|
3690
|
-
|
|
4480
|
+
tableColumns: {
|
|
3691
4481
|
title: i18n("schemas.table.columnStyle"),
|
|
3692
4482
|
type: "object",
|
|
3693
4483
|
widget: "Card",
|
|
4484
|
+
bind: false,
|
|
3694
4485
|
span: 24,
|
|
3695
|
-
properties:
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
4486
|
+
properties: { columns: {
|
|
4487
|
+
type: "void",
|
|
4488
|
+
widget: "TableColumns",
|
|
4489
|
+
bind: false,
|
|
4490
|
+
span: 24
|
|
4491
|
+
} }
|
|
3699
4492
|
}
|
|
3700
4493
|
};
|
|
3701
4494
|
},
|
|
4495
|
+
widgets: { TableColumns },
|
|
3702
4496
|
defaultSchema: {
|
|
3703
4497
|
name: "",
|
|
3704
4498
|
type: "table",
|