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

feat: add UI components #781

Closed
wants to merge 26 commits into from
Closed

feat: add UI components #781

wants to merge 26 commits into from

Conversation

alexiscolin
Copy link
Member

@alexiscolin alexiscolin commented Apr 26, 2023

Markdown UI components

Starting implementation of #439
Implementation of markdown UI components:

  • Accordion
  • Alert
  • Dropdown
  • Tab
  • Container
  • Icon link
  • Breadcrumb
  • Pagination
  • Buttons
  • Jumbotron / frame
  • Column
  • Stack
  • Typography (title, lists, link, quotes, alignments...)
  • Forms control
  • Form select
  • Form checkboxes and radio

Implementation

Here is the first simple component: Jumbotron (eg bellow).

Capture d’écran 2023-04-26 à 10 43 30

The implementation come from a marked.js extension (in order to avoid useless libs and reuse what is already used), coupled with CSS classes to frame and design it. The idea is to be able to call a component directly from the markdown by using a dedicated convention for components:

:::[component name]
[my component content]
:::

eg:

:::jumbotron
My content in markdown
:::

*Note: using this convention by naming the component would help understand we are manipulating extended markdown UI and quickly use the one we want.

The idea is to iterate and start a conversation over this implementation while I try more complex components such as inputs or Breadcrumb.

The result

The first component can be seen at /r/demo/markdown_test page.

Javascript note

I had to update the main JS function in order to remove the double rendering call from template. It seems the function was created twice (once for #home and another for #realms). I've merged them.

Related with #903

@alexiscolin alexiscolin requested a review from a team as a code owner April 26, 2023 09:02
@alexiscolin alexiscolin marked this pull request as draft April 26, 2023 11:31
@alexiscolin
Copy link
Member Author

alexiscolin commented Apr 26, 2023

A topic that can be discussed about the current implementation is about components nesting.

Right now, components nesting require using plain HTML / class, by using the same component class used by the marked.js component. So, only the way used to call the component (:::jumbotron vs <div class="jumbotron">) is different.
The marked.js (:::jumbotron) one is easier to use and read but currently doesn't allow component nesting.

@moul moul self-requested a review April 26, 2023 16:54
@zivkovicmilos zivkovicmilos linked an issue Apr 27, 2023 that may be closed by this pull request
@tbruyelle
Copy link
Contributor

I defrosted this PR from @moul and added a ui.Jumbotron :)
See commit 4153530

image

@moul
Copy link
Member

moul commented Apr 28, 2023

Thank you @alexiscolin, it looks promising.

@tbruyelle do you have feedback on the #527? I’m looking for feedback to finish a v1.

@github-actions github-actions bot added 🧾 package/realm Tag used for new Realms or Packages. 📦 ⛰️ gno.land Issues or PRs gno.land package related labels Jul 23, 2023
@alexiscolin
Copy link
Member Author

alexiscolin commented Jul 26, 2023

@moul, @tbruyelle I've added all the first components (from the list batch). The code is not perfect yet as I must finish the style and refactor the JS to improve it by factorizing, removing duplicate code and adding a better OOP system across components (so no need to check that yet). But here are the first elements that come to life and with them, some updates regarding the syntax I would like to propose:

:::alert (warning)
Warning content
:::alert/
  • I've added a name closing tag (eg. :::alert/ instead of :::) in order to improve the readability when many components are scoped or when a component is closed far in the code after being opened.
  • I've added parameters entries, between parenthesis, to give more flexibility to components. They are used to customize components for example, the column count, the form url and method, the alert type etc. You can add multiple ones (right now, only :::form component can use two parameters).
  • Allowed self closing components to avoid empty one, for example :::form-input (date)/
  • Some component need dedicated content such as ordered list or unordered list with or without links (:::breadcrumb, :::dropdown or :::form-select for example)

Right now all the components are in the homepage (of course it's temporary, I will move them into /r/demo/markdown_test page), so you can try them. I must stress test them to be sure the markdown regex is robust enough (I'm not a regex fan/expert TBH) and all HTML usecases are met. I also need to check HTML ARIA and restyle them all.

@alexiscolin
Copy link
Member Author

alexiscolin commented Jul 27, 2023

⚠️ 2023-01-08: Render updated here


