@effect-tui/core 0.1.0 → 0.1.4

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 (271) hide show
  1. package/README.md +31 -11
  2. package/dist/ansi.d.ts +127 -32
  3. package/dist/ansi.d.ts.map +1 -1
  4. package/dist/ansi.js +159 -37
  5. package/dist/ansi.js.map +1 -1
  6. package/dist/colors.d.ts +139 -0
  7. package/dist/colors.d.ts.map +1 -0
  8. package/dist/colors.js +339 -0
  9. package/dist/colors.js.map +1 -0
  10. package/dist/index.d.ts +6 -10
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +13 -11
  13. package/dist/index.js.map +1 -1
  14. package/dist/keys.d.ts +21 -0
  15. package/dist/keys.d.ts.map +1 -1
  16. package/dist/keys.js +199 -58
  17. package/dist/keys.js.map +1 -1
  18. package/dist/layout/axis-helpers.d.ts +19 -0
  19. package/dist/layout/axis-helpers.d.ts.map +1 -0
  20. package/dist/layout/axis-helpers.js +19 -0
  21. package/dist/layout/axis-helpers.js.map +1 -0
  22. package/dist/output.d.ts +59 -0
  23. package/dist/output.d.ts.map +1 -0
  24. package/dist/output.js +142 -0
  25. package/dist/output.js.map +1 -0
  26. package/dist/render/buffer.d.ts.map +1 -1
  27. package/dist/render/buffer.js +6 -25
  28. package/dist/render/buffer.js.map +1 -1
  29. package/dist/render/graphemes.d.ts +15 -0
  30. package/dist/render/graphemes.d.ts.map +1 -0
  31. package/dist/render/graphemes.js +28 -0
  32. package/dist/render/graphemes.js.map +1 -0
  33. package/dist/render/measure.d.ts +1 -0
  34. package/dist/render/measure.d.ts.map +1 -1
  35. package/dist/render/measure.js +14 -36
  36. package/dist/render/measure.js.map +1 -1
  37. package/dist/render/palette.d.ts.map +1 -1
  38. package/dist/render/palette.js +26 -1
  39. package/dist/render/palette.js.map +1 -1
  40. package/dist/render/segmenter.d.ts +8 -0
  41. package/dist/render/segmenter.d.ts.map +1 -0
  42. package/dist/render/segmenter.js +23 -0
  43. package/dist/render/segmenter.js.map +1 -0
  44. package/dist/render/surface.d.ts +6 -32
  45. package/dist/render/surface.d.ts.map +1 -1
  46. package/dist/render/surface.js +11 -80
  47. package/dist/render/surface.js.map +1 -1
  48. package/dist/runtime/backend_node.d.ts.map +1 -1
  49. package/dist/runtime/backend_node.js.map +1 -1
  50. package/dist/tailwind-colors.d.ts +291 -0
  51. package/dist/tailwind-colors.d.ts.map +1 -0
  52. package/dist/tailwind-colors.js +291 -0
  53. package/dist/tailwind-colors.js.map +1 -0
  54. package/dist/types.d.ts +15 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +3 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +55 -55
  59. package/src/ansi.ts +201 -73
  60. package/src/colors.ts +468 -0
  61. package/src/index.ts +28 -14
  62. package/src/keys.ts +467 -287
  63. package/src/layout/axis-helpers.ts +33 -0
  64. package/src/output.ts +175 -0
  65. package/src/render/buffer.ts +161 -184
  66. package/src/render/graphemes.ts +34 -0
  67. package/src/render/measure.ts +15 -38
  68. package/src/render/palette.ts +98 -77
  69. package/src/render/segmenter.ts +27 -0
  70. package/src/render/surface.ts +139 -225
  71. package/src/runtime/backend_node.ts +71 -71
  72. package/src/tailwind-colors.ts +295 -0
  73. package/src/types.ts +18 -0
  74. package/dist/anim.d.ts +0 -4
  75. package/dist/anim.d.ts.map +0 -1
  76. package/dist/anim.js +0 -5
  77. package/dist/anim.js.map +0 -1
  78. package/dist/layout/linearStack.d.ts +0 -17
  79. package/dist/layout/linearStack.d.ts.map +0 -1
  80. package/dist/layout/linearStack.js +0 -86
  81. package/dist/layout/linearStack.js.map +0 -1
  82. package/dist/motion-value.d.ts +0 -58
  83. package/dist/motion-value.d.ts.map +0 -1
  84. package/dist/motion-value.js +0 -250
  85. package/dist/motion-value.js.map +0 -1
  86. package/dist/present/display.d.ts +0 -58
  87. package/dist/present/display.d.ts.map +0 -1
  88. package/dist/present/display.js +0 -168
  89. package/dist/present/display.js.map +0 -1
  90. package/dist/present/writers/fullscreen.d.ts +0 -19
  91. package/dist/present/writers/fullscreen.d.ts.map +0 -1
  92. package/dist/present/writers/fullscreen.js +0 -55
  93. package/dist/present/writers/fullscreen.js.map +0 -1
  94. package/dist/present/writers/inline.d.ts +0 -20
  95. package/dist/present/writers/inline.d.ts.map +0 -1
  96. package/dist/present/writers/inline.js +0 -92
  97. package/dist/present/writers/inline.js.map +0 -1
  98. package/dist/render/color-utils.d.ts +0 -18
  99. package/dist/render/color-utils.d.ts.map +0 -1
  100. package/dist/render/color-utils.js +0 -58
  101. package/dist/render/color-utils.js.map +0 -1
  102. package/dist/render/diff.d.ts +0 -30
  103. package/dist/render/diff.d.ts.map +0 -1
  104. package/dist/render/diff.js +0 -83
  105. package/dist/render/diff.js.map +0 -1
  106. package/dist/spring-physics.d.ts +0 -36
  107. package/dist/spring-physics.d.ts.map +0 -1
  108. package/dist/spring-physics.js +0 -113
  109. package/dist/spring-physics.js.map +0 -1
  110. package/dist/spring.d.ts +0 -73
  111. package/dist/spring.d.ts.map +0 -1
  112. package/dist/spring.js +0 -136
  113. package/dist/spring.js.map +0 -1
  114. package/dist/ui/containers/canvas.d.ts +0 -13
  115. package/dist/ui/containers/canvas.d.ts.map +0 -1
  116. package/dist/ui/containers/canvas.js +0 -16
  117. package/dist/ui/containers/canvas.js.map +0 -1
  118. package/dist/ui/containers/geometry-reader.d.ts +0 -17
  119. package/dist/ui/containers/geometry-reader.d.ts.map +0 -1
  120. package/dist/ui/containers/geometry-reader.js +0 -24
  121. package/dist/ui/containers/geometry-reader.js.map +0 -1
  122. package/dist/ui/containers/hstack.d.ts +0 -12
  123. package/dist/ui/containers/hstack.d.ts.map +0 -1
  124. package/dist/ui/containers/hstack.js +0 -28
  125. package/dist/ui/containers/hstack.js.map +0 -1
  126. package/dist/ui/containers/scroll.d.ts +0 -28
  127. package/dist/ui/containers/scroll.d.ts.map +0 -1
  128. package/dist/ui/containers/scroll.js +0 -97
  129. package/dist/ui/containers/scroll.js.map +0 -1
  130. package/dist/ui/containers/shared.d.ts +0 -12
  131. package/dist/ui/containers/shared.d.ts.map +0 -1
  132. package/dist/ui/containers/shared.js +0 -19
  133. package/dist/ui/containers/shared.js.map +0 -1
  134. package/dist/ui/containers/vstack.d.ts +0 -12
  135. package/dist/ui/containers/vstack.d.ts.map +0 -1
  136. package/dist/ui/containers/vstack.js +0 -28
  137. package/dist/ui/containers/vstack.js.map +0 -1
  138. package/dist/ui/containers/zstack.d.ts +0 -14
  139. package/dist/ui/containers/zstack.d.ts.map +0 -1
  140. package/dist/ui/containers/zstack.js +0 -36
  141. package/dist/ui/containers/zstack.js.map +0 -1
  142. package/dist/ui/core/geometry-store.d.ts +0 -22
  143. package/dist/ui/core/geometry-store.d.ts.map +0 -1
  144. package/dist/ui/core/geometry-store.js +0 -29
  145. package/dist/ui/core/geometry-store.js.map +0 -1
  146. package/dist/ui/core/geometry.d.ts +0 -34
  147. package/dist/ui/core/geometry.d.ts.map +0 -1
  148. package/dist/ui/core/geometry.js +0 -14
  149. package/dist/ui/core/geometry.js.map +0 -1
  150. package/dist/ui/core/view.d.ts +0 -25
  151. package/dist/ui/core/view.d.ts.map +0 -1
  152. package/dist/ui/core/view.js +0 -34
  153. package/dist/ui/core/view.js.map +0 -1
  154. package/dist/ui/index.d.ts +0 -44
  155. package/dist/ui/index.d.ts.map +0 -1
  156. package/dist/ui/index.js +0 -39
  157. package/dist/ui/index.js.map +0 -1
  158. package/dist/ui/inlinetext.d.ts +0 -24
  159. package/dist/ui/inlinetext.d.ts.map +0 -1
  160. package/dist/ui/inlinetext.js +0 -131
  161. package/dist/ui/inlinetext.js.map +0 -1
  162. package/dist/ui/install.d.ts +0 -22
  163. package/dist/ui/install.d.ts.map +0 -1
  164. package/dist/ui/install.js +0 -66
  165. package/dist/ui/install.js.map +0 -1
  166. package/dist/ui/markdown.d.ts +0 -40
  167. package/dist/ui/markdown.d.ts.map +0 -1
  168. package/dist/ui/markdown.js +0 -351
  169. package/dist/ui/markdown.js.map +0 -1
  170. package/dist/ui/modifiers/border.d.ts +0 -33
  171. package/dist/ui/modifiers/border.d.ts.map +0 -1
  172. package/dist/ui/modifiers/border.js +0 -82
  173. package/dist/ui/modifiers/border.js.map +0 -1
  174. package/dist/ui/modifiers/fill.d.ts +0 -14
  175. package/dist/ui/modifiers/fill.d.ts.map +0 -1
  176. package/dist/ui/modifiers/fill.js +0 -25
  177. package/dist/ui/modifiers/fill.js.map +0 -1
  178. package/dist/ui/modifiers/frame.d.ts +0 -23
  179. package/dist/ui/modifiers/frame.d.ts.map +0 -1
  180. package/dist/ui/modifiers/frame.js +0 -54
  181. package/dist/ui/modifiers/frame.js.map +0 -1
  182. package/dist/ui/modifiers/offset.d.ts +0 -15
  183. package/dist/ui/modifiers/offset.d.ts.map +0 -1
  184. package/dist/ui/modifiers/offset.js +0 -21
  185. package/dist/ui/modifiers/offset.js.map +0 -1
  186. package/dist/ui/modifiers/opacity.d.ts +0 -15
  187. package/dist/ui/modifiers/opacity.d.ts.map +0 -1
  188. package/dist/ui/modifiers/opacity.js +0 -95
  189. package/dist/ui/modifiers/opacity.js.map +0 -1
  190. package/dist/ui/modifiers/padding.d.ts +0 -20
  191. package/dist/ui/modifiers/padding.d.ts.map +0 -1
  192. package/dist/ui/modifiers/padding.js +0 -36
  193. package/dist/ui/modifiers/padding.js.map +0 -1
  194. package/dist/ui/modifiers/styled.d.ts +0 -14
  195. package/dist/ui/modifiers/styled.d.ts.map +0 -1
  196. package/dist/ui/modifiers/styled.js +0 -26
  197. package/dist/ui/modifiers/styled.js.map +0 -1
  198. package/dist/ui/primitives/rectangle.d.ts +0 -15
  199. package/dist/ui/primitives/rectangle.d.ts.map +0 -1
  200. package/dist/ui/primitives/rectangle.js +0 -23
  201. package/dist/ui/primitives/rectangle.js.map +0 -1
  202. package/dist/ui/primitives/spacer.d.ts +0 -13
  203. package/dist/ui/primitives/spacer.d.ts.map +0 -1
  204. package/dist/ui/primitives/spacer.js +0 -16
  205. package/dist/ui/primitives/spacer.js.map +0 -1
  206. package/dist/ui/primitives/text.d.ts +0 -15
  207. package/dist/ui/primitives/text.d.ts.map +0 -1
  208. package/dist/ui/primitives/text.js +0 -79
  209. package/dist/ui/primitives/text.js.map +0 -1
  210. package/dist/ui/primitives/wrapped-text.d.ts +0 -30
  211. package/dist/ui/primitives/wrapped-text.d.ts.map +0 -1
  212. package/dist/ui/primitives/wrapped-text.js +0 -117
  213. package/dist/ui/primitives/wrapped-text.js.map +0 -1
  214. package/dist/ui/shinytext.d.ts +0 -66
  215. package/dist/ui/shinytext.d.ts.map +0 -1
  216. package/dist/ui/shinytext.js +0 -99
  217. package/dist/ui/shinytext.js.map +0 -1
  218. package/dist/ui/text/layout.d.ts +0 -35
  219. package/dist/ui/text/layout.d.ts.map +0 -1
  220. package/dist/ui/text/layout.js +0 -102
  221. package/dist/ui/text/layout.js.map +0 -1
  222. package/dist/ui/textinput.d.ts +0 -140
  223. package/dist/ui/textinput.d.ts.map +0 -1
  224. package/dist/ui/textinput.js +0 -402
  225. package/dist/ui/textinput.js.map +0 -1
  226. package/dist/ui/view-constructors.d.ts +0 -72
  227. package/dist/ui/view-constructors.d.ts.map +0 -1
  228. package/dist/ui/view-constructors.js +0 -74
  229. package/dist/ui/view-constructors.js.map +0 -1
  230. package/src/anim.ts +0 -5
  231. package/src/layout/linearStack.ts +0 -115
  232. package/src/motion-value.ts +0 -335
  233. package/src/present/display.ts +0 -206
  234. package/src/present/writers/fullscreen.ts +0 -58
  235. package/src/present/writers/inline.ts +0 -101
  236. package/src/render/color-utils.ts +0 -60
  237. package/src/render/diff.ts +0 -95
  238. package/src/spring-physics.ts +0 -151
  239. package/src/spring.ts +0 -234
  240. package/src/ui/__snapshots__/wrappedtext.test.ts.snap +0 -57
  241. package/src/ui/containers/canvas.ts +0 -18
  242. package/src/ui/containers/geometry-reader.ts +0 -32
  243. package/src/ui/containers/hstack.ts +0 -33
  244. package/src/ui/containers/scroll.ts +0 -106
  245. package/src/ui/containers/shared.ts +0 -27
  246. package/src/ui/containers/vstack.ts +0 -34
  247. package/src/ui/containers/zstack.ts +0 -37
  248. package/src/ui/core/geometry-store.ts +0 -42
  249. package/src/ui/core/geometry.ts +0 -30
  250. package/src/ui/core/view.ts +0 -49
  251. package/src/ui/index.ts +0 -84
  252. package/src/ui/inlinetext.ts +0 -135
  253. package/src/ui/install.ts +0 -110
  254. package/src/ui/markdown.test.ts +0 -74
  255. package/src/ui/markdown.ts +0 -388
  256. package/src/ui/modifiers/border.ts +0 -100
  257. package/src/ui/modifiers/fill.ts +0 -28
  258. package/src/ui/modifiers/frame.ts +0 -74
  259. package/src/ui/modifiers/offset.ts +0 -23
  260. package/src/ui/modifiers/opacity.ts +0 -93
  261. package/src/ui/modifiers/padding.ts +0 -53
  262. package/src/ui/modifiers/styled.ts +0 -31
  263. package/src/ui/primitives/rectangle.ts +0 -25
  264. package/src/ui/primitives/spacer.ts +0 -18
  265. package/src/ui/primitives/text.ts +0 -85
  266. package/src/ui/primitives/wrapped-text.ts +0 -131
  267. package/src/ui/shinytext.ts +0 -159
  268. package/src/ui/text/layout.ts +0 -119
  269. package/src/ui/textinput.ts +0 -496
  270. package/src/ui/view-constructors.ts +0 -96
  271. package/src/ui/wrappedtext.test.ts +0 -138
