⚡ Sangsakala Proxy 🏠 Home
Skip to content

fix(core): restore the css value when a local style value is reset - #11520

Merged
NathanWalker merged 2 commits into
mainfrom
fix/css-property-local-reset-restores-css
Oct 23, 2026
Merged

NathanWalker merged 2 commits into
mainfrom
fix/css-property-local-reset-restores-css

Conversation

@edusperoni

@edusperoni edusperoni commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

PR Checklist

What is the current behavior?

CssProperty and InheritedCssProperty keep a single value per style. A local value suppresses the css write and takes that slot, so resetting the local value (unsetValue, 'unset'/'initial'/'inherit'/'revert', or '') falls back to the property default (or, for inherited properties, the parent's value) even when a matching css rule sets the property:

// .red { color: red; margin-top: 4; }
label.color = 'blue';
label.color = unsetValue; // native default, not red
label.marginTop = 20;
label.marginTop = unsetValue; // 0, not 4

The css value only comes back the next time the view's CssState re-applies (a dynamic state change or a re-match, via the _isCssValueStillApplied check from #11371). Until then the view shows the wrong value.

What is the new behavior?

A local reset falls back to the value the view's CssState last resolved for the property. The cascade already records that value in _appliedPropertyValues even while a local value suppresses the write. The value is written with source Css. The property only goes back to the default, or the inherited value, when no rule sets it. This works the same way for:

  • CssProperty local resets (setLocalValue).
  • InheritedCssProperty local resets. The css value wins over the parent's value, and children that inherit get the restored value.
  • ShorthandProperty, which works through its longhands' local setters.

CssState._getAppliedPropertyValue(property) exposes the recorded value. The bag already holds evaluated values (css variables, calc(), expanded shorthands), so nothing is re-parsed. The lookup only happens on the reset path, and the set path does no extra work.

Native updates work as before: the restored value goes through the normal set path. That path covers _suspendNativeUpdatesCount/_suspendedUpdates, capturing defaultValueKey, valueChanged, equalityComparer, affectsLayout and the change event. The change event's origin stays 'script', because a script write caused it. Only css-originated resets keep the old behavior. At that point the recorded value is the one being removed.

Classes that are not affected:

  • CssAnimationProperty already keeps a separate slot per source (css/local/keyframe) and falls back on reset.
  • Property/CoercibleProperty/InheritedProperty (view-level) don't track a css source. Css and local writes overwrite each other, so a local write never suppresses a css one.

A small behavior change: a local 'initial'/'inherit' now also returns the property to the css value, if there is one. That matches what the next re-apply already did, since these keywords release the local value instead of storing it.

Related but separate: #11413 fixes the descendant reset cascade of the view-level InheritedProperty. That is a different class in the same file, and the two patches apply independently of each other.

Tests: packages/core/ui/core/properties/css-property-local-reset.spec.ts (17 cases). It covers the reset keywords, resets through the view, shorthand-sourced and var()-sourced values, a local value set before css ran, the default and inherited fallbacks when no rule applies, native writes (css value vs captured native default), the change event, and propagation to inheriting children. 14 of them fail on main, and the full nx test core suite passes with the fix.

Updated existing test: VALUE-SOURCE.test_value_Local_stronger_than_Css asserted style.color === undefined after a local unsetValue while button { color: red } applied. That was the transient value the next CSS re-apply overwrote; it now expects the CSS red right away. The part the test is named for (a local value beats CSS) is still asserted just before.

A CssProperty holds one value per style, so a local value took the slot the
cascade had written. Resetting it (unsetValue, a css-wide keyword or '') fell
back to the property default, and the css value only came back the next time
the view's css state was re-applied.

A local reset now falls back to the value the view's CssState last resolved for
the property, which it records even while a local value suppresses the write,
and only to the default (or, for inherited properties, the parent's value) when
no rule sets it. The lookup happens on the reset path only.
@nx-cloud

nx-cloud Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 06f1161

Command Status Duration Result
nx test apps-automated -c=ios ✅ Succeeded 5m 21s View ↗
nx run-many --target=test --configuration=ci --... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-10-12 18:40:12 UTC

@pkg-pr-new

pkg-pr-new Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@nativescript/core@11520
npm i https://pkg.pr.new/@nativescript/vite@11520
npm i https://pkg.pr.new/@nativescript/webpack@11520

commit: 06f1161

test_value_Local_stronger_than_Css asserted that style.color is undefined after a local unsetValue, even though a css rule applies. That was the transient value the next css re-apply overwrote; a reset now restores the css value immediately.
@NathanWalker
NathanWalker merged commit 2f1ce03 into main Oct 23, 2026
10 of 11 checks passed
@NathanWalker
NathanWalker deleted the fix/css-property-local-reset-restores-css branch October 23, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants