1

Is there a way to use the Ternary Operator in the StyleSheet?

Currently, my TextInput looks as such:

.tsx

<TextInput
  defaultValue={selectedEvent ? selectedEvent.title : ""}
  style={[
    styles.textInput,
    { color: colorScheme === "dark" ? "#ffffff" : "#000000" },
  ]}
  onChangeText={inputChangeHandler}
/>

StyleSheet

const styles = StyleSheet.create({
  textInput: {
    borderBottomColor: "#ccc",
    borderBottomWidth: 1,
    marginBottom: 15,
    paddingVertical: 4,
    paddingHorizontal: 2,
  },
})

It'd be nice not to combine internal and external styles.

Daniel Danielecki
  • 8,508
  • 6
  • 68
  • 94

3 Answers3

3

Try this: In you TextInput:

style={styles.textInput(colorScheme)}

And in StyleSheet

textInput:(colorScheme)=> ({
  borderBottomColor: '#ccc',
  borderBottomWidth: 1,
  marginBottom: 15,
  paddingVertical: 4,
  paddingHorizontal: 2,
  color: colorScheme === "dark" ? "#ffffff" : "#000000"
}),

Snack Example

Tayyab Mazhar
  • 1,560
  • 10
  • 26
  • Magic. Looks interesting, props for that, and it (partially) works. The compiler complains *a lot* and this technique drops a few of my styles hmm – Daniel Danielecki Oct 25 '21 at 08:30
  • I'm intrigued. Do you have a working demo of this? It makes sense, logically, but I wasn't able to verify/validate it in a running example (RN is sometime very illogical). – Drew Reese Oct 25 '21 at 08:34
  • @DrewReese Sure, I've added an example. – Tayyab Mazhar Oct 25 '21 at 09:04
  • Ah, I see, works on native only. – Drew Reese Oct 25 '21 at 09:07
  • @DrewReese Yes, it seem so. – Tayyab Mazhar Oct 25 '21 at 09:20
  • I'll accept the answer, because the question was if it's possible, and the answer is yes. However, I'm getting lots of compiler warnings (on `strict` & not `strict` for `TypeScript`) with this setup. Thanks for the [Snack Example](https://snack.expo.dev/@tayyabreact/switch). It helped out, I'm posting in the next comment my other compiler's long warning. Warning1: `This expression is not callable. No constituent of type 'ViewStyle | TextStyle | ImageStyle' is callable.ts(2349) (property) textInput: ViewStyle | TextStyle | ImageStyle`. In addition, as said, it cuts partially my styles... – Daniel Danielecki Oct 26 '21 at 08:39
  • Warning2: `Type '(colorScheme: string) => { borderBottomColor: string; borderBottomWidth: number; color: string; marginBottom: number; paddingVertical: number; paddingHorizontal: number; }' is not assignable to type 'ViewStyle | TextStyle | ImageStyle'. Value of type '(colorScheme: string) => { borderBottomColor: string; borderBottomWidth: number; color: string; marginBottom: number; paddingVertical: number; paddingHorizontal: number; }' has no properties in common with type 'ImageStyle'. Did you mean to call it?ts(2322)` – Daniel Danielecki Oct 26 '21 at 08:39
  • However, with this amount of warnings, I'll keep my solution ;) – Daniel Danielecki Oct 26 '21 at 08:41
2

In StyleSheet you can't use ternary. But what you can is combine ternary and stylesheet like that:

<div
    style={checkIfActive(props.position, 1)
        ? { ...styles.circle, ...styles.circleActive }
        : { ...styles.circle, ...styles.circleUnactive }}
/>

And you CSS can be:

circle: {
    width: '80%',
    margin: 'auto',
    height: 20,
    borderRadius: 10,
    borderStyle: 'solid',
    borderWidth: 1,
    borderColor: '#ffffff83',
},
circleUnactive: {
    backgroundColor: '#40c5ee4e',
},
circleActive: {
    backgroundColor: '#40c5ee',
},
Badr Filali
  • 279
  • 5
  • 21
1

The StyleSheet is generating static styling "classes", but you can define a light/dark class to use and append it to the array. It's not much different than what you've done already though.

Example:

<TextInput
  defaultValue={selectedEvent ? selectedEvent.title : ''}
  style={[
    styles.textInput,
    styles[colorScheme === 'dark' ? 'dark' : 'light'],
  ]}
  onChangeText={console.log}
/>

...

const styles = StyleSheet.create({
  ...
  textInput: {
    borderBottomColor: '#ccc',
    borderBottomWidth: 1,
    marginBottom: 15,
    paddingVertical: 4,
    paddingHorizontal: 2,
  },
  light: {
    color: '#000',
  },
  dark: {
    color: '#fff',
  },
});

Here's a running Expo Snack of the above code.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181