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(examples): MDUI framework #2976

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/gno.land/p/demo/mdui/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/p/demo/mdui
371 changes: 371 additions & 0 deletions examples/gno.land/p/demo/mdui/mdui.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
package mdui

import (
"strconv"
"strings"
)

type MarkdownBuilder struct {
thanhngoc541 marked this conversation as resolved.
Show resolved Hide resolved
elements []string
}

// NewMarkdownBuilder creates and returns a new MarkdownBuilder instance
func NewMarkdownBuilder() *MarkdownBuilder {
return &MarkdownBuilder{
elements: []string{},
}
}

// AddHeading adds a heading to the MarkdownBuilder
func (b *MarkdownBuilder) AddHeading(level int, text string) *MarkdownBuilder {
heading := Heading(level, text)
b.elements = append(b.elements, heading)
return b
}

// AddParagraph adds a paragraph to the MarkdownBuilder
func (b *MarkdownBuilder) AddParagraph(text string) *MarkdownBuilder {
paragraph := Paragraph(text)
b.elements = append(b.elements, paragraph)
return b
}

// AddButton adds a button (link) to the MarkdownBuilder
func (b *MarkdownBuilder) AddButton(text, href string) *MarkdownBuilder {
button := Button(text, href)
b.elements = append(b.elements, button)
return b
}

// AddImage adds an image to the MarkdownBuilder
func (b *MarkdownBuilder) AddImage(src, alt string) *MarkdownBuilder {
image := Image(src, alt)
b.elements = append(b.elements, image)
return b
}

// AddDivider adds a horizontal rule to the MarkdownBuilder
func (b *MarkdownBuilder) AddDivider() *MarkdownBuilder {
divider := Divider()
b.elements = append(b.elements, divider)
return b
}

// AddList adds a list (ordered or unordered) to the MarkdownBuilder
func (b *MarkdownBuilder) AddList(items []string, ordered bool) *MarkdownBuilder {
list := List(items, ordered)
b.elements = append(b.elements, list)
return b
}

// AddTable adds a table to the MarkdownBuilder
func (b *MarkdownBuilder) AddTable(headers []string, rows [][]string) *MarkdownBuilder {
table := Table(headers, rows)
b.elements = append(b.elements, table)
return b
}

// AddNavbar adds a navigation bar to the MarkdownBuilder
func (b *MarkdownBuilder) AddNavbar(links map[string]string) *MarkdownBuilder {
navbar := Navbar(links)
b.elements = append(b.elements, navbar)
return b
}

// AddQuote adds a blockquote to the MarkdownBuilder
func (b *MarkdownBuilder) AddQuote(text string) *MarkdownBuilder {
quote := Quote(text)
b.elements = append(b.elements, quote)
return b
}

// AddBold adds bold text to the MarkdownBuilder
func (b *MarkdownBuilder) AddBold(text string) *MarkdownBuilder {
bold := Bold(text)
b.elements = append(b.elements, bold)
return b
}

// AddItalic adds italic text to the MarkdownBuilder
func (b *MarkdownBuilder) AddItalic(text string) *MarkdownBuilder {
italic := Italic(text)
b.elements = append(b.elements, italic)
return b
}

// AddStrikethrough adds strikethrough text to the MarkdownBuilder
func (b *MarkdownBuilder) AddStrikethrough(text string) *MarkdownBuilder {
strikethrough := Strikethrough(text)
b.elements = append(b.elements, strikethrough)
return b
}

// AddCodeBlock adds a code block to the MarkdownBuilder
func (b *MarkdownBuilder) AddCodeBlock(code string) *MarkdownBuilder {
codeBlock := CodeBlock(code)
b.elements = append(b.elements, codeBlock)
return b
}

// AddAlert adds an alert box with a specified type to the MarkdownBuilder
func (b *MarkdownBuilder) AddAlert(content, alertType string) *MarkdownBuilder {
alert := Alert(content, alertType)
b.elements = append(b.elements, alert)
return b
}

// AddCollapsible adds a collapsible section to the MarkdownBuilder
func (b *MarkdownBuilder) AddCollapsible(title, content string) *MarkdownBuilder {
collapsible := Collapsible(title, content)
b.elements = append(b.elements, collapsible)
return b
}

