Skip to content

Parser: Add dot_notation_tags parser option#1436

Merged
marcoroth merged 2 commits intomainfrom
dot-notation-tags
Mar 21, 2026
Merged

Parser: Add dot_notation_tags parser option#1436
marcoroth merged 2 commits intomainfrom
dot-notation-tags

Conversation

@marcoroth
Copy link
Owner

@marcoroth marcoroth commented Mar 20, 2026

This pull request adds support for parsing dot-notation component tags like <Dialog.body> and <Dialog.footer> as single HTML elements. A new dot_notation_tags parser option enables this syntax (defaults to false).

When enabled, the parser recognizes <Identifier.identifier> patterns where the first segment starts with an uppercase letter as a single tag name. Subsequent segments can be any valid identifier (uppercase or lowercase). This is similar to how JSX handles compound component patterns.

For example, the following template with dot_notation_tags: true:

<Dialog.wrapper id="demo" title="Confirm">
  <Dialog.body>Are you sure?</Dialog.body>

  <Dialog.footer>
    <Dialog.cancel />
    <Dialog.confirm autofocus />
  </Dialog.footer>
</Dialog.wrapper>

Produces:

@ DocumentNode (location: (1:0)-(9:0))
└── children: (1 item)
    └── @ HTMLElementNode (location: (1:0)-(8:18))
        ├── open_tag:
           └── @ HTMLOpenTagNode (location: (1:0)-(1:43))
               ├── tag_opening: "<" (location: (1:0)-(1:1))├── tag_name: "Dialog.wrapper" (location: (1:1)-(1:15))
               ├── tag_closing: ">" (location: (1:42)-(1:43))├── children: [...]
               └── is_void: false
        
        ├── tag_name: "Dialog.wrapper" (location: (1:1)-(1:15))
        ├── body: [...]
        ├── close_tag:
           └── @ HTMLCloseTagNode (location: (8:0)-(8:18))
               ├── tag_name: "Dialog.wrapper" (location: (8:2)-(8:16))
               └── ...
        
        ├── is_void: false
        └── element_source: "HTML"

When dot_notation_tags is true and the first segment starts with a lowercase letter (e.g. <dialog.Button>), a DotNotationCasingError is reported:

@ DotNotationCasingError (location: (1:1)-(1:7))
├── message: "Dot-notation component tags require the first segment to start with an uppercase letter. `dialog` does not start with an uppercase letter."
└── segment: "dialog" (location: (1:1)-(1:7))

This is heavily inspired by Phoenix.Component and JSX.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 20, 2026

npx https://pkg.pr.new/@herb-tools/formatter@1436
npx https://pkg.pr.new/@herb-tools/language-server@1436
npx https://pkg.pr.new/@herb-tools/linter@1436

commit: ae04c74

@github-actions
Copy link

github-actions bot commented Mar 20, 2026

🌿 Interactive Playground and Documentation Preview

A preview deployment has been built for this pull request. Try out the changes live in the interactive playground:


🌱 Grown from commit ae04c74


✅ Preview deployment has been cleaned up.

@marcoroth marcoroth merged commit 4856642 into main Mar 21, 2026
38 of 39 checks passed
@marcoroth marcoroth deleted the dot-notation-tags branch March 21, 2026 01:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant