datastake-daf 0.6.474 → 0.6.476

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.
@@ -21,6 +21,7 @@ require('deepmerge');
21
21
  var countriesList = require('countries-list');
22
22
  require('country-city-location');
23
23
  require('leaflet-editable');
24
+ var client = require('react-dom/client');
24
25
  var htmlToImage = require('html-to-image');
25
26
  var docx = require('docx');
26
27
 
@@ -12639,12 +12640,10 @@ function displayMessage(type, m) {
12639
12640
  antd.message[type](m);
12640
12641
  }
12641
12642
 
12643
+ // src/helpers/imageCapture.js
12644
+
12642
12645
  /**
12643
- * Captures one or multiple DOM elements and returns their images as base64 strings.
12644
- *
12645
- * @param elements - A single element or an array of elements (or refs)
12646
- * @param options - Optional html-to-image options (e.g., { cacheBust: true })
12647
- * @returns Promise<string[]> - Array of base64 PNG strings (same order as input)
12646
+ * Captures existing DOM elements as images (requires refs)
12648
12647
  */
12649
12648
  async function captureElementsAsImages(elements, options = {
12650
12649
  cacheBust: true
@@ -12662,6 +12661,70 @@ async function captureElementsAsImages(elements, options = {
12662
12661
  return captures;
12663
12662
  }
12664
12663
 
12664
+ /**
12665
+ * Captures React components as images (no refs needed)
12666
+ */
12667
+ async function captureComponentsAsImages(components, options = {
12668
+ cacheBust: true
12669
+ }) {
12670
+ const targets = Array.isArray(components) ? components : [components];
12671
+ const captures = await Promise.all(targets.map(async ({
12672
+ component,
12673
+ width = '100%',
12674
+ height = 'auto',
12675
+ delay = 300
12676
+ }) => {
12677
+ const container = document.createElement('div');
12678
+ container.style.position = 'absolute';
12679
+ container.style.opacity = '0';
12680
+ container.style.pointerEvents = 'none';
12681
+ container.style.top = '-9999px';
12682
+ container.style.left = '-9999px';
12683
+ container.style.width = typeof width === 'number' ? `${width}px` : width;
12684
+ container.style.height = typeof height === 'number' ? `${height}px` : height;
12685
+ container.style.display = 'inline-block';
12686
+ document.body.appendChild(container);
12687
+ try {
12688
+ const root = client.createRoot(container);
12689
+ root.render(component);
12690
+
12691
+ // Wait for React to render
12692
+ await new Promise(resolve => setTimeout(resolve, 50));
12693
+
12694
+ // Wait for styled-components to inject styles
12695
+ await new Promise(resolve => requestAnimationFrame(() => {
12696
+ requestAnimationFrame(resolve);
12697
+ }));
12698
+
12699
+ // Additional delay for fonts/styles
12700
+ await new Promise(resolve => setTimeout(resolve, delay));
12701
+
12702
+ // Get the actual rendered element (first child)
12703
+ const element = container.firstChild;
12704
+ if (!element) {
12705
+ throw new Error('No element was rendered');
12706
+ }
12707
+
12708
+ // Capture the actual element, not the container
12709
+ const dataUrl = await htmlToImage.toPng(element, {
12710
+ ...options,
12711
+ backgroundColor: 'transparent',
12712
+ pixelRatio: 2 // Higher quality
12713
+ });
12714
+ root.unmount();
12715
+ document.body.removeChild(container);
12716
+ return dataUrl;
12717
+ } catch (err) {
12718
+ console.error("Error capturing component as image:", err);
12719
+ if (container.parentNode) {
12720
+ document.body.removeChild(container);
12721
+ }
12722
+ return "";
12723
+ }
12724
+ }));
12725
+ return captures;
12726
+ }
12727
+
12665
12728
  /**
12666
12729
  * Renders different types of document elements based on type
12667
12730
  * @param {Object} item - Configuration item
@@ -13358,6 +13421,7 @@ exports.btn = button;
13358
13421
  exports.camelCaseToTitle = camelCaseToTitle;
13359
13422
  exports.capitalize = capitalize;
13360
13423
  exports.capitalizeAll = capitalizeAll;
13424
+ exports.captureComponentsAsImages = captureComponentsAsImages;
13361
13425
  exports.captureElementsAsImages = captureElementsAsImages;
13362
13426
  exports.changeInputMeta = changeInputMeta;
13363
13427
  exports.convertUndefinedToNull = convertUndefinedToNull;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.474",
3
+ "version": "0.6.476",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -1,11 +1,10 @@
1
- import { toPng } from "html-to-image";
1
+ // src/helpers/imageCapture.js
2
+
3
+ import { createRoot } from 'react-dom/client';
4
+ import { toPng } from 'html-to-image';
2
5
 
3
6
  /**
4
- * Captures one or multiple DOM elements and returns their images as base64 strings.
5
- *
6
- * @param elements - A single element or an array of elements (or refs)
7
- * @param options - Optional html-to-image options (e.g., { cacheBust: true })
8
- * @returns Promise<string[]> - Array of base64 PNG strings (same order as input)
7
+ * Captures existing DOM elements as images (requires refs)
9
8
  */
10
9
  export async function captureElementsAsImages(
11
10
  elements,
@@ -27,3 +26,72 @@ export async function captureElementsAsImages(
27
26
 
28
27
  return captures;
29
28
  }
29
+
30
+ /**
31
+ * Captures React components as images (no refs needed)
32
+ */
33
+ export async function captureComponentsAsImages(
34
+ components,
35
+ options = { cacheBust: true }
36
+ ) {
37
+ const targets = Array.isArray(components) ? components : [components];
38
+
39
+ const captures = await Promise.all(
40
+ targets.map(async ({ component, width = '100%', height = 'auto', delay = 300 }) => {
41
+ const container = document.createElement('div');
42
+ container.style.position = 'absolute';
43
+ container.style.opacity = '0';
44
+ container.style.pointerEvents = 'none';
45
+ container.style.top = '-9999px';
46
+ container.style.left = '-9999px';
47
+ container.style.width = typeof width === 'number' ? `${width}px` : width;
48
+ container.style.height = typeof height === 'number' ? `${height}px` : height;
49
+ container.style.display = 'inline-block';
50
+
51
+ document.body.appendChild(container);
52
+
53
+ try {
54
+ const root = createRoot(container);
55
+ root.render(component);
56
+
57
+ // Wait for React to render
58
+ await new Promise(resolve => setTimeout(resolve, 50));
59
+
60
+ // Wait for styled-components to inject styles
61
+ await new Promise(resolve => requestAnimationFrame(() => {
62
+ requestAnimationFrame(resolve);
63
+ }));
64
+
65
+ // Additional delay for fonts/styles
66
+ await new Promise(resolve => setTimeout(resolve, delay));
67
+
68
+ // Get the actual rendered element (first child)
69
+ const element = container.firstChild;
70
+
71
+ if (!element) {
72
+ throw new Error('No element was rendered');
73
+ }
74
+
75
+ // Capture the actual element, not the container
76
+ const dataUrl = await toPng(element, {
77
+ ...options,
78
+ backgroundColor: 'transparent',
79
+ pixelRatio: 2 // Higher quality
80
+ });
81
+
82
+ root.unmount();
83
+ document.body.removeChild(container);
84
+
85
+ return dataUrl;
86
+ } catch (err) {
87
+ console.error("Error capturing component as image:", err);
88
+ if (container.parentNode) {
89
+ document.body.removeChild(container);
90
+ }
91
+ return "";
92
+ }
93
+ })
94
+ );
95
+
96
+ return captures;
97
+ }
package/src/utils.js CHANGED
@@ -35,7 +35,7 @@ export { renderNumber, renderPercentage } from "./@daf/utils/numbers.js"
35
35
 
36
36
  export { MessageTypes, displayMessage} from './helpers/messages.js'
37
37
 
38
- export { captureElementsAsImages } from './helpers/componentsToImages.js'
38
+ export { captureElementsAsImages, captureComponentsAsImages } from './helpers/componentsToImages.js'
39
39
 
40
40
  export { createDocument } from './@daf/core/components/Document/WordDocument/createDocument.js'
41
41