flexily 0.0.1 → 0.2.0

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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/dist/classic/layout.d.ts +57 -0
  4. package/dist/classic/layout.d.ts.map +1 -0
  5. package/dist/classic/layout.js +1558 -0
  6. package/dist/classic/layout.js.map +1 -0
  7. package/dist/classic/node.d.ts +648 -0
  8. package/dist/classic/node.d.ts.map +1 -0
  9. package/dist/classic/node.js +1002 -0
  10. package/dist/classic/node.js.map +1 -0
  11. package/dist/constants.d.ts +58 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +70 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/index-classic.d.ts +30 -0
  16. package/dist/index-classic.d.ts.map +1 -0
  17. package/dist/index-classic.js +57 -0
  18. package/dist/index-classic.js.map +1 -0
  19. package/dist/index.d.ts +30 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +57 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/layout-flex-lines.d.ts +77 -0
  24. package/dist/layout-flex-lines.d.ts.map +1 -0
  25. package/dist/layout-flex-lines.js +317 -0
  26. package/dist/layout-flex-lines.js.map +1 -0
  27. package/dist/layout-helpers.d.ts +48 -0
  28. package/dist/layout-helpers.d.ts.map +1 -0
  29. package/dist/layout-helpers.js +108 -0
  30. package/dist/layout-helpers.js.map +1 -0
  31. package/dist/layout-measure.d.ts +25 -0
  32. package/dist/layout-measure.d.ts.map +1 -0
  33. package/dist/layout-measure.js +231 -0
  34. package/dist/layout-measure.js.map +1 -0
  35. package/dist/layout-stats.d.ts +19 -0
  36. package/dist/layout-stats.d.ts.map +1 -0
  37. package/dist/layout-stats.js +37 -0
  38. package/dist/layout-stats.js.map +1 -0
  39. package/dist/layout-traversal.d.ts +28 -0
  40. package/dist/layout-traversal.d.ts.map +1 -0
  41. package/dist/layout-traversal.js +65 -0
  42. package/dist/layout-traversal.js.map +1 -0
  43. package/dist/layout-zero.d.ts +26 -0
  44. package/dist/layout-zero.d.ts.map +1 -0
  45. package/dist/layout-zero.js +1601 -0
  46. package/dist/layout-zero.js.map +1 -0
  47. package/dist/logger.d.ts +14 -0
  48. package/dist/logger.d.ts.map +1 -0
  49. package/dist/logger.js +61 -0
  50. package/dist/logger.js.map +1 -0
  51. package/dist/node-zero.d.ts +702 -0
  52. package/dist/node-zero.d.ts.map +1 -0
  53. package/dist/node-zero.js +1268 -0
  54. package/dist/node-zero.js.map +1 -0
  55. package/dist/testing.d.ts +69 -0
  56. package/dist/testing.d.ts.map +1 -0
  57. package/dist/testing.js +179 -0
  58. package/dist/testing.js.map +1 -0
  59. package/dist/trace.d.ts +74 -0
  60. package/dist/trace.d.ts.map +1 -0
  61. package/dist/trace.js +191 -0
  62. package/dist/trace.js.map +1 -0
  63. package/dist/types.d.ts +170 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +43 -0
  66. package/dist/types.js.map +1 -0
  67. package/dist/utils.d.ts +41 -0
  68. package/dist/utils.d.ts.map +1 -0
  69. package/dist/utils.js +197 -0
  70. package/dist/utils.js.map +1 -0
  71. package/package.json +58 -3
  72. package/src/CLAUDE.md +512 -0
  73. package/src/beorn-logger.d.ts +10 -0
  74. package/src/classic/layout.ts +1783 -0
  75. package/src/classic/node.ts +1121 -0
  76. package/src/constants.ts +81 -0
  77. package/src/index-classic.ts +110 -0
  78. package/src/index.ts +110 -0
  79. package/src/layout-flex-lines.ts +346 -0
  80. package/src/layout-helpers.ts +140 -0
  81. package/src/layout-measure.ts +259 -0
  82. package/src/layout-stats.ts +43 -0
  83. package/src/layout-traversal.ts +70 -0
  84. package/src/layout-zero.ts +1792 -0
  85. package/src/logger.ts +67 -0
  86. package/src/node-zero.ts +1412 -0
  87. package/src/testing.ts +209 -0
  88. package/src/trace.ts +252 -0
  89. package/src/types.ts +229 -0
  90. package/src/utils.ts +217 -0
