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

Details & summary tag support #1767

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

kravhen
Copy link
Contributor

@kravhen kravhen commented Dec 27, 2024

Description

Closes #1422

Added support for collapsible content sections using HTML-style <details> and <summary> tags with minimal styling.

  • Allows users to create expandable/collapsible sections in their posts
  • Preserves markdown within the details blocks

It's flexible enough in terms structures; users can use the tags in various ways. Single or multiline, with or without a summary tag, blank lines or not (blank line preceding a content block is still required to activate markdown, as is the expected behavior).

Key steps

  1. Detection: visit() and look out for <details> opening and closing tags in the content
  2. Node Collection: Gather all nodes between the tags into a details container
  3. Summary Extraction: Look for and process optional <summary> tags
  4. Node Transformation (when required, otherwise just pushed into new details node): Convert the collected content into proper AST detail node
  5. Styling: Minimal CSS for collapsed/expanded states and hover effects

Screenshots

Here is example code, see how each structure appears in screenshot below.

Structure 1:

<details>lorem ipsum
without summary tag
lorem ipsum
</details>

----------

Structure 1 with blank line:

<details>

lorem ipsum
without summary tag
lorem ipsum
</details>

----------

Structure 2:

<details>
<summary>summary text here</summary>
lorem ipsum
lorem ipsum
</details>

----------

Structure 2 with blank line:

<details>
<summary>summary text here</summary>

lorem ipsum
lorem ipsum
</details>

----------

Structure 3:

<details>
    <summary>indented summary text here</summary>
1. first thing
2. second thing 
3. third thing
</details>

----------

Structure 3 with blank line around the markdown:

<details>
    <summary>indented summary text here</summary>

1. first thing
2. second thing 
3. third thing

</details>

----------

Structure 4:

<details>
  <summary>
    multiline summary text here
  </summary>

  text inside details with inline markdown working properly, such as *italics* and **bold**
</details>

----------

Structure 5:

<details>
<summary>Shopping list</summary>
- Vegetables
- Fruits
- Fish
</details>

----------

Structure 5 with proper blank line for markdown list:

<details>
<summary>Shopping list</summary>

- Vegetables
- Fruits
- Fish
</details>

image
image
image

Note: the yellow borders in the screenshots have been reverted to a neutral color because they looked bad on light mode. Left the screenshots because I thought they kinda look cool in dark mode. If you guys like them enough, can add new theme color variables to globas.scss for this.

Additional Context

Tried to do it a few different ways because it always seemed so verbose, and every try I gave it ended up being roughly as verbose. This is the implementation I was able to do without any extra imports like rehype-raw. Previous attempts used other utilities to transform from and to markdown like mdast-util-from-markdown and mdast-util-to-hast but I realised I was overmanipulating nodes and those were not necessary to get it to work since markdown is already supported.

Details handler code had to appear early in the RehypeSN transformer or other processors would make certain structures break. For example, if code is moved after the Nostr ID handler processor, the details node still render and function but the closing tags appear duplicated outside as text.

Does not handle nesting details within details. I tried it in a prior attempt and I think it requires more node manipulation and complexity for the current use case. If users end up using these extensively and there's a real use case for nesting them in posts, maybe we can take another look at it.

Checklist

Are your changes backwards compatible? Please answer below:
Yes - existing content without details/summary tags will render as before. The changes only affect content that explicitly uses these new tags.

On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:
Around 8/10. I could do additional testing for lengthy posts with complex markdown within.

For frontend changes: Tested on mobile, light and dark mode? Please answer below:
Behaves the same on mobile. Reverted some subtle yellow borders to neutral white/greyish colors for expanded details sections because the yellow looked bad on light mode.

Did you introduce any new environment variables? If so, call them out explicitly here:
No new environment variables were introduced.

Copy link
Member

@huumn huumn left a comment

Choose a reason for hiding this comment

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

The previews look really nice.

The rehype code looks a bit more complicated than I'd expect, but I haven't done enough work with nested elements to trust my expectations.

I'll try to get you an actual review next week.

@kravhen
Copy link
Contributor Author

kravhen commented Dec 29, 2024

I also had a nagging feeling that it could be done simpler and with less code. I restarted from scratch once or twice due to life getting in the way and every time I sat down, seeing things with fresh eyes, I thought I could keep it succinct that time around.

But every time it ended up more verbose than I'd wanted heh.

I think it could be made simpler, but the tradeoff would be that users would have to use the tags in a more restrictive way, following a more opinionated structure or else it wouldn't work. e.g. you must place the tags this exact way or bust.

I'd be glad to see how it's done if the amount of code can be shaved off significantly. I honestly learned a lot about how AST, their manipulation and nodes in general, but I am no pro :P.

Here is what it actually looks like without the yellow so its more light-mode friendly. Screenshot above was if we didn't care about light mode. This is how things actually end up looking like:

sn-details-dark
sn-details-light

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.

Add collapsable answers
2 participants