// AddFootnote adds a footnote to the MarkdownBuilder
func (b *MarkdownBuilder) AddFootnote(label, text string) *MarkdownBuilder {
footnote := Footnote(label, text)
b.elements = append(b.elements, footnote)
return b
}

// AddBadge adds a badge to the MarkdownBuilder
func (b *MarkdownBuilder) AddBadge(label, color string) *MarkdownBuilder {
badge := Badge(label, color)
b.elements = append(b.elements, badge)
return b
}

// AddBadgeWithIcon adds a badge with an icon to the MarkdownBuilder
func (b *MarkdownBuilder) AddBadgeWithIcon(label, color, icon string) *MarkdownBuilder {
badgeWithIcon := BadgeWithIcon(label, color, icon)
b.elements = append(b.elements, badgeWithIcon)
return b
}

// AddKeyboardShortcut adds a keyboard shortcut to the MarkdownBuilder
func (b *MarkdownBuilder) AddKeyboardShortcut(keys ...string) *MarkdownBuilder {
shortcut := KeyboardShortcut(keys...)
b.elements = append(b.elements, shortcut)
return b
}

// AddBlockquoteWithCitation adds a blockquote with an optional citation to the MarkdownBuilder
func (b *MarkdownBuilder) AddBlockquoteWithCitation(quote, citation string) *MarkdownBuilder {
blockquoteWithCitation := BlockquoteWithCitation(quote, citation)
b.elements = append(b.elements, blockquoteWithCitation)
return b
}

// AddTableOfContents adds a table of contents to the MarkdownBuilder
func (b *MarkdownBuilder) AddTableOfContents(headings []string) *MarkdownBuilder {
toc := TableOfContents(headings)
b.elements = append(b.elements, toc)
return b
}

// AddEmoji adds an emoji to the MarkdownBuilder
func (b *MarkdownBuilder) AddEmoji(name string) *MarkdownBuilder {
emoji := Emoji(name)
b.elements = append(b.elements, emoji)
return b
}

// Render generates and returns the final Markdown content
func (b *MarkdownBuilder) Render() string {
return strings.Join(b.elements, "\n")
}

// AddIfElseRender adds conditional content to the MarkdownBuilder based on a condition
func (b *MarkdownBuilder) AddIfElseRender(condition bool, ifTrue string, ifFalse string) *MarkdownBuilder {
result := IfElseRender(condition, ifTrue, ifFalse)
b.elements = append(b.elements, result)
return b
}

func (b *MarkdownBuilder) AddBreakLine() *MarkdownBuilder {
lineBreak := BreakLine()
b.elements = append(b.elements, lineBreak)
return b
}

// BreakLine generates a Markdown line break (two spaces followed by a newline)
func BreakLine() string {
return " \n" // Two spaces followed by a newline
}

// IfElseRender generates different Markdown output based on a condition
// If the condition is true, it will render the "ifTrue" content.
// Otherwise, it renders the "ifFalse" content.
func IfElseRender(condition bool, ifTrue string, ifFalse string) string {
if condition {
return ifTrue
} else {
return ifFalse
}
}

// Navbar generates a Markdown navigation menu from a map of links
func Navbar(links map[string]string) string {
thanhngoc541 marked this conversation as resolved.
Show resolved Hide resolved
nav := ""
for text, href := range links {
if nav != "" {
nav += " | " // Add a pipe separator between links
}
nav += "[" + text + "](" + href + ")"
}
return nav + "\n"
}

// Heading creates a Markdown heading based on the level
func Heading(level int, text string) string {
if level < 1 || level > 6 {
level = 1
}
headingPrefix := strings.Repeat("#", level)
return headingPrefix + " " + text + "\n"
}

// Button generates a Markdown link styled as a button
func Button(text, href string) string {
return "[" + text + "](" + href + ")"
}

// Image generates Markdown for an image
func Image(src, alt string) string {
return "![" + alt + "](" + src + ")"
}

