twostraws / Ignite

A static site generator for Swift developers.
MIT License
984 stars 34 forks source link

Feature Request: @BlockElementBuilder func body() -> some BlockElement { #23

Open Abdiloki opened 1 month ago

Abdiloki commented 1 month ago

Property wrappers to aid in code extractions and organization. Internally Ignite has several ElementBuilder typealias, it would be useful to have public facing property wrappers for them:

//ElementBuilder.swift
typealias BlockElementBuilder = ElementBuilder<BlockElement>
typealias HeadElementBuilder = ElementBuilder<HeadElement>
typealias HTMLRootElementBuilder = ElementBuilder<HTMLRootElement>
typealias InlineElementBuilder = ElementBuilder<InlineElement>
typealias PageElementBuilder = ElementBuilder<PageElement>
typealias StaticPageBuilder = ElementBuilder<any StaticPage>
typealias ContentPageBuilder = ElementBuilder<any ContentPage>

✅ These compile

func bottomInfoSection()->BlockElement{
    Text("Thank you for reading this page")
        .font(.title6)
        .id("bottom-info")
}
func bottomInfoSection()->BlockElement{
    Group{
        let id:String = "bottom-info"
        Text("Thank you for reading this page")
            .font(.title6)
            .id(id)
        Script(code:"document.getElementById('\(id)').addEventListener('contextmenu',e=>alert(e.target.innerText))")
    }
}

❌ But these don't

//Error: Missing return in instance method expected to return 'any BlockElement'

func bottomInfoSection()->BlockElement{
    let id:String = "bottom-info"
    Text("Thank you for reading this page")
        .font(.title6)
        .id(id)
}
func bottomInfoSection()->BlockElement{
    let id:String = "bottom-info"
    Text("Thank you for reading this page")
        .font(.title6)
        .id(id)
    Script(code:"document.getElementById('\(id)').addEventListener('contextmenu',e=>alert(e.target.innerText))")
}

Something like:

@BlockElementBuilder
func bottomInfoSection()->some BlockElement{ ... }
@ElementBuilder 
func bottomInfoSection()->some BlockElement{ ... }
twostraws commented 1 month ago

Although this is both possible and easy to do, I wonder whether you're looking for the Component protocol to achieve what you want?