@@ -1,96 +0,0 @@
1
- /* view-constructors.ts — Static constructor methods for View
2
- *
3
- * This module contains all the static constructor methods that will be merged
4
- * with the View class via namespace merging to avoid circular dependencies.
5
- */
6
-
7
- import { Colors } from "../render/surface.js"
8
- import type { View } from "./core/view.js"
9
- import type { Align2D, HAlign, VAlign } from "./core/geometry.js"
10
-
11
- // Import all component classes for builders
12
- import { Text } from "./primitives/text.js"
13
- import { Rectangle } from "./primitives/rectangle.js"
14
- import { Spacer } from "./primitives/spacer.js"
15
- import { WrappedText, type WrappingOptions } from "./primitives/wrapped-text.js"
16
- import { HStack } from "./containers/hstack.js"
17
- import { VStack } from "./containers/vstack.js"
18
- import { ZStack } from "./containers/zstack.js"
19
- import { Scroll } from "./containers/scroll.js"
20
- import { Canvas } from "./containers/canvas.js"
21
- import { GeometryReader, type GeometryProxy } from "./containers/geometry-reader.js"
22
- import { TextInput, type TextInputState, type TextInputOptions } from "./textinput.js"
23
- import { Markdown, type MarkdownOptions } from "./markdown.js"
24
-
25
- // Options types for clean API (gap preferred; spacing kept for compat)
26
- type HStackOpts = { gap?: number; spacing?: number; alignment?: VAlign }
27
- type VStackOpts = { gap?: number; spacing?: number; alignment?: HAlign }
28
- type ScrollOpts = { axis?: "vertical" | "horizontal"; offset?: number; align?: VAlign | HAlign }
29
-
30
- // Constructor functions that will become static methods on View
31
- export const ViewConstructors = {
32
- // Primitives
33
- text: (s: string, wrap?: boolean): Text => {
34
- return new Text(s, wrap)
35
- },
36
-
37
- wrappedText: (s: string, options?: WrappingOptions): WrappedText => {
38
- return new WrappedText(s, options)
39
- },
40
-
41
- rect: (w: number, h: number, fill?: string | number): Rectangle => {
42
- return new Rectangle(w, h, typeof fill === "number" ? fill : (fill?.codePointAt?.(0) ?? 32))
43
- },
44
-
45
- spacer: (minLength = 0): Spacer => {
46
- return new Spacer(minLength)
47
- },
48
-
49
- // Containers (accept opts or legacy (gap, { alignment }))
50
- hstack: (children: View[], optsOrGap: number | HStackOpts = {}, maybe: { alignment?: VAlign } = {}): HStack => {
51
- const isNum = typeof optsOrGap === "number"
52
- const gap = isNum ? (optsOrGap as number) : (optsOrGap.gap ?? optsOrGap.spacing ?? 1)
53
- const alignment = (isNum ? maybe.alignment : (optsOrGap as HStackOpts).alignment) ?? "center"
54
- return new HStack(children, gap, alignment)
55
- },
56
-
57
- vstack: (children: View[], optsOrGap: number | VStackOpts = {}, maybe: { alignment?: HAlign } = {}): VStack => {
58
- const isNum = typeof optsOrGap === "number"
59
- const gap = isNum ? (optsOrGap as number) : (optsOrGap.gap ?? optsOrGap.spacing ?? 0)
60
- const alignment = (isNum ? maybe.alignment : (optsOrGap as VStackOpts).alignment) ?? "leading"
61
- return new VStack(children, gap, alignment)
62
- },
63
-
64
- zstack: (children: View[], alignment?: Align2D): ZStack => {
65
- return new ZStack(children, alignment ?? { h: "center", v: "center" })
66
- },
67
-
68
- scroll: (child: View, opts?: ScrollOpts): Scroll => {
69
- return new Scroll(child, opts ?? {})
70
- },
71
-
72
- canvas: (paint: (s: any, pal: any, rect: any) => void): Canvas => {
73
- return new Canvas(paint)
74
- },
75
-
76
- geometryReader: (reader: (proxy: GeometryProxy) => View): GeometryReader => {
77
- return new GeometryReader(reader)
78
- },
79
-
80
- // Overlay method (moved from chainer to avoid circular dependency)
81
- overlay: (base: View, overlay: View, alignment?: Align2D): ZStack => {
82
- return new ZStack([base, overlay], alignment ?? { h: "center", v: "center" })
83
- },
84
-
85
- // Components
86
- textInput: (state: TextInputState, opts?: TextInputOptions): TextInput => {
87
- return new TextInput(state, opts)
88
- },
89
-
90
- markdown: (text: string, opts?: MarkdownOptions): Markdown => {
91
- return new Markdown(text, opts)
92
- },
93
-
94
- // Utilities
95
- Colors,
96
- } as const
@@ -1,138 +0,0 @@
1
- import { describe, expect, it } from "@effect/vitest"
2
- import { Surface, Palette } from "../render/surface"
3
- import { WrappedText } from "./primitives/wrapped-text"
4
-
5
- describe("WrappedText", () => {
6
- describe("basic word wrapping", () => {
7
- it("should wrap text at word boundaries", () => {
8
- const node = new WrappedText("hello world test", { wordWrap: true })
9
- const surface = new Surface(8, 3)
10
- const palette = new Palette()
11
-
12
- // Measure should calculate height based on wrapped lines
13
- const measure = node.measure(8, 10)
14
- expect(measure.w).toBe(8) // Takes full width available
15
- expect(measure.h).toBe(3) // "hello world" splits into 3 lines at width 8
16
-
17
- // Render and check output
18
- node.render(surface, palette, { x: 0, y: 0, w: 8, h: 3 })
19
- const output = surface.toString()
20
-
21
- expect(output).toMatchSnapshot()
22
- })
23
-
24
- it("should handle single words longer than width", () => {
25
- const node = new WrappedText("verylongword", { wordWrap: true, breakWords: true })
26
- const surface = new Surface(6, 3)
27
- const palette = new Palette()
28
-
29
- const measure = node.measure(6, 10)
30
- expect(measure.w).toBe(6)
31
- expect(measure.h).toBe(2) // "verylo" + "ngword"
32
-
33
- node.render(surface, palette, { x: 0, y: 0, w: 6, h: 3 })
34
- const output = surface.toString()
35
-
36
- expect(output).toMatchSnapshot()
37
- })
38
-
39
- it("should preserve explicit line breaks", () => {
40
- const node = new WrappedText("line1\nline2\nline3")
41
- const surface = new Surface(10, 5)
42
- const palette = new Palette()
43
-
44
- const measure = node.measure(10, 10)
45
- expect(measure.w).toBe(10) // Takes full width available
46
- expect(measure.h).toBe(3) // 3 lines from explicit breaks
47
-
48
- node.render(surface, palette, { x: 0, y: 0, w: 10, h: 5 })
49
- const output = surface.toString()
50
-
51
- expect(output).toMatchSnapshot()
52
- })
53
- })
54
-
55
- describe("measurement calculations", () => {
56
- it("should calculate height correctly for wrapped text", () => {
57
- const node = new WrappedText("a b c d e f g h")
58
-
59
- // At width 3, should wrap to multiple lines
60
- const measure3 = node.measure(3, 10)
61
- expect(measure3.h).toBeGreaterThan(1)
62
-
63
- // At width 20, should fit on one line
64
- const measure20 = node.measure(20, 10)
65
- expect(measure20.h).toBe(1)
66
- })
67
-
68
- it("should respect max height constraint", () => {
69
- const node = new WrappedText("a b c d e f g h i j k l m n")
70
-
71
- const measure = node.measure(3, 2) // force to 2 lines max
72
- expect(measure.h).toBe(2)
73
- })
74
- })
75
-
76
- describe("wrapping strategies", () => {
77
- it("should default to word wrap", () => {
78
- const node = new WrappedText("hello world")
79
- const surface = new Surface(8, 2)
80
- const palette = new Palette()
81
-
82
- node.render(surface, palette, { x: 0, y: 0, w: 8, h: 2 })
83
- const output = surface.toString()
84
-
85
- // Should break at word boundary, not in middle of "world"
86
- expect(output).toContain("hello")
87
- expect(output).toContain("world")
88
- })
89
-
90
- it("should break words when breakWords is enabled", () => {
91
- const node = new WrappedText("supercalifragilisticexpialidocious", {
92
- wordWrap: true,
93
- breakWords: true,
94
- })
95
- const surface = new Surface(10, 5)
96
- const palette = new Palette()
97
-
98
- const measure = node.measure(10, 10)
99
- expect(measure.h).toBeGreaterThan(1)
100
-
101
- node.render(surface, palette, { x: 0, y: 0, w: 10, h: 5 })
102
- const output = surface.toString()
103
-
104
- expect(output).toMatchSnapshot()
105
- })
106
-
107
- it("should handle empty text", () => {
108
- const node = new WrappedText("")
109
- const surface = new Surface(10, 1)
110
- const palette = new Palette()
111
-
112
- const measure = node.measure(10, 10)
113
- expect(measure.w).toBe(10) // Takes full width available
114
- expect(measure.h).toBe(1) // Always at least 1 line
115
-
116
- node.render(surface, palette, { x: 0, y: 0, w: 10, h: 1 })
117
- const output = surface.toString()
118
-
119
- // Empty text should render as empty string (no content)
120
- expect(output).toBe("")
121
- })
122
- })
123
-
124
- describe("styling", () => {
125
- it("should apply styles to wrapped text", () => {
126
- const node = new WrappedText("hello world", { wordWrap: true }).fg("red").bold(true)
127
-
128
- const surface = new Surface(8, 3)
129
- const palette = new Palette()
130
-
131
- node.render(surface, palette, { x: 0, y: 0, w: 8, h: 3 })
132
-
133
- // Check that style was applied (we can't easily test SGR codes in snapshots,
134
- // but this ensures the style system is integrated)
135
- expect(node).toBeDefined()
136
- })
137
- })
138
- })