wyreframe 0.7.7 → 0.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wyreframe",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "ASCII wireframe + interaction DSL to HTML converter with scene transitions",
5
5
  "author": "wickedev",
6
6
  "repository": {
@@ -19,7 +19,7 @@ function calculate(content, position, boxBounds) {
19
19
  return "Left";
20
20
  } else if (rightRatio < 0.2 && leftRatio > 0.3) {
21
21
  return "Right";
22
- } else if (Math.abs(leftRatio - rightRatio) < 0.15) {
22
+ } else if (Math.abs(leftRatio - rightRatio) < 0.2) {
23
23
  return "Center";
24
24
  } else {
25
25
  return "Left";
@@ -52,9 +52,11 @@ let calculate = (
52
52
  let rightRatio = Int.toFloat(rightSpace) /. Int.toFloat(boxWidth)
53
53
 
54
54
  // Thresholds for alignment detection
55
+ // Note: centerTolerance increased from 0.15 to 0.2 to be more lenient
56
+ // This fixes issue #22 where visually centered buttons were detected as Left
55
57
  let leftThreshold = 0.2
56
58
  let rightThreshold = 0.2
57
- let centerTolerance = 0.15
59
+ let centerTolerance = 0.2
58
60
 
59
61
  // Apply alignment rules
60
62
  if leftRatio < leftThreshold && rightRatio > 0.3 {
@@ -1,6 +1,7 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Parser from "../parser/Parser.mjs";
4
+ import * as Core__Array from "@rescript/core/src/Core__Array.mjs";
4
5
  import * as Core__Option from "@rescript/core/src/Core__Option.mjs";
5
6
  import * as ErrorMessages from "../parser/Errors/ErrorMessages.mjs";
6
7
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
@@ -52,6 +53,7 @@ let defaultStyles = `
52
53
  .align-right { text-align:right; }
53
54
  .wf-row.align-center { justify-content:center; }
54
55
  .wf-row.align-right { justify-content:flex-end; }
56
+ .wf-row.distribute { justify-content:space-between; }
55
57
  .wf-button.align-center, .wf-link.align-center { margin-left:auto; margin-right:auto; }
56
58
  .wf-button.align-right, .wf-link.align-right { margin-left:auto; margin-right:0; }
57
59
  `;
@@ -102,6 +104,35 @@ function applyAlignment(el, align) {
102
104
  }
103
105
  }
104
106
 
107
+ function getElementAlignment(elem) {
108
+ switch (elem.TAG) {
109
+ case "Button" :
110
+ case "Link" :
111
+ case "Text" :
112
+ return elem.align;
113
+ default:
114
+ return;
115
+ }
116
+ }
117
+
118
+ function hasDistributedChildren(children) {
119
+ let alignments = Core__Array.filterMap(children, getElementAlignment);
120
+ if (alignments.length < 2) {
121
+ return false;
122
+ }
123
+ let hasLeft = alignments.some(a => a === "Left");
124
+ let hasCenter = alignments.some(a => a === "Center");
125
+ let hasRight = alignments.some(a => a === "Right");
126
+ let differentAlignmentCount = ((
127
+ hasLeft ? 1 : 0
128
+ ) + (
129
+ hasCenter ? 1 : 0
130
+ ) | 0) + (
131
+ hasRight ? 1 : 0
132
+ ) | 0;
133
+ return differentAlignmentCount >= 2;
134
+ }
135
+
105
136
  function deviceTypeToClass(device) {
106
137
  if (typeof device === "object") {
107
138
  return "wf-device-custom-" + device._0.toString() + "x" + device._1.toString();
@@ -257,10 +288,15 @@ function renderElement(_elem, onAction, onDeadEnd) {
257
288
  spacer.className = "wf-spacer";
258
289
  return Primitive_option.some(spacer);
259
290
  case "Row" :
291
+ let children = elem.children;
260
292
  let row = document.createElement("div");
261
293
  row.className = "wf-row";
262
- applyAlignment(row, elem.align);
263
- elem.children.forEach(child => {
294
+ if (hasDistributedChildren(children)) {
295
+ row.classList.add("distribute");
296
+ } else {
297
+ applyAlignment(row, elem.align);
298
+ }
299
+ children.forEach(child => {
264
300
  let el = renderElement(child, onAction, onDeadEnd);
265
301
  if (el !== undefined) {
266
302
  row.appendChild(Primitive_option.valFromOption(el));
@@ -565,6 +601,8 @@ export {
565
601
  getInputsFromBox,
566
602
  alignmentToClass,
567
603
  applyAlignment,
604
+ getElementAlignment,
605
+ hasDistributedChildren,
568
606
  deviceTypeToClass,
569
607
  isNavigationAction,
570
608
  hasNavigationAction,
@@ -164,6 +164,7 @@ let defaultStyles = `
164
164
  .align-right { text-align:right; }
165
165
  .wf-row.align-center { justify-content:center; }
166
166
  .wf-row.align-right { justify-content:flex-end; }
167
+ .wf-row.distribute { justify-content:space-between; }
167
168
  .wf-button.align-center, .wf-link.align-center { margin-left:auto; margin-right:auto; }
168
169
  .wf-button.align-right, .wf-link.align-right { margin-left:auto; margin-right:0; }
169
170
  `
@@ -211,6 +212,48 @@ let applyAlignment = (el: DomBindings.element, align: alignment): unit => {
211
212
  }
212
213
  }
213
214
 
215
+ /**
216
+ * Get the alignment of an element (for buttons, links, text).
217
+ */
218
+ let getElementAlignment = (elem: element): option<alignment> => {
219
+ switch elem {
220
+ | Button({align, _}) => Some(align)
221
+ | Link({align, _}) => Some(align)
222
+ | Text({align, _}) => Some(align)
223
+ | _ => None
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Check if Row children have distributed alignments (Left/Center/Right pattern).
229
+ * This indicates the buttons should be distributed using justify-content: space-between.
230
+ *
231
+ * Issue #23: When buttons are positioned across a row with different alignments
232
+ * (e.g., [ Google ] [ Apple ] [ GitHub ] with Left/Center/Right),
233
+ * use flexbox space-between distribution instead of per-element alignment.
234
+ */
235
+ let hasDistributedChildren = (children: array<element>): bool => {
236
+ // Get all child alignments
237
+ let alignments = children
238
+ ->Array.filterMap(getElementAlignment)
239
+
240
+ // Need at least 2 elements to be considered distributed
241
+ if alignments->Array.length < 2 {
242
+ false
243
+ } else {
244
+ // Check if we have different alignments
245
+ let hasLeft = alignments->Array.some(a => a == Left)
246
+ let hasCenter = alignments->Array.some(a => a == Center)
247
+ let hasRight = alignments->Array.some(a => a == Right)
248
+
249
+ // Distributed means we have at least 2 different alignments
250
+ let differentAlignmentCount =
251
+ (hasLeft ? 1 : 0) + (hasCenter ? 1 : 0) + (hasRight ? 1 : 0)
252
+
253
+ differentAlignmentCount >= 2
254
+ }
255
+ }
256
+
214
257
  /**
215
258
  * Convert device type to CSS class name.
216
259
  */
@@ -435,7 +478,13 @@ let rec renderElement = (
435
478
  | Row({children, align}) => {
436
479
  let row = DomBindings.document->DomBindings.createElement("div")
437
480
  row->DomBindings.setClassName("wf-row")
438
- applyAlignment(row, align)
481
+
482
+ // Issue #23: Use space-between distribution for rows with distributed alignments
483
+ if hasDistributedChildren(children) {
484
+ row->DomBindings.classList->DomBindings.add("distribute")
485
+ } else {
486
+ applyAlignment(row, align)
487
+ }
439
488
 
440
489
  children->Array.forEach(child => {
441
490
  switch renderElement(child, ~onAction?, ~onDeadEnd?) {