@arbisoft/react-design-tool 1.0.67 → 1.0.69

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/README.md CHANGED
@@ -21,6 +21,10 @@ Perfect for integrating into applications that require user-driven visual conten
21
21
 
22
22
  ## 🔔 What’s New
23
23
 
24
+ - **Configurable template order in sidebar**: You can now control whether **Default** or **Custom Templates** appear first using `templatesDisplayOrder` (`'defaultFirst' | 'customFirst'`).
25
+ - **Custom-template delete UX update**: The delete action for custom templates has been moved to a **top-right hover overlay** with a confirmation prompt to reduce accidental deletes.
26
+ - **Lighter out-of-bounds preview mask**: The outside-canvas preview area is now less visually heavy and can be configured with `showOutsideBoundaryPreview` and `outsideBoundaryPreviewPadding`.
27
+ - **Backspace no longer triggers browser back navigation**: When an element is selected and the user is not typing in an input/textarea/contenteditable field, pressing **Backspace/Delete** now removes the selected element instead.
24
28
  - **Image tinting for photos**: New **Tint Color** and **Tint Strength** controls appear only when an image is selected. Tint now starts at 0% and is adjustable to 100%, with a one-click **Remove Tint**.
25
29
  - **Auto-placement for QR ID**: When enabled, the QR ID text is **automatically positioned above the Location text** (`LOCATION_ELEMENT_ID`).
26
30
  If the Location element doesn’t exist, it’s **centered on the canvas**.
@@ -64,13 +68,13 @@ yarn add @arbisoft/react-design-tool
64
68
  #### ⚠️ Important: Installation Guide for React 18 and Below
65
69
 
66
70
  ```bash
67
- npm install @arbisoft/react-design-tool@1.0.66
71
+ npm install @arbisoft/react-design-tool@1.0.69
68
72
  ```
69
73
 
70
74
  OR
71
75
 
72
76
  ```bash
73
- yarn add @arbisoft/react-design-tool@1.0.66
77
+ yarn add @arbisoft/react-design-tool@1.0.69
74
78
 
75
79
  ```
76
80
 
@@ -154,6 +158,19 @@ customTemplatesList={[
154
158
  ]}
155
159
  ```
156
160
 
161
+ #### `templatesDisplayOrder` (String)
162
+
163
+ Controls the display order of template groups in the sidebar.
164
+
165
+ - `'defaultFirst'` (default): **Default** templates first, then **Custom Templates**
166
+ - `'customFirst'`: **Custom Templates** first, then **Default**
167
+
168
+ **Example:**
169
+
170
+ ```jsx
171
+ <Studio templatesDisplayOrder="customFirst" />
172
+ ```
173
+
157
174
  #### 3. `defaultImages` (Array of URLs)
158
175
 
159
176
  System-provided stock images.
@@ -446,6 +463,26 @@ Used to set configure allowed images formats for our gallert
446
463
  <Studio allowedFormats={['png', 'jpg']} />
447
464
  ```
448
465
 
466
+ #### `showOutsideBoundaryPreview` (Boolean)
467
+
468
+ Enables a padded outside-canvas preview area around the page.
469
+
470
+ **Example:**
471
+
472
+ ```jsx
473
+ <Studio showOutsideBoundaryPreview />
474
+ ```
475
+
476
+ #### `outsideBoundaryPreviewPadding` (Number)
477
+
478
+ Sets the outside preview padding (in pixels). Only used when `showOutsideBoundaryPreview` is enabled.
479
+
480
+ **Example:**
481
+
482
+ ```jsx
483
+ <Studio showOutsideBoundaryPreview outsideBoundaryPreviewPadding={120} />
484
+ ```
485
+
449
486
  ## 🆕 (Updated) QR ID Controls
450
487
 
451
488
  ### 24. `showQrIdToggle` (boolean)
@@ -486,4 +523,3 @@ but **`x`/`y` positioning fields are ignored** for insert/reflow.
486
523
  showQrIdToggle
487
524
  qrId="LOT-22-7B"
488
525
  />