127 0 0 1_8888_ (3)

@tbruyelle
Copy link
Contributor

This is neat! This will really improve the writing of contract rendering page.

@alexiscolin
Copy link
Member Author

If it's pertinent, I think I could create another PR to improve the style/class nomenclature in order to let people customize the design with their own, by overriding ours. Just like in Docusaurus theme for example.

Copy link
Member

@zivkovicmilos zivkovicmilos left a comment

Choose a reason for hiding this comment

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

I love the direction of this PR, and I can already see how it's going to supercharge our render workflow 🚀

Amazing work, as always 👏

@moul moul added this to the 🌟 main.gno.land (wanted) milestone Sep 8, 2023
@moul
Copy link
Member

moul commented Sep 14, 2023

@alexiscolin you've some comments to address before we can merge; can you give a look and fix them or tell us what you suggest instead?

@alexiscolin alexiscolin added 📖 documentation Improvements or additions to documentation and removed 📖 documentation Improvements or additions to documentation labels Oct 8, 2023
@codecov
Copy link

codecov bot commented Oct 13, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (89428c5) 47.84% compared to head (32f44ad) 47.85%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #781      +/-   ##
==========================================
+ Coverage   47.84%   47.85%   +0.01%     
==========================================
  Files         369      369              
  Lines       62764    63459     +695     
==========================================
+ Hits        30028    30371     +343     
- Misses      30308    30633     +325     
- Partials     2428     2455      +27     
Flag Coverage Δ
gno.land-_test.gnokey ?
gno.land-_test.pkgs ?
tm2-_test.flappy ?
tm2-_test.pkg.amino ?
tm2-_test.pkg.bft ?
tm2-_test.pkg.others ?

Flags with carried forward coverage won't be shown. Click here to find out more.

see 20 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@alexiscolin alexiscolin marked this pull request as ready for review October 19, 2023 21:44
@alexiscolin
Copy link
Member Author

@moul Here is an improved version of this PR. Ready to be reviewed.

@moul
Copy link
Member

moul commented Oct 29, 2023

It looks good.

‘could you make sure to give an example not only with the « ::: » lazy replacements but also for someone they would just use plain markdown and html div?

‘I like the idea of extending markdown in an opinionated way; but dislike the idea of making it mandatory to learn.

Copy link

netlify bot commented Nov 11, 2023

Deploy Preview for gno-docs2 failed.

Name Link
🔨 Latest commit 5bbfea9
🔍 Latest deploy log https://app.netlify.com/sites/gno-docs2/deploys/655014618e536100088cc010

@thehowl
Copy link
Member

thehowl commented Dec 7, 2023

Hey! I've had a look at this. I must thank you, @alexiscolin, for bringing more UI components into our rendering, as it is most definitely needed :)

I'm not sure, however, that I like this solution of extending the markdown syntax with :::. The reason for it is that it seems to me to be doing little in terms of increasing readability as compared to using standard HTML in markdown. One of the things that I don't particularly like is the necessity to still specify start/end tags, and that some components are, in my opinion, made even less readable/flexible than their HTML counterparts, such as the input syntax:

:::input(text, Label, Text)/
  • Unclear how I should specify a label which includes a comma?
  • Why do I need to put a slash at the end? Is this XHTML all over?
  • What if in my design I want to have a lot of tightly-packed input fields, which use the placeholder to indicate what goes there instead of the label?
    • An anti-design pattern, of course, but I don't think the hierarchy of specifying type > label > placeholder > value works 100% of the time.
    • And most importantly, I think being able to understand which one is a label and which one is a placeholder without keeping track of the documentation is important (hence label="my label" is actually preferrable)

My 2c:

  • I think we can make extensions to Markdown rendering slowly and carefully, trying to understand how changes can be added such that they maintain the purpose for markdown to be readable also as plain-text.
  • For now, we can add the components you added as an extension of the ui package, by simply having them render as markdown. This way we can also ensure to make programmatic "safe" rendering.
  • By ensuring a programmatic approach which for now renders HTML, we can ensure that the same code will be able to work when we switch to a different custom syntax.

A couple ideas for how I could see, for instance, syntax extensions that render the elements you created:

-----------------------------------------
> # Jumbotron
> 
> This could be the special syntax for a jumbotron.
-----------------------------------------