// CodeBlock wraps code in Markdown code block syntax
func CodeBlock(code string) string {
return "```go\n" + code + "\n```\n"
}
thanhngoc541 marked this conversation as resolved.
Show resolved Hide resolved

// Divider renders a Markdown horizontal rule
func Divider() string {
return "---\n"
}

// Paragraph formats a text paragraph in Markdown
func Paragraph(text string) string {
return text + "\n"
}

// Quote generates a Markdown blockquote
func Quote(text string) string {
return "> " + text + "\n"
}

// List generates a Markdown list (ordered or unordered)
func List(items []string, ordered bool) string {
list := ""
for i, item := range items {
if ordered {
list += strconv.Itoa(i+1) + ". " + item + "\n"
} else {
list += "- " + item + "\n"
}
}
return list
}

// Link generates a Markdown link
func Link(text, href string) string {
return "[" + text + "](" + href + ")"
}

// Table generates a Markdown table
func Table(headers []string, rows [][]string) string {
table := "| " + strings.Join(headers, " | ") + " |\n"
table += "|" + strings.Repeat("---|", len(headers)) + "\n"
for _, row := range rows {
table += "| " + strings.Join(row, " | ") + " |\n"
}
return table
}

// Bold formats text in bold
func Bold(text string) string {
return "**" + text + "**"
}

// Italic formats text in italic
func Italic(text string) string {
return "_" + text + "_"
}

// Strikethrough adds a strikethrough to the text
func Strikethrough(text string) string {
return "~~" + text + "~~"
}

// Alert creates a Markdown-styled alert block with a specified type (info, warning, danger)
func Alert(content, alertType string) string {
var prefix string
switch alertType {
case "info":
prefix = "**ℹ️ Info:** " // Info icon
case "warning":
prefix = "**⚠️ Warning:** " // Warning icon
case "danger":
prefix = "**❌ Danger:** " // Danger icon
default:
prefix = "**ℹ️ Info:** " // Default to info icon
}
return "> " + prefix + content + "\n"
}

// Collapsible creates a collapsible section with a title and content
func Collapsible(title, content string) string {
return "<details>\n<summary>" + title + "</summary>\n\n" + content + "\n\n</details>\n"
}

// Footnote generates a Markdown footnote
func Footnote(label, text string) string {
return "[^" + label + "]: " + text + "\n"
}

// Badge generates a Markdown badge (often used in documentation)
func Badge(label, color string) string {
return "![](https://img.shields.io/badge/" + strings.ReplaceAll(label, " ", "%20") + "-" + color + ")"
}

// TableOfContents generates a simple table of contents based on an array of headings
func TableOfContents(headings []string) string {
toc := "## Table of Contents\n"
for i, heading := range headings {
toc += strconv.Itoa(i+1) + ". [" + heading + "](#" + strings.ToLower(strings.ReplaceAll(heading, " ", "-")) + ")\n"
}
return toc
}

// KeyboardShortcut formats a keyboard shortcut in Markdown using code block style
func KeyboardShortcut(keys ...string) string {
return "`" + strings.Join(keys, " + ") + "`"
}

// Emoji adds an emoji to the content using a shortcode
func Emoji(name string) string {
emojiMap := map[string]string{
"smile": "😊",
"heart": "❤️",
"thumbs_up": "👍",
// Add more emoji mappings as needed
}
if emoji, exists := emojiMap[name]; exists {
return emoji
}
return name
}

// BlockquoteWithCitation generates a Markdown blockquote with an optional citation
func BlockquoteWithCitation(quote, citation string) string {
if citation != "" {
return "> " + quote + "\n> \n> — " + citation + "\n"
}
return "> " + quote + "\n"
}

// BadgeWithIcon generates a Markdown badge with an icon using Shields.io
func BadgeWithIcon(label, color, icon string) string {
return "![](https://img.shields.io/badge/" + icon + "-" + strings.ReplaceAll(label, " ", "%20") + "-" + color + "?style=flat&logo=" + icon + ")"
}
3 changes: 3 additions & 0 deletions examples/gno.land/r/demo/mdui/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module gno.land/r/demo/mdui

require gno.land/p/demo/mdui v0.0.0-latest
Loading