uicore-ts 1.1.116 → 1.1.121
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/compiledScripts/UIButton.js +5 -5
- package/compiledScripts/UIButton.js.map +2 -2
- package/compiledScripts/UICore.d.ts +2 -2
- package/compiledScripts/UICore.js +2 -2
- package/compiledScripts/UICore.js.map +2 -2
- package/compiledScripts/UIDialogView.js +3 -0
- package/compiledScripts/UIDialogView.js.map +2 -2
- package/compiledScripts/UITextView.js +61 -12
- package/compiledScripts/UITextView.js.map +2 -2
- package/compiledScripts/UIView.d.ts +2 -2
- package/compiledScripts/UIView.js +6 -3
- package/compiledScripts/UIView.js.map +2 -2
- package/package.json +1 -1
- package/scripts/UIButton.ts +1 -1
- package/scripts/UICore.ts +2 -2
- package/scripts/UIDialogView.ts +4 -0
- package/scripts/UITextView.ts +86 -14
- package/scripts/UIView.ts +23 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uicore-ts",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.121",
|
|
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",
|
package/scripts/UIButton.ts
CHANGED
|
@@ -311,7 +311,7 @@ export class UIButton extends UIBaseButton {
|
|
|
311
311
|
|
|
312
312
|
let bounds = this.bounds
|
|
313
313
|
|
|
314
|
-
this.hoverText = this.titleLabel?.text ?? ""
|
|
314
|
+
this.hoverText = this.hoverText ?? this.titleLabel?.text ?? ""
|
|
315
315
|
|
|
316
316
|
// Image only if text is not present
|
|
317
317
|
if (IS_NOT(this.imageView.hidden) && !IS(this.titleLabel?.text)) {
|
package/scripts/UICore.ts
CHANGED
|
@@ -10,7 +10,7 @@ export class UICore extends UIObject {
|
|
|
10
10
|
|
|
11
11
|
rootViewController: UIViewController
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
|
|
15
15
|
static RootViewControllerClass: typeof UIViewController
|
|
16
16
|
static main: UICore
|
|
@@ -24,7 +24,7 @@ export class UICore extends UIObject {
|
|
|
24
24
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
constructor(rootDivElementID: string, rootViewControllerClass: typeof UIViewController) {
|
|
27
|
+
constructor(rootDivElementID: string, rootViewControllerClass: typeof UIViewController, public paddingLength = 20) {
|
|
28
28
|
|
|
29
29
|
super()
|
|
30
30
|
|
package/scripts/UIDialogView.ts
CHANGED
|
@@ -118,9 +118,11 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
containerView.addSubview(this)
|
|
121
|
+
this.view.setNeedsLayoutUpToRootView()
|
|
121
122
|
|
|
122
123
|
if (animated) {
|
|
123
124
|
|
|
125
|
+
UIView.layoutViewsIfNeeded()
|
|
124
126
|
this.layoutSubviews()
|
|
125
127
|
|
|
126
128
|
UIView.animateViewOrViewsWithDurationDelayAndFunction(
|
|
@@ -250,6 +252,8 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
250
252
|
|
|
251
253
|
this.view.style.zIndex = "" + this.zIndex
|
|
252
254
|
|
|
255
|
+
this.view.setNeedsLayout()
|
|
256
|
+
|
|
253
257
|
// this.view.style.maxHeight = "" + (bounds.height - margin * 2).integerValue + "px";
|
|
254
258
|
// this.view.style.maxWidth = "" + (bounds.width - margin * 2).integerValue + "px";
|
|
255
259
|
|
package/scripts/UITextView.ts
CHANGED
|
@@ -127,25 +127,47 @@ export class UITextView extends UIView {
|
|
|
127
127
|
this._intrinsicSizesCache = {}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
private _getMeasurementStyles(): TextMeasurementStyle {
|
|
130
|
+
private _getMeasurementStyles(): TextMeasurementStyle | null {
|
|
131
131
|
if (this._cachedMeasurementStyles) {
|
|
132
132
|
return this._cachedMeasurementStyles
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
// Ensure element is in document
|
|
136
|
+
if (!this.viewHTMLElement.isConnected) {
|
|
137
|
+
return null
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Force a layout flush ONCE to ensure computed styles are available
|
|
141
|
+
// This is only paid once per style change, then we use cached values
|
|
142
|
+
this.viewHTMLElement.offsetHeight
|
|
143
|
+
|
|
135
144
|
const computed = window.getComputedStyle(this.viewHTMLElement)
|
|
136
|
-
const
|
|
145
|
+
const fontSizeStr = computed.fontSize
|
|
146
|
+
const fontSize = parseFloat(fontSizeStr)
|
|
147
|
+
|
|
148
|
+
if (!fontSize || isNaN(fontSize)) {
|
|
149
|
+
return null
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const lineHeight = this._parseLineHeight(computed.lineHeight, fontSize)
|
|
153
|
+
|
|
154
|
+
if (isNaN(lineHeight)) {
|
|
155
|
+
return null
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const font = [
|
|
159
|
+
computed.fontStyle || 'normal',
|
|
160
|
+
computed.fontVariant || 'normal',
|
|
161
|
+
computed.fontWeight || 'normal',
|
|
162
|
+
fontSize + 'px',
|
|
163
|
+
computed.fontFamily || 'sans-serif'
|
|
164
|
+
].join(" ")
|
|
137
165
|
|
|
138
166
|
this._cachedMeasurementStyles = {
|
|
139
|
-
font:
|
|
140
|
-
computed.fontStyle,
|
|
141
|
-
computed.fontVariant,
|
|
142
|
-
computed.fontWeight,
|
|
143
|
-
computed.fontSize,
|
|
144
|
-
computed.fontFamily
|
|
145
|
-
].join(" "),
|
|
167
|
+
font: font,
|
|
146
168
|
fontSize: fontSize,
|
|
147
|
-
lineHeight:
|
|
148
|
-
whiteSpace: computed.whiteSpace,
|
|
169
|
+
lineHeight: lineHeight,
|
|
170
|
+
whiteSpace: computed.whiteSpace || 'normal',
|
|
149
171
|
paddingLeft: parseFloat(computed.paddingLeft) || 0,
|
|
150
172
|
paddingRight: parseFloat(computed.paddingRight) || 0,
|
|
151
173
|
paddingTop: parseFloat(computed.paddingTop) || 0,
|
|
@@ -491,7 +513,7 @@ export class UITextView extends UIView {
|
|
|
491
513
|
_intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any
|
|
492
514
|
|
|
493
515
|
private _useFastMeasurement: boolean | undefined
|
|
494
|
-
private _cachedMeasurementStyles: TextMeasurementStyle | undefined
|
|
516
|
+
private _cachedMeasurementStyles: TextMeasurementStyle | undefined | null
|
|
495
517
|
|
|
496
518
|
override usesVirtualLayoutingForIntrinsicSizing = NO
|
|
497
519
|
|
|
@@ -513,7 +535,32 @@ export class UITextView extends UIView {
|
|
|
513
535
|
var result = cacheObject.valueForKeyPath(keyPath)
|
|
514
536
|
|
|
515
537
|
if (IS_LIKE_NULL(result)) {
|
|
516
|
-
|
|
538
|
+
// Determine if we should use fast measurement
|
|
539
|
+
const shouldUseFastPath = this._useFastMeasurement ?? this._shouldUseFastMeasurement()
|
|
540
|
+
|
|
541
|
+
if (shouldUseFastPath) {
|
|
542
|
+
// Fast path: use UITextMeasurement with pre-extracted styles
|
|
543
|
+
const styles = this._getMeasurementStyles()
|
|
544
|
+
|
|
545
|
+
// If styles are invalid (element not properly initialized), fall back to DOM
|
|
546
|
+
if (styles) {
|
|
547
|
+
const size = UITextMeasurement.calculateTextSize(
|
|
548
|
+
this.viewHTMLElement,
|
|
549
|
+
this.text || this.innerHTML,
|
|
550
|
+
constrainingWidth || undefined,
|
|
551
|
+
undefined,
|
|
552
|
+
styles
|
|
553
|
+
)
|
|
554
|
+
result = size.height
|
|
555
|
+
} else {
|
|
556
|
+
// Styles not ready, use DOM measurement
|
|
557
|
+
result = super.intrinsicContentHeight(constrainingWidth)
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
// Fallback: DOM-based measurement for complex content
|
|
561
|
+
result = super.intrinsicContentHeight(constrainingWidth)
|
|
562
|
+
}
|
|
563
|
+
|
|
517
564
|
cacheObject.setValueForKeyPath(keyPath, result)
|
|
518
565
|
}
|
|
519
566
|
|
|
@@ -539,7 +586,32 @@ export class UITextView extends UIView {
|
|
|
539
586
|
var result = cacheObject.valueForKeyPath(keyPath)
|
|
540
587
|
|
|
541
588
|
if (IS_LIKE_NULL(result)) {
|
|
542
|
-
|
|
589
|
+
// Determine if we should use fast measurement
|
|
590
|
+
const shouldUseFastPath = this._useFastMeasurement ?? this._shouldUseFastMeasurement()
|
|
591
|
+
|
|
592
|
+
if (shouldUseFastPath) {
|
|
593
|
+
// Fast path: use UITextMeasurement with pre-extracted styles
|
|
594
|
+
const styles = this._getMeasurementStyles()
|
|
595
|
+
|
|
596
|
+
// If styles are invalid (element not properly initialized), fall back to DOM
|
|
597
|
+
if (styles) {
|
|
598
|
+
const size = UITextMeasurement.calculateTextSize(
|
|
599
|
+
this.viewHTMLElement,
|
|
600
|
+
this.text || this.innerHTML,
|
|
601
|
+
undefined,
|
|
602
|
+
constrainingHeight || undefined,
|
|
603
|
+
styles
|
|
604
|
+
)
|
|
605
|
+
result = size.width
|
|
606
|
+
} else {
|
|
607
|
+
// Styles not ready, use DOM measurement
|
|
608
|
+
result = super.intrinsicContentWidth(constrainingHeight)
|
|
609
|
+
}
|
|
610
|
+
} else {
|
|
611
|
+
// Fallback: DOM-based measurement for complex content
|
|
612
|
+
result = super.intrinsicContentWidth(constrainingHeight)
|
|
613
|
+
}
|
|
614
|
+
|
|
543
615
|
cacheObject.setValueForKeyPath(keyPath, result)
|
|
544
616
|
}
|
|
545
617
|
|
package/scripts/UIView.ts
CHANGED
|
@@ -5,7 +5,21 @@ import { UICore } from "./UICore"
|
|
|
5
5
|
import "./UICoreExtensions"
|
|
6
6
|
import type { UIDialogView } from "./UIDialogView"
|
|
7
7
|
import { UILocalizedTextObject } from "./UIInterfaces"
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
FIRST,
|
|
10
|
+
FIRST_OR_NIL,
|
|
11
|
+
IF,
|
|
12
|
+
IS,
|
|
13
|
+
IS_DEFINED,
|
|
14
|
+
IS_NIL,
|
|
15
|
+
IS_NOT,
|
|
16
|
+
IS_NOT_LIKE_NULL,
|
|
17
|
+
nil,
|
|
18
|
+
NO,
|
|
19
|
+
RETURNER,
|
|
20
|
+
UIObject,
|
|
21
|
+
YES
|
|
22
|
+
} from "./UIObject"
|
|
9
23
|
import { UIPoint } from "./UIPoint"
|
|
10
24
|
import { UIRectangle } from "./UIRectangle"
|
|
11
25
|
import { UIViewController } from "./UIViewController"
|
|
@@ -642,13 +656,17 @@ export class UIView extends UIObject {
|
|
|
642
656
|
}
|
|
643
657
|
|
|
644
658
|
|
|
645
|
-
set hoverText(hoverText: string) {
|
|
646
|
-
|
|
659
|
+
set hoverText(hoverText: string | undefined | null) {
|
|
660
|
+
if (IS_NOT_LIKE_NULL(hoverText)) {
|
|
661
|
+
this.viewHTMLElement.setAttribute("title", hoverText)
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
this.viewHTMLElement.removeAttribute("title")
|
|
665
|
+
}
|
|
647
666
|
}
|
|
648
667
|
|
|
649
|
-
|
|
650
668
|
get hoverText() {
|
|
651
|
-
return this.viewHTMLElement.getAttribute("title")
|
|
669
|
+
return this.viewHTMLElement.getAttribute("title")
|
|
652
670
|
}
|
|
653
671
|
|
|
654
672
|
|