// Copyright (c) 2011 - 2019 Ed Charbeneau // License: MIT // See https://github.com/EdCharbeneau using System; using System.Collections.Generic; namespace Connected.Utilities { public struct StyleBuilder { private string stringBuffer; /// /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. /// /// /// public static StyleBuilder Default(string prop, string value) => new(prop, value); /// /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. /// /// public static StyleBuilder Default(string style) => Empty().AddStyle(style); /// /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. /// public static StyleBuilder Empty() => new(); /// /// Creates a StyleBuilder used to define conditional in-line style used in a component. Call Build() to return the completed style as a string. /// /// /// public StyleBuilder(string prop, string value) => stringBuffer = $"{prop}:{value};"; /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon. /// /// public StyleBuilder AddStyle(string style) => !string.IsNullOrWhiteSpace(style) ? AddRaw($"{style};") : this; /// /// Adds a raw string to the builder that will be concatenated with the next style or value added to the builder. /// /// /// StyleBuilder private StyleBuilder AddRaw(string style) { stringBuffer += style; return this; } /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. /// /// /// Style to add /// StyleBuilder public StyleBuilder AddStyle(string prop, string value) => AddRaw($"{prop}:{value};"); /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. /// /// /// Style to conditionally add. /// Condition in which the style is added. /// StyleBuilder public StyleBuilder AddStyle(string prop, string value, bool when = true) => when ? this.AddStyle(prop, value) : this; /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. /// /// /// Style to conditionally add. /// Condition in which the style is added. /// public StyleBuilder AddStyle(string prop, Func value, bool when = true) => when ? this.AddStyle(prop, value()) : this; /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. /// /// /// Style to conditionally add. /// Condition in which the style is added. /// StyleBuilder public StyleBuilder AddStyle(string prop, string value, Func when = null) => this.AddStyle(prop, value, when != null && when()); /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. /// /// /// Style to conditionally add. /// Condition in which the style is added. /// StyleBuilder public StyleBuilder AddStyle(string prop, Func value, Func when = null) => this.AddStyle(prop, value(), when != null && when()); /// /// Adds a conditional nested StyleBuilder to the builder with separator and closing semicolon. /// /// Style Builder to conditionally add. /// StyleBuilder public StyleBuilder AddStyle(StyleBuilder builder) => this.AddRaw(builder.Build()); /// /// Adds a conditional nested StyleBuilder to the builder with separator and closing semicolon. /// /// Style Builder to conditionally add. /// Condition in which the style is added. /// StyleBuilder public StyleBuilder AddStyle(StyleBuilder builder, bool when = true) => when ? this.AddRaw(builder.Build()) : this; /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. /// /// Style Builder to conditionally add. /// Condition in which the styles are added. /// StyleBuilder public StyleBuilder AddStyle(StyleBuilder builder, Func when = null) => this.AddStyle(builder, when != null && when()); /// /// Adds a conditional in-line style to the builder with space separator and closing semicolon.. /// A ValueBuilder action defines a complex set of values for the property. /// /// /// /// public StyleBuilder AddStyle(string prop, Action builder, bool when = true) { var values = new ValueBuilder(); builder(values); return AddStyle(prop, values.ToString(), when && values.HasValue); } /// /// Adds a conditional in-line style when it exists in a dictionary to the builder with separator. /// Null safe operation. /// /// Additional Attribute splat parameters /// StyleBuilder public StyleBuilder AddStyleFromAttributes(IReadOnlyDictionary additionalAttributes) => additionalAttributes == null ? this : additionalAttributes.TryGetValue("style", out var c) ? AddRaw(c.ToString()) : this; /// /// Finalize the completed Style as a string. /// /// string public string Build() { // String buffer finalization code return stringBuffer != null ? stringBuffer.Trim() : string.Empty; } // ToString should only and always call Build to finalize the rendered string. public override string ToString() => Build(); } }