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

JSX attributes with unbraced indented values, code children with > #1381

Merged
merged 2 commits into from
Aug 29, 2024
Merged

Conversation

edemaine
Copy link
Collaborator

@edemaine edemaine commented Aug 27, 2024

This PR makes two major advances toward #561, in two commits:

1. JSX attributes with unbraces indented values

#561 discussed a few possibilities for a symbol to indicate that the value of an attribute should be an indented block. I realized that we don't need any symbol here; we can just have an indented block (outside coffeeJSX mode which maintains full JSX compatibility without respecting indentation). Example:

<Show
  when=
    if testing
      timer() > 10
    else
      loading()
  fallback =
    <img src="loading.gif">
    <div>Loading...</div>
>

This seems like a clear (uncontroversial) win. It matches our support for indented content in various contexts, most recently condition of an if (#1364).

2. JSX child code blocks with >

I implemented my proposal from #561 (comment) to allow for a JSX code child to be prefixed with > instead of wrapping it in braces.

Examples where the content is on the same line as the > seem pretty straightforward and nice:

<div .greeting>
  Hello
  >' '
  > getUser() |> .first
  !

I also added support for indented blocks, with an indentation after the >:

<div .account>
  >
    user := getUser()
    if user?
      `Logged in as ${user.first}`
    else
      <LoginButton>

These get wrapped automatically in do, which lets you do the multiple lines of code and local declarations (which are intuitively local given the indentation). This aspect is maybe a little more controversial. It's related to facebook/jsx#39 which we've discussed implementing but haven't: making all JSX braced blocks (probably including attribute values and code blocks) implicitly wrapped in do. It's less necessary in Civet where most statements are expressions. But it's relevant exactly when you want to do multiple lines of code.

Alternatively, I could remove the indented block feature, and we could spell this as follows:

<div .account>
  >do
    user := getUser()
    if user?
      `Logged in as ${user.first}`
    else
      <LoginButton>

On the other hand, maybe > is a nice place to introduce divergent behavior like this: a single-line expression (not wrapped in do), or a multi-line block implicitly wrapped in do. Arguably we should do the same for indented attribute blocks (Part 1 of this PR), if they want to be multiple lines as well?

So potentially a bit of discussion before this should get merged. Let me know your thoughts in particular on whether indented > blocks and/or indented attribute values should be wrapped in do. (Currently the former is, but the latter isn't.)

And to be clear, this is also meant as a step toward a flag like "civet jsxCode" where the >s aren't necessary, and instead content needs to be quoted like a string. That would complete #561.

(Also deleted an old jsx.md file which seems to have been fully incorporated into reference.md long ago.)

Copy link
Contributor

@STRd6 STRd6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good intermediate step on the path towards JSX with natural code.

I'm a little concerned about this stylistically:

<div
   ... perhaps many attributes
> !! hard to tell at a glance if this is a close or starting a separate > expression

But can't really see a better solution for that at the moment, at least until we get to code as default.

The best way to move forward is probably to test this out and see if new and better ideas come to us.

Thanks for adding this!

@edemaine
Copy link
Collaborator Author

Agreed — it can be a little confusing visually. At least we don't have > in the middle of a tag like I originally suggested for attributes. 😅

The other backward-compatible option is &, which would avoid this issue, but I think > is more intuitive... Maybe we could come up with a Unicode alternative that's clearer? But I guess that wouldn't be backward-compatible either.

I think we could potentially improve this issue if I finally actually delved into the syntax highlighter. It should be relatively easy to detect a > when inside JSX child mode, and highlight accordingly.

@edemaine edemaine changed the title JSX attributes with unbraces indented values, code children with > JSX attributes with unbraced indented values, code children with > Aug 29, 2024
@edemaine edemaine merged commit 9bcb821 into main Aug 29, 2024
3 of 4 checks passed
@edemaine edemaine deleted the jsx branch August 29, 2024 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants