dotnet / dotnet/maui

Formalize Brush string syntax

Open
#4,910 1 comment 2 reactions 0 assignees View on GitHub
area-xaml proposal/open
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 15h
Merged PRs (30d)
290

Description

### Description

The string syntax for Brush, used in Xaml through BrushTypeConverter isn't formalised, described, or documented. We have a few tests for it, but that's it. There's no history of this being supported in other XAML platforms, but it is supported in CSS and our syntax is inspired from there.

This document tries to formalise the syntax so it can be used to rewrite the TypeConverter, provide a compiled-to-il version and as a start of a documentation.

Colors(as defined in the ColorTypeConverter) :
```ebnf
hex = "0" | "1" | "2" ... "e" | "f"; (* case-insensitive*)
number = ... ;
percentage = number, "%";
hexcolor = "#",hex,hex,hex(* #rgb *)
| "#", hex, hex, hex, hex (* #argb *)
| "#", hex, hex, hex, hex, hex, hex (* #rrggbb *)
| "#", hex, hex, hex, hex, hex, hex, hex, hex; (* #aarrggbb *)
rgbcolor = "rgb(",number,number,number,")" (* values outside the 0-255 range will be coerced to that range *)
| "rgb(",percentage,percentage,percentage")"; (* values outside 0-100% range will be coerced *)
rgbacolor = "rgb(",number,number,number,number")" (* opacity number will be coerced to 0-1 range *)
| "rgb(",percentage,percentage,percentage,number")"; (* opacity number will be coerced to 0-1 range *)
hslcolor = "hsl(",number,percentage,percentage,")"; (* h is mod 360, s and l coerced 0-100% *)
hslacolor = "hsla(",number,percentage,percentage,number")"; (* opacity is 0-1 *)
hsvcolor = "hsv(",number,percentage,percentage,")"; (* h is mod 360, s and v coerced 0-100% *)
hsvacolor = "hsva(",number,percentage,percentage,number")"; (* opacity is 0-1 *)
namedcolor = "aliceblue" | "antiquewhite" ... | "yellowgreen"; (*case insensitive*)
color = hexcolor | rgbcolor | rgbacolor | hslcolor | hslacolor | hsvcolor | hsvacolor | namedcolor;
```

LinearGradient(same syntax as CSS) :
```ebnf
angle = number, ("deg" | "grad" | "rad" | "turn");
side-or-corner = ["left" | "right"] | ["top" | "bottom"];
linear-color-stop = color, [" ", (number | percentage)];
color-stop-list = linear-color-stop, {linear-color-stop};
linear-gradient = "linear-gradient("[(angle | "to" side - or - corners) "," ] , color-stop-list ,")";
```

radialGradient:
```ebnf
shape = "circle"; (* I don't think we support ellipse *)
position = ["left" | "center" | "right"] , ["top" | "center" | "bottom"] ;
radial-gradient = "radial-gradient(", [[shape | number][" at " position]], color-stop-list ")";
```

brush:
```ebnf
brushstring = color | linear-gradient | radial-gradient;
```

## Syntax we will stop supporting
We found these syntax in some test and examples. They do not match the CSS one, provide no additional capability and can be confusing (opacity vs color stop):
```
Color.yellow
Color.pink.50%
#00FFff 40%
```

### (Public) API Changes

While we're at it, we plan to remove `public const` strings and `public` nested `class` from `BrushTypeConverter

### Usage Scenarios

/

### Backward Compatibility

See discontinued syntax

### Difficulty

Medium

Contributor guide

Open the contributing guide

Research direction

The issue names BrushTypeConverter, ColorTypeConverter, and existing brush tests and examples as entry points, but gives no file paths. Read those implementations and tests first, then compare their behavior with the proposed grammar; done would mean an agreed syntax, updated converter behavior, and documented handling of discontinued forms.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
frontend
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.