mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
73664f576a
Summary: Implement the cursor style prop for iOS (and consequently, visionOS), as described in this RFC: https://github.com/react-native-community/discussions-and-proposals/pull/750 See related PR in React Native macOS, where we target macOS and visionOS (not running in iPad compatibility mode) with the same change: https://github.com/microsoft/react-native-macos/pull/2080 Docs update: https://github.com/facebook/react-native-website/pull/4033 ## Changelog: [IOS] [ADDED] - Implement cursor style prop Pull Request resolved: https://github.com/facebook/react-native/pull/43078 Test Plan: See the added example page, running on iOS with the new architecture enabled. This also runs the same on the old architecture. https://github.com/facebook/react-native/assets/6722175/2af60a0c-1c1f-45c4-8d66-a20f6d5815df See the example page running on all three apple platforms. The JS is slightly different because: 1. The "macOS Cursors" example is not part of this PR but the one in React Native macOS. 2. This PR (and exapmple) has went though a bunch of iterations and It got hard taking videos of every change 😅 https://github.com/facebook/react-native/assets/6722175/7775ba7c-8624-4873-a735-7665b94b7233 ## Notes - React Native macOS added the cursor prop to View with https://github.com/microsoft/react-native-macos/pull/760 and Text with https://github.com/microsoft/react-native-macos/pull/1469 . Much of the implementation comes from there. - Due to an Apple bug, as of iOS 17.4 Beta 4, the shape of the iOS cursor hover effect doesn't render in the correct bounds (but it does on visionOS). I've worked around it with an ifdef. The result is that the hover effect will work on iOS and visionOS, but not iPad apps running in compatibility mode on visionOS. Reviewed By: NickGerleman Differential Revision: D54512945 Pulled By: vincentriemer fbshipit-source-id: 699e3a01a901f55a466a2c1a19f667aede5aab80
125 lines
3.0 KiB
JavaScript
125 lines
3.0 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const React = require('react');
|
|
const {StyleSheet, Text, View} = require('react-native');
|
|
|
|
const styles = StyleSheet.create({
|
|
invisibleBox: {
|
|
width: 100,
|
|
height: 100,
|
|
},
|
|
box: {
|
|
width: 100,
|
|
height: 100,
|
|
borderWidth: 2,
|
|
},
|
|
circle: {
|
|
width: 100,
|
|
height: 100,
|
|
borderWidth: 2,
|
|
borderRadius: 100,
|
|
},
|
|
halfcircle: {
|
|
width: 100,
|
|
height: 100,
|
|
borderWidth: 2,
|
|
borderTopStartRadius: 100,
|
|
borderBottomStartRadius: 100,
|
|
},
|
|
solid: {
|
|
backgroundColor: 'blue',
|
|
},
|
|
pointer: {
|
|
cursor: 'pointer',
|
|
},
|
|
row: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
gap: 10,
|
|
},
|
|
centerContent: {
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
});
|
|
|
|
function CursorExampleAuto() {
|
|
return (
|
|
<View style={styles.row}>
|
|
<View style={styles.box} />
|
|
<View style={styles.circle} />
|
|
<View style={styles.halfcircle} />
|
|
<View style={[styles.box, styles.solid]} />
|
|
<View style={[styles.circle, styles.solid]} />
|
|
<View style={[styles.halfcircle, styles.solid]} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function CursorExamplePointer() {
|
|
return (
|
|
<View style={styles.row}>
|
|
<View style={[styles.box, styles.pointer]} />
|
|
<View style={[styles.circle, styles.pointer]} />
|
|
<View style={[styles.halfcircle, styles.pointer]} />
|
|
<View style={[styles.box, styles.solid, styles.pointer]} />
|
|
<View style={[styles.circle, styles.solid, styles.pointer]} />
|
|
<View style={[styles.halfcircle, styles.solid, styles.pointer]} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function CursorExamplePointer() {
|
|
return (
|
|
<View style={styles.row}>
|
|
<View style={[styles.box, styles.pointer]} />
|
|
<View style={[styles.circle, styles.pointer]} />
|
|
<View style={[styles.halfcircle, styles.pointer]} />
|
|
<View style={[styles.box, styles.solid, styles.pointer]} />
|
|
<View style={[styles.circle, styles.solid, styles.pointer]} />
|
|
<View style={[styles.halfcircle, styles.solid, styles.pointer]} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function CursorExampleViewFlattening() {
|
|
return (
|
|
<View style={styles.row}>
|
|
<View style={[styles.invisibleBox, styles.centerContent, styles.pointer]}>
|
|
<Text>pointer</Text>
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
exports.title = 'Cursor';
|
|
exports.category = 'UI';
|
|
exports.description =
|
|
'Demonstrates setting a cursor, which affects the appearance when a pointer is over the View.';
|
|
exports.examples = [
|
|
{
|
|
title: 'Default',
|
|
description: "Cursor: 'auto' or no cursor set ",
|
|
render: CursorExampleAuto,
|
|
},
|
|
{
|
|
title: 'Pointer',
|
|
description: 'cursor: pointer',
|
|
render: CursorExamplePointer,
|
|
},
|
|
{
|
|
title: 'View flattening',
|
|
description: 'Views with a cursor do not get flattened',
|
|
render: CursorExampleViewFlattening,
|
|
},
|
|
];
|