breadcrumb:

1/ [Home](/)
2/ [Users](/r/demo/users)
3/ user:morgan

This may not be the best, but it is roughly how I think we should go about this, in order to make sure that plain text works too.

@alexiscolin
Copy link
Member Author

alexiscolin commented Jan 24, 2024

@moul @tbruyelle @zivkovicmilos @thehowl
I was looking at this PR and all comments. The markdown prefix and the way the md components are designed/built has not reached a consensus. Also, I'm not entirely satisfied with the HTML version (see why bellow).
As this PR is now very old I would like to push another way to achieve this, maybe in another PR:

Instead of using html/css and markdown components, I would introduce native web-components.

It would look like that:

<accordion title="Accordion title"> 
   Accordion content
</accordion>

Instead of that:

<button class="gno-btn gno-accordion-trigger" aria-expanded="true" type="button" id="gno-accordion-[UNIQUE-ID]">Accordion title</button>
<div class="gno-accordion-panel" role="region">
   Accordion content
</div>

Here is the improvements I see in this update:

  • Web components are native js components and not emulated markdown components. So it's a W3C standard, that doesn't rely on framework (such as React or Vue...).

  • The standard is html based so it's natively compatible with markdown.

  • It's a way to write less html tags and inner attribute (ARIA, id...) and class but keeping the same basic syntax. For example, the html accordion currently needs many inner div and attributes. It's harder to read, can pollute the markdown default simplicity and it is error prone (you have to read/copy past the code from the doc)

  • It's simple to read and understand what kind of component it is. We don't have to find a className between a multitude of attributes to understand what component it is.

  • It's not a markdown extension, so the prefix is not a topic.

  • It's simple to know what attribute is for what and you can omit some as it's not a function with a ordered list of arguments.

  • It is easier to mix and to couple with inner components (slots), ensuring it keeps inner scope thanks to shadow-dom usage.

  • @thehowl also mentions the fact that it is relatively straightforward to filter out the resulting HTML to only allow "good tags" and it can be parsed and used for non-HTML outputs as well

@tbruyelle
Copy link
Contributor

@alexiscolin I agree with all your points, what about browser compatibility ? The last time I read about web-components, some javascript library client had to be used to make them work properly.

@alexiscolin
Copy link
Member Author

alexiscolin commented Jan 24, 2024

@tbruyelle Yes I also thought about the browsers compatibility because I had the same feeling. It used to be an issue but now (except for some specific use cases - Cross-root Aria Delegation for example), web-components seems widely supported.

@tbruyelle
Copy link
Contributor

@alexiscolin That's nice! Though I wonder how web-components fit in with the no-JS compatibility required by gno pages (if that requirement is still relevant).

@alexiscolin
Copy link
Member Author

alexiscolin commented Jan 24, 2024

no-JS compatibility required by gno pages

@tbruyelle What is that? The whole markdown system relies on JS, even md components 🤔. Being read as raw md?

@tbruyelle
Copy link
Contributor

@alexiscolin oh OK, I though this was server-side rendered!

@thehowl
Copy link
Member

thehowl commented Jan 26, 2024

@tbruyelle: Though I wonder how web-components fit in with the no-JS compatibility required by gno pages

So, we shouldn't have <script> tags in the Markdown output as a way to have dynamic data on Gno pages. This is not what Alexis is suggesting, but we can use web extension tags to support extra functionality (which would be implemented as JS in gnoweb) while still providing a decently readable Markdown experience, also in plain text.

This also means, for instance, that it's still possible to write a native rendering of a Gno's realm Render function (ie. on mobile), without having to eval() JS code. You'd just need to re-implement the web components @alexiscolin is writing :)

I'm in favour of this approach, as it also means we're not adding any special properties to the markdown/commonmark spec. 👍 🎉 😄

@alexiscolin alexiscolin closed this by deleting the head repository Feb 8, 2024
@alexiscolin
Copy link
Member Author

I'm currently creating a new PR with dedicated web-components

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 ⛰️ gno.land Issues or PRs gno.land package related 🧾 package/realm Tag used for new Realms or Packages.
Projects
Status: 🌟 Wanted for Launch
Archived in project
Development

Successfully merging this pull request may close these issues.

Proposal: extend markdown rendering
6 participants