// 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();
}
}