@vectoriox/iox-builder 1.4.6 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -133,9 +133,9 @@ var DeviceMode;
133
133
  DeviceMode["Mobile"] = "mobile";
134
134
  })(DeviceMode || (DeviceMode = {}));
135
135
  const DEVICE_OPTIONS = [
136
- { mode: DeviceMode.Desktop, label: 'Desktop', icon: 'ph-thin ph-desktop', width: 1440 },
137
- { mode: DeviceMode.Tablet, label: 'Tablet', icon: 'ph-thin ph-device-tablet', width: 768 },
138
- { mode: DeviceMode.Mobile, label: 'Mobile', icon: 'ph-thin ph-device-mobile', width: 375 },
136
+ { mode: DeviceMode.Desktop, label: 'Desktop', icon: 'ph-thin ph-desktop', width: 1440, height: 900 },
137
+ { mode: DeviceMode.Tablet, label: 'Tablet', icon: 'ph-thin ph-device-tablet', width: 768, height: 1024 },
138
+ { mode: DeviceMode.Mobile, label: 'Mobile', icon: 'ph-thin ph-device-mobile', width: 375, height: 812 },
139
139
  ];
140
140
  const ZOOM_OPTIONS = [
141
141
  { label: '25%', value: 25 },
@@ -985,7 +985,7 @@ class ViewportService {
985
985
  const option = DEVICE_OPTIONS.find(d => d.mode === device);
986
986
  if (!option)
987
987
  return;
988
- this.update({ device, width: option.width });
988
+ this.update({ device, width: option.width, height: option.height });
989
989
  }
990
990
  setScale(scale) {
991
991
  this.update({ scale: Math.max(0.1, Math.min(2, scale)) });
@@ -996,7 +996,7 @@ class ViewportService {
996
996
  /**
997
997
  * Calculate the scale that makes the canvas fit inside the available editor width.
998
998
  * @param availableWidth The pixel width of the editor area that holds the canvas.
999
- * @param padding Optional horizontal padding to subtract (default 20px each side).
999
+ * @param padding Optional horizontal padding to subtract (default 40px total).
1000
1000
  */
1001
1001
  fitToWidth(availableWidth, padding = 40) {
1002
1002
  const usable = availableWidth - padding;
@@ -1005,6 +1005,22 @@ class ViewportService {
1005
1005
  const scale = Math.min(1, usable / this.state.width);
1006
1006
  this.setScale(scale);
1007
1007
  }
1008
+ /**
1009
+ * Calculate the scale that makes the canvas fit both the available width AND height.
1010
+ * Uses the smaller of the two scale factors so the entire viewport frame is visible.
1011
+ * @param containerWidth Available container width in screen pixels.
1012
+ * @param containerHeight Available container height in screen pixels.
1013
+ * @param padding Total padding to subtract from both dimensions (default 40px).
1014
+ */
1015
+ fitToSize(containerWidth, containerHeight, padding = 40) {
1016
+ const usableW = containerWidth - padding;
1017
+ const usableH = containerHeight - padding;
1018
+ if (usableW <= 0 || usableH <= 0)
1019
+ return;
1020
+ const scaleX = usableW / this.state.width;
1021
+ const scaleY = usableH / this.state.height;
1022
+ this.setScale(Math.min(1, scaleX, scaleY));
1023
+ }
1008
1024
  /**
1009
1025
  * Convert a screen-space coordinate to canvas-space (unscaled).
1010
1026
  * Call this when translating pointer events into canvas-relative positions.
@@ -1030,6 +1046,7 @@ class ViewportService {
1030
1046
  const defaults = {
1031
1047
  device: DeviceMode.Desktop,
1032
1048
  width: DEVICE_OPTIONS[0].width,
1049
+ height: DEVICE_OPTIONS[0].height,
1033
1050
  scale: 0.75,
1034
1051
  };
1035
1052
  try {
@@ -1044,6 +1061,7 @@ class ViewportService {
1044
1061
  return {
1045
1062
  device,
1046
1063
  width: typeof saved.width === 'number' && saved.width > 0 ? saved.width : option.width,
1064
+ height: typeof saved.height === 'number' && saved.height > 0 ? saved.height : option.height,
1047
1065
  scale: typeof saved.scale === 'number' ? Math.max(0.1, Math.min(2, saved.scale)) : defaults.scale,
1048
1066
  };
1049
1067
  }
@@ -1609,7 +1627,7 @@ class TypographyGroupStyleConfig extends GroupStyleConfig {
1609
1627
  constructor() {
1610
1628
  super(StyleCategory.Typography, [
1611
1629
  new TraitConfig('fontFamily', 'Font Family', TraitInputType.FontFamily, [], 'Poppins, sans-serif'),
1612
- new TraitConfig('fontSize', 'Font Size', TraitInputType.Scrub, { min: 8, max: 200, step: 1, units: UNITS_FIXED }, '16px'),
1630
+ new TraitConfig('fontSize', 'Font Size', TraitInputType.Scrub, { min: 8, max: 200, step: 1, units: UNITS_ALL }, '16px'),
1613
1631
  new TraitConfig('fontWeight', 'Font Weight', TraitInputType.Select, ['100', '200', '300', '400', '500', '600', '700', '800', '900'], '400'),
1614
1632
  new TraitConfig('color', 'Color', TraitInputType.Color, { allowGradient: false, allowTransparent: false, formats: ['hex', 'rgb', 'hsl'] }, '#000000'),
1615
1633
  new TraitConfig('lineHeight', 'Line Height', TraitInputType.Select, ['1', '1.2', '1.4', '1.5', '1.75', '2', '2.5'], '1.5'),
@@ -1799,11 +1817,20 @@ class StyleRegistryService {
1799
1817
  compile(className, styles) {
1800
1818
  const entries = Object.entries(styles)
1801
1819
  .filter(([, v]) => v !== undefined && v !== null && v !== '')
1802
- .map(([k, v]) => ` ${this.toKebabCase(k)}: ${v};`);
1820
+ .map(([k, v]) => ` ${this.toKebabCase(k)}: ${this.rewriteVh(String(v))};`);
1803
1821
  if (!entries.length)
1804
1822
  return '';
1805
1823
  return `.${className} {\n${entries.join('\n')}\n}`;
1806
1824
  }
1825
+ /**
1826
+ * Rewrite bare `vh` values to `calc(N * var(--preview-vh, 1vh))` so they
1827
+ * resolve to the simulated viewport height in the builder canvas.
1828
+ * In production (no --preview-vh defined) the fallback `1vh` preserves the
1829
+ * original behaviour: `calc(50 * 1vh)` == `50vh`.
1830
+ */
1831
+ rewriteVh(value) {
1832
+ return value.replace(/(-?\d*\.?\d+)vh/g, 'calc($1 * var(--preview-vh, 1vh))');
1833
+ }
1807
1834
  toKebabCase(str) {
1808
1835
  return str.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);
1809
1836
  }