@rlabs-inc/tui 0.1.0 → 0.2.1
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 +126 -13
- package/index.ts +11 -5
- package/package.json +2 -2
- package/src/api/history.ts +451 -0
- package/src/api/mount.ts +66 -31
- package/src/engine/arrays/core.ts +13 -21
- package/src/engine/arrays/dimensions.ts +22 -32
- package/src/engine/arrays/index.ts +88 -86
- package/src/engine/arrays/interaction.ts +34 -48
- package/src/engine/arrays/layout.ts +67 -92
- package/src/engine/arrays/spacing.ts +37 -52
- package/src/engine/arrays/text.ts +23 -31
- package/src/engine/arrays/visual.ts +56 -75
- package/src/engine/inheritance.ts +18 -18
- package/src/engine/registry.ts +15 -0
- package/src/pipeline/frameBuffer.ts +26 -26
- package/src/pipeline/layout/index.ts +2 -2
- package/src/pipeline/layout/titan-engine.ts +112 -84
- package/src/primitives/animation.ts +194 -0
- package/src/primitives/box.ts +74 -86
- package/src/primitives/each.ts +87 -0
- package/src/primitives/index.ts +7 -0
- package/src/primitives/scope.ts +215 -0
- package/src/primitives/show.ts +77 -0
- package/src/primitives/text.ts +63 -59
- package/src/primitives/types.ts +1 -1
- package/src/primitives/when.ts +102 -0
- package/src/renderer/append-region.ts +159 -0
- package/src/renderer/index.ts +4 -2
- package/src/renderer/output.ts +11 -34
- package/src/state/focus.ts +16 -5
- package/src/state/global-keys.ts +184 -0
- package/src/state/index.ts +44 -8
- package/src/state/input.ts +534 -0
- package/src/state/keyboard.ts +98 -674
- package/src/state/mouse.ts +163 -340
- package/src/state/scroll.ts +7 -9
- package/src/types/index.ts +23 -2
- package/src/renderer/input.ts +0 -518
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* State for scroll, focus, and mouse interactions.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* state() proxies snapshot getter values, breaking reactivity.
|
|
6
|
+
* Uses slotArray for stable reactive cells that NEVER get replaced.
|
|
8
7
|
*
|
|
9
8
|
* Exception: focusedIndex is a single signal, not an array.
|
|
10
9
|
*
|
|
@@ -12,17 +11,17 @@
|
|
|
12
11
|
* and live in ComputedLayout, not here. Only scroll OFFSETS (user state) are here.
|
|
13
12
|
*/
|
|
14
13
|
|
|
15
|
-
import { signal,
|
|
14
|
+
import { signal, slotArray, type SlotArray } from '@rlabs-inc/signals'
|
|
16
15
|
|
|
17
16
|
// =============================================================================
|
|
18
17
|
// SCROLL STATE (user-controlled position only)
|
|
19
18
|
// =============================================================================
|
|
20
19
|
|
|
21
20
|
/** Current vertical scroll offset (user state) */
|
|
22
|
-
export const scrollOffsetY:
|
|
21
|
+
export const scrollOffsetY: SlotArray<number> = slotArray<number>(0)
|
|
23
22
|
|
|
24
23
|
/** Current horizontal scroll offset (user state) */
|
|
25
|
-
export const scrollOffsetX:
|
|
24
|
+
export const scrollOffsetX: SlotArray<number> = slotArray<number>(0)
|
|
26
25
|
|
|
27
26
|
// NOTE: scrollable, maxScrollX, maxScrollY are COMPUTED values from TITAN.
|
|
28
27
|
// Read them from layoutDerived.value, not from interaction arrays.
|
|
@@ -32,10 +31,10 @@ export const scrollOffsetX: Binding<number>[] = []
|
|
|
32
31
|
// =============================================================================
|
|
33
32
|
|
|
34
33
|
/** Can this component receive focus */
|
|
35
|
-
export const focusable:
|
|
34
|
+
export const focusable: SlotArray<number> = slotArray<number>(0) // 0=no, 1=yes
|
|
36
35
|
|
|
37
36
|
/** Tab order for focus navigation (-1 = not in tab order) */
|
|
38
|
-
export const tabIndex:
|
|
37
|
+
export const tabIndex: SlotArray<number> = slotArray<number>(-1)
|
|
39
38
|
|
|
40
39
|
/** Currently focused component index (-1 = none) - SINGLE SIGNAL, not array */
|
|
41
40
|
export const focusedIndex = signal(-1)
|
|
@@ -45,68 +44,55 @@ export const focusedIndex = signal(-1)
|
|
|
45
44
|
// =============================================================================
|
|
46
45
|
|
|
47
46
|
/** Is mouse currently hovering over this component */
|
|
48
|
-
export const hovered:
|
|
47
|
+
export const hovered: SlotArray<number> = slotArray<number>(0) // 0=no, 1=yes
|
|
49
48
|
|
|
50
49
|
/** Is mouse button currently pressed on this component */
|
|
51
|
-
export const pressed:
|
|
50
|
+
export const pressed: SlotArray<number> = slotArray<number>(0) // 0=no, 1=yes
|
|
52
51
|
|
|
53
52
|
/** Is mouse events enabled for this component */
|
|
54
|
-
export const mouseEnabled:
|
|
53
|
+
export const mouseEnabled: SlotArray<number> = slotArray<number>(0) // 0=no, 1=yes
|
|
55
54
|
|
|
56
55
|
// =============================================================================
|
|
57
56
|
// CURSOR STATE (for input components)
|
|
58
57
|
// =============================================================================
|
|
59
58
|
|
|
60
59
|
/** Cursor position in text content */
|
|
61
|
-
export const cursorPosition:
|
|
60
|
+
export const cursorPosition: SlotArray<number> = slotArray<number>(0)
|
|
62
61
|
|
|
63
62
|
/** Selection start position (-1 = no selection) */
|
|
64
|
-
export const selectionStart:
|
|
63
|
+
export const selectionStart: SlotArray<number> = slotArray<number>(-1)
|
|
65
64
|
|
|
66
65
|
/** Selection end position */
|
|
67
|
-
export const selectionEnd:
|
|
66
|
+
export const selectionEnd: SlotArray<number> = slotArray<number>(-1)
|
|
68
67
|
|
|
69
68
|
// =============================================================================
|
|
70
69
|
// CAPACITY MANAGEMENT
|
|
71
70
|
// =============================================================================
|
|
72
71
|
|
|
73
|
-
/**
|
|
72
|
+
/** Ensure capacity for all interaction arrays */
|
|
74
73
|
export function ensureCapacity(index: number): void {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
selectionEnd.push(undefined as any)
|
|
86
|
-
}
|
|
74
|
+
scrollOffsetY.ensureCapacity(index)
|
|
75
|
+
scrollOffsetX.ensureCapacity(index)
|
|
76
|
+
focusable.ensureCapacity(index)
|
|
77
|
+
tabIndex.ensureCapacity(index)
|
|
78
|
+
hovered.ensureCapacity(index)
|
|
79
|
+
pressed.ensureCapacity(index)
|
|
80
|
+
mouseEnabled.ensureCapacity(index)
|
|
81
|
+
cursorPosition.ensureCapacity(index)
|
|
82
|
+
selectionStart.ensureCapacity(index)
|
|
83
|
+
selectionEnd.ensureCapacity(index)
|
|
87
84
|
}
|
|
88
85
|
|
|
86
|
+
/** Clear slot at index (reset to default) */
|
|
89
87
|
export function clearAtIndex(index: number): void {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
disconnectBinding(selectionEnd[index])
|
|
101
|
-
scrollOffsetY[index] = undefined as any
|
|
102
|
-
scrollOffsetX[index] = undefined as any
|
|
103
|
-
focusable[index] = undefined as any
|
|
104
|
-
tabIndex[index] = undefined as any
|
|
105
|
-
hovered[index] = undefined as any
|
|
106
|
-
pressed[index] = undefined as any
|
|
107
|
-
mouseEnabled[index] = undefined as any
|
|
108
|
-
cursorPosition[index] = undefined as any
|
|
109
|
-
selectionStart[index] = undefined as any
|
|
110
|
-
selectionEnd[index] = undefined as any
|
|
111
|
-
}
|
|
88
|
+
scrollOffsetY.clear(index)
|
|
89
|
+
scrollOffsetX.clear(index)
|
|
90
|
+
focusable.clear(index)
|
|
91
|
+
tabIndex.clear(index)
|
|
92
|
+
hovered.clear(index)
|
|
93
|
+
pressed.clear(index)
|
|
94
|
+
mouseEnabled.clear(index)
|
|
95
|
+
cursorPosition.clear(index)
|
|
96
|
+
selectionStart.clear(index)
|
|
97
|
+
selectionEnd.clear(index)
|
|
112
98
|
}
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* Flexbox properties, positioning, and stacking.
|
|
5
5
|
* Uses numeric enums for compact storage.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* state() proxies snapshot getter values, breaking reactivity.
|
|
7
|
+
* Uses slotArray for stable reactive cells that NEVER get replaced.
|
|
9
8
|
*
|
|
10
9
|
* Flex direction: 0=column, 1=row, 2=column-reverse, 3=row-reverse
|
|
11
10
|
* Flex wrap: 0=nowrap, 1=wrap, 2=wrap-reverse
|
|
@@ -15,161 +14,137 @@
|
|
|
15
14
|
* Overflow: 0=visible, 1=hidden, 2=scroll
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
|
-
import {
|
|
17
|
+
import { slotArray, type SlotArray } from '@rlabs-inc/signals'
|
|
19
18
|
|
|
20
19
|
// =============================================================================
|
|
21
20
|
// FLEX CONTAINER PROPERTIES
|
|
22
21
|
// =============================================================================
|
|
23
22
|
|
|
24
23
|
/** Main axis direction: 0=column, 1=row, 2=column-reverse, 3=row-reverse */
|
|
25
|
-
export const flexDirection:
|
|
24
|
+
export const flexDirection: SlotArray<number> = slotArray<number>(0)
|
|
26
25
|
|
|
27
26
|
/** Wrap behavior: 0=nowrap, 1=wrap, 2=wrap-reverse */
|
|
28
|
-
export const flexWrap:
|
|
27
|
+
export const flexWrap: SlotArray<number> = slotArray<number>(0)
|
|
29
28
|
|
|
30
29
|
/** Main axis alignment: 0=flex-start, 1=center, 2=flex-end, 3=space-between, 4=space-around, 5=space-evenly */
|
|
31
|
-
export const justifyContent:
|
|
30
|
+
export const justifyContent: SlotArray<number> = slotArray<number>(0)
|
|
32
31
|
|
|
33
32
|
/** Cross axis alignment for items: 0=stretch, 1=flex-start, 2=center, 3=flex-end, 4=baseline */
|
|
34
|
-
export const alignItems:
|
|
33
|
+
export const alignItems: SlotArray<number> = slotArray<number>(0)
|
|
35
34
|
|
|
36
35
|
/** Cross axis alignment for wrapped lines: 0=stretch, 1=flex-start, 2=center, 3=flex-end */
|
|
37
|
-
export const alignContent:
|
|
36
|
+
export const alignContent: SlotArray<number> = slotArray<number>(0)
|
|
38
37
|
|
|
39
38
|
// =============================================================================
|
|
40
39
|
// FLEX ITEM PROPERTIES
|
|
41
40
|
// =============================================================================
|
|
42
41
|
|
|
43
42
|
/** Grow factor - how much item grows to fill space (0 = don't grow) */
|
|
44
|
-
export const flexGrow:
|
|
43
|
+
export const flexGrow: SlotArray<number> = slotArray<number>(0)
|
|
45
44
|
|
|
46
45
|
/** Shrink factor - how much item shrinks when overflow (1 = default, 0 = don't shrink) */
|
|
47
|
-
export const flexShrink:
|
|
46
|
+
export const flexShrink: SlotArray<number> = slotArray<number>(1)
|
|
48
47
|
|
|
49
48
|
/** Initial size before growing/shrinking (0 = use width/height) */
|
|
50
|
-
export const flexBasis:
|
|
49
|
+
export const flexBasis: SlotArray<number> = slotArray<number>(0)
|
|
51
50
|
|
|
52
51
|
/** Override alignItems for this item: 0=auto, 1=stretch, 2=flex-start, 3=center, 4=flex-end */
|
|
53
|
-
export const alignSelf:
|
|
52
|
+
export const alignSelf: SlotArray<number> = slotArray<number>(0)
|
|
54
53
|
|
|
55
54
|
/** Visual order override (not used yet) */
|
|
56
|
-
export const order:
|
|
55
|
+
export const order: SlotArray<number> = slotArray<number>(0)
|
|
57
56
|
|
|
58
57
|
// =============================================================================
|
|
59
58
|
// POSITIONING
|
|
60
59
|
// =============================================================================
|
|
61
60
|
|
|
62
61
|
/** Position mode: 0=relative (in flow), 1=absolute (out of flow) */
|
|
63
|
-
export const position:
|
|
62
|
+
export const position: SlotArray<number> = slotArray<number>(0)
|
|
64
63
|
|
|
65
64
|
/** Offset from top of positioned ancestor (for absolute) or normal position (for relative) */
|
|
66
|
-
export const top:
|
|
65
|
+
export const top: SlotArray<number> = slotArray<number>(0)
|
|
67
66
|
|
|
68
67
|
/** Offset from right of positioned ancestor */
|
|
69
|
-
export const right:
|
|
68
|
+
export const right: SlotArray<number> = slotArray<number>(0)
|
|
70
69
|
|
|
71
70
|
/** Offset from bottom of positioned ancestor */
|
|
72
|
-
export const bottom:
|
|
71
|
+
export const bottom: SlotArray<number> = slotArray<number>(0)
|
|
73
72
|
|
|
74
73
|
/** Offset from left of positioned ancestor */
|
|
75
|
-
export const left:
|
|
74
|
+
export const left: SlotArray<number> = slotArray<number>(0)
|
|
76
75
|
|
|
77
76
|
// =============================================================================
|
|
78
77
|
// BORDER (for layout calculations)
|
|
79
78
|
// =============================================================================
|
|
80
79
|
|
|
81
80
|
/** Has top border? 0=no, 1+=yes (takes 1 cell) */
|
|
82
|
-
export const borderTop:
|
|
81
|
+
export const borderTop: SlotArray<number> = slotArray<number>(0)
|
|
83
82
|
|
|
84
83
|
/** Has right border? 0=no, 1+=yes (takes 1 cell) */
|
|
85
|
-
export const borderRight:
|
|
84
|
+
export const borderRight: SlotArray<number> = slotArray<number>(0)
|
|
86
85
|
|
|
87
86
|
/** Has bottom border? 0=no, 1+=yes (takes 1 cell) */
|
|
88
|
-
export const borderBottom:
|
|
87
|
+
export const borderBottom: SlotArray<number> = slotArray<number>(0)
|
|
89
88
|
|
|
90
89
|
/** Has left border? 0=no, 1+=yes (takes 1 cell) */
|
|
91
|
-
export const borderLeft:
|
|
90
|
+
export const borderLeft: SlotArray<number> = slotArray<number>(0)
|
|
92
91
|
|
|
93
92
|
// =============================================================================
|
|
94
93
|
// STACKING & OVERFLOW
|
|
95
94
|
// =============================================================================
|
|
96
95
|
|
|
97
96
|
/** Z-index for overlapping components (higher = on top) */
|
|
98
|
-
export const zIndex:
|
|
97
|
+
export const zIndex: SlotArray<number> = slotArray<number>(0)
|
|
99
98
|
|
|
100
99
|
/** Overflow handling: 0=visible, 1=hidden, 2=scroll, 3=auto */
|
|
101
|
-
export const overflow:
|
|
100
|
+
export const overflow: SlotArray<number> = slotArray<number>(0)
|
|
102
101
|
|
|
103
|
-
/**
|
|
102
|
+
/** Ensure capacity for all layout arrays */
|
|
104
103
|
export function ensureCapacity(index: number): void {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
overflow.push(undefined as any)
|
|
127
|
-
}
|
|
104
|
+
flexDirection.ensureCapacity(index)
|
|
105
|
+
flexWrap.ensureCapacity(index)
|
|
106
|
+
justifyContent.ensureCapacity(index)
|
|
107
|
+
alignItems.ensureCapacity(index)
|
|
108
|
+
alignContent.ensureCapacity(index)
|
|
109
|
+
flexGrow.ensureCapacity(index)
|
|
110
|
+
flexShrink.ensureCapacity(index)
|
|
111
|
+
flexBasis.ensureCapacity(index)
|
|
112
|
+
alignSelf.ensureCapacity(index)
|
|
113
|
+
order.ensureCapacity(index)
|
|
114
|
+
position.ensureCapacity(index)
|
|
115
|
+
top.ensureCapacity(index)
|
|
116
|
+
right.ensureCapacity(index)
|
|
117
|
+
bottom.ensureCapacity(index)
|
|
118
|
+
left.ensureCapacity(index)
|
|
119
|
+
borderTop.ensureCapacity(index)
|
|
120
|
+
borderRight.ensureCapacity(index)
|
|
121
|
+
borderBottom.ensureCapacity(index)
|
|
122
|
+
borderLeft.ensureCapacity(index)
|
|
123
|
+
zIndex.ensureCapacity(index)
|
|
124
|
+
overflow.ensureCapacity(index)
|
|
128
125
|
}
|
|
129
126
|
|
|
127
|
+
/** Clear slot at index (reset to default) */
|
|
130
128
|
export function clearAtIndex(index: number): void {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
disconnectBinding(overflow[index])
|
|
153
|
-
flexDirection[index] = undefined as any
|
|
154
|
-
flexWrap[index] = undefined as any
|
|
155
|
-
justifyContent[index] = undefined as any
|
|
156
|
-
alignItems[index] = undefined as any
|
|
157
|
-
alignContent[index] = undefined as any
|
|
158
|
-
flexGrow[index] = undefined as any
|
|
159
|
-
flexShrink[index] = undefined as any
|
|
160
|
-
flexBasis[index] = undefined as any
|
|
161
|
-
alignSelf[index] = undefined as any
|
|
162
|
-
order[index] = undefined as any
|
|
163
|
-
position[index] = undefined as any
|
|
164
|
-
top[index] = undefined as any
|
|
165
|
-
right[index] = undefined as any
|
|
166
|
-
bottom[index] = undefined as any
|
|
167
|
-
left[index] = undefined as any
|
|
168
|
-
borderTop[index] = undefined as any
|
|
169
|
-
borderRight[index] = undefined as any
|
|
170
|
-
borderBottom[index] = undefined as any
|
|
171
|
-
borderLeft[index] = undefined as any
|
|
172
|
-
zIndex[index] = undefined as any
|
|
173
|
-
overflow[index] = undefined as any
|
|
174
|
-
}
|
|
129
|
+
flexDirection.clear(index)
|
|
130
|
+
flexWrap.clear(index)
|
|
131
|
+
justifyContent.clear(index)
|
|
132
|
+
alignItems.clear(index)
|
|
133
|
+
alignContent.clear(index)
|
|
134
|
+
flexGrow.clear(index)
|
|
135
|
+
flexShrink.clear(index)
|
|
136
|
+
flexBasis.clear(index)
|
|
137
|
+
alignSelf.clear(index)
|
|
138
|
+
order.clear(index)
|
|
139
|
+
position.clear(index)
|
|
140
|
+
top.clear(index)
|
|
141
|
+
right.clear(index)
|
|
142
|
+
bottom.clear(index)
|
|
143
|
+
left.clear(index)
|
|
144
|
+
borderTop.clear(index)
|
|
145
|
+
borderRight.clear(index)
|
|
146
|
+
borderBottom.clear(index)
|
|
147
|
+
borderLeft.clear(index)
|
|
148
|
+
zIndex.clear(index)
|
|
149
|
+
overflow.clear(index)
|
|
175
150
|
}
|
|
@@ -4,97 +4,82 @@
|
|
|
4
4
|
* Margin, padding, and gap values.
|
|
5
5
|
* All values are in terminal cells (integers).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* state() proxies snapshot getter values, breaking reactivity.
|
|
7
|
+
* Uses slotArray for stable reactive cells that NEVER get replaced.
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
|
-
import {
|
|
10
|
+
import { slotArray, type SlotArray } from '@rlabs-inc/signals'
|
|
12
11
|
|
|
13
12
|
// =============================================================================
|
|
14
13
|
// MARGIN - Space outside the component (offsets position in parent)
|
|
15
14
|
// =============================================================================
|
|
16
15
|
|
|
17
16
|
/** Top margin - adds space above the component (in cells) */
|
|
18
|
-
export const marginTop:
|
|
17
|
+
export const marginTop: SlotArray<number> = slotArray<number>(0)
|
|
19
18
|
|
|
20
19
|
/** Right margin - adds space to the right of the component (in cells) */
|
|
21
|
-
export const marginRight:
|
|
20
|
+
export const marginRight: SlotArray<number> = slotArray<number>(0)
|
|
22
21
|
|
|
23
22
|
/** Bottom margin - adds space below the component (in cells) */
|
|
24
|
-
export const marginBottom:
|
|
23
|
+
export const marginBottom: SlotArray<number> = slotArray<number>(0)
|
|
25
24
|
|
|
26
25
|
/** Left margin - adds space to the left of the component (in cells) */
|
|
27
|
-
export const marginLeft:
|
|
26
|
+
export const marginLeft: SlotArray<number> = slotArray<number>(0)
|
|
28
27
|
|
|
29
28
|
// =============================================================================
|
|
30
29
|
// PADDING - Space inside the component (reduces content area)
|
|
31
30
|
// =============================================================================
|
|
32
31
|
|
|
33
32
|
/** Top padding - pushes content down from top edge (in cells) */
|
|
34
|
-
export const paddingTop:
|
|
33
|
+
export const paddingTop: SlotArray<number> = slotArray<number>(0)
|
|
35
34
|
|
|
36
35
|
/** Right padding - pushes content left from right edge (in cells) */
|
|
37
|
-
export const paddingRight:
|
|
36
|
+
export const paddingRight: SlotArray<number> = slotArray<number>(0)
|
|
38
37
|
|
|
39
38
|
/** Bottom padding - pushes content up from bottom edge (in cells) */
|
|
40
|
-
export const paddingBottom:
|
|
39
|
+
export const paddingBottom: SlotArray<number> = slotArray<number>(0)
|
|
41
40
|
|
|
42
41
|
/** Left padding - pushes content right from left edge (in cells) */
|
|
43
|
-
export const paddingLeft:
|
|
42
|
+
export const paddingLeft: SlotArray<number> = slotArray<number>(0)
|
|
44
43
|
|
|
45
44
|
// =============================================================================
|
|
46
45
|
// GAP - Space between flex items (CSS gap property)
|
|
47
46
|
// =============================================================================
|
|
48
47
|
|
|
49
48
|
/** Gap between flex items in both directions (in cells) */
|
|
50
|
-
export const gap:
|
|
49
|
+
export const gap: SlotArray<number> = slotArray<number>(0)
|
|
51
50
|
|
|
52
51
|
/** Row gap - vertical space between wrapped lines (in cells) */
|
|
53
|
-
export const rowGap:
|
|
52
|
+
export const rowGap: SlotArray<number> = slotArray<number>(0)
|
|
54
53
|
|
|
55
54
|
/** Column gap - horizontal space between items in a row (in cells) */
|
|
56
|
-
export const columnGap:
|
|
55
|
+
export const columnGap: SlotArray<number> = slotArray<number>(0)
|
|
57
56
|
|
|
58
|
-
/**
|
|
57
|
+
/** Ensure capacity for all spacing arrays */
|
|
59
58
|
export function ensureCapacity(index: number): void {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
columnGap.push(undefined as any)
|
|
72
|
-
}
|
|
59
|
+
marginTop.ensureCapacity(index)
|
|
60
|
+
marginRight.ensureCapacity(index)
|
|
61
|
+
marginBottom.ensureCapacity(index)
|
|
62
|
+
marginLeft.ensureCapacity(index)
|
|
63
|
+
paddingTop.ensureCapacity(index)
|
|
64
|
+
paddingRight.ensureCapacity(index)
|
|
65
|
+
paddingBottom.ensureCapacity(index)
|
|
66
|
+
paddingLeft.ensureCapacity(index)
|
|
67
|
+
gap.ensureCapacity(index)
|
|
68
|
+
rowGap.ensureCapacity(index)
|
|
69
|
+
columnGap.ensureCapacity(index)
|
|
73
70
|
}
|
|
74
71
|
|
|
72
|
+
/** Clear slot at index (reset to default) */
|
|
75
73
|
export function clearAtIndex(index: number): void {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
disconnectBinding(columnGap[index])
|
|
88
|
-
marginTop[index] = undefined as any
|
|
89
|
-
marginRight[index] = undefined as any
|
|
90
|
-
marginBottom[index] = undefined as any
|
|
91
|
-
marginLeft[index] = undefined as any
|
|
92
|
-
paddingTop[index] = undefined as any
|
|
93
|
-
paddingRight[index] = undefined as any
|
|
94
|
-
paddingBottom[index] = undefined as any
|
|
95
|
-
paddingLeft[index] = undefined as any
|
|
96
|
-
gap[index] = undefined as any
|
|
97
|
-
rowGap[index] = undefined as any
|
|
98
|
-
columnGap[index] = undefined as any
|
|
99
|
-
}
|
|
74
|
+
marginTop.clear(index)
|
|
75
|
+
marginRight.clear(index)
|
|
76
|
+
marginBottom.clear(index)
|
|
77
|
+
marginLeft.clear(index)
|
|
78
|
+
paddingTop.clear(index)
|
|
79
|
+
paddingRight.clear(index)
|
|
80
|
+
paddingBottom.clear(index)
|
|
81
|
+
paddingLeft.clear(index)
|
|
82
|
+
gap.clear(index)
|
|
83
|
+
rowGap.clear(index)
|
|
84
|
+
columnGap.clear(index)
|
|
100
85
|
}
|
|
@@ -3,53 +3,45 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Text content and styling for text/input components.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Uses slotArray for stable reactive cells that NEVER get replaced.
|
|
7
|
+
* This fixes the bind() tracking bug where deriveds miss updates
|
|
8
|
+
* when binding objects are replaced.
|
|
8
9
|
*
|
|
9
|
-
* Flow: user signal →
|
|
10
|
+
* Flow: user signal → setSource() → Slot tracks → arr[i] reads value → dependency!
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
|
-
import {
|
|
13
|
+
import { slotArray, type SlotArray } from '@rlabs-inc/signals'
|
|
13
14
|
import type { CellAttrs } from '../../types'
|
|
14
|
-
import { Attr } from '../../types'
|
|
15
15
|
|
|
16
|
-
// Text content -
|
|
17
|
-
export const textContent:
|
|
16
|
+
// Text content - SlotArray auto-tracks and auto-unwraps
|
|
17
|
+
export const textContent: SlotArray<string> = slotArray<string>('')
|
|
18
18
|
|
|
19
19
|
// Text styling (CellAttrs bitfield)
|
|
20
|
-
export const textAttrs:
|
|
20
|
+
export const textAttrs: SlotArray<CellAttrs> = slotArray<CellAttrs>(0)
|
|
21
21
|
|
|
22
22
|
// Text alignment: 0=left, 1=center, 2=right
|
|
23
|
-
export const textAlign:
|
|
23
|
+
export const textAlign: SlotArray<number> = slotArray<number>(0)
|
|
24
24
|
|
|
25
25
|
// Text wrapping: 0=nowrap, 1=wrap, 2=truncate
|
|
26
|
-
export const textWrap:
|
|
26
|
+
export const textWrap: SlotArray<number> = slotArray<number>(1) // wrap by default
|
|
27
27
|
|
|
28
28
|
// Ellipsis for truncated text
|
|
29
|
-
export const ellipsis:
|
|
29
|
+
export const ellipsis: SlotArray<string> = slotArray<string>('...')
|
|
30
30
|
|
|
31
|
-
/**
|
|
31
|
+
/** Ensure capacity for all text arrays */
|
|
32
32
|
export function ensureCapacity(index: number): void {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
ellipsis.push(undefined as any)
|
|
39
|
-
}
|
|
33
|
+
textContent.ensureCapacity(index)
|
|
34
|
+
textAttrs.ensureCapacity(index)
|
|
35
|
+
textAlign.ensureCapacity(index)
|
|
36
|
+
textWrap.ensureCapacity(index)
|
|
37
|
+
ellipsis.ensureCapacity(index)
|
|
40
38
|
}
|
|
41
39
|
|
|
40
|
+
/** Clear slot at index (reset to default) */
|
|
42
41
|
export function clearAtIndex(index: number): void {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
disconnectBinding(ellipsis[index])
|
|
49
|
-
textContent[index] = undefined as any
|
|
50
|
-
textAttrs[index] = undefined as any
|
|
51
|
-
textAlign[index] = undefined as any
|
|
52
|
-
textWrap[index] = undefined as any
|
|
53
|
-
ellipsis[index] = undefined as any
|
|
54
|
-
}
|
|
42
|
+
textContent.clear(index)
|
|
43
|
+
textAttrs.clear(index)
|
|
44
|
+
textAlign.clear(index)
|
|
45
|
+
textWrap.clear(index)
|
|
46
|
+
ellipsis.clear(index)
|
|
55
47
|
}
|