microsoft / react-native-macos

A framework for building native macOS apps with React.
https://microsoft.github.io/react-native-windows/
MIT License
3.35k stars 128 forks source link

<Switch> property 'ios_backgroundcolor' yields inconsistent results, other color properties do not work at all #2132

Open michelcrypt4d4mus opened 1 month ago

michelcrypt4d4mus commented 1 month ago

Environment

react-native -v: 12.3.6

npm ls react-native-macos: 
├── react-native-macos@0.73.27
└─┬ react-native-menubar-extra@0.3.1
  └── react-native-macos@0.73.27 deduped

node -v: v21.7.2
npm -v: 10.5.0
xcodebuild -version: Xcode 15.2 Build version 15C500b

Steps to reproduce the bug

Setting up a <Switch> element with ios_backgroundcolor property gives me different looking output seemingly at random as i minimize and activate the window (I'm using an NSPopover). It seems like I sometimes get the correct looking output (see screenshot) the first time I open the NSPopover but then it goes to the square outlilne (see "the other sreenshot") and never comes back:

<Switch
    onValueChange={e => console.log(e} 
    value={isEnabled}
    ios_backgroundColor={PlatformColor('systemOrange')}
/>

AddingthumbColor and trackColor properties (which are documented for iOS) seems to do absolutely nothing:

<Switch
    onValueChange={e => console.log(e} 
    value={isEnabled}
    // TODO: none of these attempts to color the switch seem to work correctly...
    thumbColor={PlatformColor('systemGreen')}
    trackColor={{ true: 'blue', false: 'green' }}
/>

Expected Behavior

It should at least be consistent, but ideally more like this screenshot than the other screenshot:

Screenshot 2024-05-29 at 9 28 54 AM

Actual Behavior

The other screenshot:

Screenshot 2024-05-29 at 9 29 08 AM

Reproducible Demo

import { useState } from 'react';
import { StyleSheet, Switch, View } from 'react-native';

export default function SwitchView() {
    const [stateConfig, setStateConfig] = useState(false);

    return <View style={styles.container}>
        <Switch
            onValueChange={e => setStateConfig(e)} 
            value={stateConfig}
            ios_backgroundColor={PlatformColor('systemOrange')}
            // TODO: none of these attempts to color the switch seem to work correctly...
            thumbColor={PlatformColor('systemGreen')}
            trackColor={{ true: 'blue', false: 'green' }}
        />
    </View>;
};

styles = StyleSheet.create({
    container: {
        "alignItems": "center",
        "borderRadius": 15,
        "flexDirection": "row",
        "height": 50,
        "justifyContent": "flex-start",
        "marginVertical": 6,
        "marginHorizontal": 6,
        "paddingLeft": 12,
        "paddingRight": 12,
        "shadowColor": "#000",
        "shadowOffset": {
            "width": 2,
            "height": 2
        },
        "shadowOpacity": 0.8,
        "shadowRadius": 2,
        "backgroundColor": "rgba(225, 225, 225, 1)",
        "cursor": "pointer"
    },
});

Additional context

No response

Saadnajmi commented 1 month ago

So indeed, the native macOS switch doesn't support stuff like track and thumb color and I think background color only works because of undefined behavior.

See the macOS switch: https://developer.apple.com/documentation/appkit/nsswitch And the iOS switch: https://developer.apple.com/documentation/uikit/uiswitch

Saadnajmi commented 1 month ago

So Switch is setting the color manually inside Switch.JS: https://github.com/microsoft/react-native-macos/blob/2e9c4854596ec76c6fd8ef5213c70f80f64c9024/packages/react-native/Libraries/Components/Switch/Switch.js#L230C11-L236C11

         ios_backgroundColor == null
            ? null
            : {
                backgroundColor: ios_backgroundColor,
                borderRadius: 16,
              },
        ),

And if I understand correctly, the main issue is that you're not seeing the border radius? I'm slightly more convinced I should stub this out for macOS and not let you set a color at all, given it feels kind of hacky.. Can I ask what the use case of a custom background color on switches is?

Saadnajmi commented 1 month ago

If you want a customizable Switch, perhaps FluentUI React Native Switch (which is all JS) may work better for you: https://github.com/microsoft/fluentui-react-native/blob/main/packages/components/Switch/SPEC.md

michelcrypt4d4mus commented 1 month ago

I'm slightly more convinced I should stub this out for macOS and not let you set a color at all, given it feels kind of hacky.. Can I ask what the use case of a custom background color on switches is?

I was messing around with this because as it stands the switches in my RNM app seem to blend into the background / have no border and this seemed like a way of giving them a border. there doesn't seem to be much one can do about that but it's not a feature I absolutely need.

Screenshot 2024-05-29 at 6 15 59 PM
michelcrypt4d4mus commented 1 month ago

the switches in my RNM app seem to blend into the background / have no border

fwiw this is more or less true no matter what color background the switches are placed on, though it does work a better with darker colors than lighter one.

Screenshot 2024-05-29 at 7 19 45 PM
michelcrypt4d4mus commented 1 month ago

If you want a customizable Switch, perhaps FluentUI React Native Switch

documentation for this library is horrific to nonexistent... almost 100% of the example code omits the import statements required to actually use any of the elements and the imports you would expect do not work, e.g.

import { Checkbox } from '@fluentui/react-native';

works w/a deprecation warning but

import { Switch } from '@fluentui/react-native';

fails as does

import { Switch } from '@fluentui-react-native/switch';

which is copied straight from the FluentUI test project.

michelcrypt4d4mus commented 1 month ago

for bonus points the depreaction warning on Checkbox points to a MIGRATION.md file that does not even exist in the repo 😞

Screenshot 2024-05-30 at 8 24 54 PM
Saadnajmi commented 1 month ago

I'm slightly more convinced I should stub this out for macOS and not let you set a color at all, given it feels kind of hacky.. Can I ask what the use case of a custom background color on switches is?

I was messing around with this because as it stands the switches in my RNM app seem to blend into the background / have no border and this seemed like a way of giving them a border. there doesn't seem to be much one can do about that but it's not a feature I absolutely need. Screenshot 2024-05-29 at 6 15 59 PM

So this definitely seems like a bug.. the Switch should be much more opaque. It should look like the Switch in Control Center, AKA image

michelcrypt4d4mus commented 1 month ago

it's opaque (blue) when it's switched to the "on" position but close to invisible when it's in the "off" position. the screenshots i sent in the last few messages all show the switch in the "off" position.