package/src/utils.ts ADDED
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Flexily Utility Functions
3
+ *
4
+ * Helper functions for edge value manipulation and value resolution.
5
+ */
6
+
7
+ import * as C from "./constants.js"
8
+ import type { Value } from "./types.js"
9
+
10
+ // ============================================================================
11
+ // Shared Traversal Stack
12
+ // ============================================================================
13
+ // Pre-allocated stack array for iterative tree traversal. Shared across all
14
+ // layout functions to avoid multiple allocations. Using a single stack is safe
15
+ // because layout operations are synchronous (no concurrent traversals).
16
+
17
+ /**
18
+ * Shared traversal stack for iterative tree operations.
19
+ * Avoids recursion (prevents stack overflow on deep trees) and avoids
20
+ * allocation during layout passes.
21
+ */
22
+ export const traversalStack: unknown[] = []
23
+
24
+ /**
25
+ * Set a value on an edge array (supports all edge types including logical START/END).
26
+ */
27
+ export function setEdgeValue(
28
+ arr: [Value, Value, Value, Value, Value, Value],
29
+ edge: number,
30
+ value: number,
31
+ unit: number,
32
+ ): void {
33
+ const v = { value, unit }
34
+ switch (edge) {
35
+ case C.EDGE_LEFT:
36
+ arr[0] = v
37
+ break
38
+ case C.EDGE_TOP:
39
+ arr[1] = v
40
+ break
41
+ case C.EDGE_RIGHT:
42
+ arr[2] = v
43
+ break
44
+ case C.EDGE_BOTTOM:
45
+ arr[3] = v
46
+ break
47
+ case C.EDGE_HORIZONTAL:
48
+ arr[0] = v
49
+ arr[2] = v
50
+ break
51
+ case C.EDGE_VERTICAL:
52
+ arr[1] = v
53
+ arr[3] = v
54
+ break
55
+ case C.EDGE_ALL:
56
+ arr[0] = v
57
+ arr[1] = v
58
+ arr[2] = v
59
+ arr[3] = v
60
+ break
61
+ case C.EDGE_START:
62
+ // Store in logical START slot (resolved to physical at layout time)
63
+ arr[4] = v
64
+ break
65
+ case C.EDGE_END:
66
+ // Store in logical END slot (resolved to physical at layout time)
67
+ arr[5] = v
68
+ break
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Set a border value on an edge array.
74
+ */
75
+ export function setEdgeBorder(
76
+ arr: [number, number, number, number, number, number],
77
+ edge: number,
78
+ value: number,
79
+ ): void {
80
+ switch (edge) {
81
+ case C.EDGE_LEFT:
82
+ arr[0] = value
83
+ break
84
+ case C.EDGE_TOP:
85
+ arr[1] = value
86
+ break
87
+ case C.EDGE_RIGHT:
88
+ arr[2] = value
89
+ break
90
+ case C.EDGE_BOTTOM:
91
+ arr[3] = value
92
+ break
93
+ case C.EDGE_HORIZONTAL:
94
+ arr[0] = value
95
+ arr[2] = value
96
+ break
97
+ case C.EDGE_VERTICAL:
98
+ arr[1] = value
99
+ arr[3] = value
100
+ break
101
+ case C.EDGE_ALL:
102
+ arr[0] = value
103
+ arr[1] = value
104
+ arr[2] = value
105
+ arr[3] = value
106
+ break
107
+ case C.EDGE_START:
108
+ // Store in logical START slot (resolved to physical at layout time)
109
+ arr[4] = value
110
+ break
111
+ case C.EDGE_END:
112
+ // Store in logical END slot (resolved to physical at layout time)
113
+ arr[5] = value
114
+ break
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Get a value from an edge array.
120
+ */
121
+ export function getEdgeValue(arr: [Value, Value, Value, Value, Value, Value], edge: number): Value {
122
+ switch (edge) {
123
+ case C.EDGE_LEFT:
124
+ return arr[0]
125
+ case C.EDGE_TOP:
126
+ return arr[1]
127
+ case C.EDGE_RIGHT:
128
+ return arr[2]
129
+ case C.EDGE_BOTTOM:
130
+ return arr[3]
131
+ case C.EDGE_START:
132
+ return arr[4]
133
+ case C.EDGE_END:
134
+ return arr[5]
135
+ default:
136
+ return arr[0] // Default to left
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Get a border value from an edge array.
142
+ */
143
+ export function getEdgeBorderValue(arr: [number, number, number, number, number, number], edge: number): number {
144
+ switch (edge) {
145
+ case C.EDGE_LEFT:
146
+ return arr[0]
147
+ case C.EDGE_TOP:
148
+ return arr[1]
149
+ case C.EDGE_RIGHT:
150
+ return arr[2]
151
+ case C.EDGE_BOTTOM:
152
+ return arr[3]
153
+ case C.EDGE_START:
154
+ return arr[4]
155
+ case C.EDGE_END:
156
+ return arr[5]
157
+ default:
158
+ return arr[0] // Default to left
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Resolve a value (point or percent) to an absolute number.
164
+ */
165
+ export function resolveValue(value: Value, availableSize: number): number {
166
+ switch (value.unit) {
167
+ case C.UNIT_POINT:
168
+ return value.value
169
+ case C.UNIT_PERCENT:
170
+ // Percentage against NaN (auto-sized parent) resolves to 0
171
+ if (Number.isNaN(availableSize)) {
172
+ return 0
173
+ }
174
+ return availableSize * (value.value / 100)
175
+ default:
176
+ return 0
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Apply min/max constraints to a size.
182
+ *
183
+ * When size is NaN (auto-sized), min constraints establish a floor.
184
+ * This handles the case where a parent has minWidth/maxWidth but no explicit width -
185
+ * children need to resolve percentages against the constrained size.
186
+ */
187
+ export function applyMinMax(size: number, min: Value, max: Value, available: number): number {
188
+ let result = size
189
+
190
+ if (min.unit !== C.UNIT_UNDEFINED) {
191
+ const minValue = resolveValue(min, available)
192
+ // Only apply if minValue is valid (not NaN from percent with NaN available)
193
+ if (!Number.isNaN(minValue)) {
194
+ // When size is NaN (auto-sized), min establishes the floor
195
+ if (Number.isNaN(result)) {
196
+ result = minValue
197
+ } else {
198
+ result = Math.max(result, minValue)
199
+ }
200
+ }
201
+ }
202
+
203
+ if (max.unit !== C.UNIT_UNDEFINED) {
204
+ const maxValue = resolveValue(max, available)
205
+ // Only apply if maxValue is valid (not NaN from percent with NaN available)
206
+ if (!Number.isNaN(maxValue)) {
207
+ // When size is NaN (auto-sized), max alone doesn't set the size
208
+ // (the element should shrink-wrap to content, then be capped by max)
209
+ // Only apply max if we have a concrete size to constrain
210
+ if (!Number.isNaN(result)) {
211
+ result = Math.min(result, maxValue)
212
+ }
213
+ }
214
+ }
215
+
216
+ return result
217
+ }