Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Ref - A solution for complex CSS selectors #535

Closed
aspizu opened this issue Apr 11, 2024 · 3 comments
Closed

[RFC] Ref - A solution for complex CSS selectors #535

aspizu opened this issue Apr 11, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@aspizu
Copy link
Contributor

aspizu commented Apr 11, 2024

Describe the feature request

Motivation

Currently, stylex does not support complex CSS selectors like :hover, :focus,
:active based on a specific element such as a parent or a sibling.

A ref is a object which allows you to reference a specific element in the DOM.

API Style: A

Allow to reference a ref defined in local scope.

const ref = stylex.ref()

const styles = stylex.create({
    parent: {
        background: 'blue'
    },
    child: {
        [ref(':hover')]: {
            background: 'red'
        }
    }
})

<div {...stylex.ref(ref).props(styles.parent)}>
    <div {...stylex.props(styles.child)}>
        ...
    </div>
</div>

API Style: B

Do not allow to reference a ref without passing it as a parameter.

const ref = stylex.ref()

const styles = stylex.create({
    parent: {
        background: 'blue'
    },
    child: (ref: stylex.Ref) => {
        [ref(':hover')]: {
            background: 'red'
        }
    }
})

<div {...stylex.ref(ref).props(styles.parent)}>
    <div {...stylex.props(styles.child(ref))}>
        ...
    </div>
</div>

Implementation

stylex.ref(ref).props(...) will add a unique class name (ex: .ref_1) to the element.

The call syntax ref(':hover') will be compiled down into a selector string with the
class name prefixed (ex: ._ref_1:hover .atomicClass).

Considerations

With Style A, it is easier to use ref as it is defined in the local scope. However, it
may be harder to understand where the ref is coming from if the styles are defined
in a different file. Also, it is not possible to override the ref.

With Style B, each usage of a style which uses refs will need to pass the ref as a
parameter. But it is unclear wether this style is a dynamic style or static style.

@aspizu aspizu added the enhancement New feature or request label Apr 11, 2024
@nmn
Copy link
Contributor

nmn commented Apr 11, 2024

  1. There is no need for refs
  2. We don't want to add an API that depends on React APIs.

I've shared an RFC with design proposal that enables the same feature:

#536

Please comment on that issue with your thoughts. Thank you!

@nmn nmn closed this as completed Apr 11, 2024
@aspizu
Copy link
Contributor Author

aspizu commented Apr 11, 2024

How does this depend on React API?

@nmn
Copy link
Contributor

nmn commented Apr 12, 2024

@aspizu My bad. I didn't read carefully enough and the ref threw me off. Your proposal is actually very similar to what I have written up in the RFC.

There is one problem with the API you proposed which is that stylex.ref() works in two different ways. This won't be type-safe and could cause issues for the compiler.

The other issue I see is that ref(':hover') does not say where to look for the reference. This would mean that every single complex selector would depend on a unique ID in CSS. This design would be untenable as it would lead to bloat in the CSS. We need a design that encourages maximum re-use of the same IDs within different contexts.

Other than this, the approach you suggest makes sense is also what I have suggested in the linked RFC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants