uicore-ts 1.1.105 → 1.1.110

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.
@@ -32,3 +32,4 @@ export * from "./UIInterfaces";
32
32
  export * from "./ClientCheckers";
33
33
  export * from "./UICore";
34
34
  export * from "./UIRootViewController";
35
+ export * from "./UILoadingView";
@@ -49,4 +49,5 @@ __reExport(scripts_exports, require("./UIInterfaces"), module.exports);
49
49
  __reExport(scripts_exports, require("./ClientCheckers"), module.exports);
50
50
  __reExport(scripts_exports, require("./UICore"), module.exports);
51
51
  __reExport(scripts_exports, require("./UIRootViewController"), module.exports);
52
+ __reExport(scripts_exports, require("./UILoadingView"), module.exports);
52
53
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../scripts/index.ts"],
4
- "sourcesContent": ["export * from \"./UIObject\"\nexport * from \"./UIView\"\nexport * from \"./UIViewController\"\nexport * from \"./UITimer\"\nexport * from \"./UITextArea\"\nexport * from \"./UITextView\"\nexport * from \"./UITextField\"\nexport * from \"./UITableView\"\nexport * from \"./UIStringFilter\"\nexport * from \"./UISlideScrollerView\"\nexport * from \"./UIScrollView\"\nexport * from \"./UIRoute\"\nexport * from \"./UIRectangle\"\nexport * from \"./UIPoint\"\nexport * from \"./UINativeScrollView\"\nexport * from \"./UILink\"\nexport * from \"./UILinkButton\"\nexport * from \"./UILayoutGrid\"\nexport * from \"./UIKeyValueStringFilter\"\nexport * from \"./UIKeyValueSorter\"\nexport * from \"./UIImageView\"\nexport * from \"./UIDialogView\"\nexport * from \"./UIDateTimeInput\"\nexport * from \"./UICoreExtensions\"\nexport * from \"./UICore\"\nexport * from \"./UIColor\"\nexport * from \"./UIBaseButton\"\nexport * from \"./UIButton\"\nexport * from \"./UIActionIndicator\"\nexport * from \"./UICoreExtensionValueObject\"\nexport * from \"./UIInterfaces\"\nexport * from \"./ClientCheckers\"\nexport * from \"./UICore\"\nexport * from \"./UIRootViewController\"\n\n\n\n\n\n\n\n\n"],
5
- "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,4BAAc,uBAAd;AACA,4BAAc,qBADd;AAEA,4BAAc,+BAFd;AAGA,4BAAc,sBAHd;AAIA,4BAAc,yBAJd;AAKA,4BAAc,yBALd;AAMA,4BAAc,0BANd;AAOA,4BAAc,0BAPd;AAQA,4BAAc,6BARd;AASA,4BAAc,kCATd;AAUA,4BAAc,2BAVd;AAWA,4BAAc,sBAXd;AAYA,4BAAc,0BAZd;AAaA,4BAAc,sBAbd;AAcA,4BAAc,iCAdd;AAeA,4BAAc,qBAfd;AAgBA,4BAAc,2BAhBd;AAiBA,4BAAc,2BAjBd;AAkBA,4BAAc,qCAlBd;AAmBA,4BAAc,+BAnBd;AAoBA,4BAAc,0BApBd;AAqBA,4BAAc,2BArBd;AAsBA,4BAAc,8BAtBd;AAuBA,4BAAc,+BAvBd;AAwBA,4BAAc,qBAxBd;AAyBA,4BAAc,sBAzBd;AA0BA,4BAAc,2BA1Bd;AA2BA,4BAAc,uBA3Bd;AA4BA,4BAAc,gCA5Bd;AA6BA,4BAAc,yCA7Bd;AA8BA,4BAAc,2BA9Bd;AA+BA,4BAAc,6BA/Bd;AAgCA,4BAAc,qBAhCd;AAiCA,4BAAc,mCAjCd;",
4
+ "sourcesContent": ["export * from \"./UIObject\"\nexport * from \"./UIView\"\nexport * from \"./UIViewController\"\nexport * from \"./UITimer\"\nexport * from \"./UITextArea\"\nexport * from \"./UITextView\"\nexport * from \"./UITextField\"\nexport * from \"./UITableView\"\nexport * from \"./UIStringFilter\"\nexport * from \"./UISlideScrollerView\"\nexport * from \"./UIScrollView\"\nexport * from \"./UIRoute\"\nexport * from \"./UIRectangle\"\nexport * from \"./UIPoint\"\nexport * from \"./UINativeScrollView\"\nexport * from \"./UILink\"\nexport * from \"./UILinkButton\"\nexport * from \"./UILayoutGrid\"\nexport * from \"./UIKeyValueStringFilter\"\nexport * from \"./UIKeyValueSorter\"\nexport * from \"./UIImageView\"\nexport * from \"./UIDialogView\"\nexport * from \"./UIDateTimeInput\"\nexport * from \"./UICoreExtensions\"\nexport * from \"./UICore\"\nexport * from \"./UIColor\"\nexport * from \"./UIBaseButton\"\nexport * from \"./UIButton\"\nexport * from \"./UIActionIndicator\"\nexport * from \"./UICoreExtensionValueObject\"\nexport * from \"./UIInterfaces\"\nexport * from \"./ClientCheckers\"\nexport * from \"./UICore\"\nexport * from \"./UIRootViewController\"\nexport * from \"./UILoadingView\"\n\n\n\n\n\n\n\n\n\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,4BAAc,uBAAd;AACA,4BAAc,qBADd;AAEA,4BAAc,+BAFd;AAGA,4BAAc,sBAHd;AAIA,4BAAc,yBAJd;AAKA,4BAAc,yBALd;AAMA,4BAAc,0BANd;AAOA,4BAAc,0BAPd;AAQA,4BAAc,6BARd;AASA,4BAAc,kCATd;AAUA,4BAAc,2BAVd;AAWA,4BAAc,sBAXd;AAYA,4BAAc,0BAZd;AAaA,4BAAc,sBAbd;AAcA,4BAAc,iCAdd;AAeA,4BAAc,qBAfd;AAgBA,4BAAc,2BAhBd;AAiBA,4BAAc,2BAjBd;AAkBA,4BAAc,qCAlBd;AAmBA,4BAAc,+BAnBd;AAoBA,4BAAc,0BApBd;AAqBA,4BAAc,2BArBd;AAsBA,4BAAc,8BAtBd;AAuBA,4BAAc,+BAvBd;AAwBA,4BAAc,qBAxBd;AAyBA,4BAAc,sBAzBd;AA0BA,4BAAc,2BA1Bd;AA2BA,4BAAc,uBA3Bd;AA4BA,4BAAc,gCA5Bd;AA6BA,4BAAc,yCA7Bd;AA8BA,4BAAc,2BA9Bd;AA+BA,4BAAc,6BA/Bd;AAgCA,4BAAc,qBAhCd;AAiCA,4BAAc,mCAjCd;AAkCA,4BAAc,4BAlCd;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uicore-ts",
3
- "version": "1.1.105",
3
+ "version": "1.1.110",
4
4
  "description": "UICore is a library to build native-like user interfaces using pure Typescript. No HTML is needed at all. Components are described as TS classes and all user interactions are handled explicitly. This library is strongly inspired by the UIKit framework that is used in IOS. In addition, UICore has tools to handle URL based routing, array sorting and filtering and adds a number of other utilities for convenience.",
5
5
  "main": "compiledScripts/index.js",
6
6
  "types": "compiledScripts/index.d.ts",
@@ -22,9 +22,6 @@ export class UIActionIndicator extends UIView {
22
22
  }
23
23
 
24
24
 
25
-
26
-
27
-
28
25
  set size(size: number) {
29
26
 
30
27
  this._size = size
@@ -40,15 +37,14 @@ export class UIActionIndicator extends UIView {
40
37
  }
41
38
 
42
39
 
43
-
44
40
  override set hidden(hidden: boolean) {
45
-
41
+
46
42
  super.hidden = hidden
47
-
48
- if (hidden) {
49
43
 
44
+ if (hidden) {
45
+
50
46
  this.indicatorView.removeFromSuperview()
51
-
47
+
52
48
  }
53
49
  else {
54
50
 
@@ -81,26 +77,20 @@ export class UIActionIndicator extends UIView {
81
77
 
82
78
  this.indicatorView.style.height = "" + this._size.integerValue + "px"
83
79
  this.indicatorView.style.width = "" + this._size.integerValue + "px"
84
-
80
+
85
81
  const minSize = Math.min(this.bounds.height, this.bounds.width)
86
-
82
+
87
83
  this.indicatorView.style.maxHeight = "" + minSize.integerValue + "px"
88
84
  this.indicatorView.style.maxWidth = "" + minSize.integerValue + "px"
89
-
85
+
90
86
  const size = Math.min(this._size, minSize)
91
-
87
+
92
88
  this.indicatorView.style.left = "" + ((bounds.width - size) * 0.5 - 11).integerValue + "px"
93
89
  this.indicatorView.style.top = "" + ((bounds.height - size) * 0.5 - 11).integerValue + "px"
94
90
 
95
-
96
-
97
-
98
91
  }
99
92
 
100
93
 
101
-
102
-
103
-
104
94
  }
105
95
 
106
96
 
@@ -0,0 +1,201 @@
1
+ import { UIColor } from "./UIColor"
2
+ import { IS_DEFINED, NO, YES } from "./UIObject"
3
+ import { UIRectangle } from "./UIRectangle"
4
+ import { IUILoadingView, UIView } from "./UIView"
5
+
6
+ export class UILoadingView extends UIView implements IUILoadingView {
7
+
8
+ private spinnerView: UIView
9
+ private isPulsing: boolean = NO
10
+ private _theme: "light" | "dark" = "light"
11
+
12
+ override set loading(loading: boolean) {
13
+ // cannot set loading on loading view
14
+ }
15
+
16
+ override get loading() {
17
+ return NO
18
+ }
19
+
20
+ /**
21
+ * Sets the visual theme of the loader.
22
+ * 'light' (default): Suitable for light backgrounds. Dark spinner, white-ish overlay.
23
+ * 'dark': Suitable for dark backgrounds. Light spinner, black-ish overlay.
24
+ */
25
+ set theme(theme: "light" | "dark") {
26
+ this._theme = theme
27
+ this.updateColors()
28
+ }
29
+
30
+ get theme() {
31
+ return this._theme
32
+ }
33
+
34
+ constructor(elementID?: string) {
35
+ super(elementID)
36
+
37
+ // 1. Initialize Spinner (Custom Bootstrap-like implementation)
38
+ this.spinnerView = new UIView(this.elementID + "_Spinner")
39
+ this.spinnerView.addStyleClass("UILoadingViewSpinnerContainer")
40
+ this.addSubview(this.spinnerView);
41
+
42
+ // 2. Configure defaults
43
+ (this as UILoadingView).configureWithObject({
44
+ backgroundColor: UIColor.transparentColor,
45
+ userInteractionEnabled: YES, // Blocks touches to underlying view
46
+ pausesPointerEvents: YES, // Prevents events from passing through
47
+ style: { height: "100%", width: "100%" }
48
+ })
49
+
50
+ // 3. Initialize CSS
51
+ this.initViewStyleSelectors()
52
+ this.updateColors()
53
+ }
54
+
55
+
56
+ override initViewStyleSelectors() {
57
+ super.initViewStyleSelectors()
58
+
59
+ // 1. Pulsing Animation
60
+ const pulseKeyframe = "UILoadingViewPulse"
61
+ UIView.injectCSS(`
62
+ @keyframes ${pulseKeyframe} {
63
+ 0% { background-color: rgba(0, 0, 0, 0.15); }
64
+ 50% { background-color: rgba(0, 0, 0, 0.35); }
65
+ 100% { background-color: rgba(0, 0, 0, 0.15); }
66
+ }
67
+ `, "UILoadingViewPulseCSS")
68
+ UIView.createStyleSelector(".UILoadingViewPulsing", `animation: ${pulseKeyframe} 1.2s infinite ease-in-out;`)
69
+
70
+ // 2. Spinner Rotation (Bootstrap style)
71
+ const spinKeyframe = "UILoadingViewSpin"
72
+ UIView.injectCSS(`
73
+ @keyframes ${spinKeyframe} {
74
+ from { transform: rotate(0deg); }
75
+ to { transform: rotate(-360deg); }
76
+ }
77
+ `, "UILoadingViewSpinCSS")
78
+
79
+ // We apply the animation to the ::after pseudo-element
80
+ // to avoid conflicts with the framework's positioning on the element itself.
81
+ UIView.createStyleSelector(".UILoadingViewSpinnerContainer::after", `
82
+ content: "";
83
+ display: block;
84
+ width: 100%;
85
+ height: 100%;
86
+ border-radius: 50%;
87
+ border-style: solid;
88
+ border-width: 5px;
89
+ border-color: inherit;
90
+ border-right-color: transparent !important;
91
+ animation: ${spinKeyframe} 1.5s linear infinite;
92
+ box-sizing: border-box;
93
+ `)
94
+ }
95
+
96
+ private updateColors() {
97
+ // --- Indicator Mode Styling ---
98
+ const isLightTheme = this._theme === "light"
99
+
100
+ // Background Overlay
101
+ // Light Theme -> UI is light -> Use White overlay with high alpha
102
+ // Dark Theme -> UI is dark -> Use Black overlay with medium alpha
103
+ const overlayColor = isLightTheme
104
+ ? new UIColor("rgba(255, 255, 255, 0.7)")
105
+ : new UIColor("rgba(0, 0, 0, 0.5)")
106
+
107
+ // Spinner Color
108
+ // Light Theme -> UI is light -> Spinner should be Dark (e.g. Bootstrap text-body-emphasis #212529 or primary)
109
+ // Dark Theme -> UI is dark -> Spinner should be Light (e.g. #f8f9fa)
110
+ const spinnerColor = isLightTheme
111
+ ? new UIColor("#343a40") // Dark Grey
112
+ : new UIColor("#f8f9fa") // Light/White
113
+
114
+ if (!this.isPulsing) {
115
+ this.backgroundColor = overlayColor
116
+ }
117
+
118
+ // Apply colors to spinner borders
119
+ // We set Top, Bottom, Left. Right is forced transparent by CSS class.
120
+ this.spinnerView.style.borderTopColor = spinnerColor.stringValue
121
+ this.spinnerView.style.borderBottomColor = spinnerColor.stringValue
122
+ this.spinnerView.style.borderLeftColor = spinnerColor.stringValue
123
+
124
+ // --- Pulsing Mode Styling ---
125
+ // We could switch animations here, but simply clearing the background
126
+ // allows the CSS animation to take over if the class is active.
127
+ if (this.isPulsing) {
128
+ this.style.backgroundColor = ""
129
+ }
130
+ }
131
+
132
+
133
+ override layoutSubviews() {
134
+
135
+ super.layoutSubviews();
136
+
137
+ // 1. Always fill the parent view
138
+ (this as UILoadingView).configureWithObject({
139
+ style: { height: "100%", width: "100%" }
140
+ })
141
+
142
+ const bounds = this.bounds
143
+ const minDimension = Math.min(bounds.width, bounds.height)
144
+
145
+ // 2. Adaptive Logic
146
+ // If smaller than 40px, use pulsing. Otherwise spinner.
147
+ if (minDimension < 40) {
148
+ this.enablePulsingMode()
149
+ }
150
+ else {
151
+ this.enableIndicatorMode()
152
+ }
153
+ }
154
+
155
+ private enablePulsingMode() {
156
+ if (this.isPulsing) {
157
+ return
158
+ }
159
+
160
+ this.spinnerView.hidden = YES
161
+ this.addStyleClass("UILoadingViewPulsing")
162
+
163
+ // Clear manual background so CSS animation visible
164
+ this.style.backgroundColor = ""
165
+
166
+ this.isPulsing = YES
167
+ }
168
+
169
+ private enableIndicatorMode() {
170
+ // Remove pulsing class
171
+ this.removeStyleClass("UILoadingViewPulsing")
172
+ this.isPulsing = NO
173
+
174
+ this.spinnerView.hidden = NO
175
+
176
+ // Apply Overlay Color immediately
177
+ this.updateColors()
178
+
179
+ // Layout Spinner
180
+ // Bootstrap standard is ~2rem (32px). We can scale it slightly based on available space if we wanted,
181
+ // but a fixed "neutral" size usually looks best unless very restricted.
182
+ const spinnerSize = 32
183
+ const borderWidth = 4 // 0.25em approx
184
+
185
+ const bounds = this.bounds
186
+
187
+ // Center the spinner
188
+ const x = (bounds.width - spinnerSize) / 2
189
+ const y = (bounds.height - spinnerSize) / 2
190
+
191
+ this.spinnerView.frame = new UIRectangle(x, y, spinnerSize, spinnerSize)
192
+ this.spinnerView.style.borderWidth = borderWidth + "px"
193
+ }
194
+
195
+ }
196
+
197
+ UIView.LoadingViewClass = UILoadingView
198
+
199
+
200
+
201
+
@@ -941,8 +941,32 @@ export class UIRectangle extends UIObject {
941
941
  }
942
942
 
943
943
 
944
+ IF(condition: boolean): UIRectangleConditionalChain<UIRectangle> {
945
+ const conditionalBlock = new UIRectangleConditionalBlock<UIRectangle>(this, condition)
946
+ return conditionalBlock.getProxy()
947
+ }
948
+
949
+ // These will be intercepted by the proxy, but we define them for TypeScript
950
+ ELSE_IF(condition: boolean): UIRectangle {
951
+ return this
952
+ }
953
+
954
+ ELSE(): UIRectangle {
955
+ return this
956
+ }
957
+
958
+ ENDIF(): this
959
+ ENDIF<T, R>(performFunction: (result: T) => R): R
960
+ ENDIF<T, R>(performFunction?: (result: T) => R): R | this {
961
+ if (performFunction) {
962
+ return performFunction(this as any)
963
+ }
964
+ return this
965
+ }
966
+
967
+
944
968
  // Bounding box
945
- static boundingBoxForPoints(points: string | any[]) {
969
+ static boundingBoxForPoints(points: UIPoint[]) {
946
970
  const result = new UIRectangle()
947
971
  for (let i = 0; i < points.length; i++) {
948
972
  result.updateByAddingPoint(points[i])
@@ -950,6 +974,21 @@ export class UIRectangle extends UIObject {
950
974
  return result
951
975
  }
952
976
 
977
+ static boundingBoxForRectanglesAndPoints(rectanglesAndPoints: (UIPoint | UIRectangle)[]) {
978
+ const result = new UIRectangle()
979
+ for (let i = 0; i < rectanglesAndPoints.length; i++) {
980
+ const rectangleOrPoint = rectanglesAndPoints[i]
981
+ if (rectangleOrPoint instanceof UIRectangle) {
982
+ result.updateByAddingPoint(rectangleOrPoint.min)
983
+ result.updateByAddingPoint(rectangleOrPoint.max)
984
+ }
985
+ else {
986
+ result.updateByAddingPoint(rectangleOrPoint)
987
+ }
988
+ }
989
+ return result
990
+ }
991
+
953
992
 
954
993
  beginUpdates() {
955
994
  this._isBeingUpdated = YES
@@ -977,6 +1016,119 @@ export class UIRectangle extends UIObject {
977
1016
  }
978
1017
 
979
1018
 
1019
+ type UIRectangleConditionalChain<T> = {
1020
+ [K in keyof UIRectangle]: UIRectangle[K] extends (...args: infer Args) => infer R
1021
+ ? (...args: Args) => UIRectangleConditionalChain<T | R>
1022
+ : UIRectangle[K]
1023
+ } & {
1024
+ ELSE_IF<U>(condition: boolean): UIRectangleConditionalChain<T | U>
1025
+ ELSE<U>(): UIRectangleConditionalChain<T | U>
1026
+ ENDIF(): T
1027
+ ENDIF<R>(performFunction: (result: T) => R): R
1028
+ }
1029
+
1030
+
1031
+ class UIRectangleConditionalBlock<T> {
1032
+ private parentRectangle: UIRectangle
1033
+ private conditionMet: boolean
1034
+ private branchHasExecuted: boolean = false // Renamed for clarity
1035
+ private currentResult: any
1036
+
1037
+ constructor(rectangle: UIRectangle, condition: boolean, initialResult?: any) {
1038
+ this.parentRectangle = rectangle
1039
+ this.conditionMet = condition
1040
+ this.currentResult = initialResult ?? rectangle
1041
+ }
1042
+
1043
+ private createProxy(): UIRectangleConditionalChain<T> {
1044
+ const self = this
1045
+ return new Proxy(this.parentRectangle, {
1046
+ get(target, prop) {
1047
+ // Intercept ELSE_IF
1048
+ if (prop === 'ELSE_IF') {
1049
+ return <U>(condition: boolean): UIRectangleConditionalChain<T | U> => {
1050
+ if (!self.branchHasExecuted && !self.conditionMet) {
1051
+ self.conditionMet = condition
1052
+ }
1053
+ // Return new block that tracks the union type
1054
+ const newBlock = new UIRectangleConditionalBlock<T | U>(
1055
+ self.parentRectangle,
1056
+ self.conditionMet,
1057
+ self.currentResult
1058
+ )
1059
+ newBlock.branchHasExecuted = self.branchHasExecuted
1060
+ return newBlock.createProxy() as any
1061
+ }
1062
+ }
1063
+
1064
+ // Intercept ELSE
1065
+ if (prop === 'ELSE') {
1066
+ return <U>(): UIRectangleConditionalChain<T | U> => {
1067
+ if (!self.branchHasExecuted && !self.conditionMet) {
1068
+ self.conditionMet = true
1069
+ }
1070
+ const newBlock = new UIRectangleConditionalBlock<T | U>(
1071
+ self.parentRectangle,
1072
+ self.conditionMet,
1073
+ self.currentResult
1074
+ )
1075
+ newBlock.branchHasExecuted = self.branchHasExecuted
1076
+ return newBlock.createProxy() as any
1077
+ }
1078
+ }
1079
+
1080
+ // Intercept ENDIF with overloads
1081
+ if (prop === 'ENDIF') {
1082
+ // Return an overloaded function
1083
+ function endif(): T
1084
+ function endif<R>(performFunction: (result: T) => R): R
1085
+ function endif<R>(performFunction?: (result: T) => R): R | T {
1086
+ if (performFunction) {
1087
+ return performFunction(self.currentResult)
1088
+ }
1089
+ return self.currentResult
1090
+ }
1091
+ return endif
1092
+ }
1093
+
1094
+ // For all other methods
1095
+ const value = target[prop as keyof UIRectangle]
1096
+ if (value instanceof Function) {
1097
+ return (...args: any[]) => {
1098
+ if (self.conditionMet) {
1099
+ // Mark that this branch is executing (only on first method call)
1100
+ if (!self.branchHasExecuted) {
1101
+ self.branchHasExecuted = true
1102
+ }
1103
+
1104
+ const result = (value as Function).apply(target, args)
1105
+
1106
+ // Store the result
1107
+ self.currentResult = result
1108
+
1109
+ // If the method returns a UIRectangle, update parent reference
1110
+ if (result instanceof UIRectangle) {
1111
+ self.parentRectangle = result
1112
+ }
1113
+
1114
+ return self.createProxy()
1115
+ }
1116
+ // If condition not met, return proxy to continue chain
1117
+ return self.createProxy()
1118
+ }
1119
+ }
1120
+ return value
1121
+ }
1122
+ }) as any
1123
+ }
1124
+
1125
+ getProxy(): UIRectangleConditionalChain<T> {
1126
+ return this.createProxy()
1127
+ }
1128
+ }
1129
+
1130
+
1131
+
980
1132
 
981
1133
 
982
1134
 
@@ -35,10 +35,10 @@ export class UITextView extends UIView {
35
35
  } as const
36
36
 
37
37
  static textAlignment = {
38
- "left": "left",
38
+ "left": "flex-start",
39
39
  "center": "center",
40
- "right": "right",
41
- "justify": "justify"
40
+ "right": "flex-end",
41
+ "justify": "stretch"
42
42
  } as const
43
43
 
44
44
  //#endregion
@@ -61,7 +61,24 @@ export class UITextView extends UIView {
61
61
 
62
62
  this.textColor = this.textColor
63
63
 
64
- this.userInteractionEnabled = YES
64
+ this.userInteractionEnabled = YES;
65
+
66
+ (this as UITextView).configureWithObject({
67
+ style: {
68
+ display: "flex",
69
+ flexDirection: "column", // Ensures vertical stacking logic
70
+
71
+ // 'safe' ensures that if content overflows, it aligns to the start (top)
72
+ // instead of overflowing upwards or downwards equally.
73
+ justifyContent: "safe center",
74
+ alignItems: "flex-start", // Keeps text left-aligned (change to "center" for horizontal center)
75
+
76
+ // Optional: ensure text wraps if it gets too long
77
+ whiteSpace: "normal",
78
+ wordWrap: "break-word",
79
+ overflowWrap: "break-word"
80
+ }
81
+ })
65
82
 
66
83
  if (textViewType == UITextView.type.textArea) {
67
84
  this.pausesPointerEvents = YES
@@ -188,12 +205,11 @@ export class UITextView extends UIView {
188
205
 
189
206
  get textAlignment() {
190
207
  // @ts-ignore
191
- return this.style.textAlign
208
+ return this.style.alignItems
192
209
  }
193
210
 
194
211
  set textAlignment(textAlignment: ValueOf<typeof UITextView.textAlignment>) {
195
- this._textAlignment = textAlignment
196
- this.style.textAlign = textAlignment
212
+ this.style.alignItems = textAlignment
197
213
  }
198
214
 
199
215
  //#endregion