// Copyright (c) 2011 - 2019 Ed Charbeneau // License: MIT // See https://github.com/EdCharbeneau namespace Connected.Utilities { public struct CssBuilder { private string stringBuffer; /// /// Creates a CssBuilder used to define conditional CSS classes used in a component. /// Call Build() to return the completed CSS Classes as a string. /// /// public static CssBuilder Default(string value) => new(value); /// /// Creates an Empty CssBuilder used to define conditional CSS classes used in a component. /// Call Build() to return the completed CSS Classes as a string. /// public static CssBuilder Empty() => new(); /// /// Creates a CssBuilder used to define conditional CSS classes used in a component. /// Call Build() to return the completed CSS Classes as a string. /// /// public CssBuilder(string value) => stringBuffer = value; /// /// Adds a raw string to the builder that will be concatenated with the next class or value added to the builder. /// /// /// CssBuilder public CssBuilder AddValue(string value) { stringBuffer += value; return this; } /// /// Adds a CSS Class to the builder with space separator. /// /// CSS Class to add /// CssBuilder public CssBuilder AddClass(string? value) { if (value is null) return this; return AddValue($" {value}"); } /// /// Adds a conditional CSS Class to the builder with space separator. /// /// CSS Class to conditionally add. /// Condition in which the CSS Class is added. /// CssBuilder public CssBuilder AddClass(string value, bool when = true) => when ? this.AddClass(value) : this; /// /// Adds a conditional CSS Class to the builder with space separator. /// /// CSS Class to conditionally add. /// Nullable condition in which the CSS Class is added. /// CssBuilder public CssBuilder AddClass(string value, bool? when = true) => when == true ? this.AddClass(value) : this; /// /// Adds a conditional CSS Class to the builder with space separator. /// /// CSS Class to conditionally add. /// Condition in which the CSS Class is added. /// CssBuilder public CssBuilder AddClass(string value, Func when = null) => this.AddClass(value, when != null && when()); /// /// Adds a conditional CSS Class to the builder with space separator. /// /// Function that returns a CSS Class to conditionally add. /// Condition in which the CSS Class is added. /// CssBuilder public CssBuilder AddClass(Func value, bool when = true) => when ? this.AddClass(value()) : this; /// /// Adds a conditional CSS Class to the builder with space separator. /// /// Function that returns a CSS Class to conditionally add. /// Condition in which the CSS Class is added. /// CssBuilder public CssBuilder AddClass(Func value, Func when = null) => this.AddClass(value, when != null && when()); /// /// Adds a conditional nested CssBuilder to the builder with space separator. /// /// CSS Class to conditionally add. /// Condition in which the CSS Class is added. /// CssBuilder public CssBuilder AddClass(CssBuilder builder, bool when = true) => when ? this.AddClass(builder.Build()) : this; /// /// Adds a conditional CSS Class to the builder with space separator. /// /// CSS Class to conditionally add. /// Condition in which the CSS Class is added. /// CssBuilder public CssBuilder AddClass(CssBuilder builder, Func when = null) => this.AddClass(builder, when != null && when()); /// /// Adds a conditional CSS Class when it exists in a dictionary to the builder with space separator. /// Null safe operation. /// /// Additional Attribute splat parameters /// CssBuilder public CssBuilder AddClassFromAttributes(IReadOnlyDictionary additionalAttributes) => additionalAttributes == null ? this : additionalAttributes.TryGetValue("class", out var c) ? AddClass(c.ToString()) : this; /// /// Finalize the completed CSS Classes 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(); } }