uicore-ts 1.1.218 → 1.1.225

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.
@@ -76,6 +76,12 @@ export declare class UITextView extends UIView {
76
76
  notificationAmountDidChange(notificationAmount: number): void;
77
77
  get text(): string;
78
78
  set text(text: string);
79
+ /**
80
+ * Formats a raw number string by inserting `separator` every three digits
81
+ * in the integer part. Handles negative numbers and decimals (machine locale
82
+ * "." as decimal point). Non-numeric strings are returned unchanged.
83
+ */
84
+ static applyThousandsSeparatorToNumericalString(value: string, separator: string): string;
79
85
  set innerHTML(innerHTML: string);
80
86
  get innerHTML(): string;
81
87
  setText(key: string, defaultString: string, parameters?: {
@@ -99,6 +105,9 @@ export declare class UITextView extends UIView {
99
105
  textPrefix: string;
100
106
  textSuffix: string;
101
107
  _notificationAmount: number;
108
+ _thousandsSeparator: string | null;
109
+ get thousandsSeparator(): string | null;
110
+ set thousandsSeparator(value: string | null);
102
111
  _textColor: UIColor;
103
112
  _textAlignment?: ValueOf<typeof UITextView.textAlignment>;
104
113
  _isSingleLine: boolean;
@@ -34,6 +34,7 @@ const _UITextView = class extends import_UIView.UIView {
34
34
  this.textPrefix = "";
35
35
  this.textSuffix = "";
36
36
  this._notificationAmount = 0;
37
+ this._thousandsSeparator = null;
37
38
  this._textColor = _UITextView.defaultTextColor;
38
39
  this._isSingleLine = import_UIObject.YES;
39
40
  this._automaticFontSizeSelection = import_UIObject.NO;
@@ -142,7 +143,6 @@ const _UITextView = class extends import_UIView.UIView {
142
143
  const computed = window.getComputedStyle(this.textElementView.viewHTMLElement);
143
144
  const fontSizeStr = computed.fontSize;
144
145
  const fontSize = parseFloat(fontSizeStr);
145
- console.log(computed.letterSpacing);
146
146
  if (!fontSize || isNaN(fontSize)) {
147
147
  return null;
148
148
  }
@@ -268,9 +268,10 @@ const _UITextView = class extends import_UIView.UIView {
268
268
  if (this.notificationAmount) {
269
269
  notificationText = '<span style="color: ' + _UITextView.notificationTextColor.stringValue + ';">' + (" (" + this.notificationAmount + ")").bold() + "</span>";
270
270
  }
271
- if (this.textElementView.viewHTMLElement.innerHTML != this.textPrefix + text + this.textSuffix + notificationText) {
271
+ const displayText = this.thousandsSeparator !== null ? _UITextView.applyThousandsSeparatorToNumericalString(text, this.thousandsSeparator) : text;
272
+ if (this.textElementView.viewHTMLElement.innerHTML != this.textPrefix + displayText + this.textSuffix + notificationText) {
272
273
  this.textElementView.viewHTMLElement.innerHTML = this.textPrefix + (0, import_UIObject.FIRST)(
273
- text,
274
+ displayText,
274
275
  ""
275
276
  ) + this.textSuffix + notificationText;
276
277
  }
@@ -285,6 +286,30 @@ const _UITextView = class extends import_UIView.UIView {
285
286
  this.clearIntrinsicSizeCache();
286
287
  this.setNeedsLayout();
287
288
  }
289
+ static applyThousandsSeparatorToNumericalString(value, separator) {
290
+ const trimmed = (value || "").trim();
291
+ if (trimmed === "") {
292
+ return value;
293
+ }
294
+ const parts = trimmed.split(".");
295
+ const integerPart = parts[0];
296
+ const decimalPart = parts.length > 1 ? parts[1] : null;
297
+ if (!/^-?\d+$/.test(integerPart)) {
298
+ return value;
299
+ }
300
+ const isNegative = integerPart.startsWith("-");
301
+ const digits = isNegative ? integerPart.slice(1) : integerPart;
302
+ let formatted = "";
303
+ const offset = digits.length % 3;
304
+ for (let index = 0; index < digits.length; index++) {
305
+ if (index > 0 && (index - offset) % 3 === 0) {
306
+ formatted += separator;
307
+ }
308
+ formatted += digits[index];
309
+ }
310
+ const result = (isNegative ? "-" : "") + formatted;
311
+ return decimalPart !== null ? result + "." + decimalPart : result;
312
+ }
288
313
  set innerHTML(innerHTML) {
289
314
  this.text = innerHTML;
290
315
  this.invalidateMeasurementStrategy();
@@ -371,6 +396,12 @@ const _UITextView = class extends import_UIView.UIView {
371
396
  }
372
397
  return maxFittingFontSize;
373
398
  }
399
+ get thousandsSeparator() {
400
+ return this._thousandsSeparator;
401
+ }
402
+ set thousandsSeparator(value) {
403
+ this._thousandsSeparator = value;
404
+ }
374
405
  addStyleClass(styleClass) {
375
406
  super.addStyleClass(styleClass);
376
407
  this._invalidateFontCache();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../scripts/UITextView.ts"],
4
- "sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UILocalizedTextObject } from \"./UIInterfaces\"\nimport { EXTEND, FIRST, IS_LIKE_NULL, nil, NO, UIObject, ValueOf, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { TextMeasurementStyle, UITextMeasurement } from \"./UITextMeasurement\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextView extends UIView {\n \n //#region Static Properties\n \n static defaultTextColor = UIColor.blackColor\n static notificationTextColor = UIColor.redColor\n \n // Global caches for all UILabels\n static _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n static _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n static _ptToPx: number\n static _pxToPt: number\n \n static type = {\n \"paragraph\": \"p\",\n \"header1\": \"h1\",\n \"header2\": \"h2\",\n \"header3\": \"h3\",\n \"header4\": \"h4\",\n \"header5\": \"h5\",\n \"header6\": \"h6\",\n \"textArea\": \"textarea\",\n \"textField\": \"input\",\n \"span\": \"span\",\n \"label\": \"label\"\n } as const\n \n static textAlignment = {\n \"left\": \"left\",\n \"center\": \"center\",\n \"right\": \"right\",\n \"justify\": \"justify\"\n } as const\n \n //#endregion\n \n //#region Constructor\n \n \n constructor(\n elementID?: string,\n textViewType: string | ValueOf<typeof UITextView.type> = UITextView.type.paragraph,\n viewHTMLElement = null\n ) {\n \n // Create inner text element as a UIView\n const innerElementID = elementID ? `${elementID}_textElement` : undefined\n const _textElementView = new UIView(innerElementID, null, textViewType)\n \n // Create outer container (wrapper) - this is the main viewHTMLElement\n super(elementID, viewHTMLElement, \"span\", { _textElementView })\n \n // Configure outer container for vertical centering using direct property access\n \n this.configureWithObject({\n // @ts-ignore\n viewHTMLElement: {\n style: {\n display: \"flex\",\n alignItems: \"center\", // Vertical centering\n overflow: \"hidden\"\n }\n }\n })\n \n this.text = \"\"\n \n this._textElementView = _textElementView\n \n // Configure inner text element for ellipsis and positioning\n this._textElementView.configureWithObject({\n style: {\n position: \"relative\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n width: \"100%\",\n margin: \"0\",\n padding: \"0\"\n },\n // Forward control events from text element to the container\n sendControlEventForKey: EXTEND(this.sendControlEventForKey.bind(this))\n })\n \n // Add text element as a subview\n this.addSubview(this._textElementView)\n \n \n this.isSingleLine = YES\n \n this.textColor = this.textColor\n \n this.userInteractionEnabled = YES\n \n if (textViewType == UITextView.type.textArea) {\n this.pausesPointerEvents = YES\n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n }\n }\n \n //#endregion\n \n //#region Text Element View Property\n \n private _textElementView: UIView\n \n /**\n * The inner text element that holds the actual text content\n */\n get textElementView(): UIView {\n return this._textElementView\n }\n \n /**\n * Override style to apply to the text element instead of the container\n */\n // override get style() {\n // return this._textElementView.style\n // }\n //\n // /**\n // * Override computedStyle to get computed styles from the text element\n // */\n // override get computedStyle() {\n // return this._textElementView.computedStyle\n // }\n \n /**\n * Access the outer container's style (for positioning, layout, etc.)\n */\n get containerStyle() {\n return this.viewHTMLElement.style\n }\n \n /**\n * Override styleClasses to apply to the text element\n */\n override get styleClasses() {\n return this._textElementView.styleClasses\n }\n \n override set styleClasses(styleClasses: string[]) {\n this._textElementView.styleClasses = styleClasses\n }\n \n //#endregion\n \n //#region Lifecycle Methods\n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n super.didReceiveBroadcastEvent(event)\n }\n \n override willMoveToSuperview(superview: UIView) {\n super.willMoveToSuperview(superview)\n }\n \n override documentFontsDidLoad() {\n super.documentFontsDidLoad()\n this._invalidateFontCache()\n this.invalidateMeasurementStrategy()\n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n UITextView._intrinsicHeightCache = new UIObject() as any\n UITextView._intrinsicWidthCache = new UIObject() as any\n }\n \n override layoutSubviews() {\n super.layoutSubviews()\n \n if (this._automaticFontSizeSelection) {\n this.fontSize = UITextView.automaticallyCalculatedFontSize(\n new UIRectangle(\n 0,\n 0,\n this.textElementView.viewHTMLElement.offsetHeight,\n this.textElementView.viewHTMLElement.offsetWidth\n ),\n this.intrinsicContentSize(),\n this.fontSize,\n this._minFontSize,\n this._maxFontSize\n )\n }\n }\n \n //#endregion\n \n //#region Measurement & Sizing - Private Methods\n \n private _invalidateMeasurementStyles(): void {\n this._cachedMeasurementStyles = undefined\n UITextMeasurement.invalidateElement(this.textElementView.viewHTMLElement)\n this._intrinsicSizesCache = {}\n }\n \n private _getMeasurementStyles(): TextMeasurementStyle | null {\n if (this._cachedMeasurementStyles) {\n return this._cachedMeasurementStyles\n }\n \n // Ensure element is in document\n if (!this.textElementView.viewHTMLElement.isConnected) {\n return null\n }\n \n // Force a layout flush ONCE to ensure computed styles are available\n // This is only paid once per style change, then we use cached values\n this.textElementView.viewHTMLElement.offsetHeight\n \n const computed = window.getComputedStyle(this.textElementView.viewHTMLElement)\n const fontSizeStr = computed.fontSize\n const fontSize = parseFloat(fontSizeStr)\n \n console.log(computed.letterSpacing)\n \n if (!fontSize || isNaN(fontSize)) {\n return null\n }\n \n const lineHeight = this._parseLineHeight(computed.lineHeight, fontSize)\n \n if (isNaN(lineHeight)) {\n return null\n }\n \n const font = [\n computed.fontStyle || \"normal\",\n computed.fontVariant || \"normal\",\n computed.fontWeight || \"normal\",\n fontSize + \"px\",\n computed.fontFamily || \"sans-serif\"\n ].join(\" \")\n \n this._cachedMeasurementStyles = {\n font: font,\n fontSize: fontSize,\n lineHeight: lineHeight,\n whiteSpace: computed.whiteSpace || \"normal\",\n paddingLeft: parseFloat(computed.paddingLeft) || 0,\n paddingRight: parseFloat(computed.paddingRight) || 0,\n paddingTop: parseFloat(computed.paddingTop) || 0,\n paddingBottom: parseFloat(computed.paddingBottom) || 0,\n letterSpacing: parseFloat(computed.letterSpacing) || 0,\n textTransform: computed.textTransform || \"none\"\n }\n \n return this._cachedMeasurementStyles\n }\n \n private _parseLineHeight(lineHeight: string, fontSize: number): number {\n if (lineHeight === \"normal\") {\n return fontSize * 1.2\n }\n if (lineHeight.endsWith(\"px\")) {\n return parseFloat(lineHeight)\n }\n const numericLineHeight = parseFloat(lineHeight)\n if (!isNaN(numericLineHeight)) {\n return fontSize * numericLineHeight\n }\n return fontSize * 1.2\n }\n \n private _shouldUseFastMeasurement(): boolean {\n const content = this.text || this.textElementView.innerHTML\n \n if (this._innerHTMLKey || this._localizedTextObject) {\n return false\n }\n \n if (this.notificationAmount > 0) {\n return false\n }\n \n const hasComplexHTML = /<(?!\\/?(b|i|em|strong|span|br)\\b)[^>]+>/i.test(content)\n \n if (hasComplexHTML) {\n return false\n }\n \n // Canvas measureText silently falls back to the system font when the\n // custom font hasn't been loaded into the canvas font system yet, even\n // if getComputedStyle already reports the correct font family. Guard\n // against this by checking the font is confirmed available before\n // trusting canvas-based measurement.\n const styles = this._getMeasurementStyles()\n if (styles && !document.fonts.check(styles.font)) {\n return false\n }\n \n return true\n }\n \n //#endregion\n \n //#region Measurement & Sizing - Public Methods\n \n setUseFastMeasurement(useFast: boolean): void {\n this._useFastMeasurement = useFast\n this._intrinsicSizesCache = {}\n }\n \n invalidateMeasurementStrategy(): void {\n this._useFastMeasurement = undefined\n this._invalidateMeasurementStyles()\n }\n \n //#endregion\n \n //#region Getters & Setters - Text Alignment\n \n get textAlignment() {\n return this._textElementView.style.textAlign as ValueOf<typeof UITextView.textAlignment>\n }\n \n set textAlignment(textAlignment: ValueOf<typeof UITextView.textAlignment>) {\n this._textAlignment = textAlignment\n this._textElementView.style.textAlign = textAlignment\n }\n \n //#endregion\n \n //#region Getters & Setters - Text Color\n \n get textColor() {\n return this._textColor\n }\n \n set textColor(color: UIColor) {\n this._textColor = color || UITextView.defaultTextColor\n this._textElementView.style.color = this._textColor.stringValue\n }\n \n //#endregion\n \n //#region Getters & Setters - Single Line\n \n get isSingleLine() {\n return this._isSingleLine\n }\n \n set isSingleLine(isSingleLine: boolean) {\n this._isSingleLine = isSingleLine\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n \n if (isSingleLine) {\n // Single line: use nowrap with ellipsis\n this._textElementView.style.whiteSpace = \"nowrap\"\n this._textElementView.style.textOverflow = \"ellipsis\"\n this._textElementView.style.display = \"\"\n this._textElementView.style.webkitLineClamp = \"\"\n this._textElementView.style.webkitBoxOrient = \"\"\n return\n }\n \n // Multiline: allow wrapping, but still show ellipsis if content overflows the container\n // This uses the -webkit-line-clamp approach which works for multiline ellipsis\n this._textElementView.style.whiteSpace = \"normal\"\n this._textElementView.style.textOverflow = \"ellipsis\"\n this._textElementView.style.display = \"-webkit-box\"\n this._textElementView.style.webkitBoxOrient = \"vertical\"\n // Don't set line-clamp to a specific number - let it fill available space\n // The overflow: hidden from the constructor will clip content that exceeds the height\n this.invalidateMeasurementStrategy()\n }\n \n //#endregion\n \n //#region Getters & Setters - Notification Amount\n \n get notificationAmount() {\n return this._notificationAmount\n }\n \n set notificationAmount(notificationAmount: number) {\n if (this._notificationAmount == notificationAmount) {\n return\n }\n \n this._notificationAmount = notificationAmount\n this.text = this.text\n this.setNeedsLayoutUpToRootView()\n this.notificationAmountDidChange(notificationAmount)\n }\n \n notificationAmountDidChange(notificationAmount: number) {\n }\n \n //#endregion\n \n //#region Getters & Setters - Text Content\n \n get text() {\n return (this._text || this.textElementView.viewHTMLElement.innerHTML)\n }\n \n set text(text) {\n this._text = text\n var notificationText = \"\"\n if (this.notificationAmount) {\n notificationText = \"<span style=\\\"color: \" + UITextView.notificationTextColor.stringValue + \";\\\">\" +\n (\" (\" + this.notificationAmount + \")\").bold() + \"</span>\"\n }\n \n if (this.textElementView.viewHTMLElement.innerHTML != this.textPrefix + text + this.textSuffix + notificationText) {\n this.textElementView.viewHTMLElement.innerHTML = this.textPrefix + FIRST(\n text, \"\") + this.textSuffix + notificationText\n }\n \n if (this.changesOften) {\n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n }\n \n this._useFastMeasurement = undefined\n this._intrinsicSizesCache = {}\n this.invalidateMeasurementStrategy()\n this._invalidateMeasurementStyles()\n this.clearIntrinsicSizeCache()\n \n this.setNeedsLayout()\n }\n \n override set innerHTML(innerHTML: string) {\n this.text = innerHTML\n this.invalidateMeasurementStrategy()\n }\n \n override get innerHTML() {\n return this.viewHTMLElement.innerHTML\n }\n \n setText(key: string, defaultString: string, parameters?: { [x: string]: string | UILocalizedTextObject }) {\n this.textElementView.setInnerHTML(key, defaultString, parameters)\n this.invalidateMeasurementStrategy()\n }\n \n //#endregion\n \n //#region Getters & Setters - Font Size\n \n get fontSize() {\n const style = this._textElementView.style.fontSize || window.getComputedStyle(this._textElementView.viewHTMLElement, null).fontSize\n const result = (parseFloat(style) * UITextView._pxToPt)\n return result\n }\n \n set fontSize(fontSize: number) {\n if (fontSize != this.fontSize) {\n this._textElementView.style.fontSize = \"\" + fontSize + \"pt\"\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n \n this._invalidateFontCache()\n this._invalidateMeasurementStyles()\n this.clearIntrinsicSizeCache()\n }\n }\n \n useAutomaticFontSize(minFontSize: number = nil, maxFontSize: number = nil) {\n this._automaticFontSizeSelection = YES\n this._minFontSize = minFontSize\n this._maxFontSize = maxFontSize\n this.setNeedsLayout()\n }\n \n //#endregion\n \n //#region Font Caching - Private Methods\n \n /**\n * Get a stable cache key for the font without triggering reflow.\n * Only computes font on first access or when font properties change.\n */\n private _getFontCacheKey(): string {\n // Check if font-related properties have changed\n const currentTriggers = {\n fontSize: this._textElementView.style.fontSize || \"\",\n fontFamily: this._textElementView.style.fontFamily || \"\",\n fontWeight: this._textElementView.style.fontWeight || \"\",\n fontStyle: this._textElementView.style.fontStyle || \"\",\n styleClasses: this.styleClasses.join(\",\")\n }\n \n const hasChanged =\n currentTriggers.fontSize !== this._fontInvalidationTriggers.fontSize ||\n currentTriggers.fontFamily !== this._fontInvalidationTriggers.fontFamily ||\n currentTriggers.fontWeight !== this._fontInvalidationTriggers.fontWeight ||\n currentTriggers.fontStyle !== this._fontInvalidationTriggers.fontStyle ||\n currentTriggers.styleClasses !== this._fontInvalidationTriggers.styleClasses\n \n if (!this._cachedFontKey || hasChanged) {\n // Only access computedStyle when we know something changed\n const computed = this._textElementView.computedStyle\n this._cachedFontKey = [\n computed.fontStyle,\n computed.fontVariant,\n computed.fontWeight,\n computed.fontSize,\n computed.fontFamily\n ].join(\"_\").replace(/[.\\s]/g, \"_\")\n \n this._fontInvalidationTriggers = currentTriggers\n }\n \n return this._cachedFontKey\n }\n \n /**\n * Invalidate font cache when font properties change\n */\n private _invalidateFontCache(): void {\n this._cachedFontKey = undefined\n }\n \n //#endregion\n \n //#region Static Methods\n \n static _determinePXAndPTRatios() {\n if (UITextView._ptToPx) {\n return\n }\n \n const o = document.createElement(\"div\")\n o.style.width = \"1000pt\"\n document.body.appendChild(o)\n UITextView._ptToPx = o.clientWidth / 1000\n document.body.removeChild(o)\n UITextView._pxToPt = 1 / UITextView._ptToPx\n }\n \n static automaticallyCalculatedFontSize(\n bounds: UIRectangle,\n currentSize: UIRectangle,\n currentFontSize: number,\n minFontSize?: number,\n maxFontSize?: number\n ) {\n minFontSize = FIRST(minFontSize, 1)\n maxFontSize = FIRST(maxFontSize, 100000000000)\n \n const heightMultiplier = bounds.height / (currentSize.height + 1)\n const widthMultiplier = bounds.width / (currentSize.width + 1)\n \n var multiplier = heightMultiplier\n if (heightMultiplier > widthMultiplier) {\n multiplier = widthMultiplier\n }\n \n const maxFittingFontSize = currentFontSize * multiplier\n \n if (maxFittingFontSize > maxFontSize) {\n return maxFontSize\n }\n \n if (minFontSize > maxFittingFontSize) {\n return minFontSize\n }\n \n return maxFittingFontSize\n }\n \n //#endregion\n \n //#region Instance Properties - Text Content\n \n _text?: string\n textPrefix = \"\"\n textSuffix = \"\"\n _notificationAmount = 0\n \n //#endregion\n \n //#region Instance Properties - Styling\n \n _textColor: UIColor = UITextView.defaultTextColor\n _textAlignment?: ValueOf<typeof UITextView.textAlignment>\n _isSingleLine = YES\n \n //#endregion\n \n //#region Instance Properties - Font & Sizing\n \n _minFontSize?: number\n _maxFontSize?: number\n _automaticFontSizeSelection = NO\n \n // Cache for the computed font string\n private _cachedFontKey?: string\n private _fontInvalidationTriggers = {\n fontSize: \"\",\n fontFamily: \"\",\n fontWeight: \"\",\n fontStyle: \"\",\n styleClasses: \"\"\n }\n \n //#endregion\n \n //#region Instance Properties - Caching & Performance\n \n changesOften = NO\n \n // Local cache for this instance if the label changes often\n _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n private _useFastMeasurement: boolean | undefined\n private _cachedMeasurementStyles: TextMeasurementStyle | undefined | null\n \n override usesVirtualLayoutingForIntrinsicSizing = NO\n \n //#endregion\n \n // Override addStyleClass to invalidate font cache\n override addStyleClass(styleClass: string) {\n super.addStyleClass(styleClass)\n this._invalidateFontCache()\n }\n \n // Override removeStyleClass to invalidate font cache\n override removeStyleClass(styleClass: string) {\n super.removeStyleClass(styleClass)\n this._invalidateFontCache()\n }\n \n // Override focus to focus the text element\n override focus() {\n this._textElementView.focus()\n }\n \n // Override blur to blur the text element\n override blur() {\n this._textElementView.blur()\n }\n \n override intrinsicContentHeight(constrainingWidth = 0) {\n \n const keyPath = ((this.textElementView.viewHTMLElement.innerHTML || this.text) + \"_csf_\" + this._getFontCacheKey()) + \".\" +\n (\"\" + constrainingWidth).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicHeightCache\n \n if (this.changesOften) {\n cacheObject = this._intrinsicHeightCache\n }\n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n if (IS_LIKE_NULL(result)) {\n // Determine if we should use fast measurement\n const shouldUseFastPath = this._useFastMeasurement ?? this._shouldUseFastMeasurement()\n \n if (shouldUseFastPath) {\n // Fast path: use UITextMeasurement with pre-extracted styles\n const styles = this._getMeasurementStyles()\n \n // If styles are invalid (element not properly initialized), fall back to DOM\n if (styles) {\n const size = UITextMeasurement.calculateTextSize(\n this.textElementView.viewHTMLElement,\n this.text || this.textElementView.innerHTML,\n constrainingWidth || undefined,\n undefined,\n styles\n )\n result = size.height\n }\n else {\n // Styles not ready, use DOM measurement\n result = super.intrinsicContentHeight(constrainingWidth)\n }\n }\n else {\n // Fallback: DOM-based measurement for complex content\n result = super.intrinsicContentHeight(constrainingWidth)\n }\n \n cacheObject.setValueForKeyPath(keyPath, result)\n }\n \n if (isNaN(result) || (!result && !this.text)) {\n result = super.intrinsicContentHeight(constrainingWidth)\n cacheObject.setValueForKeyPath(keyPath, result)\n }\n \n return result\n }\n \n override intrinsicContentWidth(constrainingHeight = 0) {\n \n const keyPath = ((this.textElementView.viewHTMLElement.innerHTML || this.text) + \"_csf_\" + this._getFontCacheKey()) + \".\" +\n (\"\" + constrainingHeight).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicWidthCache\n \n if (this.changesOften) {\n cacheObject = this._intrinsicWidthCache\n }\n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n if (IS_LIKE_NULL(result)) {\n // Determine if we should use fast measurement\n const shouldUseFastPath = this._useFastMeasurement ?? this._shouldUseFastMeasurement()\n \n if (shouldUseFastPath) {\n // Fast path: use UITextMeasurement with pre-extracted styles\n const styles = this._getMeasurementStyles()\n \n // If styles are invalid (element not properly initialized), fall back to DOM\n if (styles) {\n const size = UITextMeasurement.calculateTextSize(\n this.textElementView.viewHTMLElement,\n this.text || this.textElementView.innerHTML,\n undefined,\n constrainingHeight || undefined,\n styles\n )\n result = size.width\n }\n else {\n // Styles not ready, use DOM measurement\n result = super.intrinsicContentWidth(constrainingHeight)\n }\n }\n else {\n // Fallback: DOM-based measurement for complex content\n result = super.intrinsicContentWidth(constrainingHeight)\n }\n \n cacheObject.setValueForKeyPath(keyPath, result)\n }\n \n return result\n }\n \n \n override intrinsicContentSizeWithConstraints(constrainingHeight: number = 0, constrainingWidth: number = 0) {\n \n const cacheKey = this._getIntrinsicSizeCacheKey(constrainingHeight, constrainingWidth)\n const cachedResult = this._getCachedIntrinsicSize(cacheKey)\n if (cachedResult) {\n return cachedResult\n }\n \n // UITextView needs to measure the text element, not the outer container\n const result = new UIRectangle(0, 0, 0, 0)\n if (this.rootView.forceIntrinsicSizeZero) {\n return result\n }\n \n let temporarilyInViewTree = NO\n let nodeAboveThisView: Node | null = null\n if (!this.isMemberOfViewTree) {\n document.body.appendChild(this.viewHTMLElement)\n temporarilyInViewTree = YES\n nodeAboveThisView = this.viewHTMLElement.nextSibling\n }\n \n // Save and clear styles on the TEXT ELEMENT (not the container)\n const height = this._textElementView.style.height\n const width = this._textElementView.style.width\n \n this._textElementView.style.height = \"\" + constrainingHeight\n this._textElementView.style.width = \"\" + constrainingWidth\n \n const left = this._textElementView.style.left\n const right = this._textElementView.style.right\n const bottom = this._textElementView.style.bottom\n const top = this._textElementView.style.top\n \n this._textElementView.style.left = \"\"\n this._textElementView.style.right = \"\"\n this._textElementView.style.bottom = \"\"\n this._textElementView.style.top = \"\"\n \n // Measure height with the text element\n const resultHeight = this._textElementView.viewHTMLElement.scrollHeight\n \n // Measure width by temporarily setting nowrap\n const whiteSpace = this._textElementView.style.whiteSpace\n this._textElementView.style.whiteSpace = \"nowrap\"\n \n const resultWidth = this._textElementView.viewHTMLElement.scrollWidth\n \n this._textElementView.style.whiteSpace = whiteSpace\n \n // Restore styles on the TEXT ELEMENT\n this._textElementView.style.height = height\n this._textElementView.style.width = width\n \n this._textElementView.style.left = left\n this._textElementView.style.right = right\n this._textElementView.style.bottom = bottom\n this._textElementView.style.top = top\n \n if (temporarilyInViewTree) {\n document.body.removeChild(this.viewHTMLElement)\n if (this.superview) {\n if (nodeAboveThisView) {\n this.superview.viewHTMLElement.insertBefore(this.viewHTMLElement, nodeAboveThisView)\n }\n else {\n this.superview.viewHTMLElement.appendChild(this.viewHTMLElement)\n }\n }\n }\n \n result.height = resultHeight\n result.width = resultWidth\n \n this._setCachedIntrinsicSize(cacheKey, result)\n \n return result\n }\n \n \n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UILocalizedTextObject } from \"./UIInterfaces\"\nimport { EXTEND, FIRST, IS_LIKE_NULL, nil, NO, UIObject, ValueOf, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { TextMeasurementStyle, UITextMeasurement } from \"./UITextMeasurement\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextView extends UIView {\n \n //#region Static Properties\n \n static defaultTextColor = UIColor.blackColor\n static notificationTextColor = UIColor.redColor\n \n // Global caches for all UILabels\n static _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n static _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n static _ptToPx: number\n static _pxToPt: number\n \n static type = {\n \"paragraph\": \"p\",\n \"header1\": \"h1\",\n \"header2\": \"h2\",\n \"header3\": \"h3\",\n \"header4\": \"h4\",\n \"header5\": \"h5\",\n \"header6\": \"h6\",\n \"textArea\": \"textarea\",\n \"textField\": \"input\",\n \"span\": \"span\",\n \"label\": \"label\"\n } as const\n \n static textAlignment = {\n \"left\": \"left\",\n \"center\": \"center\",\n \"right\": \"right\",\n \"justify\": \"justify\"\n } as const\n \n //#endregion\n \n //#region Constructor\n \n \n constructor(\n elementID?: string,\n textViewType: string | ValueOf<typeof UITextView.type> = UITextView.type.paragraph,\n viewHTMLElement = null\n ) {\n \n // Create inner text element as a UIView\n const innerElementID = elementID ? `${elementID}_textElement` : undefined\n const _textElementView = new UIView(innerElementID, null, textViewType)\n \n // Create outer container (wrapper) - this is the main viewHTMLElement\n super(elementID, viewHTMLElement, \"span\", { _textElementView })\n \n // Configure outer container for vertical centering using direct property access\n \n this.configureWithObject({\n // @ts-ignore\n viewHTMLElement: {\n style: {\n display: \"flex\",\n alignItems: \"center\", // Vertical centering\n overflow: \"hidden\"\n }\n }\n })\n \n this.text = \"\"\n \n this._textElementView = _textElementView\n \n // Configure inner text element for ellipsis and positioning\n this._textElementView.configureWithObject({\n style: {\n position: \"relative\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n width: \"100%\",\n margin: \"0\",\n padding: \"0\"\n },\n // Forward control events from text element to the container\n sendControlEventForKey: EXTEND(this.sendControlEventForKey.bind(this))\n })\n \n // Add text element as a subview\n this.addSubview(this._textElementView)\n \n \n this.isSingleLine = YES\n \n this.textColor = this.textColor\n \n this.userInteractionEnabled = YES\n \n if (textViewType == UITextView.type.textArea) {\n this.pausesPointerEvents = YES\n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n }\n }\n \n //#endregion\n \n //#region Text Element View Property\n \n private _textElementView: UIView\n \n /**\n * The inner text element that holds the actual text content\n */\n get textElementView(): UIView {\n return this._textElementView\n }\n \n /**\n * Override style to apply to the text element instead of the container\n */\n // override get style() {\n // return this._textElementView.style\n // }\n //\n // /**\n // * Override computedStyle to get computed styles from the text element\n // */\n // override get computedStyle() {\n // return this._textElementView.computedStyle\n // }\n \n /**\n * Access the outer container's style (for positioning, layout, etc.)\n */\n get containerStyle() {\n return this.viewHTMLElement.style\n }\n \n /**\n * Override styleClasses to apply to the text element\n */\n override get styleClasses() {\n return this._textElementView.styleClasses\n }\n \n override set styleClasses(styleClasses: string[]) {\n this._textElementView.styleClasses = styleClasses\n }\n \n //#endregion\n \n //#region Lifecycle Methods\n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n super.didReceiveBroadcastEvent(event)\n }\n \n override willMoveToSuperview(superview: UIView) {\n super.willMoveToSuperview(superview)\n }\n \n override documentFontsDidLoad() {\n super.documentFontsDidLoad()\n this._invalidateFontCache()\n this.invalidateMeasurementStrategy()\n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n UITextView._intrinsicHeightCache = new UIObject() as any\n UITextView._intrinsicWidthCache = new UIObject() as any\n }\n \n override layoutSubviews() {\n super.layoutSubviews()\n \n if (this._automaticFontSizeSelection) {\n this.fontSize = UITextView.automaticallyCalculatedFontSize(\n new UIRectangle(\n 0,\n 0,\n this.textElementView.viewHTMLElement.offsetHeight,\n this.textElementView.viewHTMLElement.offsetWidth\n ),\n this.intrinsicContentSize(),\n this.fontSize,\n this._minFontSize,\n this._maxFontSize\n )\n }\n }\n \n //#endregion\n \n //#region Measurement & Sizing - Private Methods\n \n private _invalidateMeasurementStyles(): void {\n this._cachedMeasurementStyles = undefined\n UITextMeasurement.invalidateElement(this.textElementView.viewHTMLElement)\n this._intrinsicSizesCache = {}\n }\n \n private _getMeasurementStyles(): TextMeasurementStyle | null {\n if (this._cachedMeasurementStyles) {\n return this._cachedMeasurementStyles\n }\n \n // Ensure element is in document\n if (!this.textElementView.viewHTMLElement.isConnected) {\n return null\n }\n \n // Force a layout flush ONCE to ensure computed styles are available\n // This is only paid once per style change, then we use cached values\n this.textElementView.viewHTMLElement.offsetHeight\n \n const computed = window.getComputedStyle(this.textElementView.viewHTMLElement)\n const fontSizeStr = computed.fontSize\n const fontSize = parseFloat(fontSizeStr)\n \n if (!fontSize || isNaN(fontSize)) {\n return null\n }\n \n const lineHeight = this._parseLineHeight(computed.lineHeight, fontSize)\n \n if (isNaN(lineHeight)) {\n return null\n }\n \n const font = [\n computed.fontStyle || \"normal\",\n computed.fontVariant || \"normal\",\n computed.fontWeight || \"normal\",\n fontSize + \"px\",\n computed.fontFamily || \"sans-serif\"\n ].join(\" \")\n \n this._cachedMeasurementStyles = {\n font: font,\n fontSize: fontSize,\n lineHeight: lineHeight,\n whiteSpace: computed.whiteSpace || \"normal\",\n paddingLeft: parseFloat(computed.paddingLeft) || 0,\n paddingRight: parseFloat(computed.paddingRight) || 0,\n paddingTop: parseFloat(computed.paddingTop) || 0,\n paddingBottom: parseFloat(computed.paddingBottom) || 0,\n letterSpacing: parseFloat(computed.letterSpacing) || 0,\n textTransform: computed.textTransform || \"none\"\n }\n \n return this._cachedMeasurementStyles\n }\n \n private _parseLineHeight(lineHeight: string, fontSize: number): number {\n if (lineHeight === \"normal\") {\n return fontSize * 1.2\n }\n if (lineHeight.endsWith(\"px\")) {\n return parseFloat(lineHeight)\n }\n const numericLineHeight = parseFloat(lineHeight)\n if (!isNaN(numericLineHeight)) {\n return fontSize * numericLineHeight\n }\n return fontSize * 1.2\n }\n \n private _shouldUseFastMeasurement(): boolean {\n const content = this.text || this.textElementView.innerHTML\n \n if (this._innerHTMLKey || this._localizedTextObject) {\n return false\n }\n \n if (this.notificationAmount > 0) {\n return false\n }\n \n const hasComplexHTML = /<(?!\\/?(b|i|em|strong|span|br)\\b)[^>]+>/i.test(content)\n \n if (hasComplexHTML) {\n return false\n }\n \n // Canvas measureText silently falls back to the system font when the\n // custom font hasn't been loaded into the canvas font system yet, even\n // if getComputedStyle already reports the correct font family. Guard\n // against this by checking the font is confirmed available before\n // trusting canvas-based measurement.\n const styles = this._getMeasurementStyles()\n if (styles && !document.fonts.check(styles.font)) {\n return false\n }\n \n return true\n }\n \n //#endregion\n \n //#region Measurement & Sizing - Public Methods\n \n setUseFastMeasurement(useFast: boolean): void {\n this._useFastMeasurement = useFast\n this._intrinsicSizesCache = {}\n }\n \n invalidateMeasurementStrategy(): void {\n this._useFastMeasurement = undefined\n this._invalidateMeasurementStyles()\n }\n \n //#endregion\n \n //#region Getters & Setters - Text Alignment\n \n get textAlignment() {\n return this._textElementView.style.textAlign as ValueOf<typeof UITextView.textAlignment>\n }\n \n set textAlignment(textAlignment: ValueOf<typeof UITextView.textAlignment>) {\n this._textAlignment = textAlignment\n this._textElementView.style.textAlign = textAlignment\n }\n \n //#endregion\n \n //#region Getters & Setters - Text Color\n \n get textColor() {\n return this._textColor\n }\n \n set textColor(color: UIColor) {\n this._textColor = color || UITextView.defaultTextColor\n this._textElementView.style.color = this._textColor.stringValue\n }\n \n //#endregion\n \n //#region Getters & Setters - Single Line\n \n get isSingleLine() {\n return this._isSingleLine\n }\n \n set isSingleLine(isSingleLine: boolean) {\n this._isSingleLine = isSingleLine\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n \n if (isSingleLine) {\n // Single line: use nowrap with ellipsis\n this._textElementView.style.whiteSpace = \"nowrap\"\n this._textElementView.style.textOverflow = \"ellipsis\"\n this._textElementView.style.display = \"\"\n this._textElementView.style.webkitLineClamp = \"\"\n this._textElementView.style.webkitBoxOrient = \"\"\n return\n }\n \n // Multiline: allow wrapping, but still show ellipsis if content overflows the container\n // This uses the -webkit-line-clamp approach which works for multiline ellipsis\n this._textElementView.style.whiteSpace = \"normal\"\n this._textElementView.style.textOverflow = \"ellipsis\"\n this._textElementView.style.display = \"-webkit-box\"\n this._textElementView.style.webkitBoxOrient = \"vertical\"\n // Don't set line-clamp to a specific number - let it fill available space\n // The overflow: hidden from the constructor will clip content that exceeds the height\n this.invalidateMeasurementStrategy()\n }\n \n //#endregion\n \n //#region Getters & Setters - Notification Amount\n \n get notificationAmount() {\n return this._notificationAmount\n }\n \n set notificationAmount(notificationAmount: number) {\n if (this._notificationAmount == notificationAmount) {\n return\n }\n \n this._notificationAmount = notificationAmount\n this.text = this.text\n this.setNeedsLayoutUpToRootView()\n this.notificationAmountDidChange(notificationAmount)\n }\n \n notificationAmountDidChange(notificationAmount: number) {\n }\n \n //#endregion\n \n //#region Getters & Setters - Text Content\n \n get text() {\n return (this._text || this.textElementView.viewHTMLElement.innerHTML)\n }\n \n set text(text) {\n this._text = text\n var notificationText = \"\"\n if (this.notificationAmount) {\n notificationText = \"<span style=\\\"color: \" + UITextView.notificationTextColor.stringValue + \";\\\">\" +\n (\" (\" + this.notificationAmount + \")\").bold() + \"</span>\"\n }\n \n const displayText = this.thousandsSeparator !== null\n ? UITextView.applyThousandsSeparatorToNumericalString(text, this.thousandsSeparator)\n : text\n \n if (this.textElementView.viewHTMLElement.innerHTML != this.textPrefix + displayText + this.textSuffix + notificationText) {\n this.textElementView.viewHTMLElement.innerHTML = this.textPrefix + FIRST(\n displayText, \"\") + this.textSuffix + notificationText\n }\n \n if (this.changesOften) {\n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n }\n \n this._useFastMeasurement = undefined\n this._intrinsicSizesCache = {}\n this.invalidateMeasurementStrategy()\n this._invalidateMeasurementStyles()\n this.clearIntrinsicSizeCache()\n \n this.setNeedsLayout()\n }\n \n \n /**\n * Formats a raw number string by inserting `separator` every three digits\n * in the integer part. Handles negative numbers and decimals (machine locale\n * \".\" as decimal point). Non-numeric strings are returned unchanged.\n */\n static applyThousandsSeparatorToNumericalString(value: string, separator: string): string {\n const trimmed = (value || \"\").trim()\n if (trimmed === \"\") {\n return value\n }\n \n // Split on the decimal point (machine locale uses \".\")\n const parts = trimmed.split(\".\")\n const integerPart = parts[0]\n const decimalPart = parts.length > 1 ? parts[1] : null\n \n // Only format if the integer part consists solely of digits (optionally\n // prefixed with a minus sign). Non-numeric strings pass through as-is.\n if (!/^-?\\d+$/.test(integerPart)) {\n return value\n }\n \n const isNegative = integerPart.startsWith(\"-\")\n const digits = isNegative ? integerPart.slice(1) : integerPart\n \n let formatted = \"\"\n const offset = digits.length % 3\n for (let index = 0; index < digits.length; index++) {\n if (index > 0 && (index - offset) % 3 === 0) {\n formatted += separator\n }\n formatted += digits[index]\n }\n \n const result = (isNegative ? \"-\" : \"\") + formatted\n return decimalPart !== null ? result + \".\" + decimalPart : result\n }\n \n override set innerHTML(innerHTML: string) {\n this.text = innerHTML\n this.invalidateMeasurementStrategy()\n }\n \n override get innerHTML() {\n return this.viewHTMLElement.innerHTML\n }\n \n setText(key: string, defaultString: string, parameters?: { [x: string]: string | UILocalizedTextObject }) {\n this.textElementView.setInnerHTML(key, defaultString, parameters)\n this.invalidateMeasurementStrategy()\n }\n \n //#endregion\n \n //#region Getters & Setters - Font Size\n \n get fontSize() {\n const style = this._textElementView.style.fontSize || window.getComputedStyle(this._textElementView.viewHTMLElement, null).fontSize\n const result = (parseFloat(style) * UITextView._pxToPt)\n return result\n }\n \n set fontSize(fontSize: number) {\n if (fontSize != this.fontSize) {\n this._textElementView.style.fontSize = \"\" + fontSize + \"pt\"\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n \n this._invalidateFontCache()\n this._invalidateMeasurementStyles()\n this.clearIntrinsicSizeCache()\n }\n }\n \n useAutomaticFontSize(minFontSize: number = nil, maxFontSize: number = nil) {\n this._automaticFontSizeSelection = YES\n this._minFontSize = minFontSize\n this._maxFontSize = maxFontSize\n this.setNeedsLayout()\n }\n \n //#endregion\n \n //#region Font Caching - Private Methods\n \n /**\n * Get a stable cache key for the font without triggering reflow.\n * Only computes font on first access or when font properties change.\n */\n private _getFontCacheKey(): string {\n // Check if font-related properties have changed\n const currentTriggers = {\n fontSize: this._textElementView.style.fontSize || \"\",\n fontFamily: this._textElementView.style.fontFamily || \"\",\n fontWeight: this._textElementView.style.fontWeight || \"\",\n fontStyle: this._textElementView.style.fontStyle || \"\",\n styleClasses: this.styleClasses.join(\",\")\n }\n \n const hasChanged =\n currentTriggers.fontSize !== this._fontInvalidationTriggers.fontSize ||\n currentTriggers.fontFamily !== this._fontInvalidationTriggers.fontFamily ||\n currentTriggers.fontWeight !== this._fontInvalidationTriggers.fontWeight ||\n currentTriggers.fontStyle !== this._fontInvalidationTriggers.fontStyle ||\n currentTriggers.styleClasses !== this._fontInvalidationTriggers.styleClasses\n \n if (!this._cachedFontKey || hasChanged) {\n // Only access computedStyle when we know something changed\n const computed = this._textElementView.computedStyle\n this._cachedFontKey = [\n computed.fontStyle,\n computed.fontVariant,\n computed.fontWeight,\n computed.fontSize,\n computed.fontFamily\n ].join(\"_\").replace(/[.\\s]/g, \"_\")\n \n this._fontInvalidationTriggers = currentTriggers\n }\n \n return this._cachedFontKey\n }\n \n /**\n * Invalidate font cache when font properties change\n */\n private _invalidateFontCache(): void {\n this._cachedFontKey = undefined\n }\n \n //#endregion\n \n //#region Static Methods\n \n static _determinePXAndPTRatios() {\n if (UITextView._ptToPx) {\n return\n }\n \n const o = document.createElement(\"div\")\n o.style.width = \"1000pt\"\n document.body.appendChild(o)\n UITextView._ptToPx = o.clientWidth / 1000\n document.body.removeChild(o)\n UITextView._pxToPt = 1 / UITextView._ptToPx\n }\n \n static automaticallyCalculatedFontSize(\n bounds: UIRectangle,\n currentSize: UIRectangle,\n currentFontSize: number,\n minFontSize?: number,\n maxFontSize?: number\n ) {\n minFontSize = FIRST(minFontSize, 1)\n maxFontSize = FIRST(maxFontSize, 100000000000)\n \n const heightMultiplier = bounds.height / (currentSize.height + 1)\n const widthMultiplier = bounds.width / (currentSize.width + 1)\n \n var multiplier = heightMultiplier\n if (heightMultiplier > widthMultiplier) {\n multiplier = widthMultiplier\n }\n \n const maxFittingFontSize = currentFontSize * multiplier\n \n if (maxFittingFontSize > maxFontSize) {\n return maxFontSize\n }\n \n if (minFontSize > maxFittingFontSize) {\n return minFontSize\n }\n \n return maxFittingFontSize\n }\n \n //#endregion\n \n //#region Instance Properties - Text Content\n \n _text?: string\n textPrefix = \"\"\n textSuffix = \"\"\n _notificationAmount = 0\n \n _thousandsSeparator: string | null = null\n \n get thousandsSeparator(): string | null {\n return this._thousandsSeparator\n }\n \n set thousandsSeparator(value: string | null) {\n this._thousandsSeparator = value\n }\n \n //#endregion\n \n //#region Instance Properties - Styling\n \n _textColor: UIColor = UITextView.defaultTextColor\n _textAlignment?: ValueOf<typeof UITextView.textAlignment>\n _isSingleLine = YES\n \n //#endregion\n \n //#region Instance Properties - Font & Sizing\n \n _minFontSize?: number\n _maxFontSize?: number\n _automaticFontSizeSelection = NO\n \n // Cache for the computed font string\n private _cachedFontKey?: string\n private _fontInvalidationTriggers = {\n fontSize: \"\",\n fontFamily: \"\",\n fontWeight: \"\",\n fontStyle: \"\",\n styleClasses: \"\"\n }\n \n //#endregion\n \n //#region Instance Properties - Caching & Performance\n \n changesOften = NO\n \n // Local cache for this instance if the label changes often\n _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n private _useFastMeasurement: boolean | undefined\n private _cachedMeasurementStyles: TextMeasurementStyle | undefined | null\n \n override usesVirtualLayoutingForIntrinsicSizing = NO\n \n //#endregion\n \n // Override addStyleClass to invalidate font cache\n override addStyleClass(styleClass: string) {\n super.addStyleClass(styleClass)\n this._invalidateFontCache()\n }\n \n // Override removeStyleClass to invalidate font cache\n override removeStyleClass(styleClass: string) {\n super.removeStyleClass(styleClass)\n this._invalidateFontCache()\n }\n \n // Override focus to focus the text element\n override focus() {\n this._textElementView.focus()\n }\n \n // Override blur to blur the text element\n override blur() {\n this._textElementView.blur()\n }\n \n override intrinsicContentHeight(constrainingWidth = 0) {\n \n const keyPath = ((this.textElementView.viewHTMLElement.innerHTML || this.text) + \"_csf_\" + this._getFontCacheKey()) + \".\" +\n (\"\" + constrainingWidth).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicHeightCache\n \n if (this.changesOften) {\n cacheObject = this._intrinsicHeightCache\n }\n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n if (IS_LIKE_NULL(result)) {\n // Determine if we should use fast measurement\n const shouldUseFastPath = this._useFastMeasurement ?? this._shouldUseFastMeasurement()\n \n if (shouldUseFastPath) {\n // Fast path: use UITextMeasurement with pre-extracted styles\n const styles = this._getMeasurementStyles()\n \n // If styles are invalid (element not properly initialized), fall back to DOM\n if (styles) {\n const size = UITextMeasurement.calculateTextSize(\n this.textElementView.viewHTMLElement,\n this.text || this.textElementView.innerHTML,\n constrainingWidth || undefined,\n undefined,\n styles\n )\n result = size.height\n }\n else {\n // Styles not ready, use DOM measurement\n result = super.intrinsicContentHeight(constrainingWidth)\n }\n }\n else {\n // Fallback: DOM-based measurement for complex content\n result = super.intrinsicContentHeight(constrainingWidth)\n }\n \n cacheObject.setValueForKeyPath(keyPath, result)\n }\n \n if (isNaN(result) || (!result && !this.text)) {\n result = super.intrinsicContentHeight(constrainingWidth)\n cacheObject.setValueForKeyPath(keyPath, result)\n }\n \n return result\n }\n \n override intrinsicContentWidth(constrainingHeight = 0) {\n \n const keyPath = ((this.textElementView.viewHTMLElement.innerHTML || this.text) + \"_csf_\" + this._getFontCacheKey()) + \".\" +\n (\"\" + constrainingHeight).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicWidthCache\n \n if (this.changesOften) {\n cacheObject = this._intrinsicWidthCache\n }\n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n if (IS_LIKE_NULL(result)) {\n // Determine if we should use fast measurement\n const shouldUseFastPath = this._useFastMeasurement ?? this._shouldUseFastMeasurement()\n \n if (shouldUseFastPath) {\n // Fast path: use UITextMeasurement with pre-extracted styles\n const styles = this._getMeasurementStyles()\n \n // If styles are invalid (element not properly initialized), fall back to DOM\n if (styles) {\n const size = UITextMeasurement.calculateTextSize(\n this.textElementView.viewHTMLElement,\n this.text || this.textElementView.innerHTML,\n undefined,\n constrainingHeight || undefined,\n styles\n )\n result = size.width\n }\n else {\n // Styles not ready, use DOM measurement\n result = super.intrinsicContentWidth(constrainingHeight)\n }\n }\n else {\n // Fallback: DOM-based measurement for complex content\n result = super.intrinsicContentWidth(constrainingHeight)\n }\n \n cacheObject.setValueForKeyPath(keyPath, result)\n }\n \n return result\n }\n \n \n override intrinsicContentSizeWithConstraints(constrainingHeight: number = 0, constrainingWidth: number = 0) {\n \n const cacheKey = this._getIntrinsicSizeCacheKey(constrainingHeight, constrainingWidth)\n const cachedResult = this._getCachedIntrinsicSize(cacheKey)\n if (cachedResult) {\n return cachedResult\n }\n \n // UITextView needs to measure the text element, not the outer container\n const result = new UIRectangle(0, 0, 0, 0)\n if (this.rootView.forceIntrinsicSizeZero) {\n return result\n }\n \n let temporarilyInViewTree = NO\n let nodeAboveThisView: Node | null = null\n if (!this.isMemberOfViewTree) {\n document.body.appendChild(this.viewHTMLElement)\n temporarilyInViewTree = YES\n nodeAboveThisView = this.viewHTMLElement.nextSibling\n }\n \n // Save and clear styles on the TEXT ELEMENT (not the container)\n const height = this._textElementView.style.height\n const width = this._textElementView.style.width\n \n this._textElementView.style.height = \"\" + constrainingHeight\n this._textElementView.style.width = \"\" + constrainingWidth\n \n const left = this._textElementView.style.left\n const right = this._textElementView.style.right\n const bottom = this._textElementView.style.bottom\n const top = this._textElementView.style.top\n \n this._textElementView.style.left = \"\"\n this._textElementView.style.right = \"\"\n this._textElementView.style.bottom = \"\"\n this._textElementView.style.top = \"\"\n \n // Measure height with the text element\n const resultHeight = this._textElementView.viewHTMLElement.scrollHeight\n \n // Measure width by temporarily setting nowrap\n const whiteSpace = this._textElementView.style.whiteSpace\n this._textElementView.style.whiteSpace = \"nowrap\"\n \n const resultWidth = this._textElementView.viewHTMLElement.scrollWidth\n \n this._textElementView.style.whiteSpace = whiteSpace\n \n // Restore styles on the TEXT ELEMENT\n this._textElementView.style.height = height\n this._textElementView.style.width = width\n \n this._textElementView.style.left = left\n this._textElementView.style.right = right\n this._textElementView.style.bottom = bottom\n this._textElementView.style.top = top\n \n if (temporarilyInViewTree) {\n document.body.removeChild(this.viewHTMLElement)\n if (this.superview) {\n if (nodeAboveThisView) {\n this.superview.viewHTMLElement.insertBefore(this.viewHTMLElement, nodeAboveThisView)\n }\n else {\n this.superview.viewHTMLElement.appendChild(this.viewHTMLElement)\n }\n }\n }\n \n result.height = resultHeight\n result.width = resultWidth\n \n this._setCachedIntrinsicSize(cacheKey, result)\n \n return result\n }\n \n \n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uicore-ts",
3
- "version": "1.1.218",
3
+ "version": "1.1.225",
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",
@@ -223,8 +223,6 @@ export class UITextView extends UIView {
223
223
  const fontSizeStr = computed.fontSize
224
224
  const fontSize = parseFloat(fontSizeStr)
225
225
 
226
- console.log(computed.letterSpacing)
227
-
228
226
  if (!fontSize || isNaN(fontSize)) {
229
227
  return null
230
228
  }
@@ -416,9 +414,13 @@ export class UITextView extends UIView {
416
414
  (" (" + this.notificationAmount + ")").bold() + "</span>"
417
415
  }
418
416
 
419
- if (this.textElementView.viewHTMLElement.innerHTML != this.textPrefix + text + this.textSuffix + notificationText) {
417
+ const displayText = this.thousandsSeparator !== null
418
+ ? UITextView.applyThousandsSeparatorToNumericalString(text, this.thousandsSeparator)
419
+ : text
420
+
421
+ if (this.textElementView.viewHTMLElement.innerHTML != this.textPrefix + displayText + this.textSuffix + notificationText) {
420
422
  this.textElementView.viewHTMLElement.innerHTML = this.textPrefix + FIRST(
421
- text, "") + this.textSuffix + notificationText
423
+ displayText, "") + this.textSuffix + notificationText
422
424
  }
423
425
 
424
426
  if (this.changesOften) {
@@ -435,6 +437,45 @@ export class UITextView extends UIView {
435
437
  this.setNeedsLayout()
436
438
  }
437
439
 
440
+
441
+ /**
442
+ * Formats a raw number string by inserting `separator` every three digits
443
+ * in the integer part. Handles negative numbers and decimals (machine locale
444
+ * "." as decimal point). Non-numeric strings are returned unchanged.
445
+ */
446
+ static applyThousandsSeparatorToNumericalString(value: string, separator: string): string {
447
+ const trimmed = (value || "").trim()
448
+ if (trimmed === "") {
449
+ return value
450
+ }
451
+
452
+ // Split on the decimal point (machine locale uses ".")
453
+ const parts = trimmed.split(".")
454
+ const integerPart = parts[0]
455
+ const decimalPart = parts.length > 1 ? parts[1] : null
456
+
457
+ // Only format if the integer part consists solely of digits (optionally
458
+ // prefixed with a minus sign). Non-numeric strings pass through as-is.
459
+ if (!/^-?\d+$/.test(integerPart)) {
460
+ return value
461
+ }
462
+
463
+ const isNegative = integerPart.startsWith("-")
464
+ const digits = isNegative ? integerPart.slice(1) : integerPart
465
+
466
+ let formatted = ""
467
+ const offset = digits.length % 3
468
+ for (let index = 0; index < digits.length; index++) {
469
+ if (index > 0 && (index - offset) % 3 === 0) {
470
+ formatted += separator
471
+ }
472
+ formatted += digits[index]
473
+ }
474
+
475
+ const result = (isNegative ? "-" : "") + formatted
476
+ return decimalPart !== null ? result + "." + decimalPart : result
477
+ }
478
+
438
479
  override set innerHTML(innerHTML: string) {
439
480
  this.text = innerHTML
440
481
  this.invalidateMeasurementStrategy()
@@ -585,6 +626,16 @@ export class UITextView extends UIView {
585
626
  textSuffix = ""
586
627
  _notificationAmount = 0
587
628
 
629
+ _thousandsSeparator: string | null = null
630
+
631
+ get thousandsSeparator(): string | null {
632
+ return this._thousandsSeparator
633
+ }
634
+
635
+ set thousandsSeparator(value: string | null) {
636
+ this._thousandsSeparator = value
637
+ }
638
+
588
639
  //#endregion
589
640
 
590
641
  //#region Instance Properties - Styling