improve the page, sections, components

This commit is contained in:
2025-08-22 00:51:55 -06:00
parent e28b6c89ef
commit da43647b54
5 changed files with 1262 additions and 911 deletions

File diff suppressed because one or more lines are too long

View File

@ -2,13 +2,13 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil"
"masonry/lang" "masonry/lang"
"os"
) )
func main() { func main() {
// Read the example.masonry file // Read the example.masonry file
content, err := ioutil.ReadFile("example.masonry") content, err := os.ReadFile("example.masonry")
if err != nil { if err != nil {
fmt.Printf("Error reading example.masonry: %v\n", err) fmt.Printf("Error reading example.masonry: %v\n", err)
return return
@ -20,7 +20,7 @@ func main() {
if err != nil { if err != nil {
fmt.Printf("Error: %v\n", err) fmt.Printf("Error: %v\n", err)
} else { } else {
fmt.Printf("🎉 Successfully parsed complete DSL with pages!\n\n") fmt.Printf("🎉 Successfully parsed enhanced DSL with containers and detailed fields!\n\n")
for _, def := range ast.Definitions { for _, def := range ast.Definitions {
if def.Server != nil { if def.Server != nil {
@ -55,6 +55,27 @@ func main() {
if field.Default != nil { if field.Default != nil {
fmt.Printf(" default=%s", *field.Default) fmt.Printf(" default=%s", *field.Default)
} }
if field.Relationship != nil {
fmt.Printf(" relates to %s as %s", field.Relationship.Type, field.Relationship.Cardinality)
if field.Relationship.ForeignKey != nil {
fmt.Printf(" via %s", *field.Relationship.ForeignKey)
}
if field.Relationship.Through != nil {
fmt.Printf(" through %s", *field.Relationship.Through)
}
}
if len(field.Validations) > 0 {
fmt.Printf(" validates: ")
for i, val := range field.Validations {
if i > 0 {
fmt.Printf(", ")
}
fmt.Printf("%s", val.Type)
if val.Value != nil {
fmt.Printf("(%s)", *val.Value)
}
}
}
fmt.Printf("\n") fmt.Printf("\n")
} }
fmt.Printf("\n") fmt.Printf("\n")
@ -72,7 +93,31 @@ func main() {
if endpoint.Auth { if endpoint.Auth {
fmt.Printf(" [AUTH]") fmt.Printf(" [AUTH]")
} }
fmt.Printf("\n\n") fmt.Printf("\n")
for _, param := range endpoint.Params {
fmt.Printf(" param %s: %s from %s", param.Name, param.Type, param.Source)
if param.Required {
fmt.Printf(" (required)")
}
fmt.Printf("\n")
}
if endpoint.Response != nil {
fmt.Printf(" returns %s", endpoint.Response.Type)
if endpoint.Response.Format != nil {
fmt.Printf(" as %s", *endpoint.Response.Format)
}
if len(endpoint.Response.Fields) > 0 {
fmt.Printf(" fields: %v", endpoint.Response.Fields)
}
fmt.Printf("\n")
}
if endpoint.CustomLogic != nil {
fmt.Printf(" custom logic: %s\n", *endpoint.CustomLogic)
}
fmt.Printf("\n")
} }
if def.Page != nil { if def.Page != nil {
@ -87,23 +132,139 @@ func main() {
fmt.Printf("\n") fmt.Printf("\n")
fmt.Printf(" Layout: %s\n", page.Layout) fmt.Printf(" Layout: %s\n", page.Layout)
if page.LayoutType != nil {
fmt.Printf(" Layout Type: %s\n", *page.LayoutType)
}
for _, meta := range page.Meta { for _, meta := range page.Meta {
fmt.Printf(" Meta %s: %s\n", meta.Name, meta.Content) fmt.Printf(" Meta %s: %s\n", meta.Name, meta.Content)
} }
// Display containers
for _, container := range page.Containers {
fmt.Printf(" 📦 Container: %s", container.Type)
if container.Class != nil {
fmt.Printf(" class=\"%s\"", *container.Class)
}
fmt.Printf("\n")
for _, section := range container.Sections {
fmt.Printf(" 📂 Section: %s", section.Name)
if section.Class != nil {
fmt.Printf(" class=\"%s\"", *section.Class)
}
fmt.Printf("\n")
for _, comp := range section.Components {
displayComponent(comp, " ")
}
for _, panel := range section.Panels {
fmt.Printf(" 🗂️ Panel: %s trigger=\"%s\"", panel.Name, panel.Trigger)
if panel.Position != nil {
fmt.Printf(" position=\"%s\"", *panel.Position)
}
fmt.Printf("\n")
for _, comp := range panel.Components {
displayComponent(comp, " ")
}
}
}
for _, tab := range container.Tabs {
fmt.Printf(" 📋 Tab: %s label=\"%s\"", tab.Name, tab.Label)
if tab.Active {
fmt.Printf(" (active)")
}
fmt.Printf("\n")
for _, comp := range tab.Components {
displayComponent(comp, " ")
}
}
for _, comp := range container.Components {
displayComponent(comp, " ")
}
}
// Display direct components
for _, comp := range page.Components { for _, comp := range page.Components {
fmt.Printf(" 📦 Component: %s", comp.Type) displayComponent(comp, " ")
}
// Display modals
for _, modal := range page.Modals {
fmt.Printf(" 🪟 Modal: %s trigger=\"%s\"\n", modal.Name, modal.Trigger)
for _, comp := range modal.Components {
displayComponent(comp, " ")
}
}
// Display master-detail layout
if page.MasterDetail != nil {
fmt.Printf(" 🔄 Master-Detail Layout\n")
if page.MasterDetail.Master != nil {
fmt.Printf(" 📋 Master: %s\n", page.MasterDetail.Master.Name)
for _, comp := range page.MasterDetail.Master.Components {
displayComponent(comp, " ")
}
}
if page.MasterDetail.Detail != nil {
fmt.Printf(" 📄 Detail: %s", page.MasterDetail.Detail.Name)
if page.MasterDetail.Detail.Trigger != nil {
fmt.Printf(" trigger=\"%s\"", *page.MasterDetail.Detail.Trigger)
}
fmt.Printf("\n")
for _, comp := range page.MasterDetail.Detail.Components {
displayComponent(comp, " ")
}
}
}
fmt.Printf("\n")
}
}
}
}
func displayComponent(comp lang.Component, indent string) {
fmt.Printf("%s🧩 Component: %s", indent, comp.Type)
if comp.Entity != nil { if comp.Entity != nil {
fmt.Printf(" for %s", *comp.Entity) fmt.Printf(" for %s", *comp.Entity)
} }
fmt.Printf("\n") fmt.Printf("\n")
for _, attr := range comp.Config { // Process elements to extract fields, config, conditions, sections, and actions
var fields []lang.ComponentField
var config []lang.ComponentAttr
var conditions []lang.WhenCondition
var sections []lang.ComponentSection
var actions []lang.ComponentButtonAttr
for _, element := range comp.Elements {
if element.Field != nil {
fields = append(fields, *element.Field)
}
if element.Config != nil {
config = append(config, *element.Config)
}
if element.Condition != nil {
conditions = append(conditions, *element.Condition)
}
if element.Section != nil {
sections = append(sections, *element.Section)
}
if element.Action != nil {
actions = append(actions, *element.Action)
}
}
// Display config attributes
for _, attr := range config {
if attr.Fields != nil { if attr.Fields != nil {
fmt.Printf(" fields: %v\n", attr.Fields.Fields) fmt.Printf("%s fields: %v\n", indent, attr.Fields.Fields)
} }
if attr.Actions != nil { if attr.Actions != nil {
fmt.Printf(" actions: ") fmt.Printf("%s actions: ", indent)
for i, action := range attr.Actions.Actions { for i, action := range attr.Actions.Actions {
if i > 0 { if i > 0 {
fmt.Printf(", ") fmt.Printf(", ")
@ -116,24 +277,24 @@ func main() {
fmt.Printf("\n") fmt.Printf("\n")
} }
if attr.DataSource != nil { if attr.DataSource != nil {
fmt.Printf(" data from: %s\n", attr.DataSource.Endpoint) fmt.Printf("%s data from: %s\n", indent, attr.DataSource.Endpoint)
} }
if attr.Style != nil { if attr.Style != nil {
fmt.Printf(" style: %s", *attr.Style.Theme) fmt.Printf("%s style: %s", indent, *attr.Style.Theme)
if len(attr.Style.Classes) > 0 { if len(attr.Style.Classes) > 0 {
fmt.Printf(" classes: %v", attr.Style.Classes) fmt.Printf(" classes: %v", attr.Style.Classes)
} }
fmt.Printf("\n") fmt.Printf("\n")
} }
if attr.Pagination != nil { if attr.Pagination != nil {
fmt.Printf(" pagination: enabled") fmt.Printf("%s pagination: enabled", indent)
if attr.Pagination.PageSize != nil { if attr.Pagination.PageSize != nil {
fmt.Printf(" size %d", *attr.Pagination.PageSize) fmt.Printf(" size %d", *attr.Pagination.PageSize)
} }
fmt.Printf("\n") fmt.Printf("\n")
} }
if attr.Filters != nil { if attr.Filters != nil {
fmt.Printf(" filters: ") fmt.Printf("%s filters: ", indent)
for i, filter := range attr.Filters.Filters { for i, filter := range attr.Filters.Filters {
if i > 0 { if i > 0 {
fmt.Printf(", ") fmt.Printf(", ")
@ -146,12 +307,165 @@ func main() {
fmt.Printf("\n") fmt.Printf("\n")
} }
if attr.Validation { if attr.Validation {
fmt.Printf(" validation: enabled\n") fmt.Printf("%s validation: enabled\n", indent)
}
}
// Display enhanced fields
for _, field := range fields {
fmt.Printf("%s 📝 Field: %s type %s", indent, field.Name, field.Type)
// Process attributes
for _, attr := range field.Attributes {
if attr.Label != nil {
fmt.Printf(" label=\"%s\"", *attr.Label)
}
if attr.Placeholder != nil {
fmt.Printf(" placeholder=\"%s\"", *attr.Placeholder)
}
if attr.Required {
fmt.Printf(" (required)")
}
if attr.Sortable {
fmt.Printf(" (sortable)")
}
if attr.Searchable {
fmt.Printf(" (searchable)")
}
if attr.Thumbnail {
fmt.Printf(" (thumbnail)")
}
if attr.Default != nil {
fmt.Printf(" default=\"%s\"", *attr.Default)
}
if len(attr.Options) > 0 {
fmt.Printf(" options=%v", attr.Options)
}
if attr.Accept != nil {
fmt.Printf(" accept=\"%s\"", *attr.Accept)
}
if attr.Rows != nil {
fmt.Printf(" rows=%d", *attr.Rows)
}
if attr.Format != nil {
fmt.Printf(" format=\"%s\"", *attr.Format)
}
if attr.Size != nil {
fmt.Printf(" size=\"%s\"", *attr.Size)
}
if attr.Source != nil {
fmt.Printf(" source=\"%s\"", *attr.Source)
}
if attr.Display != nil {
fmt.Printf(" display=\"%s\"", *attr.Display)
}
if attr.Value != nil {
fmt.Printf(" value=\"%s\"", *attr.Value)
}
if attr.Relates != nil {
fmt.Printf(" relates to %s", attr.Relates.Type)
}
if attr.Validation != nil {
fmt.Printf(" validates: %s", attr.Validation.Type)
if attr.Validation.Value != nil {
fmt.Printf("(%s)", *attr.Validation.Value)
} }
} }
} }
fmt.Printf("\n") fmt.Printf("\n")
} }
// Display conditions
for _, condition := range conditions {
fmt.Printf("%s 🔀 When %s %s \"%s\":\n", indent, condition.Field, condition.Operator, condition.Value)
for _, field := range condition.Fields {
fmt.Printf("%s 📝 Field: %s type %s", indent, field.Name, field.Type)
// Process attributes for conditional fields
for _, attr := range field.Attributes {
if attr.Label != nil {
fmt.Printf(" label=\"%s\"", *attr.Label)
} }
if len(attr.Options) > 0 {
fmt.Printf(" options=%v", attr.Options)
}
}
fmt.Printf("\n")
}
for _, section := range condition.Sections {
fmt.Printf("%s 📂 Section: %s\n", indent, section.Name)
}
for _, button := range condition.Buttons {
fmt.Printf("%s 🔘 Button: %s label=\"%s\"", indent, button.Name, button.Label)
if button.Style != nil {
fmt.Printf(" style=\"%s\"", *button.Style)
}
fmt.Printf("\n")
}
}
// Display sections
for _, section := range sections {
fmt.Printf("%s 📂 Section: %s", indent, section.Name)
if section.Class != nil {
fmt.Printf(" class=\"%s\"", *section.Class)
}
fmt.Printf("\n")
for _, field := range section.Fields {
fmt.Printf("%s 📝 Field: %s type %s", indent, field.Name, field.Type)
// Process attributes for section fields
for _, attr := range field.Attributes {
if attr.Label != nil {
fmt.Printf(" label=\"%s\"", *attr.Label)
}
}
fmt.Printf("\n")
}
for _, button := range section.Buttons {
fmt.Printf("%s 🔘 Button: %s label=\"%s\"", indent, button.Name, button.Label)
if button.Style != nil {
fmt.Printf(" style=\"%s\"", *button.Style)
}
if button.Via != nil {
fmt.Printf(" via=\"%s\"", *button.Via)
}
fmt.Printf("\n")
}
for _, action := range section.Actions {
fmt.Printf("%s ⚡ Action: %s label=\"%s\"", indent, action.Name, action.Label)
if action.Style != nil {
fmt.Printf(" style=\"%s\"", *action.Style)
}
fmt.Printf("\n")
}
}
// Display direct actions/buttons
for _, action := range actions {
fmt.Printf("%s 🔘 Button: %s label=\"%s\"", indent, action.Name, action.Label)
if action.Style != nil {
fmt.Printf(" style=\"%s\"", *action.Style)
}
if action.Icon != nil {
fmt.Printf(" icon=\"%s\"", *action.Icon)
}
if action.Loading != nil {
fmt.Printf(" loading=\"%s\"", *action.Loading)
}
if action.Disabled != nil {
fmt.Printf(" disabled when %s", *action.Disabled)
}
if action.Confirm != nil {
fmt.Printf(" confirm=\"%s\"", *action.Confirm)
}
if action.Target != nil {
fmt.Printf(" target=\"%s\"", *action.Target)
}
if action.Position != nil {
fmt.Printf(" position=\"%s\"", *action.Position)
}
if action.Via != nil {
fmt.Printf(" via=\"%s\"", *action.Via)
}
fmt.Printf("\n")
} }
} }

View File

@ -1,5 +1,5 @@
// Example Masonry DSL definition // Enhanced Masonry DSL example demonstrating new features
// This demonstrates the comprehensive language structure // This shows the comprehensive language structure with containers, detailed fields, and layouts
// Server configuration // Server configuration
server MyApp host "localhost" port 8080 server MyApp host "localhost" port 8080
@ -65,61 +65,122 @@ endpoint POST "/posts" for Post desc "Create post" auth
param post_data: object required from body param post_data: object required from body
returns object fields [id, title, content, author_id] returns object fields [id, title, content, author_id]
// Frontend pages with components // Enhanced User Management page with container layout
page UserManagement at "/admin/users" layout AdminLayout title "User Management" auth page UserManagement at "/admin/users" layout AdminLayout title "User Management" auth
meta description "Manage system users" meta description "Manage system users"
meta keywords "users, admin, management" meta keywords "users, admin, management"
component Table for User container main class "grid grid-cols-3 gap-4"
fields [email, name, id] section sidebar class "col-span-1"
actions [edit via "/users/{id}", delete via "/users/{id}", create via "/users"] component UserStats for User
data from "/users" data from "/users/stats"
style modern classes ["table-striped", "table-hover"]
pagination size 20
filters [email as text label "Search email", name as text label "Search name"]
validate
section content class "col-span-2"
component UserTable for User
fields [email, name, role, created_at]
actions [edit, delete, view]
data from "/users"
panel UserEditPanel for User trigger "edit" position "slide-right"
component UserForm for User
field email type text label "Email" required
field name type text label "Name" required
field role type select options ["admin", "user"]
button save label "Save User" style "primary" via "/users/{id}"
button cancel label "Cancel" style "secondary"
// Enhanced Form component with detailed field configurations
page UserFormPage at "/admin/users/new" layout AdminLayout title "Create User" auth
component Form for User component Form for User
fields [email, name] field email type text label "Email Address" placeholder "Enter your email" required validate email
actions [save via "/users", cancel] field name type text label "Full Name" placeholder "Enter your full name" required
style clean field role type select label "User Role" options ["admin", "user", "moderator"] default "user"
validate field avatar type file label "Profile Picture" accept "image/*"
field bio type textarea label "Biography" placeholder "Tell us about yourself" rows 4
page UserList at "/users" layout MainLayout title "Users" when role equals "admin"
meta description "Browse all users" field permissions type multiselect label "Permissions"
options ["users.manage", "posts.manage", "system.config"]
component Table for User section actions
fields [email, name] button save label "Save User" style "primary" loading "Saving..." via "/users"
button cancel label "Cancel" style "secondary"
// Dashboard with tabbed interface
page Dashboard at "/dashboard" layout MainLayout title "Dashboard"
container tabs
tab overview label "Overview" active
component StatsCards
component RecentActivity
tab users label "Users"
component UserTable for User
data from "/users" data from "/users"
pagination size 10
filters [name as text label "Search by name"]
tab posts label "Posts"
component PostTable for Post
data from "/posts"
modal CreateUserModal trigger "create-user"
component UserForm for User
field email type text label "Email" required
field name type text label "Name" required
button save label "Create" via "/users"
button cancel label "Cancel"
// Post Management with master-detail layout
page PostManagement at "/admin/posts" layout AdminLayout title "Post Management" auth page PostManagement at "/admin/posts" layout AdminLayout title "Post Management" auth
meta description "Manage blog posts" layout "master-detail"
meta keywords "posts, blog, content"
master PostList
component Table for Post component Table for Post
fields [title, author_id, published, created_at] field title type text label "Title" sortable
actions [edit via "/posts/{id}", delete via "/posts/{id}", create via "/posts"] field author type relation label "Author" display "name" relates to User
data from "/posts" field status type badge label "Status"
style modern
pagination size 15
filters [title as text label "Search title", published as select label "Published status"]
validate
page CreatePost at "/posts/new" layout MainLayout title "Create Post" auth detail PostEditor trigger "edit"
component Form for Post component Form for Post
fields [title, content] section basic class "mb-4"
actions [save via "/posts", cancel] field title type text label "Post Title" required
style clean field content type richtext label "Content" required
validate
page BlogList at "/blog" layout PublicLayout title "Blog Posts" section metadata class "grid grid-cols-2 gap-4"
meta description "Read our latest blog posts" field author_id type autocomplete label "Author"
meta keywords "blog, articles, content" source "/users" display "name" value "id"
field published type toggle label "Published" default "false"
field tags type multiselect label "Tags"
source "/tags" display "name" value "id"
component Table for Post // Simple table component with smart defaults
fields [title, created_at] page SimpleUserList at "/users" layout MainLayout title "Users"
data from "/posts" component SimpleTable for User
pagination size 5 fields [email, name, created_at]
filters [title as text label "Search posts"] actions [edit, delete]
data from "/users"
// Detailed table when more control is needed
page DetailedUserList at "/admin/users/detailed" layout AdminLayout title "Detailed User Management" auth
component DetailedTable for User
field email type text label "Email Address"
field name type text label "Full Name"
data from "/users"
pagination size 20
// Conditional rendering example
page ConditionalForm at "/conditional" layout MainLayout title "Conditional Form"
component UserForm for User
field email type text label "Email" required
field role type select options ["admin", "user", "moderator"]
when role equals "admin"
field permissions type multiselect label "Admin Permissions"
options ["users.manage", "posts.manage", "system.config"]
when role equals "moderator"
field moderation_level type select label "Moderation Level"
options ["basic", "advanced", "full"]
section actions
button save label "Save User" style "primary" loading "Saving..."
button cancel label "Cancel" style "secondary"

View File

@ -88,7 +88,7 @@ type ResponseSpec struct {
Fields []string `parser:"('fields' '[' @Ident (',' @Ident)* ']')?"` Fields []string `parser:"('fields' '[' @Ident (',' @Ident)* ']')?"`
} }
// Page definitions for frontend with clean syntax // Enhanced Page definitions with layout containers and composition
type Page struct { type Page struct {
Name string `parser:"'page' @Ident"` Name string `parser:"'page' @Ident"`
Path string `parser:"'at' @String"` Path string `parser:"'at' @String"`
@ -96,8 +96,12 @@ type Page struct {
Title *string `parser:"('title' @String)?"` Title *string `parser:"('title' @String)?"`
Description *string `parser:"('desc' @String)?"` Description *string `parser:"('desc' @String)?"`
Auth bool `parser:"@'auth'?"` Auth bool `parser:"@'auth'?"`
LayoutType *string `parser:"('layout' @String)?"`
Meta []MetaTag `parser:"@@*"` Meta []MetaTag `parser:"@@*"`
MasterDetail *MasterDetail `parser:"@@?"`
Containers []Container `parser:"@@*"`
Components []Component `parser:"@@*"` Components []Component `parser:"@@*"`
Modals []Modal `parser:"@@*"`
} }
// Meta tags for SEO // Meta tags for SEO
@ -106,14 +110,153 @@ type MetaTag struct {
Content string `parser:"@String"` Content string `parser:"@String"`
} }
// Component definitions with endpoint references // Container types for layout organization
type Container struct {
Type string `parser:"'container' @Ident"`
Class *string `parser:"('class' @String)?"`
Sections []Section `parser:"@@*"`
Tabs []Tab `parser:"@@*"`
Components []Component `parser:"@@*"`
}
// Sections within containers
type Section struct {
Name string `parser:"'section' @Ident"`
Class *string `parser:"('class' @String)?"`
Components []Component `parser:"@@*"`
Panels []Panel `parser:"@@*"`
}
// Tab definitions for tabbed interfaces
type Tab struct {
Name string `parser:"'tab' @Ident"`
Label string `parser:"'label' @String"`
Active bool `parser:"@'active'?"`
Components []Component `parser:"@@*"`
}
// Panel definitions for slide-out or overlay interfaces
type Panel struct {
Name string `parser:"'panel' @Ident"`
Entity *string `parser:"('for' @Ident)?"`
Trigger string `parser:"'trigger' @String"`
Position *string `parser:"('position' @String)?"`
Components []Component `parser:"@@*"`
}
// Modal definitions
type Modal struct {
Name string `parser:"'modal' @Ident"`
Trigger string `parser:"'trigger' @String"`
Components []Component `parser:"@@*"`
}
// Master-detail layout components - simplified parsing
type MasterDetail struct {
Master *MasterSection `parser:"'master' @@"`
Detail *DetailSection `parser:"'detail' @@"`
}
type MasterSection struct {
Name string `parser:"@Ident"`
Components []Component `parser:"@@*"`
}
type DetailSection struct {
Name string `parser:"@Ident"`
Trigger *string `parser:"('trigger' @String)?"`
Components []Component `parser:"@@*"`
}
// Enhanced Component definitions with detailed field configurations
type Component struct { type Component struct {
Type string `parser:"'component' @Ident"` Type string `parser:"'component' @Ident"`
Entity *string `parser:"('for' @Ident)?"` Entity *string `parser:"('for' @Ident)?"`
Config []ComponentAttr `parser:"@@*"` Elements []ComponentElement `parser:"@@*"`
} }
// Component attributes and configurations // Union type for component elements to allow flexible ordering
type ComponentElement struct {
Config *ComponentAttr `parser:"@@"`
Field *ComponentField `parser:"| @@"`
Condition *WhenCondition `parser:"| @@"`
Section *ComponentSection `parser:"| @@"`
Action *ComponentButtonAttr `parser:"| @@"`
}
// Enhanced component field with detailed configuration using flexible attributes
type ComponentField struct {
Name string `parser:"'field' @Ident"`
Type string `parser:"'type' @Ident"`
Attributes []ComponentFieldAttribute `parser:"@@*"`
}
// Flexible field attribute system
type ComponentFieldAttribute struct {
Label *string `parser:"('label' @String)"`
Placeholder *string `parser:"| ('placeholder' @String)"`
Required bool `parser:"| @'required'"`
Sortable bool `parser:"| @'sortable'"`
Searchable bool `parser:"| @'searchable'"`
Thumbnail bool `parser:"| @'thumbnail'"`
Default *string `parser:"| ('default' @String)"`
Options []string `parser:"| ('options' '[' @String (',' @String)* ']')"`
Accept *string `parser:"| ('accept' @String)"`
Rows *int `parser:"| ('rows' @Int)"`
Format *string `parser:"| ('format' @String)"`
Size *string `parser:"| ('size' @String)"`
Display *string `parser:"| ('display' @String)"`
Value *string `parser:"| ('value' @String)"`
Source *string `parser:"| ('source' @String)"`
Relates *FieldRelation `parser:"| @@"`
Validation *ComponentValidation `parser:"| @@"`
}
// Field relationship for autocomplete and select fields
type FieldRelation struct {
Type string `parser:"'relates' 'to' @Ident"`
}
// Component validation
type ComponentValidation struct {
Type string `parser:"'validate' @Ident"`
Value *string `parser:"@String?"`
}
// Conditional rendering
type WhenCondition struct {
Field string `parser:"'when' @Ident"`
Operator string `parser:"@('equals' | 'not_equals' | 'contains')"`
Value string `parser:"@String"`
Fields []ComponentField `parser:"@@*"`
Sections []ComponentSection `parser:"@@*"`
Buttons []ComponentButtonAttr `parser:"@@*"`
}
// Component sections for grouping
type ComponentSection struct {
Name string `parser:"'section' @Ident"`
Class *string `parser:"('class' @String)?"`
Fields []ComponentField `parser:"@@*"`
Buttons []ComponentButtonAttr `parser:"@@*"`
Actions []ComponentButtonAttr `parser:"@@*"`
}
// Enhanced component buttons/actions with detailed configuration
type ComponentButtonAttr struct {
Name string `parser:"'button' @Ident"`
Label string `parser:"'label' @String"`
Style *string `parser:"('style' @String)?"`
Icon *string `parser:"('icon' @String)?"`
Loading *string `parser:"('loading' @String)?"`
Disabled *string `parser:"('disabled' 'when' @Ident)?"`
Confirm *string `parser:"('confirm' @String)?"`
Target *string `parser:"('target' @Ident)?"`
Position *string `parser:"('position' @String)?"`
Via *string `parser:"('via' @String)?"`
}
// Component attributes and configurations (keeping existing for backward compatibility)
type ComponentAttr struct { type ComponentAttr struct {
Fields *ComponentFields `parser:"@@"` Fields *ComponentFields `parser:"@@"`
Actions *ComponentActions `parser:"| @@"` Actions *ComponentActions `parser:"| @@"`
@ -124,19 +267,25 @@ type ComponentAttr struct {
Validation bool `parser:"| @'validate'"` Validation bool `parser:"| @'validate'"`
} }
// Component field specification // Component field specification (simple version for backward compatibility)
type ComponentFields struct { type ComponentFields struct {
Fields []string `parser:"'fields' '[' @Ident (',' @Ident)* ']'"` Fields []string `parser:"'fields' '[' @Ident (',' @Ident)* ']'"`
} }
// Component actions (can reference endpoints) // Enhanced component actions
type ComponentActions struct { type ComponentActions struct {
Actions []ComponentAction `parser:"'actions' '[' @@ (',' @@)* ']'"` Actions []ComponentAction `parser:"'actions' '[' @@ (',' @@)* ']'"`
} }
type ComponentAction struct { type ComponentAction struct {
Name string `parser:"@Ident"` Name string `parser:"@Ident"`
Label *string `parser:"('label' @String)?"`
Icon *string `parser:"('icon' @String)?"`
Style *string `parser:"('style' @String)?"`
Endpoint *string `parser:"('via' @String)?"` Endpoint *string `parser:"('via' @String)?"`
Target *string `parser:"('target' @Ident)?"`
Position *string `parser:"('position' @String)?"`
Confirm *string `parser:"('confirm' @String)?"`
} }
// Data source configuration (can reference endpoints) // Data source configuration (can reference endpoints)

File diff suppressed because it is too large Load Diff