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.
- package/LICENSE +21 -0
- package/README.md +200 -0
- package/dist/classic/layout.d.ts +57 -0
- package/dist/classic/layout.d.ts.map +1 -0
- package/dist/classic/layout.js +1558 -0
- package/dist/classic/layout.js.map +1 -0
- package/dist/classic/node.d.ts +648 -0
- package/dist/classic/node.d.ts.map +1 -0
- package/dist/classic/node.js +1002 -0
- package/dist/classic/node.js.map +1 -0
- package/dist/constants.d.ts +58 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +70 -0
- package/dist/constants.js.map +1 -0
- package/dist/index-classic.d.ts +30 -0
- package/dist/index-classic.d.ts.map +1 -0
- package/dist/index-classic.js +57 -0
- package/dist/index-classic.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/layout-flex-lines.d.ts +77 -0
- package/dist/layout-flex-lines.d.ts.map +1 -0
- package/dist/layout-flex-lines.js +317 -0
- package/dist/layout-flex-lines.js.map +1 -0
- package/dist/layout-helpers.d.ts +48 -0
- package/dist/layout-helpers.d.ts.map +1 -0
- package/dist/layout-helpers.js +108 -0
- package/dist/layout-helpers.js.map +1 -0
- package/dist/layout-measure.d.ts +25 -0
- package/dist/layout-measure.d.ts.map +1 -0
- package/dist/layout-measure.js +231 -0
- package/dist/layout-measure.js.map +1 -0
- package/dist/layout-stats.d.ts +19 -0
- package/dist/layout-stats.d.ts.map +1 -0
- package/dist/layout-stats.js +37 -0
- package/dist/layout-stats.js.map +1 -0
- package/dist/layout-traversal.d.ts +28 -0
- package/dist/layout-traversal.d.ts.map +1 -0
- package/dist/layout-traversal.js +65 -0
- package/dist/layout-traversal.js.map +1 -0
- package/dist/layout-zero.d.ts +26 -0
- package/dist/layout-zero.d.ts.map +1 -0
- package/dist/layout-zero.js +1601 -0
- package/dist/layout-zero.js.map +1 -0
- package/dist/logger.d.ts +14 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +61 -0
- package/dist/logger.js.map +1 -0
- package/dist/node-zero.d.ts +702 -0
- package/dist/node-zero.d.ts.map +1 -0
- package/dist/node-zero.js +1268 -0
- package/dist/node-zero.js.map +1 -0
- package/dist/testing.d.ts +69 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +179 -0
- package/dist/testing.js.map +1 -0
- package/dist/trace.d.ts +74 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +191 -0
- package/dist/trace.js.map +1 -0
- package/dist/types.d.ts +170 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +43 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +41 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +197 -0
- package/dist/utils.js.map +1 -0
- package/package.json +58 -3
- package/src/CLAUDE.md +512 -0
- package/src/beorn-logger.d.ts +10 -0
- package/src/classic/layout.ts +1783 -0
- package/src/classic/node.ts +1121 -0
- package/src/constants.ts +81 -0
- package/src/index-classic.ts +110 -0
- package/src/index.ts +110 -0
- package/src/layout-flex-lines.ts +346 -0
- package/src/layout-helpers.ts +140 -0
- package/src/layout-measure.ts +259 -0
- package/src/layout-stats.ts +43 -0
- package/src/layout-traversal.ts +70 -0
- package/src/layout-zero.ts +1792 -0
- package/src/logger.ts +67 -0
- package/src/node-zero.ts +1412 -0
- package/src/testing.ts +209 -0
- package/src/trace.ts +252 -0
- package/src/types.ts +229 -0
- 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
|
+
}
|