jsx_curly_spacing

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 14, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var JsxCurlySpacingRule = rule.Rule{
	Name: "react/jsx-curly-spacing",
	Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {
		attrsConfig, childrenConfig := parseOptions(options)

		text := ctx.SourceFile.Text()

		validate := func(node *ast.Node) {
			parent := node.Parent
			if parent == nil {
				return
			}

			var cfg *sideConfig
			switch node.Kind {
			case ast.KindJsxExpression:

				if je := node.AsJsxExpression(); je != nil && je.DotDotDotToken != nil {
					return
				}
				switch parent.Kind {
				case ast.KindJsxAttribute:
					cfg = attrsConfig
				case ast.KindJsxElement, ast.KindJsxFragment:
					cfg = childrenConfig
				default:
					return
				}
			case ast.KindJsxSpreadAttribute:
				cfg = attrsConfig
			default:
				return
			}
			if cfg == nil {
				return
			}

			trimmed := utils.TrimNodeTextRange(ctx.SourceFile, node)
			start := trimmed.Pos()
			end := trimmed.End()
			if start >= end || text[start] != '{' || text[end-1] != '}' {
				return
			}
			openPos := start
			closePos := end - 1
			innerLow := openPos + 1
			innerHigh := closePos

			scan := scanBraceBody(text, innerLow, innerHigh)

			openRange := core.NewTextRange(openPos, openPos+1)
			closeRange := core.NewTextRange(closePos, closePos+1)

			isObjectLiteral := scan.secondPos < innerHigh && text[scan.secondPos] == '{'
			spacing := cfg.when
			if isObjectLiteral {
				spacing = cfg.objectLiteralSpaces
			}

			hasSpaceAfterOpen := scan.secondPos > innerLow
			hasSpaceBeforeClose := scan.penultimateEnd < innerHigh
			multilineAfterOpen := containsNewline(text, innerLow, scan.secondPos)
			multilineBeforeClose := containsNewline(text, scan.penultimateEnd, innerHigh)

			reportNoBeginningSpace := func() {
				toLoc := scan.nextRealStart
				if scan.secondPos < scan.nextRealStart {

					toLoc = scan.secondPos
				}
				ctx.ReportRangeWithFixes(
					openRange,
					rule.RuleMessage{
						Id:          "noSpaceAfter",
						Description: "There should be no space after '{'",
					},
					fixByTrimmingWhitespace(text, innerLow, toLoc, "start", ""),
				)
			}

			reportNoEndingSpace := func() {
				fromLoc := scan.prevRealEnd
				if scan.penultimateEnd > scan.prevRealEnd {

					fromLoc = scan.penultimateEnd
				}
				ctx.ReportRangeWithFixes(
					closeRange,
					rule.RuleMessage{
						Id:          "noSpaceBefore",
						Description: "There should be no space before '}'",
					},
					fixByTrimmingWhitespace(text, fromLoc, innerHigh, "end", ""),
				)
			}

			reportNoBeginningNewline := func() {
				ctx.ReportRangeWithFixes(
					openRange,
					rule.RuleMessage{
						Id:          "noNewlineAfter",
						Description: "There should be no newline after '{'",
					},
					fixByTrimmingWhitespace(text, innerLow, scan.nextRealStart, "start", spacing),
				)
			}

			reportNoEndingNewline := func() {
				ctx.ReportRangeWithFixes(
					closeRange,
					rule.RuleMessage{
						Id:          "noNewlineBefore",
						Description: "There should be no newline before '}'",
					},
					fixByTrimmingWhitespace(text, scan.prevRealEnd, innerHigh, "end", spacing),
				)
			}

			reportRequiredBeginningSpace := func() {
				ctx.ReportRangeWithFixes(
					openRange,
					rule.RuleMessage{
						Id:          "spaceNeededAfter",
						Description: "A space is required after '{'",
					},
					rule.RuleFix{
						Text:  " ",
						Range: core.NewTextRange(openPos+1, openPos+1),
					},
				)
			}

			reportRequiredEndingSpace := func() {
				ctx.ReportRangeWithFixes(
					closeRange,
					rule.RuleMessage{
						Id:          "spaceNeededBefore",
						Description: "A space is required before '}'",
					},
					rule.RuleFix{
						Text:  " ",
						Range: core.NewTextRange(closePos, closePos),
					},
				)
			}

			switch spacing {
			case spacingAlways:
				if !hasSpaceAfterOpen {
					reportRequiredBeginningSpace()
				} else if !cfg.allowMultiline && multilineAfterOpen {
					reportNoBeginningNewline()
				}
				if !hasSpaceBeforeClose {
					reportRequiredEndingSpace()
				} else if !cfg.allowMultiline && multilineBeforeClose {
					reportNoEndingNewline()
				}
			case spacingNever:
				if multilineAfterOpen {
					if !cfg.allowMultiline {
						reportNoBeginningNewline()
					}
				} else if hasSpaceAfterOpen {
					reportNoBeginningSpace()
				}
				if multilineBeforeClose {
					if !cfg.allowMultiline {
						reportNoEndingNewline()
					}
				} else if hasSpaceBeforeClose {
					reportNoEndingSpace()
				}
			}
		}

		return rule.RuleListeners{
			ast.KindJsxExpression:      validate,
			ast.KindJsxSpreadAttribute: validate,
		}
	},
}

JsxCurlySpacingRule enforces or disallows whitespace inside JSX braces in attribute and child positions. Listens for `JsxExpression` (covers the `JSXExpressionContainer` use-cases — both attribute initializers and element children) and `JsxSpreadAttribute` (attribute spread).

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL