@effect-tui/react 0.16.0 → 2.0.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 +9 -0
- package/dist/src/codeblock.d.ts +1 -1
- package/dist/src/codeblock.d.ts.map +1 -1
- package/dist/src/codeblock.js +2 -2
- package/dist/src/codeblock.js.map +1 -1
- package/dist/src/components/Markdown.js +3 -3
- package/dist/src/components/Markdown.js.map +1 -1
- package/dist/src/components/MultilineTextInput.d.ts.map +1 -1
- package/dist/src/components/MultilineTextInput.js +133 -305
- package/dist/src/components/MultilineTextInput.js.map +1 -1
- package/dist/src/components/TextInput.d.ts.map +1 -1
- package/dist/src/components/TextInput.js +51 -98
- package/dist/src/components/TextInput.js.map +1 -1
- package/dist/src/components/text-editing.d.ts +61 -0
- package/dist/src/components/text-editing.d.ts.map +1 -1
- package/dist/src/components/text-editing.js +131 -0
- package/dist/src/components/text-editing.js.map +1 -1
- package/dist/src/hosts/base.d.ts +13 -2
- package/dist/src/hosts/base.d.ts.map +1 -1
- package/dist/src/hosts/base.js +74 -2
- package/dist/src/hosts/base.js.map +1 -1
- package/dist/src/hosts/box.d.ts +2 -2
- package/dist/src/hosts/box.d.ts.map +1 -1
- package/dist/src/hosts/box.js +29 -2
- package/dist/src/hosts/box.js.map +1 -1
- package/dist/src/hosts/canvas.d.ts +22 -2
- package/dist/src/hosts/canvas.d.ts.map +1 -1
- package/dist/src/hosts/canvas.js +99 -31
- package/dist/src/hosts/canvas.js.map +1 -1
- package/dist/src/hosts/codeblock.d.ts +8 -10
- package/dist/src/hosts/codeblock.d.ts.map +1 -1
- package/dist/src/hosts/codeblock.js +36 -33
- package/dist/src/hosts/codeblock.js.map +1 -1
- package/dist/src/hosts/flex-container.d.ts +2 -2
- package/dist/src/hosts/flex-container.d.ts.map +1 -1
- package/dist/src/hosts/flex-container.js +17 -2
- package/dist/src/hosts/flex-container.js.map +1 -1
- package/dist/src/hosts/index.d.ts +1 -1
- package/dist/src/hosts/index.d.ts.map +1 -1
- package/dist/src/hosts/index.js.map +1 -1
- package/dist/src/hosts/overlay-item.d.ts +2 -2
- package/dist/src/hosts/overlay-item.d.ts.map +1 -1
- package/dist/src/hosts/overlay-item.js +7 -2
- package/dist/src/hosts/overlay-item.js.map +1 -1
- package/dist/src/hosts/overlay.d.ts +2 -2
- package/dist/src/hosts/overlay.d.ts.map +1 -1
- package/dist/src/hosts/overlay.js +2 -2
- package/dist/src/hosts/overlay.js.map +1 -1
- package/dist/src/hosts/scroll.d.ts +7 -2
- package/dist/src/hosts/scroll.d.ts.map +1 -1
- package/dist/src/hosts/scroll.js +126 -45
- package/dist/src/hosts/scroll.js.map +1 -1
- package/dist/src/hosts/single-child.d.ts.map +1 -1
- package/dist/src/hosts/single-child.js +2 -0
- package/dist/src/hosts/single-child.js.map +1 -1
- package/dist/src/hosts/spacer.d.ts +1 -1
- package/dist/src/hosts/spacer.d.ts.map +1 -1
- package/dist/src/hosts/spacer.js +6 -1
- package/dist/src/hosts/spacer.js.map +1 -1
- package/dist/src/hosts/text.d.ts +20 -15
- package/dist/src/hosts/text.d.ts.map +1 -1
- package/dist/src/hosts/text.js +104 -71
- package/dist/src/hosts/text.js.map +1 -1
- package/dist/src/hosts/zstack.d.ts +2 -2
- package/dist/src/hosts/zstack.d.ts.map +1 -1
- package/dist/src/hosts/zstack.js +7 -2
- package/dist/src/hosts/zstack.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/internal/renderer/index.d.ts.map +1 -1
- package/dist/src/internal/renderer/index.js +41 -16
- package/dist/src/internal/renderer/index.js.map +1 -1
- package/dist/src/internal/renderer/types.d.ts +4 -0
- package/dist/src/internal/renderer/types.d.ts.map +1 -1
- package/dist/src/motion/hooks.d.ts +1 -1
- package/dist/src/motion/hooks.js +1 -1
- package/dist/src/reconciler/host-config.js +2 -2
- package/dist/src/reconciler/host-config.js.map +1 -1
- package/dist/src/reconciler/types.d.ts +5 -1
- package/dist/src/reconciler/types.d.ts.map +1 -1
- package/dist/src/utils/border.d.ts +1 -1
- package/dist/src/utils/border.d.ts.map +1 -1
- package/dist/src/utils/border.js +2 -0
- package/dist/src/utils/border.js.map +1 -1
- package/dist/src/utils/index.d.ts +2 -1
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +2 -1
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/text-layout.d.ts +22 -0
- package/dist/src/utils/text-layout.d.ts.map +1 -0
- package/dist/src/utils/text-layout.js +37 -0
- package/dist/src/utils/text-layout.js.map +1 -0
- package/dist/src/utils/text-wrap.d.ts +26 -1
- package/dist/src/utils/text-wrap.d.ts.map +1 -1
- package/dist/src/utils/text-wrap.js +106 -11
- package/dist/src/utils/text-wrap.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/codeblock.tsx +2 -2
- package/src/components/Markdown.tsx +3 -3
- package/src/components/MultilineTextInput.tsx +138 -344
- package/src/components/TextInput.tsx +54 -99
- package/src/components/text-editing.ts +180 -0
- package/src/hosts/base.ts +86 -3
- package/src/hosts/box.ts +37 -2
- package/src/hosts/canvas.ts +120 -31
- package/src/hosts/codeblock.ts +46 -33
- package/src/hosts/flex-container.ts +21 -2
- package/src/hosts/index.ts +1 -1
- package/src/hosts/overlay-item.ts +8 -2
- package/src/hosts/overlay.ts +2 -2
- package/src/hosts/scroll.ts +142 -45
- package/src/hosts/single-child.ts +2 -0
- package/src/hosts/spacer.ts +6 -1
- package/src/hosts/text.ts +122 -75
- package/src/hosts/zstack.ts +7 -2
- package/src/index.ts +1 -1
- package/src/internal/renderer/index.ts +53 -20
- package/src/internal/renderer/types.ts +4 -0
- package/src/motion/hooks.ts +1 -1
- package/src/reconciler/host-config.ts +2 -2
- package/src/reconciler/types.ts +7 -1
- package/src/utils/border.ts +11 -1
- package/src/utils/index.ts +15 -1
- package/src/utils/text-layout.ts +65 -0
- package/src/utils/text-wrap.ts +135 -13
package/src/hosts/scroll.ts
CHANGED
|
@@ -80,6 +80,12 @@ export class ScrollHost extends SingleChildHost {
|
|
|
80
80
|
// Measured content dimensions (full size before clipping)
|
|
81
81
|
private contentWidth = 0
|
|
82
82
|
private contentHeight = 0
|
|
83
|
+
// Effective viewport dimensions (excludes scrollbar gutter when visible)
|
|
84
|
+
private viewportWidth = 0
|
|
85
|
+
private viewportHeight = 0
|
|
86
|
+
// Scrollbar visibility after accounting for content overflow
|
|
87
|
+
private showVerticalScrollbar = false
|
|
88
|
+
private showHorizontalScrollbar = false
|
|
83
89
|
// Track last reported sizes to avoid redundant callbacks
|
|
84
90
|
private lastReportedContentW = -1
|
|
85
91
|
private lastReportedContentH = -1
|
|
@@ -103,45 +109,114 @@ export class ScrollHost extends SingleChildHost {
|
|
|
103
109
|
this.updateProps(props as unknown as Record<string, unknown>)
|
|
104
110
|
}
|
|
105
111
|
|
|
106
|
-
|
|
112
|
+
private computeViewport(baseW: number, baseH: number, contentW: number, contentH: number): {
|
|
113
|
+
viewportW: number
|
|
114
|
+
viewportH: number
|
|
115
|
+
showV: boolean
|
|
116
|
+
showH: boolean
|
|
117
|
+
} {
|
|
118
|
+
const allowV = this.showScrollbar && (this.axis === "vertical" || this.axis === "both")
|
|
119
|
+
const allowH = this.showScrollbar && (this.axis === "horizontal" || this.axis === "both")
|
|
120
|
+
let viewportW = Math.max(0, baseW)
|
|
121
|
+
let viewportH = Math.max(0, baseH)
|
|
122
|
+
let showV = false
|
|
123
|
+
let showH = false
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < 2; i++) {
|
|
126
|
+
const nextShowV = allowV && contentH > viewportH
|
|
127
|
+
const nextShowH = allowH && contentW > viewportW
|
|
128
|
+
if (nextShowV === showV && nextShowH === showH) break
|
|
129
|
+
showV = nextShowV
|
|
130
|
+
showH = nextShowH
|
|
131
|
+
viewportW = Math.max(0, baseW - (showV ? 1 : 0))
|
|
132
|
+
viewportH = Math.max(0, baseH - (showH ? 1 : 0))
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return { viewportW, viewportH, showV, showH }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
protected measureSelf(maxW: number, maxH: number): Size {
|
|
107
139
|
// Apply frame constraints to determine our size
|
|
108
140
|
const constrained = this.constrainProposal(maxW, maxH)
|
|
109
141
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
142
|
+
const child = this.child
|
|
143
|
+
if (!child) {
|
|
144
|
+
this.contentWidth = 0
|
|
145
|
+
this.contentHeight = 0
|
|
146
|
+
const viewport = this.computeViewport(constrained.w, constrained.h, 0, 0)
|
|
147
|
+
this.viewportWidth = viewport.viewportW
|
|
148
|
+
this.viewportHeight = viewport.viewportH
|
|
149
|
+
this.showVerticalScrollbar = viewport.showV
|
|
150
|
+
this.showHorizontalScrollbar = viewport.showH
|
|
151
|
+
return this.constrainResult({ w: 0, h: 0 })
|
|
116
152
|
}
|
|
117
|
-
|
|
118
|
-
|
|
153
|
+
|
|
154
|
+
const measureChild = (proposalW: number, proposalH: number): Size => {
|
|
155
|
+
let childMaxW = proposalW
|
|
156
|
+
let childMaxH = proposalH
|
|
157
|
+
|
|
158
|
+
if (this.axis === "vertical" || this.axis === "both") {
|
|
159
|
+
childMaxH = Number.MAX_SAFE_INTEGER
|
|
160
|
+
}
|
|
161
|
+
if (this.axis === "horizontal" || this.axis === "both") {
|
|
162
|
+
childMaxW = Number.MAX_SAFE_INTEGER
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return child.measure(childMaxW, childMaxH)
|
|
119
166
|
}
|
|
120
167
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
168
|
+
let viewportW = constrained.w
|
|
169
|
+
let viewportH = constrained.h
|
|
170
|
+
let contentW = 0
|
|
171
|
+
let contentH = 0
|
|
172
|
+
let showV = false
|
|
173
|
+
let showH = false
|
|
174
|
+
|
|
175
|
+
for (let i = 0; i < 3; i++) {
|
|
176
|
+
const childSize = measureChild(viewportW, viewportH)
|
|
177
|
+
contentW = childSize.w
|
|
178
|
+
contentH = childSize.h
|
|
179
|
+
const viewport = this.computeViewport(constrained.w, constrained.h, contentW, contentH)
|
|
180
|
+
if (viewport.viewportW === viewportW && viewport.viewportH === viewportH) {
|
|
181
|
+
showV = viewport.showV
|
|
182
|
+
showH = viewport.showH
|
|
183
|
+
break
|
|
184
|
+
}
|
|
185
|
+
viewportW = viewport.viewportW
|
|
186
|
+
viewportH = viewport.viewportH
|
|
187
|
+
showV = viewport.showV
|
|
188
|
+
showH = viewport.showH
|
|
128
189
|
}
|
|
129
190
|
|
|
191
|
+
this.contentWidth = contentW
|
|
192
|
+
this.contentHeight = contentH
|
|
193
|
+
this.viewportWidth = viewportW
|
|
194
|
+
this.viewportHeight = viewportH
|
|
195
|
+
this.showVerticalScrollbar = showV
|
|
196
|
+
this.showHorizontalScrollbar = showH
|
|
197
|
+
|
|
130
198
|
// Report natural content size (clamped to constrained bounds)
|
|
131
199
|
// Greedy expansion happens in layout phase via layoutFlex
|
|
132
|
-
const naturalW = Math.min(this.contentWidth, constrained.w)
|
|
133
|
-
const naturalH = Math.min(this.contentHeight, constrained.h)
|
|
200
|
+
const naturalW = Math.min(this.contentWidth + (this.showVerticalScrollbar ? 1 : 0), constrained.w)
|
|
201
|
+
const naturalH = Math.min(this.contentHeight + (this.showHorizontalScrollbar ? 1 : 0), constrained.h)
|
|
134
202
|
|
|
135
203
|
return this.constrainResult({ w: naturalW, h: naturalH })
|
|
136
204
|
}
|
|
137
205
|
|
|
138
|
-
override
|
|
206
|
+
protected override layoutSelf(rect: Rect): void {
|
|
139
207
|
const layoutRect = this.layoutWithConstraints(rect)
|
|
208
|
+
const viewport = this.computeViewport(layoutRect.w, layoutRect.h, this.contentWidth, this.contentHeight)
|
|
209
|
+
this.viewportWidth = viewport.viewportW
|
|
210
|
+
this.viewportHeight = viewport.viewportH
|
|
211
|
+
this.showVerticalScrollbar = viewport.showV
|
|
212
|
+
this.showHorizontalScrollbar = viewport.showH
|
|
213
|
+
|
|
140
214
|
const { x: alignX, y: alignY } = resolveAlign(this.align)
|
|
141
215
|
|
|
142
216
|
const contentChanged =
|
|
143
217
|
this.contentWidth !== this.lastReportedContentW || this.contentHeight !== this.lastReportedContentH
|
|
144
|
-
const viewportChanged =
|
|
218
|
+
const viewportChanged =
|
|
219
|
+
this.viewportWidth !== this.lastViewportW || this.viewportHeight !== this.lastViewportH
|
|
145
220
|
const rectChanged =
|
|
146
221
|
layoutRect.x !== this.lastRectX ||
|
|
147
222
|
layoutRect.y !== this.lastRectY ||
|
|
@@ -152,8 +227,8 @@ export class ScrollHost extends SingleChildHost {
|
|
|
152
227
|
if (!child) return
|
|
153
228
|
|
|
154
229
|
// Calculate max scroll offsets
|
|
155
|
-
const maxScrollY = Math.max(0, this.contentHeight -
|
|
156
|
-
const maxScrollX = Math.max(0, this.contentWidth -
|
|
230
|
+
const maxScrollY = Math.max(0, this.contentHeight - this.viewportHeight)
|
|
231
|
+
const maxScrollX = Math.max(0, this.contentWidth - this.viewportWidth)
|
|
157
232
|
|
|
158
233
|
// Start with the offset from props (controlled by useScroll)
|
|
159
234
|
let scrollY = this.offsetY
|
|
@@ -200,18 +275,18 @@ export class ScrollHost extends SingleChildHost {
|
|
|
200
275
|
const offsetChanged = this.effectiveOffset !== this.lastOffsetY || this.effectiveOffsetX !== this.lastOffsetX
|
|
201
276
|
|
|
202
277
|
// Handle alignment when content is smaller than viewport
|
|
203
|
-
if (this.contentHeight <
|
|
278
|
+
if (this.contentHeight < this.viewportHeight && (this.axis === "vertical" || this.axis === "both")) {
|
|
204
279
|
if (alignY === "bottom") {
|
|
205
|
-
scrollY = -(
|
|
280
|
+
scrollY = -(this.viewportHeight - this.contentHeight)
|
|
206
281
|
} else if (alignY === "center") {
|
|
207
|
-
scrollY = -Math.floor((
|
|
282
|
+
scrollY = -Math.floor((this.viewportHeight - this.contentHeight) / 2)
|
|
208
283
|
}
|
|
209
284
|
}
|
|
210
|
-
if (this.contentWidth <
|
|
285
|
+
if (this.contentWidth < this.viewportWidth && (this.axis === "horizontal" || this.axis === "both")) {
|
|
211
286
|
if (alignX === "right") {
|
|
212
|
-
scrollX = -(
|
|
287
|
+
scrollX = -(this.viewportWidth - this.contentWidth)
|
|
213
288
|
} else if (alignX === "center") {
|
|
214
|
-
scrollX = -Math.floor((
|
|
289
|
+
scrollX = -Math.floor((this.viewportWidth - this.contentWidth) / 2)
|
|
215
290
|
}
|
|
216
291
|
}
|
|
217
292
|
|
|
@@ -227,8 +302,8 @@ export class ScrollHost extends SingleChildHost {
|
|
|
227
302
|
if (this.onScrollLayoutChange && (contentChanged || viewportChanged || rectChanged || offsetChanged)) {
|
|
228
303
|
this.lastReportedContentW = this.contentWidth
|
|
229
304
|
this.lastReportedContentH = this.contentHeight
|
|
230
|
-
this.lastViewportW =
|
|
231
|
-
this.lastViewportH =
|
|
305
|
+
this.lastViewportW = this.viewportWidth
|
|
306
|
+
this.lastViewportH = this.viewportHeight
|
|
232
307
|
this.lastRectX = layoutRect.x
|
|
233
308
|
this.lastRectY = layoutRect.y
|
|
234
309
|
this.lastRectW = layoutRect.w
|
|
@@ -238,7 +313,7 @@ export class ScrollHost extends SingleChildHost {
|
|
|
238
313
|
|
|
239
314
|
this.onScrollLayoutChange({
|
|
240
315
|
content: { width: this.contentWidth, height: this.contentHeight },
|
|
241
|
-
viewport: { width:
|
|
316
|
+
viewport: { width: this.viewportWidth, height: this.viewportHeight },
|
|
242
317
|
offset: { x: this.effectiveOffsetX, y: this.effectiveOffset },
|
|
243
318
|
rect: { x: layoutRect.x, y: layoutRect.y, w: layoutRect.w, h: layoutRect.h },
|
|
244
319
|
axis: this.axis,
|
|
@@ -253,8 +328,8 @@ export class ScrollHost extends SingleChildHost {
|
|
|
253
328
|
// Fill background (inherit from parent if not explicitly set)
|
|
254
329
|
fillRectWithInheritedBg(buffer, palette, { x, y, w, h }, this.bg, this.parent)
|
|
255
330
|
|
|
256
|
-
// Render children with clipping
|
|
257
|
-
buffer.withClip(x, y,
|
|
331
|
+
// Render children with clipping (exclude scrollbar gutters)
|
|
332
|
+
buffer.withClip(x, y, this.viewportWidth, this.viewportHeight, () => {
|
|
258
333
|
const child = this.child
|
|
259
334
|
if (child) {
|
|
260
335
|
child.render(buffer, palette)
|
|
@@ -272,18 +347,18 @@ export class ScrollHost extends SingleChildHost {
|
|
|
272
347
|
const { x, y, w, h } = this.rect
|
|
273
348
|
|
|
274
349
|
// Vertical scrollbar
|
|
275
|
-
if (
|
|
276
|
-
const maxScroll = this.contentHeight -
|
|
350
|
+
if (this.showVerticalScrollbar) {
|
|
351
|
+
const maxScroll = Math.max(1, this.contentHeight - this.viewportHeight)
|
|
277
352
|
const scrollRatio = Math.min(1, this.effectiveOffset / maxScroll)
|
|
278
|
-
const thumbRatio =
|
|
279
|
-
const thumbHeight = Math.max(1, Math.floor(
|
|
280
|
-
const thumbY = Math.floor((
|
|
353
|
+
const thumbRatio = this.viewportHeight / this.contentHeight
|
|
354
|
+
const thumbHeight = Math.max(1, Math.floor(this.viewportHeight * thumbRatio))
|
|
355
|
+
const thumbY = Math.floor((this.viewportHeight - thumbHeight) * scrollRatio)
|
|
281
356
|
|
|
282
357
|
const trackStyle = palette.id({ fg: 8 }) // dim
|
|
283
358
|
const thumbStyle = palette.id({ fg: 7 }) // brighter
|
|
284
359
|
|
|
285
360
|
// Draw track
|
|
286
|
-
for (let row = 0; row <
|
|
361
|
+
for (let row = 0; row < this.viewportHeight; row++) {
|
|
287
362
|
const char = row >= thumbY && row < thumbY + thumbHeight ? "┃" : "│"
|
|
288
363
|
const style = row >= thumbY && row < thumbY + thumbHeight ? thumbStyle : trackStyle
|
|
289
364
|
buffer.drawCP(x + w - 1, y + row, char.codePointAt(0)!, style)
|
|
@@ -291,18 +366,18 @@ export class ScrollHost extends SingleChildHost {
|
|
|
291
366
|
}
|
|
292
367
|
|
|
293
368
|
// Horizontal scrollbar
|
|
294
|
-
if (
|
|
295
|
-
const maxScroll = this.contentWidth -
|
|
369
|
+
if (this.showHorizontalScrollbar) {
|
|
370
|
+
const maxScroll = Math.max(1, this.contentWidth - this.viewportWidth)
|
|
296
371
|
const scrollRatio = Math.min(1, this.effectiveOffsetX / maxScroll)
|
|
297
|
-
const thumbRatio =
|
|
298
|
-
const thumbWidth = Math.max(1, Math.floor(
|
|
299
|
-
const thumbX = Math.floor((
|
|
372
|
+
const thumbRatio = this.viewportWidth / this.contentWidth
|
|
373
|
+
const thumbWidth = Math.max(1, Math.floor(this.viewportWidth * thumbRatio))
|
|
374
|
+
const thumbX = Math.floor((this.viewportWidth - thumbWidth) * scrollRatio)
|
|
300
375
|
|
|
301
376
|
const trackStyle = palette.id({ fg: 8 })
|
|
302
377
|
const thumbStyle = palette.id({ fg: 7 })
|
|
303
378
|
|
|
304
379
|
// Draw track
|
|
305
|
-
for (let col = 0; col <
|
|
380
|
+
for (let col = 0; col < this.viewportWidth; col++) {
|
|
306
381
|
const char = col >= thumbX && col < thumbX + thumbWidth ? "━" : "─"
|
|
307
382
|
const style = col >= thumbX && col < thumbX + thumbWidth ? thumbStyle : trackStyle
|
|
308
383
|
buffer.drawCP(x + col, y + h - 1, char.codePointAt(0)!, style)
|
|
@@ -314,6 +389,14 @@ export class ScrollHost extends SingleChildHost {
|
|
|
314
389
|
super.updateProps(props)
|
|
315
390
|
// Scroll is greedy by default unless explicitly set to false
|
|
316
391
|
this.applyGreedyDefault(props, 1)
|
|
392
|
+
const prevAxis = this.axis
|
|
393
|
+
const prevOffsetY = this.offsetY
|
|
394
|
+
const prevOffsetX = this.offsetX
|
|
395
|
+
const prevAlign = this.align
|
|
396
|
+
const prevBg = this.bg
|
|
397
|
+
const prevShowScrollbar = this.showScrollbar
|
|
398
|
+
const prevSticky = this.sticky
|
|
399
|
+
|
|
317
400
|
if (props.axis !== undefined) this.axis = (props.axis as ScrollProps["axis"]) ?? "vertical"
|
|
318
401
|
if (props.offsetY !== undefined) this.offsetY = props.offsetY as number
|
|
319
402
|
if (props.offsetX !== undefined) this.offsetX = props.offsetX as number
|
|
@@ -322,5 +405,19 @@ export class ScrollHost extends SingleChildHost {
|
|
|
322
405
|
if (props.showScrollbar !== undefined) this.showScrollbar = props.showScrollbar as boolean
|
|
323
406
|
if (props.sticky !== undefined) this.sticky = props.sticky as boolean
|
|
324
407
|
this.onScrollLayoutChange = props.onScrollLayoutChange as ScrollProps["onScrollLayoutChange"]
|
|
408
|
+
|
|
409
|
+
const layoutChanged =
|
|
410
|
+
prevAxis !== this.axis ||
|
|
411
|
+
prevOffsetY !== this.offsetY ||
|
|
412
|
+
prevOffsetX !== this.offsetX ||
|
|
413
|
+
prevSticky !== this.sticky ||
|
|
414
|
+
prevAlign !== this.align ||
|
|
415
|
+
prevShowScrollbar !== this.showScrollbar
|
|
416
|
+
|
|
417
|
+
if (layoutChanged) {
|
|
418
|
+
this.invalidateLayout()
|
|
419
|
+
} else if (prevBg !== this.bg) {
|
|
420
|
+
this.invalidateRender()
|
|
421
|
+
}
|
|
325
422
|
}
|
|
326
423
|
}
|
|
@@ -26,6 +26,7 @@ export abstract class SingleChildHost extends BaseHost {
|
|
|
26
26
|
this.children.splice(0, 1)
|
|
27
27
|
}
|
|
28
28
|
child.parent = null
|
|
29
|
+
this.invalidateLayout()
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
private setSingleChild(child: HostInstance): void {
|
|
@@ -44,5 +45,6 @@ export abstract class SingleChildHost extends BaseHost {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
child.parent = this
|
|
48
|
+
this.invalidateLayout()
|
|
47
49
|
}
|
|
48
50
|
}
|
package/src/hosts/spacer.ts
CHANGED
|
@@ -21,7 +21,7 @@ export class SpacerHost extends LeafHost {
|
|
|
21
21
|
this.updateProps(props as unknown as Record<string, unknown>)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
protected measureSelf(_maxW: number, _maxH: number): Size {
|
|
25
25
|
// Spacers have no natural size, they expand via greedy
|
|
26
26
|
return { w: this.minWidth, h: this.minHeight }
|
|
27
27
|
}
|
|
@@ -34,7 +34,12 @@ export class SpacerHost extends LeafHost {
|
|
|
34
34
|
super.updateProps(props)
|
|
35
35
|
// Spacer is greedy by default unless explicitly set to false
|
|
36
36
|
this.applyGreedyDefault(props, 1)
|
|
37
|
+
const prevMinWidth = this.minWidth
|
|
38
|
+
const prevMinHeight = this.minHeight
|
|
37
39
|
if (props.minWidth !== undefined) this.minWidth = props.minWidth as number
|
|
38
40
|
if (props.minHeight !== undefined) this.minHeight = props.minHeight as number
|
|
41
|
+
if (prevMinWidth !== this.minWidth || prevMinHeight !== this.minHeight) {
|
|
42
|
+
this.invalidateLayout()
|
|
43
|
+
}
|
|
39
44
|
}
|
|
40
45
|
}
|