489
-
package/dist/cjs/index.js CHANGED
@@ -342,6 +342,9 @@ var propTypes$z = {
342
342
  disableWhiteLabel: PropTypes.bool,
343
343
  defaultTemplatesList: PropTypes.array,
344
344
  customTemplatesList: PropTypes.array,
345
+ templatesDisplayOrder: PropTypes.oneOf(['defaultFirst', 'customFirst']),
346
+ showOutsideBoundaryPreview: PropTypes.bool,
347
+ outsideBoundaryPreviewPadding: PropTypes.number,
345
348
  qrLink: PropTypes.string,
346
349
  styleProps: PropTypes.object,
347
350
  defaultText: PropTypes.string,
@@ -2269,10 +2272,12 @@ var propTypes$w = {
2269
2272
  setLoadingUploadImage: PropTypes.func,
2270
2273
  cuttingGuideStroke: PropTypes.number,
2271
2274
  cuttingGuideStrokeColor: PropTypes.string,
2272
- onChangeCuttingGuideProp: PropTypes.func
2275
+ onChangeCuttingGuideProp: PropTypes.func,
2276
+ showOutsideBoundaryPreview: PropTypes.bool,
2277
+ outsideBoundaryPreviewPadding: PropTypes.number
2273
2278
  };
2274
2279
 
2275
- var _templateObject$r, _templateObject2$l, _templateObject3$b, _templateObject4$7, _templateObject5$3;
2280
+ var _templateObject$r, _templateObject2$l, _templateObject3$b, _templateObject4$7, _templateObject5$4;
2276
2281
  var Container$4 = styled.div(_templateObject$r || (_templateObject$r = _taggedTemplateLiteral(["\n flex: 1;\n display: flex;\n background-color: ", ";\n background-image: ", ";\n position: relative;\n flex-direction: column;\n overflow: hidden;\n"])), theme.color.white_F7F7F7, function (_ref) {
2277
2282
  var selectedTab = _ref.selectedTab;
2278
2283
  return selectedTab ? 'none' : "url(".concat(EditorBg, ")");
@@ -2292,7 +2297,7 @@ var InnerContainerWrapper = styled.div(_templateObject3$b || (_templateObject3$b
2292
2297
  return editorWidth || 400;
2293
2298
  });
2294
2299
  var Title = styled.p(_templateObject4$7 || (_templateObject4$7 = _taggedTemplateLiteral(["\n border: 1px solid ", ";\n align-self: flex-start;\n font-size: 14px;\n font-family: ", ";\n font-weight: ", ";\n color: ", ";\n padding: 0 6px;\n border-bottom-width: 0;\n"])), theme.color.gray_E8E8E8, theme.fonts.primary, theme.fontWeights[300], theme.color.gray_7A7979);
2295
- var EditorBox = styled.div(_templateObject5$3 || (_templateObject5$3 = _taggedTemplateLiteral(["\n height: ", "px;\n width: ", "px;\n min-height: ", "px;\n min-width: ", "px;\n background: ", ";\n box-shadow: 1.317px 1.317px 1.317px 0px rgba(0, 0, 0, 0.08);\n // transition: all 0.1s ease-in-out;\n overflow: hidden;\n"])), function (_ref6) {
2300
+ var EditorBox = styled.div(_templateObject5$4 || (_templateObject5$4 = _taggedTemplateLiteral(["\n height: ", "px;\n width: ", "px;\n min-height: ", "px;\n min-width: ", "px;\n background: ", ";\n box-shadow: 1.317px 1.317px 1.317px 0px rgba(0, 0, 0, 0.08);\n // transition: all 0.1s ease-in-out;\n overflow: hidden;\n"])), function (_ref6) {
2296
2301
  var editorHeight = _ref6.editorHeight;
2297
2302
  return editorHeight || 470;
2298
2303
  }, function (_ref7) {
@@ -2443,7 +2448,7 @@ var StyledContainer$6 = styled.div(_templateObject$p || (_templateObject$p = _ta
2443
2448
  return disabled ? 'none' : 'all';
2444
2449
  });
2445
2450
 
2446
- var _templateObject$o, _templateObject2$j, _templateObject3$a, _templateObject4$6, _templateObject5$2, _templateObject6, _templateObject7;
2451
+ var _templateObject$o, _templateObject2$j, _templateObject3$a, _templateObject4$6, _templateObject5$3, _templateObject6$1, _templateObject7$1;
2447
2452
  var Wrapper = styled.span(_templateObject$o || (_templateObject$o = _taggedTemplateLiteral(["\n position: relative;\n display: inline-flex;\n cursor: ", ";\n"])), function (_ref) {
2448
2453
  var disabled = _ref.disabled;
2449
2454
  return disabled ? 'not-allowed' : 'pointer';
@@ -2454,13 +2459,13 @@ styled.div(_templateObject3$a || (_templateObject3$a = _taggedTemplateLiteral(["
2454
2459
  return position === 'top' && styled.css(_templateObject4$6 || (_templateObject4$6 = _taggedTemplateLiteral(["\n bottom: 110%;\n left: 50%;\n transform: translateX(-50%);\n "])));
2455
2460
  }, function (_ref3) {
2456
2461
  var position = _ref3.position;
2457
- return position === 'right' && styled.css(_templateObject5$2 || (_templateObject5$2 = _taggedTemplateLiteral(["\n top: 50%;\n left: 105%;\n transform: translateY(-50%);\n "])));
2462
+ return position === 'right' && styled.css(_templateObject5$3 || (_templateObject5$3 = _taggedTemplateLiteral(["\n top: 50%;\n left: 105%;\n transform: translateY(-50%);\n "])));
2458
2463
  }, function (_ref4) {
2459
2464
  var position = _ref4.position;
2460
- return position === 'bottom' && styled.css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n top: 110%;\n left: 50%;\n transform: translateX(-50%);\n "])));
2465
+ return position === 'bottom' && styled.css(_templateObject6$1 || (_templateObject6$1 = _taggedTemplateLiteral(["\n top: 110%;\n left: 50%;\n transform: translateX(-50%);\n "])));
2461
2466
  }, function (_ref5) {
2462
2467
  var position = _ref5.position;
2463
- return position === 'left' && styled.css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n top: 50%;\n right: 105%;\n transform: translateY(-50%);\n "])));
2468
+ return position === 'left' && styled.css(_templateObject7$1 || (_templateObject7$1 = _taggedTemplateLiteral(["\n top: 50%;\n right: 105%;\n transform: translateY(-50%);\n "])));
2464
2469
  }, Wrapper);
2465
2470
 
2466
2471
  var Tooltip = function Tooltip(_ref) {
@@ -3016,14 +3021,16 @@ var removeImageProperty = function removeImageProperty() {
3016
3021
  var exportStageAsImage = /*#__PURE__*/function () {
3017
3022
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(stageRef, pageSizeKey) {
3018
3023
  var scale,
3024
+ cropArea,
3019
3025
  _args3 = arguments;
3020
3026
  return _regenerator().w(function (_context3) {
3021
3027
  while (1) switch (_context3.n) {
3022
3028
  case 0:
3023
3029
  scale = _args3.length > 2 && _args3[2] !== undefined ? _args3[2] : 2;
3030
+ cropArea = _args3.length > 3 && _args3[3] !== undefined ? _args3[3] : null;
3024
3031
  return _context3.a(2, new Promise(/*#__PURE__*/function () {
3025
3032
  var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(resolve, reject) {
3026
- var stage, canvas, dataURL, _t;
3033
+ var stage, canvasOptions, canvas, dataURL, _t;
3027
3034
  return _regenerator().w(function (_context2) {
3028
3035
  while (1) switch (_context2.p = _context2.n) {
3029
3036
  case 0:
@@ -3035,10 +3042,19 @@ var exportStageAsImage = /*#__PURE__*/function () {
3035
3042
  }
3036
3043
  return _context2.a(2, reject('Stage is not available'));
3037
3044
  case 1:
3038
- _context2.n = 2;
3039
- return stage.toCanvas({
3045
+ canvasOptions = {
3040
3046
  pixelRatio: scale
3041
- });
3047
+ };
3048
+ if (cropArea && Number.isFinite(cropArea.x) && Number.isFinite(cropArea.y) && Number.isFinite(cropArea.width) && Number.isFinite(cropArea.height)) {
3049
+ canvasOptions.x = cropArea.x;
3050
+ canvasOptions.y = cropArea.y;
3051
+ canvasOptions.width = cropArea.width;
3052
+ canvasOptions.height = cropArea.height;
3053
+ }
3054
+
3055
+ // Create a canvas with the scale factor
3056
+ _context2.n = 2;
3057
+ return stage.toCanvas(canvasOptions);
3042
3058
  case 2:
3043
3059
  canvas = _context2.v;
3044
3060
  _context2.n = 3;
@@ -4091,12 +4107,12 @@ var propTypes$i = {
4091
4107
  translation: PropTypes.object
4092
4108
  };
4093
4109
 
4094
- var _templateObject$e, _templateObject2$a, _templateObject3$7, _templateObject4$4, _templateObject5$1;
4110
+ var _templateObject$e, _templateObject2$a, _templateObject3$7, _templateObject4$4, _templateObject5$2;
4095
4111
  var Container$3 = styled.div(_templateObject$e || (_templateObject$e = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n align-items: center;\n position: relative;\n"])));
4096
4112
  var ZoomControlWrapper = styled.div(_templateObject2$a || (_templateObject2$a = _taggedTemplateLiteral(["\n border: 1px solid ", ";\n border-radius: 6px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n background: white;\n"])), theme.color.gray_200);
4097
4113
  var ZoomButton = styled.div(_templateObject3$7 || (_templateObject3$7 = _taggedTemplateLiteral(["\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 0 14px;\n cursor: pointer;\n"])));
4098
4114
  var Divider = styled.div(_templateObject4$4 || (_templateObject4$4 = _taggedTemplateLiteral(["\n width: 1px;\n height: 80%;\n background: rgba(77, 98, 119, 0.2);\n"])));
4099
- var ZoomPercentage = styled.p(_templateObject5$1 || (_templateObject5$1 = _taggedTemplateLiteral(["\n padding: 0 14px;\n font-family: ", ";\n font-weight: ", ";\n color: ", ";\n"])), theme.fonts.primary, theme.fontWeights[500], theme.color.icon_gray);
4115
+ var ZoomPercentage = styled.p(_templateObject5$2 || (_templateObject5$2 = _taggedTemplateLiteral(["\n padding: 0 14px;\n font-family: ", ";\n font-weight: ", ";\n color: ", ";\n"])), theme.fonts.primary, theme.fontWeights[500], theme.color.icon_gray);
4100
4116
 
4101
4117
  var propTypes$h = {
4102
4118
  varient: PropTypes.oneOf(Object.values(ButtonVarients)),
@@ -5364,8 +5380,23 @@ var Editor = function Editor(_ref) {
5364
5380
  onRemoveBackgroundImage = _ref.onRemoveBackgroundImage,
5365
5381
  showBackgroundImagePicker = _ref.showBackgroundImagePicker,
5366
5382
  showOpacityPicker = _ref.showOpacityPicker,
5367
- changeSelectedElementProperty = _ref.changeSelectedElementProperty;
5383
+ changeSelectedElementProperty = _ref.changeSelectedElementProperty,
5384
+ _ref$showOutsideBound = _ref.showOutsideBoundaryPreview,
5385
+ showOutsideBoundaryPreview = _ref$showOutsideBound === void 0 ? false : _ref$showOutsideBound,
5386
+ _ref$outsideBoundaryP = _ref.outsideBoundaryPreviewPadding,
5387
+ outsideBoundaryPreviewPadding = _ref$outsideBoundaryP === void 0 ? 120 : _ref$outsideBoundaryP;
5368
5388
  var transformerRef = React.useRef(null);
5389
+ var previewPadding = React.useMemo(function () {
5390
+ return showOutsideBoundaryPreview ? Math.max(0, Number(outsideBoundaryPreviewPadding) || 0) : 0;
5391
+ }, [showOutsideBoundaryPreview, outsideBoundaryPreviewPadding]);
5392
+ var stageWidth = React.useMemo(function () {
5393
+ return editorWidth + previewPadding * 2;
5394
+ }, [editorWidth, previewPadding]);
5395
+ var stageHeight = React.useMemo(function () {
5396
+ return editorHeight + previewPadding * 2;
5397
+ }, [editorHeight, previewPadding]);
5398
+ var pageOffsetX = previewPadding;
5399
+ var pageOffsetY = previewPadding;
5369
5400
  React.useEffect(function () {
5370
5401
  if (transformerRef !== null && transformerRef !== void 0 && transformerRef.current) {
5371
5402
  var _stageRef$current;
@@ -5701,14 +5732,14 @@ var Editor = function Editor(_ref) {
5701
5732
  showOpacityPicker: showOpacityPicker,
5702
5733
  changeSelectedElementProperty: changeSelectedElementProperty
5703
5734
  }), /*#__PURE__*/React.createElement(InnerContainer, null, /*#__PURE__*/React.createElement(InnerContainerWrapper, {
5704
- editorHeight: editorHeight + 50,
5705
- editorWidth: editorWidth
5735
+ editorHeight: stageHeight + 50,
5736
+ editorWidth: stageWidth
5706
5737
  }, title && /*#__PURE__*/React.createElement(Title, null, title), /*#__PURE__*/React.createElement(EditorBox, {
5707
- editorHeight: editorHeight,
5708
- editorWidth: editorWidth
5738
+ editorHeight: stageHeight,
5739
+ editorWidth: stageWidth
5709
5740
  }, !loadingImages && !loadingFonts && /*#__PURE__*/React.createElement(reactKonva.Stage, {
5710
- width: editorWidth,
5711
- height: editorHeight,
5741
+ width: stageWidth,
5742
+ height: stageHeight,
5712
5743
  ref: stageRef,
5713
5744
  onMouseDown: function onMouseDown(e) {
5714
5745
  if (e.target === e.target.getStage()) {
@@ -5723,15 +5754,21 @@ var Editor = function Editor(_ref) {
5723
5754
  },
5724
5755
  listening: false
5725
5756
  }, /*#__PURE__*/React.createElement(reactKonva.Rect, {
5757
+ x: pageOffsetX,
5758
+ y: pageOffsetY,
5726
5759
  width: editorWidth,
5727
5760
  height: editorHeight,
5728
5761
  fill: canvasBackgroundColor || theme.color.white
5729
5762
  }), canvasBackgroundImage && /*#__PURE__*/React.createElement(CanvasImage, {
5730
5763
  element: _objectSpread2(_objectSpread2({}, canvasBackgroundImage), {}, {
5764
+ x: pageOffsetX,
5765
+ y: pageOffsetY,
5731
5766
  width: editorWidth,
5732
5767
  height: editorHeight
5733
5768
  })
5734
5769
  })), /*#__PURE__*/React.createElement(reactKonva.Layer, null, /*#__PURE__*/React.createElement(reactKonva.Group, {
5770
+ x: pageOffsetX,
5771
+ y: pageOffsetY,
5735
5772
  scaleX: zoomPercentage / 100,
5736
5773
  scaleY: zoomPercentage / 100
5737
5774
  }, elements === null || elements === void 0 ? void 0 : elements.map(function (el) {
@@ -5762,12 +5799,42 @@ var Editor = function Editor(_ref) {
5762
5799
  }
5763
5800
  return newBox;
5764
5801
  }
5765
- }))), /*#__PURE__*/React.createElement(reactKonva.Layer, {
5802
+ }))), showOutsideBoundaryPreview && previewPadding > 0 ? /*#__PURE__*/React.createElement(reactKonva.Layer, {
5766
5803
  listening: false
5767
5804
  }, /*#__PURE__*/React.createElement(reactKonva.Rect, {
5768
5805
  listening: false,
5769
5806
  x: 0,
5770
5807
  y: 0,
5808
+ width: stageWidth,
5809
+ height: pageOffsetY,
5810
+ fill: "rgba(0, 0, 0, 0.14)"
5811
+ }), /*#__PURE__*/React.createElement(reactKonva.Rect, {
5812
+ listening: false,
5813
+ x: 0,
5814
+ y: pageOffsetY,
5815
+ width: pageOffsetX,
5816
+ height: editorHeight,
5817
+ fill: "rgba(0, 0, 0, 0.14)"
5818
+ }), /*#__PURE__*/React.createElement(reactKonva.Rect, {
5819
+ listening: false,
5820
+ x: pageOffsetX + editorWidth,
5821
+ y: pageOffsetY,
5822
+ width: stageWidth - (pageOffsetX + editorWidth),
5823
+ height: editorHeight,
5824
+ fill: "rgba(0, 0, 0, 0.14)"
5825
+ }), /*#__PURE__*/React.createElement(reactKonva.Rect, {
5826
+ listening: false,
5827
+ x: 0,
5828
+ y: pageOffsetY + editorHeight,
5829
+ width: stageWidth,
5830
+ height: stageHeight - (pageOffsetY + editorHeight),
5831
+ fill: "rgba(0, 0, 0, 0.14)"
5832
+ })) : null, /*#__PURE__*/React.createElement(reactKonva.Layer, {
5833
+ listening: false
5834
+ }, /*#__PURE__*/React.createElement(reactKonva.Rect, {
5835
+ listening: false,
5836
+ x: pageOffsetX,
5837
+ y: pageOffsetY,
5771
5838
  width: editorWidth,
5772
5839
  height: editorHeight,
5773
5840
  stroke: cuttingGuideStrokeColor,
@@ -5819,6 +5886,7 @@ var propTypes$b = {
5819
5886
  setLoadingUploadImage: PropTypes.func,
5820
5887
  defaultTemplatesList: PropTypes.array,
5821
5888
  customTemplatesList: PropTypes.array,
5889
+ templatesDisplayOrder: PropTypes.oneOf(['defaultFirst', 'customFirst']),
5822
5890
  styleProps: PropTypes.object
5823
5891
  };
5824
5892
 
@@ -5873,7 +5941,8 @@ var propTypes$9 = {
5873
5941
  oncreateNewTemplate: PropTypes.func,
5874
5942
  languageLocale: PropTypes.string,
5875
5943
  defaultTemplatesList: PropTypes.array,
5876
- customTemplatesList: PropTypes.array
5944
+ customTemplatesList: PropTypes.array,
5945
+ templatesDisplayOrder: PropTypes.oneOf(['defaultFirst', 'customFirst'])
5877
5946
  };
5878
5947
 
5879
5948
  var propTypes$8 = {
@@ -5885,7 +5954,7 @@ var propTypes$8 = {
5885
5954
  content: PropTypes.node
5886
5955
  };
5887
5956
 
5888
- var _templateObject$8, _templateObject2$6, _templateObject3$6, _templateObject4$3, _templateObject5;
5957
+ var _templateObject$8, _templateObject2$6, _templateObject3$6, _templateObject4$3, _templateObject5$1;
5889
5958
  var CollapsableContainer = styled.div(_templateObject$8 || (_templateObject$8 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n margin-top: ", "px;\n margin-bottom: ", "px;\n"])), function (_ref) {
5890
5959
  var marginTop = _ref.marginTop;
5891
5960
  return marginTop;
@@ -5896,7 +5965,7 @@ var CollapsableContainer = styled.div(_templateObject$8 || (_templateObject$8 =
5896
5965
  var CollapsableHeader = styled.div(_templateObject2$6 || (_templateObject2$6 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: row;\n align-items: center;\n cursor: pointer;\n justify-content: flex-start;\n align-self: flex-start;\n margin-bottom: 14px;\n"])));
5897
5966
  var LeftIconWrapper = styled.div(_templateObject3$6 || (_templateObject3$6 = _taggedTemplateLiteral(["\n margin-right: 6px;\n display: flex;\n align-items: center;\n"])));
5898
5967
  var IconWrapper = styled.div(_templateObject4$3 || (_templateObject4$3 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: row;\n align-items: center;\n margin-top: 3px;\n"])));
5899
- var CollapsableContent = styled.div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n display: ", ";\n"])), function (_ref3) {
5968
+ var CollapsableContent = styled.div(_templateObject5$1 || (_templateObject5$1 = _taggedTemplateLiteral(["\n display: ", ";\n"])), function (_ref3) {
5900
5969
  var visible = _ref3.visible;
5901
5970
  return visible ? 'flex' : 'none';
5902
5971
  });
@@ -5936,11 +6005,14 @@ var Collapsable = function Collapsable(_ref) {
5936
6005
  };
5937
6006
  Collapsable.propTypes = propTypes$8;
5938
6007
 
5939
- var _templateObject$7, _templateObject2$5, _templateObject3$5, _templateObject4$2;
6008
+ var _templateObject$7, _templateObject2$5, _templateObject3$5, _templateObject4$2, _templateObject5, _templateObject6, _templateObject7;
5940
6009
  var TemplatesContainer = styled.div(_templateObject$7 || (_templateObject$7 = _taggedTemplateLiteral(["\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n gap: 10px;\n align-items: flex-start;\n"])));
5941
- var TemplateItem = styled.div(_templateObject2$5 || (_templateObject2$5 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n cursor: pointer;\n position: relative;\n overflow: hidden;\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.2);\n opacity: 0;\n transition: opacity 0.3s ease;\n z-index: 1;\n }\n\n &:hover::before {\n opacity: 1;\n }\n &:hover > button {\n display: flex;\n z-index: 2;\n }\n"])));
5942
- var StyledDeleteButton = styled.button(_templateObject3$5 || (_templateObject3$5 = _taggedTemplateLiteral(["\n display: none;\n justify-content: center;\n align-items: center;\n height: 30px;\n width: 30px;\n padding: 8px;\n border-radius: 100%;\n background: rgba(255, 255, 255, 1);\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:hover {\n border-color: #d91919;\n }\n &:focus {\n outline: none;\n }\n"])));
5943
- var StyledContainer$5 = styled.div(_templateObject4$2 || (_templateObject4$2 = _taggedTemplateLiteral(["\n display: flex;\n flex: 1;\n flex-direction: column;\n padding: 20px 18px;\n overflow: auto;\n"])));
6010
+ var TemplateItem = styled.div(_templateObject2$5 || (_templateObject2$5 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n cursor: pointer;\n position: relative;\n gap: 6px;\n overflow: hidden;\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.2);\n opacity: 0;\n transition: opacity 0.3s ease;\n z-index: 1;\n pointer-events: none;\n }\n\n &:hover::before {\n opacity: 1;\n }\n"])));
6011
+ var StyledDeleteButton = styled.button(_templateObject3$5 || (_templateObject3$5 = _taggedTemplateLiteral(["\n display: inline-flex;\n justify-content: center;\n align-items: center;\n height: 24px;\n width: 24px;\n padding: 0;\n border-radius: 6px;\n background: #fff;\n border: 1px solid #e7e7e7;\n flex-shrink: 0;\n z-index: 3;\n cursor: pointer;\n position: absolute;\n top: 6px;\n right: 6px;\n opacity: 0;\n pointer-events: none;\n transform: translateY(-4px);\n transition:\n border-color 0.2s ease,\n background-color 0.2s ease,\n opacity 0.2s ease,\n transform 0.2s ease;\n\n ", ":hover &,\n ", ":focus-within & {\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0);\n }\n\n img {\n height: 14px;\n }\n\n &:hover {\n border-color: #d91919;\n background: #fff5f5;\n }\n\n &:focus {\n outline: 2px solid #d91919;\n outline-offset: 1px;\n }\n"])), TemplateItem, TemplateItem);
6012
+ var TemplateFooter = styled.div(_templateObject4$2 || (_templateObject4$2 = _taggedTemplateLiteral(["\n width: 115px;\n display: flex;\n align-items: center;\n gap: 6px;\n"])));
6013
+ var TemplateTitle = styled.div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n color: #a1a1a1;\n font-size: 10px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 0;\n line-height: 1.2;\n padding-bottom: 2px;\n"])));
6014
+ var TemplatePreview = styled.div(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n position: relative;\n width: 115px;\n height: 125px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n overflow: hidden;\n\n img {\n border-radius: 6px;\n }\n"])));
6015
+ var StyledContainer$5 = styled.div(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n display: flex;\n flex: 1;\n flex-direction: column;\n padding: 20px 18px;\n overflow: auto;\n"])));
5944
6016
 
5945
6017
  var propTypes$7 = {
5946
6018
  text: PropTypes.string,
@@ -5997,12 +6069,14 @@ var RadioSection = function RadioSection(_ref) {
5997
6069
  RadioSection.propTypes = propTypes$7;
5998
6070
 
5999
6071
  var TemplateSideBar = function TemplateSideBar(_ref) {
6000
- var _TEXT_DICTIONARY$lang, _TEXT_DICTIONARY$lang2, _TEXT_DICTIONARY$lang3, _TEXT_DICTIONARY$lang4, _TEXT_DICTIONARY$lang5, _TEXT_DICTIONARY$lang6, _TEXT_DICTIONARY$lang7;
6072
+ var _TEXT_DICTIONARY$lang, _TEXT_DICTIONARY$lang2, _TEXT_DICTIONARY$lang3, _TEXT_DICTIONARY$lang4, _TEXT_DICTIONARY$lang5, _TEXT_DICTIONARY$lang6, _TEXT_DICTIONARY$lang7, _TEXT_DICTIONARY$lang8;
6001
6073
  var oncreateNewTemplate = _ref.oncreateNewTemplate,
6002
6074
  languageLocale = _ref.languageLocale,
6003
6075
  onDeleteCustomTemplate = _ref.onDeleteCustomTemplate,
6004
6076
  defaultTemplatesList = _ref.defaultTemplatesList,
6005
6077
  customTemplatesList = _ref.customTemplatesList,
6078
+ _ref$templatesDisplay = _ref.templatesDisplayOrder,
6079
+ templatesDisplayOrder = _ref$templatesDisplay === void 0 ? 'defaultFirst' : _ref$templatesDisplay,
6006
6080
  onTemplateSelect = _ref.onTemplateSelect,
6007
6081
  isLocationTextActive = _ref.isLocationTextActive,
6008
6082
  onToggleLocationText = _ref.onToggleLocationText,
@@ -6019,21 +6093,12 @@ var TemplateSideBar = function TemplateSideBar(_ref) {
6019
6093
  onTemplateSelect(item === null || item === void 0 ? void 0 : item.id);
6020
6094
  }
6021
6095
  }
6022
- }, /*#__PURE__*/React.createElement(StyledImage, {
6096
+ }, /*#__PURE__*/React.createElement(TemplatePreview, null, /*#__PURE__*/React.createElement(StyledImage, {
6023
6097
  src: item === null || item === void 0 ? void 0 : item.image,
6024
6098
  maxHeight: 125,
6025
6099
  maxWidth: 115,
6026
6100
  borderRadius: 6
6027
- }), /*#__PURE__*/React.createElement(StyledText, {
6028
- color: theme.color.gray_A1A1A1,
6029
- fontSize: 10,
6030
- style: {
6031
- whiteSpace: 'nowrap',
6032
- overflow: 'hidden',
6033
- textOverflow: 'ellipsis',
6034
- maxWidth: 115
6035
- }
6036
- }, item === null || item === void 0 ? void 0 : item.title));
6101
+ })), /*#__PURE__*/React.createElement(TemplateFooter, null, /*#__PURE__*/React.createElement(TemplateTitle, null, item === null || item === void 0 ? void 0 : item.title)));
6037
6102
  }));
6038
6103
  }, []);
6039
6104
  var renderCustomContent = React.useMemo(function () {
@@ -6046,29 +6111,23 @@ var TemplateSideBar = function TemplateSideBar(_ref) {
6046
6111
  onTemplateSelect(item === null || item === void 0 ? void 0 : item.id);
6047
6112
  }
6048
6113
  }
6049
- }, /*#__PURE__*/React.createElement(StyledImage, {
6114
+ }, /*#__PURE__*/React.createElement(TemplatePreview, null, /*#__PURE__*/React.createElement(StyledImage, {
6050
6115
  src: item === null || item === void 0 ? void 0 : item.image,
6051
6116
  maxHeight: 125,
6052
6117
  maxWidth: 115,
6053
6118
  borderRadius: 6
6054
6119
  }), /*#__PURE__*/React.createElement(StyledDeleteButton, {
6120
+ "aria-label": "Delete ".concat((item === null || item === void 0 ? void 0 : item.title) || 'template'),
6055
6121
  onClick: function onClick(e) {
6056
- e.stopPropagation(); // ⛔ Prevents parent onClick
6057
- onDeleteCustomTemplate === null || onDeleteCustomTemplate === void 0 || onDeleteCustomTemplate(item);
6122
+ e.stopPropagation();
6123
+ var shouldDelete = window.confirm("Delete \"".concat((item === null || item === void 0 ? void 0 : item.title) || 'this template', "\"?"));
6124
+ if (shouldDelete) {
6125
+ onDeleteCustomTemplate === null || onDeleteCustomTemplate === void 0 || onDeleteCustomTemplate(item);
6126
+ }
6058
6127
  }
6059
6128
  }, /*#__PURE__*/React.createElement(StyledImage, {
6060
- src: IconDelete,
6061
- height: 24
6062
- })), /*#__PURE__*/React.createElement(StyledText, {
6063
- color: theme.color.gray_A1A1A1,
6064
- fontSize: 10,
6065
- style: {
6066
- whiteSpace: 'nowrap',
6067
- overflow: 'hidden',
6068
- textOverflow: 'ellipsis',
6069
- maxWidth: 115
6070
- }
6071
- }, item === null || item === void 0 ? void 0 : item.title));
6129
+ src: IconDelete
6130
+ }))), /*#__PURE__*/React.createElement(TemplateFooter, null, /*#__PURE__*/React.createElement(TemplateTitle, null, item === null || item === void 0 ? void 0 : item.title)));
6072
6131
  }));
6073
6132
  }, []);
6074
6133
  return /*#__PURE__*/React.createElement(StyledContainer$5, null, /*#__PURE__*/React.createElement(Button, {
@@ -6120,13 +6179,16 @@ var TemplateSideBar = function TemplateSideBar(_ref) {
6120
6179
  isActive: !!isQrIdTextActive,
6121
6180
  onToggle: onToggleQrIdText,
6122
6181
  disabled: false
6123
- })) : null), /*#__PURE__*/React.createElement(Collapsable, {
6124
- title: TEXT_DICTIONARY === null || TEXT_DICTIONARY === void 0 || (_TEXT_DICTIONARY$lang6 = TEXT_DICTIONARY[languageLocale]) === null || _TEXT_DICTIONARY$lang6 === void 0 ? void 0 : _TEXT_DICTIONARY$lang6.DEFAULT,
6182
+ })) : null), templatesDisplayOrder === 'customFirst' && customTemplatesList.length > 0 ? /*#__PURE__*/React.createElement(Collapsable, {
6183
+ title: TEXT_DICTIONARY === null || TEXT_DICTIONARY === void 0 || (_TEXT_DICTIONARY$lang6 = TEXT_DICTIONARY[languageLocale]) === null || _TEXT_DICTIONARY$lang6 === void 0 ? void 0 : _TEXT_DICTIONARY$lang6.CUSTOM_TEMPLATES,
6184
+ content: renderCustomContent
6185
+ }) : null, /*#__PURE__*/React.createElement(Collapsable, {
6186
+ title: TEXT_DICTIONARY === null || TEXT_DICTIONARY === void 0 || (_TEXT_DICTIONARY$lang7 = TEXT_DICTIONARY[languageLocale]) === null || _TEXT_DICTIONARY$lang7 === void 0 ? void 0 : _TEXT_DICTIONARY$lang7.DEFAULT,
6125
6187
  content: renderDefaultContent
6126
- }), customTemplatesList.length > 0 && /*#__PURE__*/React.createElement(Collapsable, {
6127
- title: TEXT_DICTIONARY === null || TEXT_DICTIONARY === void 0 || (_TEXT_DICTIONARY$lang7 = TEXT_DICTIONARY[languageLocale]) === null || _TEXT_DICTIONARY$lang7 === void 0 ? void 0 : _TEXT_DICTIONARY$lang7.CUSTOM_TEMPLATES,
6188
+ }), templatesDisplayOrder !== 'customFirst' && customTemplatesList.length > 0 ? /*#__PURE__*/React.createElement(Collapsable, {
6189
+ title: TEXT_DICTIONARY === null || TEXT_DICTIONARY === void 0 || (_TEXT_DICTIONARY$lang8 = TEXT_DICTIONARY[languageLocale]) === null || _TEXT_DICTIONARY$lang8 === void 0 ? void 0 : _TEXT_DICTIONARY$lang8.CUSTOM_TEMPLATES,
6128
6190
  content: renderCustomContent
6129
- }));
6191
+ }) : null);
6130
6192
  };
6131
6193
  TemplateSideBar.propTypes = propTypes$9;
6132
6194
 
@@ -6466,6 +6528,7 @@ var HelperSideBar = function HelperSideBar(_ref) {
6466
6528
  setLoadingUploadImage = _ref.setLoadingUploadImage,
6467
6529
  defaultTemplatesList = _ref.defaultTemplatesList,
6468
6530
  customTemplatesList = _ref.customTemplatesList,
6531
+ templatesDisplayOrder = _ref.templatesDisplayOrder,
6469
6532
  onDeleteCustomTemplate = _ref.onDeleteCustomTemplate,
6470
6533
  styleProps = _ref.styleProps,
6471
6534
  defaultText = _ref.defaultText,
@@ -6491,6 +6554,7 @@ var HelperSideBar = function HelperSideBar(_ref) {
6491
6554
  onDeleteCustomTemplate: onDeleteCustomTemplate,
6492
6555
  defaultTemplatesList: defaultTemplatesList,
6493
6556
  customTemplatesList: customTemplatesList,
6557
+ templatesDisplayOrder: templatesDisplayOrder,
6494
6558
  onTemplateSelect: onTemplateSelect,
6495
6559
  styleProps: styleProps,
6496
6560
  isLocationTextActive: isLocationTextActive,
@@ -6629,6 +6693,9 @@ var isPropValid = /* #__PURE__ */memoize(function (prop) {
6629
6693
  * @property {boolean} [disableWhiteLabel]
6630
6694
  * @property {Array} [defaultTemplatesList]
6631
6695
  * @property {Array} [customTemplatesList]
6696
+ * @property {'defaultFirst'|'customFirst'} [templatesDisplayOrder]
6697
+ * @property {boolean} [showOutsideBoundaryPreview]
6698
+ * @property {number} [outsideBoundaryPreviewPadding]
6632
6699
  * @property {string} [qrLink]
6633
6700
  * @property {Object} [styleProps]
6634
6701
  * @property {string} [defaultText]
@@ -6667,6 +6734,12 @@ var Studio = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
6667
6734
  defaultTemplatesList = _ref$defaultTemplates === void 0 ? [] : _ref$defaultTemplates,
6668
6735
  _ref$customTemplatesL = _ref.customTemplatesList,
6669
6736
  customTemplatesList = _ref$customTemplatesL === void 0 ? [] : _ref$customTemplatesL,
6737
+ _ref$templatesDisplay = _ref.templatesDisplayOrder,
6738
+ templatesDisplayOrder = _ref$templatesDisplay === void 0 ? 'defaultFirst' : _ref$templatesDisplay,
6739
+ _ref$showOutsideBound = _ref.showOutsideBoundaryPreview,
6740
+ showOutsideBoundaryPreview = _ref$showOutsideBound === void 0 ? false : _ref$showOutsideBound,
6741
+ _ref$outsideBoundaryP = _ref.outsideBoundaryPreviewPadding,
6742
+ outsideBoundaryPreviewPadding = _ref$outsideBoundaryP === void 0 ? 120 : _ref$outsideBoundaryP,
6670
6743
  onDeleteCustomTemplate = _ref.onDeleteCustomTemplate,
6671
6744
  _ref$qrLink = _ref.qrLink,
6672
6745
  qrLink = _ref$qrLink === void 0 ? 'www.google.com' : _ref$qrLink,
@@ -6898,7 +6971,7 @@ var Studio = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
6898
6971
  case 1:
6899
6972
  processedElements = removeImageProperty(elements);
6900
6973
  _context.n = 2;
6901
- return exportStageAsImage(stageRef);
6974
+ return exportStageAsImage(stageRef, null, 2, exportCropArea);
6902
6975
  case 2:
6903
6976
  dataURL = _context.v;
6904
6977
  setLoading(false);
@@ -6963,9 +7036,13 @@ var Studio = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
6963
7036
  var isMac = navigator.platform.toUpperCase().includes('MAC');
6964
7037
  var ctrlOrCmd = isMac ? e.metaKey : e.ctrlKey;
6965
7038
  var shiftKey = e.shiftKey;
7039
+ var activeElement = document.activeElement;
7040
+ var isTypingTarget = ['INPUT', 'TEXTAREA'].includes(activeElement === null || activeElement === void 0 ? void 0 : activeElement.tagName) || (activeElement === null || activeElement === void 0 ? void 0 : activeElement.isContentEditable);
7041
+ var isDeleteKey = e.key === 'Delete' || e.key === 'Del';
7042
+ var isBackspaceKey = e.key === 'Backspace';
6966
7043
 
6967
- // Delete
6968
- if ((e.key === 'Delete' || e.key === 'Backspace') && selectedElement && (selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.draggable) !== false && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName) && !document.activeElement.isContentEditable) {
7044
+ // Delete selected element with Delete (Win) or Backspace (Mac)
7045
+ if ((isDeleteKey || isBackspaceKey) && selectedElement && !isTypingTarget) {
6969
7046
  e.preventDefault();
6970
7047
  onDeleteSelectedElement();
6971
7048
  }
@@ -7072,6 +7149,18 @@ var Studio = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
7072
7149
  return (e === null || e === void 0 ? void 0 : e.type) === (elementTypes === null || elementTypes === void 0 ? void 0 : elementTypes.pageSize);
7073
7150
  })) === null || _elements$find2 === void 0 ? void 0 : _elements$find2.size) || (pageSizes === null || pageSizes === void 0 ? void 0 : pageSizes.A4)]) === null || _pageSizesDimensions2 === void 0 ? void 0 : _pageSizesDimensions2.width, zoomPercentage);
7074
7151
  }, [zoomPercentage, elements]);
7152
+ var normalizedOutsidePreviewPadding = React.useMemo(function () {
7153
+ return Math.max(0, Number(outsideBoundaryPreviewPadding) || 0);
7154
+ }, [outsideBoundaryPreviewPadding]);
7155
+ var exportCropArea = React.useMemo(function () {
7156
+ if (!showOutsideBoundaryPreview) return null;
7157
+ return {
7158
+ x: normalizedOutsidePreviewPadding,
7159
+ y: normalizedOutsidePreviewPadding,
7160
+ width: editorWidth,
7161
+ height: editorHeight
7162
+ };
7163
+ }, [showOutsideBoundaryPreview, normalizedOutsidePreviewPadding, editorWidth, editorHeight]);
7075
7164
  var selectedPageSize = React.useMemo(function () {
7076
7165
  var _elements$find3;
7077
7166
  return (elements === null || elements === void 0 || (_elements$find3 = elements.find(function (e) {
@@ -7814,7 +7903,7 @@ var Studio = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
7814
7903
  case 2:
7815
7904
  processedElements = removeImageProperty(elements);
7816
7905
  _context3.n = 3;
7817
- return exportStageAsImage(stageRef);
7906
+ return exportStageAsImage(stageRef, null, 2, exportCropArea);
7818
7907
  case 3:
7819
7908
  dataURL = _context3.v;
7820
7909
  setLoading(false);
@@ -7864,6 +7953,7 @@ var Studio = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
7864
7953
  setLoadingUploadImage: setLoadingUploadImage,
7865
7954
  defaultTemplatesList: defaultTemplatesList,
7866
7955
  customTemplatesList: customTemplatesList,
7956
+ templatesDisplayOrder: templatesDisplayOrder,
7867
7957
  onDeleteCustomTemplate: onDeleteCustomTemplate,
7868
7958
  styleProps: styleProps,
7869
7959
  defaultText: defaultText,
@@ -7953,7 +8043,9 @@ var Studio = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
7953
8043
  onRemoveBackgroundImage: onRemoveBackgroundImage,
7954
8044
  showBackgroundImagePicker: showBackgroundImagePicker,
7955
8045
  showOpacityPicker: showOpacityPicker,
7956
- changeSelectedElementProperty: changeSelectedElementProperty
8046
+ changeSelectedElementProperty: changeSelectedElementProperty,
8047
+ showOutsideBoundaryPreview: showOutsideBoundaryPreview,
8048
+ outsideBoundaryPreviewPadding: normalizedOutsidePreviewPadding
7957
8049
  }), overallLoading && /*#__PURE__*/React.createElement(Overlay, null, /*#__PURE__*/React.createElement(LoadingSpinner, {
7958
8050
  size: "60px",
7959
8051
  color: theme.color.secondary