Skip to content

Conversation

@dyc3
Copy link
Contributor

@dyc3 dyc3 commented Nov 23, 2025

Summary

Lets the HTML parser handle v-slot shorthand syntax: <template #foo>

fixes #8222

Test Plan

added snapshot tests

Docs

@changeset-bot
Copy link

changeset-bot bot commented Nov 23, 2025

🦋 Changeset detected

Latest commit: 6aceb12

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-HTML Language: HTML and super languages labels Nov 23, 2025
@github-actions
Copy link
Contributor

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 51437 51437 0
Passed 50224 50224 0
Failed 1171 1171 0
Panics 42 42 0
Coverage 97.64% 97.64% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 40 40 0
Passed 37 37 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.50% 92.50% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6323 6323 0
Passed 2106 2106 0
Failed 4217 4217 0
Panics 0 0 0
Coverage 33.31% 33.31% 0.00%

ts/babel

Test result main count This PR count Difference
Total 835 835 0
Passed 742 742 0
Failed 93 93 0
Panics 0 0 0
Coverage 88.86% 88.86% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18823 18823 0
Passed 14069 14069 0
Failed 4753 4753 0
Panics 1 1 0
Coverage 74.74% 74.74% 0.00%

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 23, 2025

Walkthrough

Adds explicit support for Vue v-slot shorthand (#) across lexer, parser, codegen and formatter. Lexer recognises # inside Vue tags; parser adds parse_vue_v_slot_shorthand_directive, accepts # as an attribute-start token, and produces a new node kind VUE_V_SLOT_SHORTHAND_DIRECTIVE; codegen registers the # punct and the node kind; formatter implements a FormatNodeRule and wiring for VueVSlotShorthandDirective. Tests for valid and invalid v-slot shorthand were added and a patch changeset bumps the package.

Possibly related PRs

Suggested reviewers

  • ematipico

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding Vue v-slot shorthand syntax parsing to the HTML parser.
Description check ✅ Passed The description relates to the changeset by explaining the motivation (handling v-slot shorthand syntax) and referencing the fixed issue #8222.
Linked Issues check ✅ Passed All coding requirements from issue #8222 are met: the parser now accepts v-slot shorthand syntax (#foo), handles both static and dynamic arguments, includes modifiers and initializers, and provides test cases demonstrating the fix.
Out of Scope Changes check ✅ Passed All changes are scoped to the v-slot shorthand parsing feature; no unrelated modifications to other parser functionality or unrelated features are present.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dyc3/vue-slot-shorthand

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd399eb and 6aceb12.

⛔ Files ignored due to path filters (9)
  • crates/biome_html_factory/src/generated/node_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_factory/src/generated/syntax_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_parser/tests/html_specs/error/vue/invalid-v-slot-shorthand.vue.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/vue/v-mixed-complex.vue.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/vue/v-slot-shorthand.vue.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_syntax/src/generated/kind.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/macros.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/nodes.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/nodes_mut.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (12)
  • .changeset/forty-falcons-pick.md (1 hunks)
  • crates/biome_html_formatter/src/generated.rs (1 hunks)
  • crates/biome_html_formatter/src/vue/any/directive.rs (1 hunks)
  • crates/biome_html_formatter/src/vue/auxiliary/mod.rs (1 hunks)
  • crates/biome_html_formatter/src/vue/auxiliary/v_slot_shorthand_directive.rs (1 hunks)
  • crates/biome_html_parser/src/lexer/mod.rs (1 hunks)
  • crates/biome_html_parser/src/syntax/mod.rs (3 hunks)
  • crates/biome_html_parser/src/syntax/vue.rs (1 hunks)
  • crates/biome_html_parser/tests/html_specs/error/vue/invalid-v-slot-shorthand.vue (1 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/vue/v-slot-shorthand.vue (1 hunks)
  • xtask/codegen/html.ungram (2 hunks)
  • xtask/codegen/src/html_kinds_src.rs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • crates/biome_html_formatter/src/vue/auxiliary/v_slot_shorthand_directive.rs
  • xtask/codegen/html.ungram
  • crates/biome_html_formatter/src/vue/auxiliary/mod.rs
  • .changeset/forty-falcons-pick.md
  • crates/biome_html_parser/tests/html_specs/error/vue/invalid-v-slot-shorthand.vue
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/syntax/vue.rs
  • xtask/codegen/src/html_kinds_src.rs
  • crates/biome_html_parser/tests/html_specs/ok/vue/v-slot-shorthand.vue
  • crates/biome_html_formatter/src/vue/any/directive.rs
🧰 Additional context used
🧬 Code graph analysis (2)
crates/biome_html_formatter/src/generated.rs (1)
crates/biome_html_formatter/src/vue/any/directive.rs (1)
  • fmt (9-17)
crates/biome_html_parser/src/syntax/mod.rs (2)
crates/biome_html_parser/src/syntax/vue.rs (1)
  • parse_vue_v_slot_shorthand_directive (85-112)
crates/biome_html_parser/src/syntax/parse_error.rs (1)
  • disabled_vue (108-110)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: End-to-end tests
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test Node.js API
  • GitHub Check: autofix
  • GitHub Check: Parser conformance
🔇 Additional comments (4)
crates/biome_html_formatter/src/generated.rs (1)

1501-1532: Vue v-slot shorthand wiring is consistent with existing Vue shorthand directives

The VueVSlotShorthandDirective FormatRule, AsFormat, and IntoFormat impls line up with the existing VueVBindShorthandDirective/VueVOnShorthandDirective patterns, so the formatter plumbing for # looks sound.

crates/biome_html_parser/src/syntax/mod.rs (3)

15-15: LGTM—import addition is spot on.

Bringing in parse_vue_v_slot_shorthand_directive alongside the other Vue directive parsers. Consistent with the existing imports.


373-377: Perfect consistency with existing Vue shorthand directives.

The new # handling mirrors the patterns for : (v-bind) and @ (v-on) exactly—uses parse_exclusive_syntax, checks Vue enablement, and provides the appropriate diagnostic when disabled.


407-414: Token set update looks good—consistent with existing Vue shorthands.

Adding T![#] to the token set unconditionally (like : and @) enables the parser to provide a specific "Vue syntax isn't enabled" diagnostic in parse_attribute rather than a generic error. The past discussion about conditional vs unconditional tokens was addressed, and this approach is intentional for better UX.


Comment @coderabbitai help to get the list of available commands and usage tips.

@dyc3 dyc3 force-pushed the dyc3/vue-slot-shorthand branch from da06f37 to d803d0e Compare November 23, 2025 15:42
@dyc3 dyc3 requested review from a team November 23, 2025 23:37
@dyc3 dyc3 force-pushed the dyc3/vue-slot-shorthand branch from d803d0e to cd399eb Compare November 24, 2025 13:51
Comment on lines +95 to +102
// is there any trivia after the hash and before argument?
if let Some(last_trivia) = p.source().trivia_list.last()
&& pos < last_trivia.text_range().start()
{
// `# slot="5"` is not valid syntax
// but we want to recover gracefully
p.error(expected_vue_directive_argument(p, last_trivia.text_range()));
return Present(m.complete(p, VUE_BOGUS_DIRECTIVE));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently don't handle this for the other shorthand syntaxes. I left it out of this PR for brevity. Will fix in another PR.

Copy link
Member

@ematipico ematipico Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently don't handle this for the other shorthand syntaxes. I left it out of this PR for brevity. Will fix in another PR.

Optionally, we could evaluate syntax rules for these cases. I believe they would be easier to implement, because the current solutions feel more like a hack

@dyc3 dyc3 force-pushed the dyc3/vue-slot-shorthand branch from cd399eb to 6aceb12 Compare November 24, 2025 13:57
@dyc3 dyc3 merged commit 3f19b52 into main Nov 24, 2025
14 of 15 checks passed
@dyc3 dyc3 deleted the dyc3/vue-slot-shorthand branch November 24, 2025 14:25
@github-actions github-actions bot mentioned this pull request Nov 24, 2025
@github-actions github-actions bot mentioned this pull request Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Formatter Area: formatter A-Parser Area: parser A-Tooling Area: internal tools L-HTML Language: HTML and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📝 Vue custom slots cause parse errors

3 participants