-
Hi I'm trying to style my input field to have a different border color when it is focused vs when it is invalid. const isFocused = ':has([data-focus])';
const isInvalid = ':has([data-invalid])';
export const styles = stylex.create({
input: {
borderColor: {
default: 'gray',
[isFocused]: 'black',
[isInvalid]: 'red',
},
},
}); The problem is that, when I focus an invalid input field, the border uses the focus styles. I want to keep the border red because the invalid state should take priority over the focused state. (I'm using the I also tried applying the focus and invalid styles in a separate declaration to take advantage of "the last style applied always wins": export const styles = stylex.create({
input: {
borderColor: 'gray',
},
focus: {
borderColor: {
default: null,
[isFocused]: 'black',
},
},
invalid: {
borderColor: {
default: null,
[isInvalid]: 'red',
},
},
});
// Input.tsx:
<div {...stylex.props(styles.input, styles.focus, styles.invalid)}> But in this case, the focus styling never gets applied (because the invalid style sets What is the correct way to achieve what I'm trying to do? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
My quick suggestion would be this const isFocused = ':has([data-focus])';
const isInvalid = ':has([data-invalid])';
const isInvalidAndFocused = ':has([data-focus]):has([data-invalid])';
export const styles = stylex.create({
input: {
borderColor: {
default: 'gray',
[isFocused]: 'black',
[isInvalid]: 'red',
[isInvalidAndFocused]: 'red',
},
},
}); |
Beta Was this translation helpful? Give feedback.
-
I am also not crazy about having to use the data-attributes to style things. But it will work. However, you said you are using HeadlessUI, which does expose render props. I wonder if something like this will work for you (taken from their documentation and modified) import { Input } from '@headlessui/react'
import clsx from 'clsx'
import { Fragment } from 'react'
function Example() {
return (
<Input type="text" name="full_name" as={Fragment}>
{({ focus, hover }) => <input {...stylex.props(
styles.input,
focus && styles.focus,
invalid && styles.invalid
)}
</Input>
)
} |
Beta Was this translation helpful? Give feedback.
Pseudo classes have an internal defined order. Same with media queries. You're expected to define styles with mutually-exclusive conditions when it matters by nesting additional levels.
So your contrived example would look like this: