uicore-ts 1.1.118 → 1.1.122

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uicore-ts",
3
- "version": "1.1.118",
3
+ "version": "1.1.122",
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",
@@ -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 fontSize = parseFloat(computed.fontSize)
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: this._parseLineHeight(computed.lineHeight, fontSize),
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
- result = super.intrinsicContentHeight(constrainingWidth)
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
- result = super.intrinsicContentWidth(constrainingHeight)
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
@@ -153,6 +153,16 @@ export interface IUILoadingView extends UIView {
153
153
  }
154
154
 
155
155
 
156
+ /**
157
+ * A template literal tag to enable CSS highlighting in IDEs.
158
+ * Example: css` .myClass { color: red; } `
159
+ */
160
+ export function css(strings: TemplateStringsArray, ...values: any[]): string {
161
+ // Simply combine the strings and values to return a valid CSS string
162
+ return strings.reduce((acc, str, i) => acc + str + (values[i] ?? ''), '');
163
+ }
164
+
165
+
156
166
  export function UIComponentView(target: Function, context: ClassDecoratorContext) {
157
167
  console.log("Recording annotation UIComponentView on " + target.name)
158
168
  UIObject.recordAnnotation(UIComponentView, target)