onejs-react 0.1.17 → 0.1.19
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 +1 -1
- package/src/components.tsx +4 -0
- package/src/host-config.ts +112 -97
package/package.json
CHANGED
package/src/components.tsx
CHANGED
|
@@ -36,6 +36,10 @@ const _imageCache = new Map<string, any>()
|
|
|
36
36
|
|
|
37
37
|
function _resolveAssetPath(src: string): string {
|
|
38
38
|
const Path = CS.System.IO.Path
|
|
39
|
+
// Absolute paths bypass asset resolution entirely
|
|
40
|
+
if (Path.IsPathRooted(src)) {
|
|
41
|
+
return src
|
|
42
|
+
}
|
|
39
43
|
if (CS.UnityEngine.Application.isEditor) {
|
|
40
44
|
const workingDir = typeof (globalThis as any).__workingDir === "string"
|
|
41
45
|
? (globalThis as any).__workingDir
|
package/src/host-config.ts
CHANGED
|
@@ -316,6 +316,21 @@ function escapeClassName(name: string): string {
|
|
|
316
316
|
return escaped;
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
+
// Shallow equality check for plain objects (style, props).
|
|
320
|
+
// Returns true if both have identical own-property values (===).
|
|
321
|
+
function shallowEqual(a: Record<string, unknown> | undefined, b: Record<string, unknown> | undefined): boolean {
|
|
322
|
+
if (a === b) return true;
|
|
323
|
+
if (!a || !b) return false;
|
|
324
|
+
const keysA = Object.keys(a);
|
|
325
|
+
const keysB = Object.keys(b);
|
|
326
|
+
if (keysA.length !== keysB.length) return false;
|
|
327
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
328
|
+
const k = keysA[i];
|
|
329
|
+
if (a[k] !== b[k]) return false;
|
|
330
|
+
}
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
|
|
319
334
|
// Get all expanded property keys for a style object
|
|
320
335
|
function getExpandedStyleKeys(style: ViewStyle | undefined): Set<string> {
|
|
321
336
|
const keys = new Set<string>();
|
|
@@ -618,70 +633,68 @@ function removeMergedTextChild(parentInstance: Instance, child: Instance) {
|
|
|
618
633
|
|
|
619
634
|
// MARK: Component-specific prop handlers
|
|
620
635
|
|
|
621
|
-
// Apply common props (text, value, label)
|
|
622
|
-
function applyCommonProps(element: CSObject, props: Record<string, unknown>) {
|
|
636
|
+
// Apply common props (text, value, label) - skip unchanged values
|
|
637
|
+
function applyCommonProps(element: CSObject, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
623
638
|
const el = element as any;
|
|
624
|
-
if (props.text !== undefined) el.text = props.text as string;
|
|
625
|
-
if (props.value !== undefined) el.value = props.value;
|
|
626
|
-
if (props.label !== undefined) el.label = props.label as string;
|
|
639
|
+
if (props.text !== undefined && props.text !== oldProps?.text) el.text = props.text as string;
|
|
640
|
+
if (props.value !== undefined && props.value !== oldProps?.value) el.value = props.value;
|
|
641
|
+
if (props.label !== undefined && props.label !== oldProps?.label) el.label = props.label as string;
|
|
627
642
|
}
|
|
628
643
|
|
|
629
|
-
// Helper to set enum prop if defined
|
|
630
|
-
function setEnumProp<T>(target: T, key: keyof T, props: Record<string, unknown>, propKey: string, enumType: CSEnum) {
|
|
631
|
-
if (props[propKey] !== undefined) {
|
|
644
|
+
// Helper to set enum prop if defined and changed
|
|
645
|
+
function setEnumProp<T>(target: T, key: keyof T, props: Record<string, unknown>, propKey: string, enumType: CSEnum, oldProps?: Record<string, unknown>) {
|
|
646
|
+
if (props[propKey] !== undefined && props[propKey] !== oldProps?.[propKey]) {
|
|
632
647
|
(target as Record<string, unknown>)[key as string] = enumType[props[propKey] as string];
|
|
633
648
|
}
|
|
634
649
|
}
|
|
635
650
|
|
|
636
|
-
// Helper to set value prop if defined
|
|
637
|
-
function setValueProp<T>(target: T, key: keyof T, props: Record<string, unknown>, propKey: string) {
|
|
638
|
-
if (props[propKey] !== undefined) {
|
|
651
|
+
// Helper to set value prop if defined and changed
|
|
652
|
+
function setValueProp<T>(target: T, key: keyof T, props: Record<string, unknown>, propKey: string, oldProps?: Record<string, unknown>) {
|
|
653
|
+
if (props[propKey] !== undefined && props[propKey] !== oldProps?.[propKey]) {
|
|
639
654
|
(target as Record<string, unknown>)[key as string] = props[propKey];
|
|
640
655
|
}
|
|
641
656
|
}
|
|
642
657
|
|
|
643
|
-
// Apply TextField-specific properties
|
|
644
|
-
function applyTextFieldProps(element: CSObject, props: Record<string, unknown>) {
|
|
658
|
+
// Apply TextField-specific properties - skip unchanged values
|
|
659
|
+
function applyTextFieldProps(element: CSObject, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
645
660
|
const el = element as any;
|
|
646
|
-
if (props.readOnly !== undefined) el.isReadOnly = props.readOnly;
|
|
647
|
-
if (props.multiline !== undefined) el.multiline = props.multiline;
|
|
648
|
-
if (props.maxLength !== undefined) el.maxLength = props.maxLength;
|
|
649
|
-
if (props.isPasswordField !== undefined) el.isPasswordField = props.isPasswordField;
|
|
650
|
-
if (props.maskChar !== undefined) el.maskChar = (props.maskChar as string).charAt(0);
|
|
651
|
-
if (props.isDelayed !== undefined) el.isDelayed = props.isDelayed;
|
|
652
|
-
if (props.selectAllOnFocus !== undefined) el.selectAllOnFocus = props.selectAllOnFocus;
|
|
653
|
-
if (props.selectAllOnMouseUp !== undefined) el.selectAllOnMouseUp = props.selectAllOnMouseUp;
|
|
654
|
-
if (props.hideMobileInput !== undefined) el.hideMobileInput = props.hideMobileInput;
|
|
655
|
-
if (props.autoCorrection !== undefined) el.autoCorrection = props.autoCorrection;
|
|
656
|
-
// Note: placeholder is handled differently in Unity - it's set via the textEdition interface
|
|
657
|
-
// For now we skip it as it requires more complex handling
|
|
661
|
+
if (props.readOnly !== undefined && props.readOnly !== oldProps?.readOnly) el.isReadOnly = props.readOnly;
|
|
662
|
+
if (props.multiline !== undefined && props.multiline !== oldProps?.multiline) el.multiline = props.multiline;
|
|
663
|
+
if (props.maxLength !== undefined && props.maxLength !== oldProps?.maxLength) el.maxLength = props.maxLength;
|
|
664
|
+
if (props.isPasswordField !== undefined && props.isPasswordField !== oldProps?.isPasswordField) el.isPasswordField = props.isPasswordField;
|
|
665
|
+
if (props.maskChar !== undefined && props.maskChar !== oldProps?.maskChar) el.maskChar = (props.maskChar as string).charAt(0);
|
|
666
|
+
if (props.isDelayed !== undefined && props.isDelayed !== oldProps?.isDelayed) el.isDelayed = props.isDelayed;
|
|
667
|
+
if (props.selectAllOnFocus !== undefined && props.selectAllOnFocus !== oldProps?.selectAllOnFocus) el.selectAllOnFocus = props.selectAllOnFocus;
|
|
668
|
+
if (props.selectAllOnMouseUp !== undefined && props.selectAllOnMouseUp !== oldProps?.selectAllOnMouseUp) el.selectAllOnMouseUp = props.selectAllOnMouseUp;
|
|
669
|
+
if (props.hideMobileInput !== undefined && props.hideMobileInput !== oldProps?.hideMobileInput) el.hideMobileInput = props.hideMobileInput;
|
|
670
|
+
if (props.autoCorrection !== undefined && props.autoCorrection !== oldProps?.autoCorrection) el.autoCorrection = props.autoCorrection;
|
|
658
671
|
}
|
|
659
672
|
|
|
660
|
-
// Apply Slider-specific properties
|
|
661
|
-
function applySliderProps(element: CSObject, props: Record<string, unknown>) {
|
|
673
|
+
// Apply Slider-specific properties - skip unchanged values
|
|
674
|
+
function applySliderProps(element: CSObject, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
662
675
|
const el = element as any;
|
|
663
|
-
if (props.lowValue !== undefined) el.lowValue = props.lowValue;
|
|
664
|
-
if (props.highValue !== undefined) el.highValue = props.highValue;
|
|
665
|
-
if (props.showInputField !== undefined) el.showInputField = props.showInputField;
|
|
666
|
-
if (props.inverted !== undefined) el.inverted = props.inverted;
|
|
667
|
-
if (props.pageSize !== undefined) el.pageSize = props.pageSize;
|
|
668
|
-
if (props.fill !== undefined) el.fill = props.fill;
|
|
669
|
-
if (props.direction !== undefined) {
|
|
676
|
+
if (props.lowValue !== undefined && props.lowValue !== oldProps?.lowValue) el.lowValue = props.lowValue;
|
|
677
|
+
if (props.highValue !== undefined && props.highValue !== oldProps?.highValue) el.highValue = props.highValue;
|
|
678
|
+
if (props.showInputField !== undefined && props.showInputField !== oldProps?.showInputField) el.showInputField = props.showInputField;
|
|
679
|
+
if (props.inverted !== undefined && props.inverted !== oldProps?.inverted) el.inverted = props.inverted;
|
|
680
|
+
if (props.pageSize !== undefined && props.pageSize !== oldProps?.pageSize) el.pageSize = props.pageSize;
|
|
681
|
+
if (props.fill !== undefined && props.fill !== oldProps?.fill) el.fill = props.fill;
|
|
682
|
+
if (props.direction !== undefined && props.direction !== oldProps?.direction) {
|
|
670
683
|
el.direction = CS.UnityEngine.UIElements.SliderDirection[props.direction as string];
|
|
671
684
|
}
|
|
672
685
|
}
|
|
673
686
|
|
|
674
|
-
// Apply Toggle-specific properties
|
|
675
|
-
function applyToggleProps(element: CSObject, props: Record<string, unknown>) {
|
|
687
|
+
// Apply Toggle-specific properties - skip unchanged values
|
|
688
|
+
function applyToggleProps(element: CSObject, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
676
689
|
const el = element as any;
|
|
677
|
-
if (props.text !== undefined) el.text = props.text;
|
|
678
|
-
if (props.toggleOnLabelClick !== undefined) el.toggleOnLabelClick = props.toggleOnLabelClick;
|
|
690
|
+
if (props.text !== undefined && props.text !== oldProps?.text) el.text = props.text;
|
|
691
|
+
if (props.toggleOnLabelClick !== undefined && props.toggleOnLabelClick !== oldProps?.toggleOnLabelClick) el.toggleOnLabelClick = props.toggleOnLabelClick;
|
|
679
692
|
}
|
|
680
693
|
|
|
681
|
-
// Apply Image-specific properties
|
|
682
|
-
function applyImageProps(element: CSObject, props: Record<string, unknown>) {
|
|
694
|
+
// Apply Image-specific properties - skip unchanged values
|
|
695
|
+
function applyImageProps(element: CSObject, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
683
696
|
const el = element as any;
|
|
684
|
-
if (props.image !== undefined) {
|
|
697
|
+
if (props.image !== undefined && props.image !== oldProps?.image) {
|
|
685
698
|
const img = props.image;
|
|
686
699
|
if (img != null && (img as any).GetType?.().Name === "VectorImage") {
|
|
687
700
|
el.image = null;
|
|
@@ -691,73 +704,73 @@ function applyImageProps(element: CSObject, props: Record<string, unknown>) {
|
|
|
691
704
|
el.image = img;
|
|
692
705
|
}
|
|
693
706
|
}
|
|
694
|
-
if (props.sprite !== undefined) el.sprite = props.sprite;
|
|
695
|
-
if (props.vectorImage !== undefined) el.vectorImage = props.vectorImage;
|
|
696
|
-
if (props.scaleMode !== undefined) {
|
|
707
|
+
if (props.sprite !== undefined && props.sprite !== oldProps?.sprite) el.sprite = props.sprite;
|
|
708
|
+
if (props.vectorImage !== undefined && props.vectorImage !== oldProps?.vectorImage) el.vectorImage = props.vectorImage;
|
|
709
|
+
if (props.scaleMode !== undefined && props.scaleMode !== oldProps?.scaleMode) {
|
|
697
710
|
el.scaleMode = CS.UnityEngine.ScaleMode[props.scaleMode as string];
|
|
698
711
|
}
|
|
699
|
-
if (props.tintColor !== undefined) {
|
|
712
|
+
if (props.tintColor !== undefined && props.tintColor !== oldProps?.tintColor) {
|
|
700
713
|
const color = parseColor(props.tintColor as string);
|
|
701
714
|
if (color) el.tintColor = color;
|
|
702
715
|
}
|
|
703
|
-
if (props.sourceRect !== undefined) {
|
|
716
|
+
if (props.sourceRect !== undefined && props.sourceRect !== oldProps?.sourceRect) {
|
|
704
717
|
const rect = props.sourceRect as { x: number; y: number; width: number; height: number };
|
|
705
718
|
el.sourceRect = new CS.UnityEngine.Rect(rect.x, rect.y, rect.width, rect.height);
|
|
706
719
|
}
|
|
707
|
-
if (props.uv !== undefined) {
|
|
720
|
+
if (props.uv !== undefined && props.uv !== oldProps?.uv) {
|
|
708
721
|
const rect = props.uv as { x: number; y: number; width: number; height: number };
|
|
709
722
|
el.uv = new CS.UnityEngine.Rect(rect.x, rect.y, rect.width, rect.height);
|
|
710
723
|
}
|
|
711
724
|
}
|
|
712
725
|
|
|
713
|
-
// Apply ScrollView-specific properties
|
|
714
|
-
function applyScrollViewProps(element: CSScrollView, props: Record<string, unknown>) {
|
|
726
|
+
// Apply ScrollView-specific properties - skip unchanged values
|
|
727
|
+
function applyScrollViewProps(element: CSScrollView, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
715
728
|
const UIE = CS.UnityEngine.UIElements;
|
|
716
|
-
setEnumProp(element, 'mode', props, 'mode', UIE.ScrollViewMode);
|
|
717
|
-
setEnumProp(element, 'horizontalScrollerVisibility', props, 'horizontalScrollerVisibility', UIE.ScrollerVisibility);
|
|
718
|
-
setEnumProp(element, 'verticalScrollerVisibility', props, 'verticalScrollerVisibility', UIE.ScrollerVisibility);
|
|
719
|
-
setEnumProp(element, 'touchScrollBehavior', props, 'touchScrollBehavior', UIE.TouchScrollBehavior);
|
|
720
|
-
setEnumProp(element, 'nestedInteractionKind', props, 'nestedInteractionKind', UIE.NestedInteractionKind);
|
|
721
|
-
setValueProp(element, 'elasticity', props, 'elasticity');
|
|
722
|
-
setValueProp(element, 'elasticAnimationIntervalMs', props, 'elasticAnimationIntervalMs');
|
|
723
|
-
setValueProp(element, 'scrollDecelerationRate', props, 'scrollDecelerationRate');
|
|
724
|
-
setValueProp(element, 'mouseWheelScrollSize', props, 'mouseWheelScrollSize');
|
|
725
|
-
setValueProp(element, 'horizontalPageSize', props, 'horizontalPageSize');
|
|
726
|
-
setValueProp(element, 'verticalPageSize', props, 'verticalPageSize');
|
|
729
|
+
setEnumProp(element, 'mode', props, 'mode', UIE.ScrollViewMode, oldProps);
|
|
730
|
+
setEnumProp(element, 'horizontalScrollerVisibility', props, 'horizontalScrollerVisibility', UIE.ScrollerVisibility, oldProps);
|
|
731
|
+
setEnumProp(element, 'verticalScrollerVisibility', props, 'verticalScrollerVisibility', UIE.ScrollerVisibility, oldProps);
|
|
732
|
+
setEnumProp(element, 'touchScrollBehavior', props, 'touchScrollBehavior', UIE.TouchScrollBehavior, oldProps);
|
|
733
|
+
setEnumProp(element, 'nestedInteractionKind', props, 'nestedInteractionKind', UIE.NestedInteractionKind, oldProps);
|
|
734
|
+
setValueProp(element, 'elasticity', props, 'elasticity', oldProps);
|
|
735
|
+
setValueProp(element, 'elasticAnimationIntervalMs', props, 'elasticAnimationIntervalMs', oldProps);
|
|
736
|
+
setValueProp(element, 'scrollDecelerationRate', props, 'scrollDecelerationRate', oldProps);
|
|
737
|
+
setValueProp(element, 'mouseWheelScrollSize', props, 'mouseWheelScrollSize', oldProps);
|
|
738
|
+
setValueProp(element, 'horizontalPageSize', props, 'horizontalPageSize', oldProps);
|
|
739
|
+
setValueProp(element, 'verticalPageSize', props, 'verticalPageSize', oldProps);
|
|
727
740
|
}
|
|
728
741
|
|
|
729
|
-
// Apply ListView-specific properties
|
|
730
|
-
function applyListViewProps(element: CSListView, props: Record<string, unknown>) {
|
|
742
|
+
// Apply ListView-specific properties - skip unchanged values
|
|
743
|
+
function applyListViewProps(element: CSListView, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
731
744
|
const UIE = CS.UnityEngine.UIElements;
|
|
732
745
|
|
|
733
746
|
// Data binding callbacks
|
|
734
|
-
setValueProp(element, 'itemsSource', props, 'itemsSource');
|
|
735
|
-
setValueProp(element, 'makeItem', props, 'makeItem');
|
|
736
|
-
setValueProp(element, 'bindItem', props, 'bindItem');
|
|
737
|
-
setValueProp(element, 'unbindItem', props, 'unbindItem');
|
|
738
|
-
setValueProp(element, 'destroyItem', props, 'destroyItem');
|
|
747
|
+
setValueProp(element, 'itemsSource', props, 'itemsSource', oldProps);
|
|
748
|
+
setValueProp(element, 'makeItem', props, 'makeItem', oldProps);
|
|
749
|
+
setValueProp(element, 'bindItem', props, 'bindItem', oldProps);
|
|
750
|
+
setValueProp(element, 'unbindItem', props, 'unbindItem', oldProps);
|
|
751
|
+
setValueProp(element, 'destroyItem', props, 'destroyItem', oldProps);
|
|
739
752
|
|
|
740
753
|
// Virtualization
|
|
741
|
-
setValueProp(element, 'fixedItemHeight', props, 'fixedItemHeight');
|
|
742
|
-
setEnumProp(element, 'virtualizationMethod', props, 'virtualizationMethod', UIE.CollectionVirtualizationMethod);
|
|
754
|
+
setValueProp(element, 'fixedItemHeight', props, 'fixedItemHeight', oldProps);
|
|
755
|
+
setEnumProp(element, 'virtualizationMethod', props, 'virtualizationMethod', UIE.CollectionVirtualizationMethod, oldProps);
|
|
743
756
|
|
|
744
757
|
// Selection
|
|
745
|
-
setEnumProp(element, 'selectionType', props, 'selectionType', UIE.SelectionType);
|
|
746
|
-
setValueProp(element, 'selectedIndex', props, 'selectedIndex');
|
|
747
|
-
setValueProp(element, 'selectedIndices', props, 'selectedIndices');
|
|
758
|
+
setEnumProp(element, 'selectionType', props, 'selectionType', UIE.SelectionType, oldProps);
|
|
759
|
+
setValueProp(element, 'selectedIndex', props, 'selectedIndex', oldProps);
|
|
760
|
+
setValueProp(element, 'selectedIndices', props, 'selectedIndices', oldProps);
|
|
748
761
|
|
|
749
762
|
// Reordering
|
|
750
|
-
setValueProp(element, 'reorderable', props, 'reorderable');
|
|
751
|
-
setEnumProp(element, 'reorderMode', props, 'reorderMode', UIE.ListViewReorderMode);
|
|
763
|
+
setValueProp(element, 'reorderable', props, 'reorderable', oldProps);
|
|
764
|
+
setEnumProp(element, 'reorderMode', props, 'reorderMode', UIE.ListViewReorderMode, oldProps);
|
|
752
765
|
|
|
753
766
|
// Header/Footer
|
|
754
|
-
setValueProp(element, 'showFoldoutHeader', props, 'showFoldoutHeader');
|
|
755
|
-
setValueProp(element, 'headerTitle', props, 'headerTitle');
|
|
756
|
-
setValueProp(element, 'showAddRemoveFooter', props, 'showAddRemoveFooter');
|
|
767
|
+
setValueProp(element, 'showFoldoutHeader', props, 'showFoldoutHeader', oldProps);
|
|
768
|
+
setValueProp(element, 'headerTitle', props, 'headerTitle', oldProps);
|
|
769
|
+
setValueProp(element, 'showAddRemoveFooter', props, 'showAddRemoveFooter', oldProps);
|
|
757
770
|
|
|
758
771
|
// Appearance
|
|
759
|
-
setValueProp(element, 'showBorder', props, 'showBorder');
|
|
760
|
-
setEnumProp(element, 'showAlternatingRowBackgrounds', props, 'showAlternatingRowBackgrounds', UIE.AlternatingRowBackground);
|
|
772
|
+
setValueProp(element, 'showBorder', props, 'showBorder', oldProps);
|
|
773
|
+
setEnumProp(element, 'showAlternatingRowBackgrounds', props, 'showAlternatingRowBackgrounds', UIE.AlternatingRowBackground, oldProps);
|
|
761
774
|
}
|
|
762
775
|
|
|
763
776
|
// Props handled by the reconciler infrastructure - not forwarded to C# elements
|
|
@@ -767,46 +780,47 @@ const RESERVED_PROPS = new Set([
|
|
|
767
780
|
...Object.keys(EVENT_PROPS),
|
|
768
781
|
]);
|
|
769
782
|
|
|
770
|
-
// Forward non-reserved props directly to C# element (for custom elements)
|
|
771
|
-
function applyCustomProps(element: CSObject, props: Record<string, unknown>) {
|
|
783
|
+
// Forward non-reserved props directly to C# element (for custom elements) - skip unchanged
|
|
784
|
+
function applyCustomProps(element: CSObject, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
772
785
|
for (const [key, value] of Object.entries(props)) {
|
|
773
786
|
if (value === undefined || RESERVED_PROPS.has(key)) continue;
|
|
787
|
+
if (value === oldProps?.[key]) continue;
|
|
774
788
|
(element as any)[key] = value;
|
|
775
789
|
}
|
|
776
790
|
}
|
|
777
791
|
|
|
778
792
|
// Apply component-specific props based on element type
|
|
779
|
-
function applyComponentProps(element: CSObject, type: string, props: Record<string, unknown>) {
|
|
793
|
+
function applyComponentProps(element: CSObject, type: string, props: Record<string, unknown>, oldProps?: Record<string, unknown>) {
|
|
780
794
|
// Custom elements: forward all non-reserved props directly to C# element
|
|
781
795
|
if (!BUILT_IN_TYPES.has(type)) {
|
|
782
|
-
applyCustomProps(element, props);
|
|
796
|
+
applyCustomProps(element, props, oldProps);
|
|
783
797
|
return;
|
|
784
798
|
}
|
|
785
799
|
|
|
786
800
|
// For Slider, apply range props (lowValue/highValue) BEFORE value
|
|
787
801
|
// Unity's Slider clamps value to [lowValue, highValue], so range must be set first
|
|
788
802
|
if (type === 'ojs-slider') {
|
|
789
|
-
applySliderProps(element, props);
|
|
790
|
-
applyCommonProps(element, props);
|
|
803
|
+
applySliderProps(element, props, oldProps);
|
|
804
|
+
applyCommonProps(element, props, oldProps);
|
|
791
805
|
return;
|
|
792
806
|
}
|
|
793
807
|
|
|
794
|
-
applyCommonProps(element, props);
|
|
808
|
+
applyCommonProps(element, props, oldProps);
|
|
795
809
|
|
|
796
810
|
if (type === 'ojs-textfield') {
|
|
797
|
-
applyTextFieldProps(element, props);
|
|
811
|
+
applyTextFieldProps(element, props, oldProps);
|
|
798
812
|
} else if (type === 'ojs-toggle') {
|
|
799
|
-
applyToggleProps(element, props);
|
|
813
|
+
applyToggleProps(element, props, oldProps);
|
|
800
814
|
} else if (type === 'ojs-image') {
|
|
801
|
-
applyImageProps(element, props);
|
|
815
|
+
applyImageProps(element, props, oldProps);
|
|
802
816
|
} else if (type === 'ojs-scrollview') {
|
|
803
|
-
applyScrollViewProps(element as CSScrollView, props);
|
|
817
|
+
applyScrollViewProps(element as CSScrollView, props, oldProps);
|
|
804
818
|
} else if (type === 'ojs-listview') {
|
|
805
|
-
applyListViewProps(element as CSListView, props);
|
|
819
|
+
applyListViewProps(element as CSListView, props, oldProps);
|
|
806
820
|
} else if (type === 'ojs-frostedglass') {
|
|
807
821
|
const el = element as any;
|
|
808
|
-
if (props.blurRadius !== undefined) el.BlurRadius = props.blurRadius;
|
|
809
|
-
if (props.tintColor !== undefined) el.TintColor = props.tintColor;
|
|
822
|
+
if (props.blurRadius !== undefined && props.blurRadius !== oldProps?.blurRadius) el.BlurRadius = props.blurRadius;
|
|
823
|
+
if (props.tintColor !== undefined && props.tintColor !== oldProps?.tintColor) el.TintColor = props.tintColor;
|
|
810
824
|
}
|
|
811
825
|
}
|
|
812
826
|
|
|
@@ -844,8 +858,9 @@ function createInstance(type: string, props: BaseProps): Instance {
|
|
|
844
858
|
function updateInstance(instance: Instance, oldProps: BaseProps, newProps: BaseProps) {
|
|
845
859
|
const element = instance.element;
|
|
846
860
|
|
|
847
|
-
// Update style -
|
|
848
|
-
|
|
861
|
+
// Update style - skip if values are shallowly equal (inline style objects are
|
|
862
|
+
// new references each render but usually contain the same values)
|
|
863
|
+
if (oldProps.style !== newProps.style && !shallowEqual(oldProps.style as any, newProps.style as any)) {
|
|
849
864
|
const newStyleKeys = getExpandedStyleKeys(newProps.style);
|
|
850
865
|
clearRemovedStyles(element, instance.appliedStyleKeys, newStyleKeys);
|
|
851
866
|
instance.appliedStyleKeys = applyStyle(element, newProps.style);
|
|
@@ -862,8 +877,8 @@ function updateInstance(instance: Instance, oldProps: BaseProps, newProps: BaseP
|
|
|
862
877
|
// Update vector drawing callback
|
|
863
878
|
applyVisualContentCallback(instance, newProps);
|
|
864
879
|
|
|
865
|
-
// Update component-specific props
|
|
866
|
-
applyComponentProps(element, instance.type, newProps as Record<string, unknown>);
|
|
880
|
+
// Update component-specific props - pass oldProps to skip unchanged values
|
|
881
|
+
applyComponentProps(element, instance.type, newProps as Record<string, unknown>, oldProps as Record<string, unknown>);
|
|
867
882
|
|
|
868
883
|
// Update pickingMode
|
|
869
884
|
if (oldProps.pickingMode !== newProps.pickingMode) {
|