kritzel-stencil 0.4.8 → 0.4.9
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/cjs/index.cjs.js +9 -1
- package/dist/cjs/kritzel-active-users_47.cjs.entry.js +1386 -1250
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{schema.constants-gDeS7USU.js → schema.constants-ByNZ_qAj.js} +61 -0
- package/dist/cjs/stencil.cjs.js +1 -1
- package/dist/collection/classes/objects/image.class.js +9 -0
- package/dist/collection/classes/objects/path.class.js +9 -0
- package/dist/collection/classes/objects/shape.class.js +9 -0
- package/dist/collection/classes/providers/sync/broadcast-sync-provider.class.js +1 -0
- package/dist/collection/classes/providers/sync/hocuspocus-sync-provider.class.js +2 -0
- package/dist/collection/classes/providers/sync/in-memory-sync-provider.class.js +1 -0
- package/dist/collection/classes/providers/sync/indexeddb-sync-provider.class.js +1 -0
- package/dist/collection/classes/providers/sync/websocket-sync-provider.class.js +2 -0
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +197 -67
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +136 -169
- package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
- package/dist/collection/components/ui/kritzel-loading-overlay/kritzel-loading-overlay.js +1 -1
- package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
- package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +90 -4
- package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +1 -1
- package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +2 -2
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
- package/dist/collection/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.js +1 -1
- package/dist/collection/constants/version.js +1 -1
- package/dist/collection/helpers/object.helper.js +11 -0
- package/dist/collection/index.js +1 -0
- package/dist/collection/interfaces/object-export.interface.js +1 -0
- package/dist/collection/interfaces/sync-config.interface.js +21 -1
- package/dist/components/index.js +10 -3
- package/dist/components/kritzel-awareness-cursors.js +1 -1
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-editor.js +175 -78
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-export.js +1 -1
- package/dist/components/kritzel-loading-overlay.js +1 -1
- package/dist/components/kritzel-login-dialog.js +1 -1
- package/dist/components/kritzel-menu-item.js +1 -1
- package/dist/components/kritzel-menu.js +1 -1
- package/dist/components/kritzel-more-menu.js +1 -1
- package/dist/components/kritzel-portal.js +1 -1
- package/dist/components/kritzel-settings.js +1 -1
- package/dist/components/kritzel-share-dialog.js +1 -1
- package/dist/components/kritzel-split-button.js +1 -1
- package/dist/components/kritzel-utility-panel.js +1 -1
- package/dist/components/kritzel-workspace-manager.js +1 -1
- package/dist/components/kritzel-zoom-panel.js +1 -1
- package/dist/components/{p-DwY5pghH.js → p-6rQICkGr.js} +1 -1
- package/dist/components/{p-BknTMcbz.js → p-8ScektIm.js} +1 -1
- package/dist/components/{p-DkY7pIg5.js → p-BRGufCki.js} +95 -6
- package/dist/components/{p-BKOsmXB5.js → p-BqWiEmYI.js} +1 -1
- package/dist/components/{p-BLOPBDUF.js → p-C2CeSrTm.js} +1 -1
- package/dist/components/{p-DDbO5q-e.js → p-CXJZxJvp.js} +4 -4
- package/dist/components/{p-7Rt7ml3v.js → p-Cj0NElII.js} +1 -1
- package/dist/components/{p-BVEGQLBD.js → p-CoY7emAj.js} +1 -1
- package/dist/components/{p-DgA865Tp.js → p-D7H8oxZb.js} +2 -2
- package/dist/components/{p-Dd-pMvlr.js → p-DPONTran.js} +11 -0
- package/dist/components/{p-BMRln59F.js → p-DW7WW4EN.js} +2 -2
- package/dist/components/{p-D8TOEhPY.js → p-DuVkk58V.js} +2 -2
- package/dist/components/{p-OLfoATNk.js → p-U9FjWrp-.js} +1 -1
- package/dist/components/{p-D8bHNNEm.js → p-ZPPtEla5.js} +1227 -1218
- package/dist/components/{p-COjsYPir.js → p-dVfh-Sy9.js} +1 -1
- package/dist/components/{p-0H4HOJjy.js → p-lQ7nfhOy.js} +10 -1
- package/dist/esm/index.js +9 -2
- package/dist/esm/kritzel-active-users_47.entry.js +1386 -1250
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{schema.constants-Rpm1NA9u.js → schema.constants-1t45c2_U.js} +61 -1
- package/dist/esm/stencil.js +1 -1
- package/dist/stencil/index.esm.js +9 -2
- package/dist/stencil/{p-Rpm1NA9u.js → p-1t45c2_U.js} +61 -1
- package/dist/stencil/{p-8c1b7b08.entry.js → p-f5f088ea.entry.js} +1386 -1250
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/objects/image.class.d.ts +3 -0
- package/dist/types/classes/objects/path.class.d.ts +3 -0
- package/dist/types/classes/objects/shape.class.d.ts +3 -0
- package/dist/types/classes/providers/sync/broadcast-sync-provider.class.d.ts +1 -0
- package/dist/types/classes/providers/sync/hocuspocus-sync-provider.class.d.ts +1 -0
- package/dist/types/classes/providers/sync/in-memory-sync-provider.class.d.ts +1 -0
- package/dist/types/classes/providers/sync/indexeddb-sync-provider.class.d.ts +1 -0
- package/dist/types/classes/providers/sync/websocket-sync-provider.class.d.ts +1 -0
- package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +15 -3
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +16 -34
- package/dist/types/components/ui/kritzel-more-menu/kritzel-more-menu.d.ts +10 -1
- package/dist/types/components.d.ts +27 -26
- package/dist/types/constants/version.d.ts +1 -1
- package/dist/types/helpers/object.helper.d.ts +4 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interfaces/menu-item.interface.d.ts +1 -1
- package/dist/types/interfaces/object-export.interface.d.ts +20 -0
- package/dist/types/interfaces/sync-config.interface.d.ts +5 -0
- package/dist/types/interfaces/sync-provider.interface.d.ts +5 -0
- package/package.json +1 -1
|
@@ -21,11 +21,11 @@ import { KritzelCore } from "../../../classes/core/core.class";
|
|
|
21
21
|
import { KritzelDevicesHelper } from "../../../helpers/devices.helper";
|
|
22
22
|
import { throttle } from "lodash";
|
|
23
23
|
import { KritzelColorHelper } from "../../../helpers/color.helper";
|
|
24
|
-
import { KritzelSvgExportHelper } from "../../../helpers/svg-export.helper";
|
|
25
24
|
import { toPng, toSvg } from "html-to-image";
|
|
26
25
|
import { ObjectHelper } from "../../../helpers/object.helper";
|
|
27
26
|
import { KritzelWheelHelper } from "../../../helpers/wheel.helper";
|
|
28
27
|
import { resolveTextToolAvailableFonts } from "../../../constants/text-tool-fonts.constants";
|
|
28
|
+
import { KritzelSvgExportHelper } from "../../../helpers/svg-export.helper";
|
|
29
29
|
export class KritzelEngine {
|
|
30
30
|
host;
|
|
31
31
|
/** The workspace to load and display. Changing this prop switches the active workspace. */
|
|
@@ -1217,10 +1217,7 @@ export class KritzelEngine {
|
|
|
1217
1217
|
console.error('Failed to export viewport as PNG: screenshot could not be generated');
|
|
1218
1218
|
return;
|
|
1219
1219
|
}
|
|
1220
|
-
|
|
1221
|
-
link.download = filename;
|
|
1222
|
-
link.href = dataUrl;
|
|
1223
|
-
link.click();
|
|
1220
|
+
this.triggerDataUrlDownload(dataUrl, filename);
|
|
1224
1221
|
}
|
|
1225
1222
|
catch (error) {
|
|
1226
1223
|
console.error('Failed to export viewport as PNG:', error);
|
|
@@ -1242,129 +1239,57 @@ export class KritzelEngine {
|
|
|
1242
1239
|
console.error('Failed to export viewport as SVG: screenshot could not be generated');
|
|
1243
1240
|
return;
|
|
1244
1241
|
}
|
|
1245
|
-
|
|
1246
|
-
link.download = filename;
|
|
1247
|
-
link.href = dataUrl;
|
|
1248
|
-
link.click();
|
|
1242
|
+
this.triggerDataUrlDownload(dataUrl, filename);
|
|
1249
1243
|
}
|
|
1250
1244
|
catch (error) {
|
|
1251
1245
|
console.error('Failed to export viewport as SVG:', error);
|
|
1252
1246
|
}
|
|
1253
1247
|
}
|
|
1254
1248
|
/**
|
|
1255
|
-
*
|
|
1256
|
-
*
|
|
1257
|
-
* @param options - Optional export settings (theme, padding, raster-safe mode for canvas export).
|
|
1258
|
-
* @returns SVG markup string, or null if no objects are selected.
|
|
1249
|
+
* Returns export formats supported by the currently selected object.
|
|
1250
|
+
* Only returns formats when exactly one object is selected.
|
|
1259
1251
|
*/
|
|
1260
|
-
async
|
|
1261
|
-
const
|
|
1262
|
-
if (!
|
|
1263
|
-
return
|
|
1252
|
+
async getSelectedObjectSupportedExportFormats() {
|
|
1253
|
+
const selected = this.getSingleSelectedExportableObject();
|
|
1254
|
+
if (!selected) {
|
|
1255
|
+
return [];
|
|
1264
1256
|
}
|
|
1265
|
-
|
|
1266
|
-
// Inline image bytes as data URLs so they survive both standalone SVG
|
|
1267
|
-
// files and rasterization to PNG (a `blob:` href is not loaded when an
|
|
1268
|
-
// SVG is drawn into a canvas, which otherwise yields a broken image).
|
|
1269
|
-
const imageDataUrls = await KritzelSvgExportHelper.resolveImageDataUrls(selectedObjects, this.core.assetResolver);
|
|
1270
|
-
return KritzelSvgExportHelper.generateSvg(selectedObjects, {
|
|
1271
|
-
theme,
|
|
1272
|
-
padding: options?.padding ?? 0,
|
|
1273
|
-
includeXmlDeclaration: true,
|
|
1274
|
-
rasterSafeForCanvas: options?.rasterSafeForCanvas ?? false,
|
|
1275
|
-
imageDataUrls,
|
|
1276
|
-
});
|
|
1257
|
+
return selected.getSupportedExportFormats();
|
|
1277
1258
|
}
|
|
1278
1259
|
/**
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1281
|
-
* @param options - Optional export settings (theme, padding).
|
|
1260
|
+
* Checks whether the currently selected object supports a specific export format.
|
|
1261
|
+
* Returns false when none or multiple objects are selected.
|
|
1282
1262
|
*/
|
|
1283
|
-
async
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
console.warn('No objects selected for SVG export');
|
|
1288
|
-
return;
|
|
1289
|
-
}
|
|
1290
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
1291
|
-
const filename = `selection-${timestamp}.svg`;
|
|
1292
|
-
const blob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
|
|
1293
|
-
const url = URL.createObjectURL(blob);
|
|
1294
|
-
const link = document.createElement('a');
|
|
1295
|
-
link.download = filename;
|
|
1296
|
-
link.href = url;
|
|
1297
|
-
link.click();
|
|
1298
|
-
URL.revokeObjectURL(url);
|
|
1299
|
-
}
|
|
1300
|
-
catch (error) {
|
|
1301
|
-
console.error('Failed to export selected objects as SVG:', error);
|
|
1263
|
+
async canExportSelectedObjectAs(format) {
|
|
1264
|
+
const selected = this.getSingleSelectedExportableObject();
|
|
1265
|
+
if (!selected) {
|
|
1266
|
+
return false;
|
|
1302
1267
|
}
|
|
1268
|
+
return selected.getSupportedExportFormats().includes(format);
|
|
1303
1269
|
}
|
|
1304
1270
|
/**
|
|
1305
|
-
*
|
|
1306
|
-
*
|
|
1307
|
-
* @param options - Optional export settings (theme, padding, scale for resolution).
|
|
1308
|
-
* @returns PNG data URL string, or null if no objects are selected.
|
|
1271
|
+
* Exports the currently selected object in the requested format and triggers a file download.
|
|
1272
|
+
* Only supports single selection.
|
|
1309
1273
|
*/
|
|
1310
|
-
async
|
|
1311
|
-
const
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
// Avoid foreignObject-based text serialization, which taints the
|
|
1315
|
-
// canvas in SVG->PNG conversion paths.
|
|
1316
|
-
rasterSafeForCanvas: true,
|
|
1317
|
-
});
|
|
1318
|
-
if (!svgString) {
|
|
1319
|
-
return null;
|
|
1274
|
+
async exportSelectedObject(format) {
|
|
1275
|
+
const selected = this.getSingleSelectedExportableObject();
|
|
1276
|
+
if (!selected) {
|
|
1277
|
+
return;
|
|
1320
1278
|
}
|
|
1321
|
-
const scale = options?.scale ?? 2; // Default 2x for better quality
|
|
1322
|
-
return new Promise((resolve, reject) => {
|
|
1323
|
-
const img = new Image();
|
|
1324
|
-
const svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
|
|
1325
|
-
const url = URL.createObjectURL(svgBlob);
|
|
1326
|
-
img.onload = () => {
|
|
1327
|
-
const canvas = document.createElement('canvas');
|
|
1328
|
-
canvas.width = img.width * scale;
|
|
1329
|
-
canvas.height = img.height * scale;
|
|
1330
|
-
const ctx = canvas.getContext('2d');
|
|
1331
|
-
if (!ctx) {
|
|
1332
|
-
URL.revokeObjectURL(url);
|
|
1333
|
-
reject(new Error('Failed to get canvas context'));
|
|
1334
|
-
return;
|
|
1335
|
-
}
|
|
1336
|
-
ctx.scale(scale, scale);
|
|
1337
|
-
ctx.drawImage(img, 0, 0);
|
|
1338
|
-
URL.revokeObjectURL(url);
|
|
1339
|
-
resolve(canvas.toDataURL('image/png'));
|
|
1340
|
-
};
|
|
1341
|
-
img.onerror = () => {
|
|
1342
|
-
URL.revokeObjectURL(url);
|
|
1343
|
-
reject(new Error('Failed to load SVG for PNG conversion'));
|
|
1344
|
-
};
|
|
1345
|
-
img.src = url;
|
|
1346
|
-
});
|
|
1347
|
-
}
|
|
1348
|
-
/**
|
|
1349
|
-
* Exports the currently selected objects as a PNG file and triggers a browser download.
|
|
1350
|
-
* @param options - Optional export settings (theme, padding, scale for resolution).
|
|
1351
|
-
*/
|
|
1352
|
-
async exportSelectedObjectsAsPng(options) {
|
|
1353
1279
|
try {
|
|
1354
|
-
const dataUrl = await this.
|
|
1280
|
+
const dataUrl = await selected.exportAs(format, this.getObjectExportContext());
|
|
1355
1281
|
if (!dataUrl) {
|
|
1356
|
-
console.
|
|
1282
|
+
console.error(`Failed to export selected object as ${format}: export returned no data URL`);
|
|
1357
1283
|
return;
|
|
1358
1284
|
}
|
|
1285
|
+
const activeWorkspaceName = this.core.store.state?.activeWorkspace?.name || 'workspace';
|
|
1286
|
+
const objectName = selected.__class__.replace(/^Kritzel/, '').toLowerCase() || 'object';
|
|
1359
1287
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
1360
|
-
const filename =
|
|
1361
|
-
|
|
1362
|
-
link.download = filename;
|
|
1363
|
-
link.href = dataUrl;
|
|
1364
|
-
link.click();
|
|
1288
|
+
const filename = `${activeWorkspaceName}-${objectName}-${timestamp}.${format}`;
|
|
1289
|
+
this.triggerDataUrlDownload(dataUrl, filename);
|
|
1365
1290
|
}
|
|
1366
1291
|
catch (error) {
|
|
1367
|
-
console.error(
|
|
1292
|
+
console.error(`Failed to export selected object as ${format}:`, error);
|
|
1368
1293
|
}
|
|
1369
1294
|
}
|
|
1370
1295
|
/**
|
|
@@ -1559,6 +1484,73 @@ export class KritzelEngine {
|
|
|
1559
1484
|
const response = await fetch(dataUrl);
|
|
1560
1485
|
return response.blob();
|
|
1561
1486
|
}
|
|
1487
|
+
triggerDataUrlDownload(dataUrl, filename) {
|
|
1488
|
+
const link = document.createElement('a');
|
|
1489
|
+
link.download = filename;
|
|
1490
|
+
link.href = dataUrl;
|
|
1491
|
+
link.click();
|
|
1492
|
+
}
|
|
1493
|
+
getSingleSelectedExportableObject() {
|
|
1494
|
+
const selectedObjects = this.core.store.selectionGroup?.objects ?? [];
|
|
1495
|
+
if (selectedObjects.length !== 1) {
|
|
1496
|
+
return null;
|
|
1497
|
+
}
|
|
1498
|
+
const [selected] = selectedObjects;
|
|
1499
|
+
if (!ObjectHelper.isKritzelExportable(selected)) {
|
|
1500
|
+
return null;
|
|
1501
|
+
}
|
|
1502
|
+
return selected;
|
|
1503
|
+
}
|
|
1504
|
+
getObjectExportContext() {
|
|
1505
|
+
return {
|
|
1506
|
+
getObjectAsSvgDataUrl: async (object, options) => {
|
|
1507
|
+
const svg = await this.getObjectAsSvgMarkup(object, options?.rasterSafeForCanvas ?? false);
|
|
1508
|
+
return svg ? this.svgMarkupToDataUrl(svg) : null;
|
|
1509
|
+
},
|
|
1510
|
+
getObjectAsPngDataUrl: async (object) => {
|
|
1511
|
+
const svg = await this.getObjectAsSvgMarkup(object, true);
|
|
1512
|
+
return svg ? this.svgMarkupToPngDataUrl(svg) : null;
|
|
1513
|
+
},
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
async getObjectAsSvgMarkup(object, rasterSafeForCanvas) {
|
|
1517
|
+
const imageDataUrls = await KritzelSvgExportHelper.resolveImageDataUrls([object], this.core.assetResolver);
|
|
1518
|
+
const svg = KritzelSvgExportHelper.generateSvg([object], {
|
|
1519
|
+
theme: this.theme,
|
|
1520
|
+
rasterSafeForCanvas,
|
|
1521
|
+
imageDataUrls,
|
|
1522
|
+
});
|
|
1523
|
+
return svg || null;
|
|
1524
|
+
}
|
|
1525
|
+
svgMarkupToDataUrl(svgMarkup) {
|
|
1526
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgMarkup)}`;
|
|
1527
|
+
}
|
|
1528
|
+
async svgMarkupToPngDataUrl(svgMarkup) {
|
|
1529
|
+
const svgBlob = new Blob([svgMarkup], { type: 'image/svg+xml;charset=utf-8' });
|
|
1530
|
+
const svgBlobUrl = URL.createObjectURL(svgBlob);
|
|
1531
|
+
try {
|
|
1532
|
+
const img = await new Promise((resolve, reject) => {
|
|
1533
|
+
const element = new Image();
|
|
1534
|
+
element.onload = () => resolve(element);
|
|
1535
|
+
element.onerror = err => reject(err);
|
|
1536
|
+
element.src = svgBlobUrl;
|
|
1537
|
+
});
|
|
1538
|
+
const width = Math.max(1, Math.ceil(img.naturalWidth || img.width));
|
|
1539
|
+
const height = Math.max(1, Math.ceil(img.naturalHeight || img.height));
|
|
1540
|
+
const canvas = document.createElement('canvas');
|
|
1541
|
+
canvas.width = width;
|
|
1542
|
+
canvas.height = height;
|
|
1543
|
+
const context = canvas.getContext('2d');
|
|
1544
|
+
if (!context) {
|
|
1545
|
+
throw new Error('Could not create 2D canvas context for PNG export');
|
|
1546
|
+
}
|
|
1547
|
+
context.drawImage(img, 0, 0, width, height);
|
|
1548
|
+
return canvas.toDataURL('image/png');
|
|
1549
|
+
}
|
|
1550
|
+
finally {
|
|
1551
|
+
URL.revokeObjectURL(svgBlobUrl);
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1562
1554
|
getImportedWorkspaceName(rawName) {
|
|
1563
1555
|
if (typeof rawName === 'string' && rawName.trim().length > 0) {
|
|
1564
1556
|
return rawName;
|
|
@@ -5453,106 +5445,81 @@ export class KritzelEngine {
|
|
|
5453
5445
|
}]
|
|
5454
5446
|
}
|
|
5455
5447
|
},
|
|
5456
|
-
"
|
|
5448
|
+
"getSelectedObjectSupportedExportFormats": {
|
|
5457
5449
|
"complexType": {
|
|
5458
|
-
"signature": "(
|
|
5459
|
-
"parameters": [
|
|
5460
|
-
"name": "options",
|
|
5461
|
-
"type": "{ theme?: \"light\" | \"dark\"; padding?: number; rasterSafeForCanvas?: boolean; }",
|
|
5462
|
-
"docs": "- Optional export settings (theme, padding, raster-safe mode for canvas export)."
|
|
5463
|
-
}],
|
|
5464
|
-
"references": {
|
|
5465
|
-
"Promise": {
|
|
5466
|
-
"location": "global",
|
|
5467
|
-
"id": "global::Promise"
|
|
5468
|
-
}
|
|
5469
|
-
},
|
|
5470
|
-
"return": "Promise<string>"
|
|
5471
|
-
},
|
|
5472
|
-
"docs": {
|
|
5473
|
-
"text": "Generates an SVG string from the currently selected objects.\nCreates clean, standards-compliant SVG markup by directly serializing object properties.",
|
|
5474
|
-
"tags": [{
|
|
5475
|
-
"name": "param",
|
|
5476
|
-
"text": "options - Optional export settings (theme, padding, raster-safe mode for canvas export)."
|
|
5477
|
-
}, {
|
|
5478
|
-
"name": "returns",
|
|
5479
|
-
"text": "SVG markup string, or null if no objects are selected."
|
|
5480
|
-
}]
|
|
5481
|
-
}
|
|
5482
|
-
},
|
|
5483
|
-
"exportSelectedObjectsAsSvg": {
|
|
5484
|
-
"complexType": {
|
|
5485
|
-
"signature": "(options?: { theme?: \"light\" | \"dark\"; padding?: number; }) => Promise<void>",
|
|
5486
|
-
"parameters": [{
|
|
5487
|
-
"name": "options",
|
|
5488
|
-
"type": "{ theme?: \"light\" | \"dark\"; padding?: number; }",
|
|
5489
|
-
"docs": "- Optional export settings (theme, padding)."
|
|
5490
|
-
}],
|
|
5450
|
+
"signature": "() => Promise<KritzelObjectExportFormat[]>",
|
|
5451
|
+
"parameters": [],
|
|
5491
5452
|
"references": {
|
|
5492
5453
|
"Promise": {
|
|
5493
5454
|
"location": "global",
|
|
5494
5455
|
"id": "global::Promise"
|
|
5456
|
+
},
|
|
5457
|
+
"KritzelObjectExportFormat": {
|
|
5458
|
+
"location": "import",
|
|
5459
|
+
"path": "../../../interfaces/object-export.interface",
|
|
5460
|
+
"id": "src/interfaces/object-export.interface.ts::KritzelObjectExportFormat",
|
|
5461
|
+
"referenceLocation": "KritzelObjectExportFormat"
|
|
5495
5462
|
}
|
|
5496
5463
|
},
|
|
5497
|
-
"return": "Promise<
|
|
5464
|
+
"return": "Promise<KritzelObjectExportFormat[]>"
|
|
5498
5465
|
},
|
|
5499
5466
|
"docs": {
|
|
5500
|
-
"text": "
|
|
5501
|
-
"tags": [
|
|
5502
|
-
"name": "param",
|
|
5503
|
-
"text": "options - Optional export settings (theme, padding)."
|
|
5504
|
-
}]
|
|
5467
|
+
"text": "Returns export formats supported by the currently selected object.\nOnly returns formats when exactly one object is selected.",
|
|
5468
|
+
"tags": []
|
|
5505
5469
|
}
|
|
5506
5470
|
},
|
|
5507
|
-
"
|
|
5471
|
+
"canExportSelectedObjectAs": {
|
|
5508
5472
|
"complexType": {
|
|
5509
|
-
"signature": "(
|
|
5473
|
+
"signature": "(format: KritzelObjectExportFormat) => Promise<boolean>",
|
|
5510
5474
|
"parameters": [{
|
|
5511
|
-
"name": "
|
|
5512
|
-
"type": "
|
|
5513
|
-
"docs": "
|
|
5475
|
+
"name": "format",
|
|
5476
|
+
"type": "\"svg\" | \"png\"",
|
|
5477
|
+
"docs": ""
|
|
5514
5478
|
}],
|
|
5515
5479
|
"references": {
|
|
5516
5480
|
"Promise": {
|
|
5517
5481
|
"location": "global",
|
|
5518
5482
|
"id": "global::Promise"
|
|
5483
|
+
},
|
|
5484
|
+
"KritzelObjectExportFormat": {
|
|
5485
|
+
"location": "import",
|
|
5486
|
+
"path": "../../../interfaces/object-export.interface",
|
|
5487
|
+
"id": "src/interfaces/object-export.interface.ts::KritzelObjectExportFormat",
|
|
5488
|
+
"referenceLocation": "KritzelObjectExportFormat"
|
|
5519
5489
|
}
|
|
5520
5490
|
},
|
|
5521
|
-
"return": "Promise<
|
|
5491
|
+
"return": "Promise<boolean>"
|
|
5522
5492
|
},
|
|
5523
5493
|
"docs": {
|
|
5524
|
-
"text": "
|
|
5525
|
-
"tags": [
|
|
5526
|
-
"name": "param",
|
|
5527
|
-
"text": "options - Optional export settings (theme, padding, scale for resolution)."
|
|
5528
|
-
}, {
|
|
5529
|
-
"name": "returns",
|
|
5530
|
-
"text": "PNG data URL string, or null if no objects are selected."
|
|
5531
|
-
}]
|
|
5494
|
+
"text": "Checks whether the currently selected object supports a specific export format.\nReturns false when none or multiple objects are selected.",
|
|
5495
|
+
"tags": []
|
|
5532
5496
|
}
|
|
5533
5497
|
},
|
|
5534
|
-
"
|
|
5498
|
+
"exportSelectedObject": {
|
|
5535
5499
|
"complexType": {
|
|
5536
|
-
"signature": "(
|
|
5500
|
+
"signature": "(format: KritzelObjectExportFormat) => Promise<void>",
|
|
5537
5501
|
"parameters": [{
|
|
5538
|
-
"name": "
|
|
5539
|
-
"type": "
|
|
5540
|
-
"docs": "
|
|
5502
|
+
"name": "format",
|
|
5503
|
+
"type": "\"svg\" | \"png\"",
|
|
5504
|
+
"docs": ""
|
|
5541
5505
|
}],
|
|
5542
5506
|
"references": {
|
|
5543
5507
|
"Promise": {
|
|
5544
5508
|
"location": "global",
|
|
5545
5509
|
"id": "global::Promise"
|
|
5510
|
+
},
|
|
5511
|
+
"KritzelObjectExportFormat": {
|
|
5512
|
+
"location": "import",
|
|
5513
|
+
"path": "../../../interfaces/object-export.interface",
|
|
5514
|
+
"id": "src/interfaces/object-export.interface.ts::KritzelObjectExportFormat",
|
|
5515
|
+
"referenceLocation": "KritzelObjectExportFormat"
|
|
5546
5516
|
}
|
|
5547
5517
|
},
|
|
5548
5518
|
"return": "Promise<void>"
|
|
5549
5519
|
},
|
|
5550
5520
|
"docs": {
|
|
5551
|
-
"text": "Exports the currently selected
|
|
5552
|
-
"tags": [
|
|
5553
|
-
"name": "param",
|
|
5554
|
-
"text": "options - Optional export settings (theme, padding, scale for resolution)."
|
|
5555
|
-
}]
|
|
5521
|
+
"text": "Exports the currently selected object in the requested format and triggers a file download.\nOnly supports single selection.",
|
|
5522
|
+
"tags": []
|
|
5556
5523
|
}
|
|
5557
5524
|
},
|
|
5558
5525
|
"exportAsJson": {
|
|
@@ -69,7 +69,7 @@ export class KritzelExport {
|
|
|
69
69
|
return (h("div", { class: "export-tab-content" }, h("kritzel-input", { label: this.terms['export.filename.label'] ?? 'Filename', value: this.exportFilename, placeholder: this.terms['export.filename.placeholder'] ?? 'Enter filename', suffix: ".json", onValueChange: this.handleFilenameChange })));
|
|
70
70
|
}
|
|
71
71
|
render() {
|
|
72
|
-
return (h(Host, { key: '0bc45e80716be4a7b19ae12a6464a641b5bd4550' }, h("kritzel-dialog", { key: 'f336f8b1e4ae10954d48ca67da88504faf06b295', isOpen: this.isDialogOpen, dialogTitle: this.terms['export.dialogTitle'] ?? 'Export', closable: true, contained: true, onDialogClose: this.closeDialog }, h("div", { key: 'e2d1209652bb54fb7f623e50bc4bbbb703083b76', class: "export-content" }, h("kritzel-pill-tabs", { key: 'dd78430b78d1e8c4ac0a76e8a6a5d48bebf5e889', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), h("button", { key: '
|
|
72
|
+
return (h(Host, { key: '0bc45e80716be4a7b19ae12a6464a641b5bd4550' }, h("kritzel-dialog", { key: 'f336f8b1e4ae10954d48ca67da88504faf06b295', isOpen: this.isDialogOpen, dialogTitle: this.terms['export.dialogTitle'] ?? 'Export', closable: true, contained: true, onDialogClose: this.closeDialog }, h("div", { key: 'e2d1209652bb54fb7f623e50bc4bbbb703083b76', class: "export-content" }, h("kritzel-pill-tabs", { key: 'dd78430b78d1e8c4ac0a76e8a6a5d48bebf5e889', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport()), h("div", { key: 'd04221d9f98a066d538f98f8c9409c558fdfa29f', slot: "footer" }, h("button", { key: '5cbb062756f29a897088d6647c6b8eae9f5781e2', class: "export-primary-button", onClick: this.handleExport }, this.terms['export.exportButton'] ?? 'Export')))));
|
|
73
73
|
}
|
|
74
74
|
static get is() { return "kritzel-export"; }
|
|
75
75
|
static get encapsulation() { return "shadow"; }
|
|
@@ -9,7 +9,7 @@ export class KritzelLoadingOverlay {
|
|
|
9
9
|
*/
|
|
10
10
|
text = 'Loading...';
|
|
11
11
|
render() {
|
|
12
|
-
return (h(Host, { key: '
|
|
12
|
+
return (h(Host, { key: 'ce2edf698db335518979f597ad32fa259c3055b9' }, h("div", { key: '7cf019929b72d18fdd1cea55157dc5b5fc2ea151', class: { 'loading-overlay': true, visible: this.visible }, "aria-hidden": this.visible ? 'false' : 'true' }, h("span", { key: '86b7cb040bcfb1abb2161a38f9cff153d5aa6c18', class: "loading-spinner" }), this.text)));
|
|
13
13
|
}
|
|
14
14
|
static get is() { return "kritzel-loading-overlay"; }
|
|
15
15
|
static get encapsulation() { return "shadow"; }
|
|
@@ -44,7 +44,7 @@ export class KritzelLoginDialog {
|
|
|
44
44
|
this.dialogClosed.emit();
|
|
45
45
|
};
|
|
46
46
|
render() {
|
|
47
|
-
return (h(Host, { key: '
|
|
47
|
+
return (h(Host, { key: '561b4e76017e71d99f05cd33ed9f6e3769bb9aec' }, h("kritzel-dialog", { key: '74b904f67496debebf7a1854e3e3dd193f14a445', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: 'dcc2a024349fcdfcad7c7c6d5b7754e5ae990ae3', class: "login-content" }, this.subtitle && (h("p", { key: 'fdc927c84294a2ac92aec90001c3da373cc5f082', class: "login-subtitle" }, this.subtitle)), h("div", { key: 'a6e74ff9b3211df195b05edd2be0ce69d1b128df', class: "login-providers" }, this.providers.map(provider => (h("button", { key: provider.name, class: {
|
|
48
48
|
'provider-button': true,
|
|
49
49
|
'is-loading': this.loadingProvider === provider.name,
|
|
50
50
|
'is-disabled': this.loadingProvider !== null && this.loadingProvider !== provider.name,
|
|
@@ -32,6 +32,14 @@ export class KritzelMoreMenu {
|
|
|
32
32
|
itemSelect;
|
|
33
33
|
menuAnchor = null;
|
|
34
34
|
isTouchDevice = KritzelDevicesHelper.isTouchDevice();
|
|
35
|
+
visibleItems = [];
|
|
36
|
+
visibilityResolveVersion = 0;
|
|
37
|
+
onItemsChange() {
|
|
38
|
+
void this.resolveVisibleItems();
|
|
39
|
+
}
|
|
40
|
+
componentWillLoad() {
|
|
41
|
+
void this.resolveVisibleItems();
|
|
42
|
+
}
|
|
35
43
|
toggleMenu = (event) => {
|
|
36
44
|
event.stopPropagation();
|
|
37
45
|
if (this.menuAnchor) {
|
|
@@ -40,13 +48,84 @@ export class KritzelMoreMenu {
|
|
|
40
48
|
else {
|
|
41
49
|
window.dispatchEvent(new CustomEvent('kritzel-dismiss-menus'));
|
|
42
50
|
this.menuAnchor = this.host;
|
|
51
|
+
this.visibleItems = this.filterVisibleItemsSync(this.items ?? []);
|
|
52
|
+
void this.resolveVisibleItems();
|
|
43
53
|
}
|
|
44
54
|
};
|
|
45
55
|
closeMenu = () => {
|
|
46
56
|
this.menuAnchor = null;
|
|
47
57
|
};
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
async evaluateVisibility(visibility) {
|
|
59
|
+
if (typeof visibility === 'function') {
|
|
60
|
+
try {
|
|
61
|
+
return (await visibility()) !== false;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return visibility !== false;
|
|
68
|
+
}
|
|
69
|
+
evaluateVisibilitySync(visibility) {
|
|
70
|
+
if (typeof visibility === 'function') {
|
|
71
|
+
try {
|
|
72
|
+
const result = visibility();
|
|
73
|
+
return result instanceof Promise ? null : result !== false;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return visibility !== false;
|
|
80
|
+
}
|
|
81
|
+
filterVisibleItemsSync(items) {
|
|
82
|
+
return items.reduce((visibleItems, item) => {
|
|
83
|
+
const isVisible = this.evaluateVisibilitySync(item.isVisible);
|
|
84
|
+
if (isVisible === null || !isVisible) {
|
|
85
|
+
return visibleItems;
|
|
86
|
+
}
|
|
87
|
+
if (!item.children?.length) {
|
|
88
|
+
visibleItems.push(item);
|
|
89
|
+
return visibleItems;
|
|
90
|
+
}
|
|
91
|
+
visibleItems.push({
|
|
92
|
+
...item,
|
|
93
|
+
children: this.filterVisibleItemsSync(item.children),
|
|
94
|
+
});
|
|
95
|
+
return visibleItems;
|
|
96
|
+
}, []);
|
|
97
|
+
}
|
|
98
|
+
async filterVisibleItems(items) {
|
|
99
|
+
const resolved = await Promise.all(items.map(async (item) => {
|
|
100
|
+
const isVisible = await this.evaluateVisibility(item.isVisible);
|
|
101
|
+
if (!isVisible) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
if (!item.children?.length) {
|
|
105
|
+
return item;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
...item,
|
|
109
|
+
children: await this.filterVisibleItems(item.children),
|
|
110
|
+
};
|
|
111
|
+
}));
|
|
112
|
+
return resolved.filter((item) => !!item);
|
|
113
|
+
}
|
|
114
|
+
async resolveVisibleItems() {
|
|
115
|
+
const version = ++this.visibilityResolveVersion;
|
|
116
|
+
const items = this.items ?? [];
|
|
117
|
+
const resolvedItems = await this.filterVisibleItems(items);
|
|
118
|
+
if (version !== this.visibilityResolveVersion) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
this.visibleItems = resolvedItems;
|
|
122
|
+
}
|
|
123
|
+
resolveMenuLabels(items) {
|
|
124
|
+
return items.map(item => ({
|
|
125
|
+
...item,
|
|
126
|
+
label: this.terms[item.label] ?? item.label,
|
|
127
|
+
children: item.children ? this.resolveMenuLabels(item.children) : undefined,
|
|
128
|
+
}));
|
|
50
129
|
}
|
|
51
130
|
handleMenuItemSelect = (event) => {
|
|
52
131
|
const { item, parent } = event.detail;
|
|
@@ -57,7 +136,7 @@ export class KritzelMoreMenu {
|
|
|
57
136
|
this.closeMenu();
|
|
58
137
|
};
|
|
59
138
|
render() {
|
|
60
|
-
return (h(Host, { key: '
|
|
139
|
+
return (h(Host, { key: 'dbfe312eccd24901ffc68179ef93ba0a94a765c5', class: { mobile: this.isTouchDevice }, style: { display: this.visible ? '' : 'none' } }, h("div", { key: '33bd535bb58ae32a32d44133a109fdd3667b4947', class: { 'more-menu-wrapper': true, visible: this.visible } }, h("button", { key: '23dbae51d73b92b181721bdef4a44049ec6484c5', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu, "aria-label": this.terms['moreMenu.ariaLabel'] ?? 'More options' }, h("kritzel-icon", { key: 'bda7c092b57af366b5d6b882cbab991cd9bb77ba', name: this.icon, size: this.iconSize })), h("kritzel-portal", { key: '2959ac3e6e0a5598c735ce7a01619bda8753039f', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, h("kritzel-menu", { key: 'a5481a1bc02dc059dc0ad188b93b9eaf9b56e98f', items: this.resolveMenuLabels(this.visibleItems), onItemSelect: this.handleMenuItemSelect })))));
|
|
61
140
|
}
|
|
62
141
|
static get is() { return "kritzel-more-menu"; }
|
|
63
142
|
static get encapsulation() { return "shadow"; }
|
|
@@ -216,7 +295,8 @@ export class KritzelMoreMenu {
|
|
|
216
295
|
static get states() {
|
|
217
296
|
return {
|
|
218
297
|
"menuAnchor": {},
|
|
219
|
-
"isTouchDevice": {}
|
|
298
|
+
"isTouchDevice": {},
|
|
299
|
+
"visibleItems": {}
|
|
220
300
|
};
|
|
221
301
|
}
|
|
222
302
|
static get events() {
|
|
@@ -245,4 +325,10 @@ export class KritzelMoreMenu {
|
|
|
245
325
|
}];
|
|
246
326
|
}
|
|
247
327
|
static get elementRef() { return "host"; }
|
|
328
|
+
static get watchers() {
|
|
329
|
+
return [{
|
|
330
|
+
"propName": "items",
|
|
331
|
+
"methodName": "onItemsChange"
|
|
332
|
+
}];
|
|
333
|
+
}
|
|
248
334
|
}
|
|
@@ -205,7 +205,7 @@ export class KritzelSettings {
|
|
|
205
205
|
return (h("div", { class: "settings-categories-wrapper" }, h("div", { class: { 'settings-tab-panel': true, 'is-active': this.selectedCategoryId === 'general' } }, h("div", { class: "settings-content" }, h("h3", null, this.t('settings.general.title', 'General Settings')), h("div", { class: "settings-group" }, h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.general.theme.label', 'Theme')), h("p", { class: "settings-description" }, this.t('settings.general.theme.description', 'Select a registered color theme for the editor interface.')), h("kritzel-dropdown", { options: this.availableThemes.map(t => ({ value: t, label: t })), value: this.theme, onValueChanged: this.handleThemeChange })), this.availableLocales.length > 0 && (h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.general.language.label', 'Language')), h("p", { class: "settings-description" }, this.t('settings.general.language.description', 'Select the display language for the editor interface.')), h("kritzel-dropdown", { options: this.availableLocales.map(l => ({ value: l.code, label: l.label })), value: this.locale, onValueChanged: this.handleLocaleChange }))), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.general.lockDrawingScale.label', 'Lock Drawing Scale')), h("p", { class: "settings-description" }, this.t('settings.general.lockDrawingScale.description', 'When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level.')), h("kritzel-slide-toggle", { checked: this.lockDrawingScale, label: this.t('settings.general.lockDrawingScale.label', 'Lock Drawing Scale'), onCheckedChange: this.handleLockDrawingScaleChange }))))), h("div", { class: { 'settings-tab-panel': true, 'is-active': this.selectedCategoryId === 'viewport' } }, h("div", { class: "settings-content" }, h("h3", null, this.t('settings.viewport.title', 'Viewport Settings')), h("div", { class: "settings-group" }, h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.viewport.minZoom.label', 'Minimum Zoom Level')), h("p", { class: "settings-description" }, this.t('settings.viewport.minZoom.description', 'Sets the minimum zoom level. Lower values allow zooming out further to see more of the canvas.')), h("kritzel-numeric-input", { value: this.scaleMin, min: 0.0001, max: 1, step: 0.0001, onValueChange: this.handleScaleMinChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.viewport.maxZoom.label', 'Maximum Zoom Level')), h("p", { class: "settings-description" }, this.t('settings.viewport.maxZoom.description', 'Sets the maximum zoom level. Higher values allow zooming in closer for detailed work.')), h("kritzel-numeric-input", { value: this.scaleMax, min: 1, max: 1000, step: 1, onValueChange: this.handleScaleMaxChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.viewport.boundaryLeft.label', 'Viewport Boundary Left')), h("p", { class: "settings-description" }, this.t('settings.viewport.boundaryLeft.description', 'Left boundary in world coordinates. Set to limit how far left the viewport can pan.')), h("kritzel-numeric-input", { value: this.viewportBoundaryLeft, step: 100, placeholder: this.t('settings.viewport.boundaryPlaceholder', 'Infinite'), onValueChange: this.handleViewportBoundaryLeftChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.viewport.boundaryRight.label', 'Viewport Boundary Right')), h("p", { class: "settings-description" }, this.t('settings.viewport.boundaryRight.description', 'Right boundary in world coordinates. Set to limit how far right the viewport can pan.')), h("kritzel-numeric-input", { value: this.viewportBoundaryRight, step: 100, placeholder: this.t('settings.viewport.boundaryPlaceholder', 'Infinite'), onValueChange: this.handleViewportBoundaryRightChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.viewport.boundaryTop.label', 'Viewport Boundary Top')), h("p", { class: "settings-description" }, this.t('settings.viewport.boundaryTop.description', 'Top boundary in world coordinates. Set to limit how far up the viewport can pan.')), h("kritzel-numeric-input", { value: this.viewportBoundaryTop, step: 100, placeholder: this.t('settings.viewport.boundaryPlaceholder', 'Infinite'), onValueChange: this.handleViewportBoundaryTopChange })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.viewport.boundaryBottom.label', 'Viewport Boundary Bottom')), h("p", { class: "settings-description" }, this.t('settings.viewport.boundaryBottom.description', 'Bottom boundary in world coordinates. Set to limit how far down the viewport can pan.')), h("kritzel-numeric-input", { value: this.viewportBoundaryBottom, step: 100, placeholder: this.t('settings.viewport.boundaryPlaceholder', 'Infinite'), onValueChange: this.handleViewportBoundaryBottomChange }))))), h("div", { class: { 'settings-tab-panel': true, 'is-active': this.selectedCategoryId === 'shortcuts' } }, h("div", { class: "settings-content" }, h("h3", null, this.t('settings.shortcuts.title', 'Keyboard Shortcuts')), h("div", { class: "shortcuts-list" }, Array.from(this.groupShortcutsByCategory()).map(([category, shortcuts]) => (h("div", { class: "shortcuts-category", key: category }, h("h4", { class: "shortcuts-category-title" }, category), h("div", { class: "shortcuts-group" }, shortcuts.map(shortcut => (h("div", { class: "shortcut-item", key: shortcut.key + shortcut.label }, h("span", { class: "shortcut-label" }, shortcut.label), h("kbd", { class: "shortcut-key" }, this.formatKeyCombo(shortcut)))))))))))), h("div", { class: { 'settings-tab-panel': true, 'is-active': this.selectedCategoryId === 'developer' } }, h("div", { class: "settings-content" }, h("h3", null, this.t('settings.developer.title', 'Developer Options')), h("div", { class: "settings-group" }, h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.developer.showViewportInfo.label', 'Show Viewport Info')), h("p", { class: "settings-description" }, this.t('settings.developer.showViewportInfo.description', 'Display viewport debug information such as position, zoom level, and boundaries.')), h("kritzel-slide-toggle", { checked: this.debugInfo.showViewportInfo, label: this.t('settings.developer.showViewportInfo.label', 'Show Viewport Info'), onCheckedChange: this.handleDebugInfoChange('showViewportInfo') })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.developer.showObjectInfo.label', 'Show Object Info')), h("p", { class: "settings-description" }, this.t('settings.developer.showObjectInfo.description', 'Display debug information about objects on the canvas.')), h("kritzel-slide-toggle", { checked: this.debugInfo.showObjectInfo, label: this.t('settings.developer.showObjectInfo.label', 'Show Object Info'), onCheckedChange: this.handleDebugInfoChange('showObjectInfo') })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.developer.showSyncProviderInfo.label', 'Show Sync Provider Info')), h("p", { class: "settings-description" }, this.t('settings.developer.showSyncProviderInfo.description', 'Display debug information about the sync provider connection status.')), h("kritzel-slide-toggle", { checked: this.debugInfo.showSyncProviderInfo, label: this.t('settings.developer.showSyncProviderInfo.label', 'Show Sync Provider Info'), onCheckedChange: this.handleDebugInfoChange('showSyncProviderInfo') })), h("div", { class: "settings-item" }, h("label", { class: "settings-label" }, this.t('settings.developer.showMigrationInfo.label', 'Show Migration Info')), h("p", { class: "settings-description" }, this.t('settings.developer.showMigrationInfo.description', 'Display debug information about data migrations.')), h("kritzel-slide-toggle", { checked: this.debugInfo.showMigrationInfo, label: this.t('settings.developer.showMigrationInfo.label', 'Show Migration Info'), onCheckedChange: this.handleDebugInfoChange('showMigrationInfo') }))))), h("div", { class: { 'settings-tab-panel': true, 'is-active': this.selectedCategoryId === 'about' } }, h("div", { class: "settings-content" }, h("h3", null, this.t('settings.about.title', 'About')), h("p", null, this.t('settings.about.description', 'Kritzel - A drawing application')), h("p", { class: "version-info" }, "Version ", KRITZEL_VERSION), h("p", { class: "version-info" }, "App-State Schema v", CURRENT_APP_STATE_SCHEMA_VERSION), h("p", { class: "version-info" }, "Workspace Schema v", CURRENT_WORKSPACE_SCHEMA_VERSION)))));
|
|
206
206
|
}
|
|
207
207
|
render() {
|
|
208
|
-
return (h(Host, { key: '
|
|
208
|
+
return (h(Host, { key: 'b8a899abd3dd55bc3493b7d124ac5505e2284036' }, h("kritzel-dialog", { key: '8d47f3548271e24a8a280a30139f04b2e4b4ec2b', isOpen: this.isDialogOpen, dialogTitle: this.t('settings.dialogTitle', 'Settings'), size: "large", contained: true, onDialogClose: this.closeDialog }, h("kritzel-master-detail", { key: 'a5213307761b84b8f5f67cb35409ab1c0c1fa57b', items: this.categories, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
|
|
209
209
|
}
|
|
210
210
|
static get is() { return "kritzel-settings"; }
|
|
211
211
|
static get encapsulation() { return "shadow"; }
|
|
@@ -123,9 +123,9 @@ export class KritzelShareDialog {
|
|
|
123
123
|
this.dialogClosed.emit();
|
|
124
124
|
};
|
|
125
125
|
render() {
|
|
126
|
-
return (h(Host, { key: '
|
|
126
|
+
return (h(Host, { key: '75deaa66e6a6f640506985a8b3a2746892b5da07' }, h("kritzel-dialog", { key: '237413c9302e3756c5f7653e69326fac80d9e181', dialogTitle: this.terms['share.dialogTitle'] ?? 'Share Workspace', size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, h("div", { key: '295394b851cc2210fece6f3e297dfbc0c516b0f7', class: "share-content" }, h("div", { key: 'df64d71f9c7a7064d36db6d0a196071f1e8835a9', class: "share-section" }, h("div", { key: '9db4902a5edd917efb5ad6c183f0862b12313635', class: "share-row" }, h("div", { key: '8ead1d363d3430a4e65fa3b5835401b0e20006db', class: "share-label-group" }, h("label", { key: '2f3c28a3909eab86a123ba6cf7386b79894717c5', class: "share-label" }, this.terms['share.linkSharing.label'] ?? 'Link sharing'), h("p", { key: '3167ae1ed6ff52abc531eafdd905f1397807f551', class: "share-description" }, this.internalIsPublic
|
|
127
127
|
? (this.terms['share.linkSharing.enabledDescription'] ?? 'Anyone with the link can access this workspace.')
|
|
128
|
-
: (this.terms['share.linkSharing.disabledDescription'] ?? 'Link sharing is disabled. Only you can access this workspace.'))), h("kritzel-slide-toggle", { key: '
|
|
128
|
+
: (this.terms['share.linkSharing.disabledDescription'] ?? 'Link sharing is disabled. Only you can access this workspace.'))), h("kritzel-slide-toggle", { key: '3ff608b262e2ff3fa779f7d1e9a4ee3c0b9a16c0', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: this.terms['share.linkSharing.toggleLabel'] ?? 'Enable link sharing' }))), this.internalIsPublic && (h("div", { key: '355261384b0ed386f3b48c041bcf0039db0534c1', class: "share-section" }, h("div", { key: 'ad3d975c650757d0b6dbd5317c9bac4f98029e0c', class: "share-url-container" }, h("input", { key: '0da2cc9cb30f1da8bcab3aa82c679b8d685641bd', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), h("button", { key: 'aee232b7a70b524d52a4b4cf9074c099d29a5300', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? (this.terms['share.copyLink.copied'] ?? 'Copied!') : (this.terms['share.copyLink.title'] ?? 'Copy link') }, h("kritzel-icon", { key: 'c151baf7b890dbf51c4f4831d60b0ebb1a5d05fa', name: this.copySuccess ? 'check' : 'copy', size: 18 }))), this.qrCodeDataUrl && (h("div", { key: '63b43efe3dc5929054af9e5ee7f64d093864b3b0', class: "share-qr-container" }, h("img", { key: '9d3b0418eb80ff8c7e9106ad86d7cc211d017504', class: "share-qr-image", src: this.qrCodeDataUrl, alt: "QR code for share link" })))))))));
|
|
129
129
|
}
|
|
130
130
|
static get is() { return "kritzel-share-dialog"; }
|
|
131
131
|
static get encapsulation() { return "shadow"; }
|