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

Nested TCSS interacts poorly with pseudo-classes in selectors. #4039

Closed
rodrigogiraoserrao opened this issue Jan 17, 2024 · 2 comments · Fixed by #4252
Closed

Nested TCSS interacts poorly with pseudo-classes in selectors. #4039

rodrigogiraoserrao opened this issue Jan 17, 2024 · 2 comments · Fixed by #4252
Assignees
Labels
bug Something isn't working Task

Comments

@rodrigogiraoserrao
Copy link
Contributor

rodrigogiraoserrao commented Jan 17, 2024

Working on #3969 and #3999 we realised that pseudo-classes in nested selectors aren't correctly handled.

(In short, to the tokenizer, a selector + pseudo-class looks the same as a rule + value in a nested context.)

Examples of CSS that breaks the tokenizer:

from textual.app import App, ComposeResult
from textual.widgets import Label


class NestedCSSTokenErrorApp(App[None]):
    CSS = """
    Screen {
        Label:hover {
                border: solid red;
        }
    }
    """

    def compose(self) -> ComposeResult:
        yield Label("This is class foo", classes="foo")
        yield Label("This is class bar", classes="bar")


if __name__ == "__main__":
    NestedCSSTokenErrorApp().run()
from textual.app import App, ComposeResult
from textual.widgets import Label


class NestedCSSTokenErrorApp(App[None]):
    CSS = """
    Screen {
        Label {
            &.foo, &.bar:hover {
                border: solid red;
            }
        }

        border: solid green;
    }
    """

    def compose(self) -> ComposeResult:
        yield Label("This is class foo", classes="foo")
        yield Label("This is class bar", classes="bar")


if __name__ == "__main__":
    NestedCSSTokenErrorApp().run()
@rodrigogiraoserrao
Copy link
Contributor Author

See Will's comment showing how the use of & “makes” some cases work.

@rodrigogiraoserrao rodrigogiraoserrao self-assigned this Feb 13, 2024
@rodrigogiraoserrao rodrigogiraoserrao linked a pull request Feb 15, 2024 that will close this issue
rodrigogiraoserrao added a commit that referenced this issue Mar 4, 2024
To be able to disambiguate between selector:pseudo-class and declaration:rule-value in nested TCSS (see #4039 for the original issue and #4163 for a first attempt at solving this) we establish that selectors with widget type names always start with an upper case letter A-Z or an underscore _ whereas declarations always start with a lower case letter a-z.
When a user creates a widget subclass that doesn't conform to this, we issue a 'SyntaxWarning' to let the user know.
Because we do this with the standard module 'warnings', the warning can easily be supressed if the user has a good reason to create a widget subclass with a name starting with a lower case letter (which is valid Python, just unhelpful to Textual).
Copy link

github-actions bot commented Mar 5, 2024

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Task
Projects
None yet
1 participant