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 (
"fmt"
"io/ioutil"
"masonry/lang"
"os"
)
func main() {
// Read the example.masonry file
content, err := ioutil.ReadFile("example.masonry")
content, err := os.ReadFile("example.masonry")
if err != nil {
fmt.Printf("Error reading example.masonry: %v\n", err)
return
@ -20,7 +20,7 @@ func main() {
if err != nil {
fmt.Printf("Error: %v\n", err)
} 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 {
if def.Server != nil {
@ -55,6 +55,27 @@ func main() {
if field.Default != nil {
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")
@ -72,7 +93,31 @@ func main() {
if endpoint.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 {
@ -87,66 +132,91 @@ func main() {
fmt.Printf("\n")
fmt.Printf(" Layout: %s\n", page.Layout)
if page.LayoutType != nil {
fmt.Printf(" Layout Type: %s\n", *page.LayoutType)
}
for _, meta := range page.Meta {
fmt.Printf(" Meta %s: %s\n", meta.Name, meta.Content)
}
for _, comp := range page.Components {
fmt.Printf(" 📦 Component: %s", comp.Type)
if comp.Entity != nil {
fmt.Printf(" for %s", *comp.Entity)
// 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 _, attr := range comp.Config {
if attr.Fields != nil {
fmt.Printf(" fields: %v\n", attr.Fields.Fields)
for _, section := range container.Sections {
fmt.Printf(" 📂 Section: %s", section.Name)
if section.Class != nil {
fmt.Printf(" class=\"%s\"", *section.Class)
}
if attr.Actions != nil {
fmt.Printf(" actions: ")
for i, action := range attr.Actions.Actions {
if i > 0 {
fmt.Printf(", ")
}
fmt.Printf("%s", action.Name)
if action.Endpoint != nil {
fmt.Printf(" via %s", *action.Endpoint)
}
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")
}
if attr.DataSource != nil {
fmt.Printf(" data from: %s\n", attr.DataSource.Endpoint)
}
if attr.Style != nil {
fmt.Printf(" style: %s", *attr.Style.Theme)
if len(attr.Style.Classes) > 0 {
fmt.Printf(" classes: %v", attr.Style.Classes)
for _, comp := range panel.Components {
displayComponent(comp, " ")
}
fmt.Printf("\n")
}
if attr.Pagination != nil {
fmt.Printf(" pagination: enabled")
if attr.Pagination.PageSize != nil {
fmt.Printf(" size %d", *attr.Pagination.PageSize)
}
fmt.Printf("\n")
}
for _, tab := range container.Tabs {
fmt.Printf(" 📋 Tab: %s label=\"%s\"", tab.Name, tab.Label)
if tab.Active {
fmt.Printf(" (active)")
}
if attr.Filters != nil {
fmt.Printf(" filters: ")
for i, filter := range attr.Filters.Filters {
if i > 0 {
fmt.Printf(", ")
}
fmt.Printf("%s as %s", filter.Field, filter.Type)
if filter.Label != nil {
fmt.Printf(" (%s)", *filter.Label)
}
}
fmt.Printf("\n")
fmt.Printf("\n")
for _, comp := range tab.Components {
displayComponent(comp, " ")
}
if attr.Validation {
fmt.Printf(" validation: enabled\n")
}
for _, comp := range container.Components {
displayComponent(comp, " ")
}
}
// Display direct components
for _, comp := range page.Components {
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, " ")
}
}
}
@ -155,3 +225,247 @@ func main() {
}
}
}
func displayComponent(comp lang.Component, indent string) {
fmt.Printf("%s🧩 Component: %s", indent, comp.Type)
if comp.Entity != nil {
fmt.Printf(" for %s", *comp.Entity)
}
fmt.Printf("\n")
// 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 {
fmt.Printf("%s fields: %v\n", indent, attr.Fields.Fields)
}
if attr.Actions != nil {
fmt.Printf("%s actions: ", indent)
for i, action := range attr.Actions.Actions {
if i > 0 {
fmt.Printf(", ")
}
fmt.Printf("%s", action.Name)
if action.Endpoint != nil {
fmt.Printf(" via %s", *action.Endpoint)
}
}
fmt.Printf("\n")
}
if attr.DataSource != nil {
fmt.Printf("%s data from: %s\n", indent, attr.DataSource.Endpoint)
}
if attr.Style != nil {
fmt.Printf("%s style: %s", indent, *attr.Style.Theme)
if len(attr.Style.Classes) > 0 {
fmt.Printf(" classes: %v", attr.Style.Classes)
}
fmt.Printf("\n")
}
if attr.Pagination != nil {
fmt.Printf("%s pagination: enabled", indent)
if attr.Pagination.PageSize != nil {
fmt.Printf(" size %d", *attr.Pagination.PageSize)
}
fmt.Printf("\n")
}
if attr.Filters != nil {
fmt.Printf("%s filters: ", indent)
for i, filter := range attr.Filters.Filters {
if i > 0 {
fmt.Printf(", ")
}
fmt.Printf("%s as %s", filter.Field, filter.Type)
if filter.Label != nil {
fmt.Printf(" (%s)", *filter.Label)
}
}
fmt.Printf("\n")
}
if attr.Validation {
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")
}
// 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
// This demonstrates the comprehensive language structure
// Enhanced Masonry DSL example demonstrating new features
// This shows the comprehensive language structure with containers, detailed fields, and layouts
// Server configuration
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
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
meta description "Manage system users"
meta keywords "users, admin, management"
component Table for User
fields [email, name, id]
actions [edit via "/users/{id}", delete via "/users/{id}", create via "/users"]
data from "/users"
style modern classes ["table-striped", "table-hover"]
pagination size 20
filters [email as text label "Search email", name as text label "Search name"]
validate
container main class "grid grid-cols-3 gap-4"
section sidebar class "col-span-1"
component UserStats for User
data from "/users/stats"
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
fields [email, name]
actions [save via "/users", cancel]
style clean
validate
field email type text label "Email Address" placeholder "Enter your email" required validate email
field name type text label "Full Name" placeholder "Enter your full name" required
field role type select label "User Role" options ["admin", "user", "moderator"] default "user"
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"
meta description "Browse all users"
when role equals "admin"
field permissions type multiselect label "Permissions"
options ["users.manage", "posts.manage", "system.config"]
component Table for User
fields [email, name]
data from "/users"
pagination size 10
filters [name as text label "Search by name"]
section actions
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"
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
meta description "Manage blog posts"
meta keywords "posts, blog, content"
layout "master-detail"
component Table for Post
fields [title, author_id, published, created_at]
actions [edit via "/posts/{id}", delete via "/posts/{id}", create via "/posts"]
data from "/posts"
style modern
pagination size 15
filters [title as text label "Search title", published as select label "Published status"]
validate
master PostList
component Table for Post
field title type text label "Title" sortable
field author type relation label "Author" display "name" relates to User
field status type badge label "Status"
page CreatePost at "/posts/new" layout MainLayout title "Create Post" auth
component Form for Post
fields [title, content]
actions [save via "/posts", cancel]
style clean
validate
detail PostEditor trigger "edit"
component Form for Post
section basic class "mb-4"
field title type text label "Post Title" required
field content type richtext label "Content" required
page BlogList at "/blog" layout PublicLayout title "Blog Posts"
meta description "Read our latest blog posts"
meta keywords "blog, articles, content"
section metadata class "grid grid-cols-2 gap-4"
field author_id type autocomplete label "Author"
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
fields [title, created_at]
data from "/posts"
pagination size 5
filters [title as text label "Search posts"]
// Simple table component with smart defaults
page SimpleUserList at "/users" layout MainLayout title "Users"
component SimpleTable for User
fields [email, name, created_at]
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,16 +88,20 @@ type ResponseSpec struct {
Fields []string `parser:"('fields' '[' @Ident (',' @Ident)* ']')?"`
}
// Page definitions for frontend with clean syntax
// Enhanced Page definitions with layout containers and composition
type Page struct {
Name string `parser:"'page' @Ident"`
Path string `parser:"'at' @String"`
Layout string `parser:"'layout' @Ident"`
Title *string `parser:"('title' @String)?"`
Description *string `parser:"('desc' @String)?"`
Auth bool `parser:"@'auth'?"`
Meta []MetaTag `parser:"@@*"`
Components []Component `parser:"@@*"`
Name string `parser:"'page' @Ident"`
Path string `parser:"'at' @String"`
Layout string `parser:"'layout' @Ident"`
Title *string `parser:"('title' @String)?"`
Description *string `parser:"('desc' @String)?"`
Auth bool `parser:"@'auth'?"`
LayoutType *string `parser:"('layout' @String)?"`
Meta []MetaTag `parser:"@@*"`
MasterDetail *MasterDetail `parser:"@@?"`
Containers []Container `parser:"@@*"`
Components []Component `parser:"@@*"`
Modals []Modal `parser:"@@*"`
}
// Meta tags for SEO
@ -106,14 +110,153 @@ type MetaTag struct {
Content string `parser:"@String"`
}
// Component definitions with endpoint references
type Component struct {
Type string `parser:"'component' @Ident"`
Entity *string `parser:"('for' @Ident)?"`
Config []ComponentAttr `parser:"@@*"`
// 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:"@@*"`
}
// Component attributes and configurations
// 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 string `parser:"'component' @Ident"`
Entity *string `parser:"('for' @Ident)?"`
Elements []ComponentElement `parser:"@@*"`
}
// 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 {
Fields *ComponentFields `parser:"@@"`
Actions *ComponentActions `parser:"| @@"`
@ -124,19 +267,25 @@ type ComponentAttr struct {
Validation bool `parser:"| @'validate'"`
}
// Component field specification
// Component field specification (simple version for backward compatibility)
type ComponentFields struct {
Fields []string `parser:"'fields' '[' @Ident (',' @Ident)* ']'"`
}
// Component actions (can reference endpoints)
// Enhanced component actions
type ComponentActions struct {
Actions []ComponentAction `parser:"'actions' '[' @@ (',' @@)* ']'"`
}
type ComponentAction struct {
Name string `parser:"@Ident"`
Label *string `parser:"('label' @String)?"`
Icon *string `parser:"('icon' @String)?"`
Style *string `parser:"('style' @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)

File diff suppressed because it is too large Load Diff