From 794985ec3562b001cff73498d13fefe8bf0b471e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Wi=C5=9Bniewski?= Date: Wed, 17 Jun 2026 12:29:59 +0200 Subject: [PATCH 1/5] initial stuff --- .../apps/css/examples/transitions/routes.ts | 4 + .../pseudoSelectors/ActiveBlocksRender.tsx | 80 +++++++++++++++++++ .../screens/pseudoSelectors/index.ts | 2 + .../CSS/core/transition/CSSTransition.cpp | 10 +++ .../CSS/core/transition/CSSTransition.h | 3 + .../CSS/registries/CSSTransitionsRegistry.cpp | 8 ++ .../CSS/registries/CSSTransitionsRegistry.h | 2 + .../PseudoStyles/PseudoStylesRegistry.cpp | 13 +++ 8 files changed, 122 insertions(+) create mode 100644 apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/ActiveBlocksRender.tsx diff --git a/apps/common-app/src/apps/css/examples/transitions/routes.ts b/apps/common-app/src/apps/css/examples/transitions/routes.ts index 38b2b1a9c58..503d5d8997f 100644 --- a/apps/common-app/src/apps/css/examples/transitions/routes.ts +++ b/apps/common-app/src/apps/css/examples/transitions/routes.ts @@ -100,6 +100,10 @@ const routes = { name: ':active', Component: pseudoSelectors.Active, }, + PseudoActiveBlocksRender: { + name: ':active blocks render transition', + Component: pseudoSelectors.ActiveBlocksRender, + }, PseudoActiveDeepest: { name: ':active-deepest', Component: pseudoSelectors.ActiveDeepest, diff --git a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/ActiveBlocksRender.tsx b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/ActiveBlocksRender.tsx new file mode 100644 index 00000000000..2df677291b4 --- /dev/null +++ b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/ActiveBlocksRender.tsx @@ -0,0 +1,80 @@ +import { useEffect, useState } from 'react'; +import { StyleSheet } from 'react-native'; +import Animated from 'react-native-reanimated'; + +import { + Screen, + Scroll, + Section, + VerticalExampleCard, +} from '@/apps/css/components'; +import { colors, radius, sizes, spacing } from '@/theme'; + +export default function ActiveBlocksRender() { + const [phase, setPhase] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setPhase((prev) => (prev + 1) % 2); + }, 1000); + return () => clearInterval(interval); + }, []); + + const renderColor = phase === 0 ? colors.danger : colors.primaryLight; + + return ( + + +
+ true} +/>`} + collapsedCode={`backgroundColor: { + default: renderColor, + ':active': colors.primaryDark, +},`}> + true} + /> + +
+
+
+ ); +} + +const styles = StyleSheet.create({ + box: { + borderRadius: radius.md, + height: sizes.md, + width: sizes.md, + }, + content: { + gap: spacing.xs, + }, +}); diff --git a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts index 7f50d2207ef..2b22735b5bc 100644 --- a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts +++ b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts @@ -1,4 +1,5 @@ import Active from './Active'; +import ActiveBlocksRender from './ActiveBlocksRender'; import ActiveDeepest from './ActiveDeepest'; import ArbitraryWebSelectors from './ArbitraryWebSelectors'; import Focus from './Focus'; @@ -10,6 +11,7 @@ import Showcase from './Showcase'; export default { Active, + ActiveBlocksRender, ActiveDeepest, ArbitraryWebSelectors, Focus, diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.cpp index 2e8022088ab..c26a7b9c96e 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.cpp @@ -36,6 +36,12 @@ TransitionProperties CSSTransition::getProperties() const { folly::dynamic CSSTransition::run(jsi::Runtime &rt, CSSTransitionConfig &&config, const folly::dynamic &lastUpdates) { const auto timestamp = loop_->resolveTimestamp(); + for (const auto &propertyName : pseudoLockedProperties_) { + config.changedPropertiesSettings.erase(propertyName); + config.changedProperties.erase(propertyName); + std::erase(config.removedProperties, propertyName); + } + // CSSTransition owns routing: platform-routed props run immediately on the platform // transition; the loop-routed remainder is applied to the loop transition below. auto processed = platformTransitionProxy_->processConfig(std::move(config), routing_); @@ -100,6 +106,10 @@ folly::dynamic CSSTransition::computeCurrentLoopStyle() { return loopTransition_->computeCurrentStyle(shadowNode_); } +void CSSTransition::setPseudoLockedProperties(TransitionProperties properties) { + pseudoLockedProperties_ = std::move(properties); +} + void CSSTransition::cancel() { if (loopTransition_) { loop_->remove(loopTransition_); diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.h index bee13a233e7..3ed910835f2 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.h @@ -55,6 +55,8 @@ class CSSTransition { folly::dynamic run(const PropertyValueDynamicDiffsMap &propertyDiffs, const folly::dynamic &lastUpdates); void cancel(); + void setPseudoLockedProperties(TransitionProperties properties); + private: const std::shared_ptr shadowNode_; const std::shared_ptr viewStylesRepository_; @@ -63,6 +65,7 @@ class CSSTransition { Observer &observer_; CSSTransitionRouting routing_; + TransitionProperties pseudoLockedProperties_; std::unique_ptr platformTransition_; std::shared_ptr loopTransition_; diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.cpp index 6dc38cc4f3e..d2374cbddac 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.cpp @@ -39,6 +39,14 @@ void CSSTransitionsRegistry::run( recordInitialUpdate(transition, initialUpdate); } +void CSSTransitionsRegistry::setPseudoLockedProperties(const Tag viewTag, const TransitionProperties &properties) { + react_native_assert(UpdatesRegistryManager::isLockedByCurrentThread()); + const auto it = registry_.find(viewTag); + if (it != registry_.end()) { + it->second->setPseudoLockedProperties(properties); + } +} + void CSSTransitionsRegistry::flushUpdates(UpdatesBatch &updatesBatch) { react_native_assert(UpdatesRegistryManager::isLockedByCurrentThread()); const auto tags = std::exchange(updatedTags_, {}); diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.h b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.h index f422641317a..b9a74fc2ec5 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.h +++ b/packages/react-native-reanimated/Common/cpp/reanimated/CSS/registries/CSSTransitionsRegistry.h @@ -28,6 +28,8 @@ class CSSTransitionsRegistry : public UpdatesRegistry { CSSTransitionConfig &&config); void run(const std::shared_ptr &shadowNode, const PropertyValueDynamicDiffsMap &propertyDiffs); + void setPseudoLockedProperties(Tag viewTag, const TransitionProperties &properties); + void flushUpdates(UpdatesBatch &updatesBatch); #if REACT_NATIVE_VERSION_MINOR >= 85 void flushUpdates(UpdatesBatchAnimatedProps &updatesBatch); diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp index d68df6e4ccd..659c7abd751 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp @@ -100,6 +100,19 @@ void PseudoStylesRegistry::onSelectorStateChanged(Tag tag, PseudoSelector select const auto &fromStyle = entry.precomputedStyles[oldMask]; const auto &toStyle = entry.precomputedStyles[entry.activeMask]; + css::TransitionProperties lockedProperties; + for (const auto &[sel, data] : entry.selectors) { + if (!(entry.activeMask & (1u << static_cast(sel)))) { + continue; + } + for (const auto &[propKey, val] : data.selectorStyle.items()) { + if (!val.isNull()) { + lockedProperties.insert(propKey.asString()); + } + } + } + cssTransitionsRegistry_->setPseudoLockedProperties(tag, lockedProperties); + css::PropertyValueDynamicDiffsMap valueChanges; for (const auto &[propKey, toVal] : toStyle.items()) { const auto propName = propKey.asString(); From f7721a9bd8b044a052c585784df99de259209954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Wi=C5=9Bniewski?= Date: Wed, 17 Jun 2026 13:25:49 +0200 Subject: [PATCH 2/5] Dont detach on render --- .../PseudoStyles/PseudoStylesRegistry.cpp | 19 +++++++----- .../native/managers/CSSPseudoStylesManager.ts | 31 ++++++++++++++++--- .../__tests__/CSSPseudoStylesManager.test.ts | 22 ++++++++++--- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp index 659c7abd751..0eb69a5cfe5 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/PseudoStyles/PseudoStylesRegistry.cpp @@ -55,17 +55,20 @@ void PseudoStylesRegistry::registerPseudoStyle( auto &entry = registry_[tag]; entry.shadowNode = shadowNode; + const bool isNewSelector = !entry.selectors.contains(selector); entry.selectors[selector] = {selectorStyle, defaultStyle}; entry.precomputedStyles = recomputeAllStyles(entry); - attachFn_( - tag, - selector, - [weakThis = std::weak_ptr(shared_from_this()), tag, selector](bool isActive) { - if (auto strongThis = weakThis.lock()) { - strongThis->onSelectorStateChanged(tag, selector, isActive); - } - }); + if (isNewSelector) { + attachFn_( + tag, + selector, + [weakThis = std::weak_ptr(shared_from_this()), tag, selector](bool isActive) { + if (auto strongThis = weakThis.lock()) { + strongThis->onSelectorStateChanged(tag, selector, isActive); + } + }); + } } void PseudoStylesRegistry::remove(Tag tag) { diff --git a/packages/react-native-reanimated/src/css/native/managers/CSSPseudoStylesManager.ts b/packages/react-native-reanimated/src/css/native/managers/CSSPseudoStylesManager.ts index 8fc9b62e679..b7ff2df34f5 100644 --- a/packages/react-native-reanimated/src/css/native/managers/CSSPseudoStylesManager.ts +++ b/packages/react-native-reanimated/src/css/native/managers/CSSPseudoStylesManager.ts @@ -47,17 +47,25 @@ export default class CSSPseudoStylesManager implements ICSSPseudoStylesManager { ) { return; } + const removedSelector = hasRemovedNativeSelector( + this.prevPseudoStylesBySelector, + pseudoStylesBySelector + ); + this.prevPseudoStylesBySelector = pseudoStylesBySelector; this.prevTransitionProperties = transitionProperties; - if (this.isRegistered) { - this.detach(); - } - if (!pseudoStylesBySelector) { + if (this.isRegistered) { + this.detach(); + } return; } + if (this.isRegistered && removedSelector) { + this.detach(); + } + const normalizedTransition = transitionProperties ? normalizeCSSTransitionProperties(transitionProperties) : null; @@ -140,6 +148,21 @@ export default class CSSPseudoStylesManager implements ICSSPseudoStylesManager { } } +function hasRemovedNativeSelector( + prev: PseudoStylesBySelector | null, + next: PseudoStylesBySelector | null +): boolean { + if (!prev) { + return false; + } + const nextKeys = next ? new Set(Object.keys(next)) : new Set(); + return Object.keys(prev).some( + (selector) => + NATIVE_PSEUDO_SELECTORS.has(selector as NativePseudoSelectorKey) && + !nextKeys.has(selector) + ); +} + function nullifyUndefinedValues(style: UnknownRecord): void { for (const key in style) { if (style[key] === undefined) { diff --git a/packages/react-native-reanimated/src/css/native/managers/__tests__/CSSPseudoStylesManager.test.ts b/packages/react-native-reanimated/src/css/native/managers/__tests__/CSSPseudoStylesManager.test.ts index ac02d2911bd..73afafda9b7 100644 --- a/packages/react-native-reanimated/src/css/native/managers/__tests__/CSSPseudoStylesManager.test.ts +++ b/packages/react-native-reanimated/src/css/native/managers/__tests__/CSSPseudoStylesManager.test.ts @@ -326,7 +326,7 @@ describe('CSSPseudoStylesManager', () => { expect(unregisterPseudoStyle).not.toHaveBeenCalled(); }); - test('detaches and re-registers when selector style changes', () => { + test('updates in place without detaching when only selector style changes', () => { pushStyle(manager, { opacity: { default: 0, ':hover': 1 }, }); @@ -336,7 +336,7 @@ describe('CSSPseudoStylesManager', () => { opacity: { default: 0, ':hover': 0.5 }, }); - expect(unregisterPseudoStyle).toHaveBeenCalledWith(viewTag); + expect(unregisterPseudoStyle).not.toHaveBeenCalled(); expect(registerPseudoStyle).toHaveBeenCalledWith( shadowNodeWrapper, expect.objectContaining({ @@ -345,7 +345,7 @@ describe('CSSPseudoStylesManager', () => { ); }); - test('detaches and re-registers when only the transition changes', () => { + test('updates in place without detaching when only the transition changes', () => { pushStyle(manager, { opacity: { default: 0, ':hover': 1 }, transitionProperty: 'opacity', @@ -359,7 +359,7 @@ describe('CSSPseudoStylesManager', () => { transitionDuration: '500ms', }); - expect(unregisterPseudoStyle).toHaveBeenCalledWith(viewTag); + expect(unregisterPseudoStyle).not.toHaveBeenCalled(); expect(registerPseudoStyle).toHaveBeenCalledWith( shadowNodeWrapper, expect.objectContaining({ @@ -369,6 +369,20 @@ describe('CSSPseudoStylesManager', () => { }) ); }); + + test('detaches and re-registers when a selector is removed', () => { + pushStyle(manager, { + opacity: { default: 0, ':hover': 1, ':active': 0.5 }, + }); + jest.clearAllMocks(); + + pushStyle(manager, { + opacity: { default: 0, ':hover': 1 }, + }); + + expect(unregisterPseudoStyle).toHaveBeenCalledWith(viewTag); + expect(registerPseudoStyle).toHaveBeenCalled(); + }); }); describe('detach (via removing pseudo styles)', () => { From fdaa473167fba20da54f3a21a169121956837df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Wi=C5=9Bniewski?= Date: Wed, 17 Jun 2026 17:17:38 +0200 Subject: [PATCH 3/5] Add example --- .../apps/css/examples/transitions/routes.ts | 4 + .../screens/pseudoSelectors/Planets.tsx | 163 ++++++++++++++++++ .../screens/pseudoSelectors/index.ts | 2 + 3 files changed, 169 insertions(+) create mode 100644 apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx diff --git a/apps/common-app/src/apps/css/examples/transitions/routes.ts b/apps/common-app/src/apps/css/examples/transitions/routes.ts index 503d5d8997f..1dd15dd1860 100644 --- a/apps/common-app/src/apps/css/examples/transitions/routes.ts +++ b/apps/common-app/src/apps/css/examples/transitions/routes.ts @@ -124,6 +124,10 @@ const routes = { name: 'Per-state transition configs', Component: pseudoSelectors.PerStateTransitionConfig, }, + PseudoPlanets: { + name: 'Planets', + Component: pseudoSelectors.Planets, + }, PseudoArbitraryWebSelectors: { name: 'Arbitrary web selectors', Component: pseudoSelectors.ArbitraryWebSelectors, diff --git a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx new file mode 100644 index 00000000000..d7bc4d9d1ed --- /dev/null +++ b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx @@ -0,0 +1,163 @@ +import { StyleSheet, Text } from 'react-native'; +import Animated, { css } from 'react-native-reanimated'; + +import { + Screen, + Scroll, + Section, + VerticalExampleCard, +} from '@/apps/css/components'; +import { colors, spacing } from '@/theme'; + +// Elliptical orbit kept tight so the planets stay on screen; wider than tall +// fakes the "tilted into the screen" look. +const ORBIT_RX = 90; +const ORBIT_RY = 40; +const ORBIT_DURATION = '12s'; +// Smoothness of the path the planet's frame is moved along. +const ORBIT_STEPS = 36; + +const PLANETS = [ + { color: colors.danger, name: 'Mars', size: 44 }, + { color: colors.primary, name: 'Venus', size: 60 }, + { color: colors.primaryDark, name: 'Jupiter', size: 78 }, +]; + +const MAX_PLANET_SIZE = Math.max(...PLANETS.map((planet) => planet.size)); +const PLANE_WIDTH = 2 * ORBIT_RX + MAX_PLANET_SIZE; +const PLANE_HEIGHT = 2 * ORBIT_RY + MAX_PLANET_SIZE; +const CENTER_X = PLANE_WIDTH / 2; +const CENTER_Y = PLANE_HEIGHT / 2; + +// The orbit is driven by animating left/top (layout) rather than a transform. +// On iOS the touch hit-area follows animated layout but NOT an animated +// transform, so this keeps the orbiting planets tappable (:active) there. +function makeOrbit(offsetDeg: number, size: number) { + const frames: Record = {}; + for (let step = 0; step <= ORBIT_STEPS; step++) { + const percent = ((step / ORBIT_STEPS) * 100).toFixed(4); + const angle = ((offsetDeg + (360 * step) / ORBIT_STEPS) * Math.PI) / 180; + frames[`${percent}%`] = { + left: CENTER_X + ORBIT_RX * Math.cos(angle) - size / 2, + top: CENTER_Y + ORBIT_RY * Math.sin(angle) - size / 2, + }; + } + return css.keyframes(frames); +} + +const ORBITS = PLANETS.map((planet, index) => + makeOrbit((360 / PLANETS.length) * index, planet.size) +); + +export default function Planets() { + return ( + + +
+ true}> + {name} +`} + collapsedCode={`opacity: { + default: 0.02, + ':active': 1, +},`}> + + + {PLANETS.map((planet, index) => ( + + true}> + {planet.name} + + + ))} + + + +
+
+
+ ); +} + +const styles = StyleSheet.create({ + content: { + gap: spacing.xs, + }, + name: { + color: colors.white, + fontSize: 12, + fontWeight: '600', + textAlign: 'center', + }, + nameWrapper: { + alignItems: 'center', + bottom: 0, + justifyContent: 'center', + left: 0, + position: 'absolute', + right: 0, + top: 0, + }, + orbitPlane: { + height: PLANE_HEIGHT, + width: PLANE_WIDTH, + }, + orbiter: { + position: 'absolute', + shadowOffset: { height: 0, width: 0 }, + }, + stage: { + alignItems: 'center', + height: PLANE_HEIGHT + spacing.xl, + justifyContent: 'center', + }, +}); diff --git a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts index 2b22735b5bc..27bbf3360ad 100644 --- a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts +++ b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts @@ -7,6 +7,7 @@ import FocusWithin from './FocusWithin'; import Hover from './Hover'; import HoverWithLoop from './HoverWithLoop'; import PerStateTransitionConfig from './PerStateTransitionConfig'; +import Planets from './Planets'; import Showcase from './Showcase'; export default { @@ -19,5 +20,6 @@ export default { Hover, HoverWithLoop, PerStateTransitionConfig, + Planets, Showcase, }; From 241a9e85908b17c446fa8b5f6173c44936cecc31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Wi=C5=9Bniewski?= Date: Wed, 17 Jun 2026 17:36:38 +0200 Subject: [PATCH 4/5] Refine example --- .../screens/pseudoSelectors/Planets.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx index d7bc4d9d1ed..67e548ddcfb 100644 --- a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx +++ b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Planets.tsx @@ -9,12 +9,9 @@ import { } from '@/apps/css/components'; import { colors, spacing } from '@/theme'; -// Elliptical orbit kept tight so the planets stay on screen; wider than tall -// fakes the "tilted into the screen" look. const ORBIT_RX = 90; const ORBIT_RY = 40; const ORBIT_DURATION = '12s'; -// Smoothness of the path the planet's frame is moved along. const ORBIT_STEPS = 36; const PLANETS = [ @@ -29,9 +26,6 @@ const PLANE_HEIGHT = 2 * ORBIT_RY + MAX_PLANET_SIZE; const CENTER_X = PLANE_WIDTH / 2; const CENTER_Y = PLANE_HEIGHT / 2; -// The orbit is driven by animating left/top (layout) rather than a transform. -// On iOS the touch hit-area follows animated layout but NOT an animated -// transform, so this keeps the orbiting planets tappable (:active) there. function makeOrbit(offsetDeg: number, size: number) { const frames: Record = {}; for (let step = 0; step <= ORBIT_STEPS; step++) { @@ -54,7 +48,7 @@ export default function Planets() {
Date: Fri, 19 Jun 2026 09:21:35 +0200 Subject: [PATCH 5/5] Move showcase to a separate tab --- .../src/apps/css/examples/transitions/routes.ts | 17 +++++++++++------ .../pseudoSelectors/{Showcase.tsx => Form.tsx} | 2 +- .../screens/pseudoSelectors/index.ts | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) rename apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/{Showcase.tsx => Form.tsx} (99%) diff --git a/apps/common-app/src/apps/css/examples/transitions/routes.ts b/apps/common-app/src/apps/css/examples/transitions/routes.ts index 1dd15dd1860..75905bd6611 100644 --- a/apps/common-app/src/apps/css/examples/transitions/routes.ts +++ b/apps/common-app/src/apps/css/examples/transitions/routes.ts @@ -124,17 +124,22 @@ const routes = { name: 'Per-state transition configs', Component: pseudoSelectors.PerStateTransitionConfig, }, - PseudoPlanets: { - name: 'Planets', - Component: pseudoSelectors.Planets, - }, PseudoArbitraryWebSelectors: { name: 'Arbitrary web selectors', Component: pseudoSelectors.ArbitraryWebSelectors, }, - PseudoShowcase: { + Showcase: { name: 'Showcase', - Component: pseudoSelectors.Showcase, + routes: { + PseudoPlanets: { + name: 'Planets', + Component: pseudoSelectors.Planets, + }, + PseudoForm: { + name: 'Form', + Component: pseudoSelectors.Form, + }, + }, }, }, }, diff --git a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Showcase.tsx b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Form.tsx similarity index 99% rename from apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Showcase.tsx rename to apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Form.tsx index f5a6eee3c27..0234bd293cc 100644 --- a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Showcase.tsx +++ b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/Form.tsx @@ -139,7 +139,7 @@ function Card({ ); } -export default function Showcase() { +export default function Form() { return ( diff --git a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts index 27bbf3360ad..6c3c8bb2ac8 100644 --- a/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts +++ b/apps/common-app/src/apps/css/examples/transitions/screens/pseudoSelectors/index.ts @@ -4,11 +4,11 @@ import ActiveDeepest from './ActiveDeepest'; import ArbitraryWebSelectors from './ArbitraryWebSelectors'; import Focus from './Focus'; import FocusWithin from './FocusWithin'; +import Form from './Form'; import Hover from './Hover'; import HoverWithLoop from './HoverWithLoop'; import PerStateTransitionConfig from './PerStateTransitionConfig'; import Planets from './Planets'; -import Showcase from './Showcase'; export default { Active, @@ -17,9 +17,9 @@ export default { ArbitraryWebSelectors, Focus, FocusWithin, + Form, Hover, HoverWithLoop, PerStateTransitionConfig, Planets, - Showcase, };