< Summary

Information
Class: Allyaria.Theming.ThemeTypes.ThemeVariant
Assembly: Allyaria.Theming
File(s): /home/runner/work/allyaria/allyaria/src/Allyaria.Theming/ThemeTypes/ThemeVariant.cs
Line coverage
100%
Covered lines: 25
Uncovered lines: 0
Coverable lines: 25
Total lines: 102
Line coverage: 100%
Branch coverage
95%
Covered branches: 21
Total branches: 22
Branch coverage: 95.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
BuildCss(...)100%1010100%
Get(...)100%11100%
Set(...)83.33%66100%
SetPrefix(...)100%66100%

File(s)

/home/runner/work/allyaria/allyaria/src/Allyaria.Theming/ThemeTypes/ThemeVariant.cs

#LineLine coverage
 1namespace Allyaria.Theming.ThemeTypes;
 2
 3/// <summary>
 4/// Represents a collection of <see cref="ThemeState" /> objects grouped by <see cref="ThemeType" />, forming a
 5/// hierarchical layer in the Allyaria theming structure.
 6/// </summary>
 7/// <remarks>
 8///     <para>
 9///     Each <see cref="ThemeVariant" /> corresponds to a specific set of theme variants (e.g., Light, Dark,
 10///     HighContrastLight, HighContrastDark) under a particular <see cref="ComponentType" />. It recursively builds CSS
 11///     output and applies updates for its child <see cref="ThemeState" /> instances.
 12///     </para>
 13///     <para>
 14///     This class participates in the theming resolution chain alongside <see cref="ThemeComponent" />,
 15///     <see cref="ThemeState" />, and <see cref="ThemeUpdater" />.
 16///     </para>
 17/// </remarks>
 18internal sealed class ThemeVariant
 19{
 20    /// <summary>
 21    /// A dictionary mapping <see cref="ThemeType" /> values to their respective <see cref="ThemeState" /> definitions.
 22    /// </summary>
 11423    private readonly Dictionary<ThemeType, ThemeState> _children = new();
 24
 25    /// <summary>
 26    /// Builds CSS for this theme variant and its child <see cref="ThemeState" /> instances using the provided context.
 27    /// </summary>
 28    /// <param name="builder">The <see cref="CssBuilder" /> used to accumulate CSS declarations.</param>
 29    /// <param name="navigator">
 30    /// The <see cref="ThemeNavigator" /> describing the scope of components, themes, and states to include.
 31    /// </param>
 32    /// <param name="varPrefix">An optional variable prefix used when generating CSS variable declarations.</param>
 33    /// <returns>A <see cref="CssBuilder" /> instance containing the concatenated CSS output for this variant.</returns>
 34    internal CssBuilder BuildCss(CssBuilder builder, ThemeNavigator navigator, string? varPrefix = "")
 35    {
 3336        if (navigator.ThemeTypes.Count is 0)
 37        {
 2638            foreach (var child in _children)
 39            {
 840                builder = child.Value.BuildCss(
 841                    builder: builder,
 842                    navigator: navigator,
 843                    varPrefix: SetPrefix(varPrefix: varPrefix, type: child.Key)
 844                );
 45            }
 46        }
 47        else
 48        {
 11449            foreach (var key in navigator.ThemeTypes)
 50            {
 2951                builder = Get(key: key)?.BuildCss(
 2952                    builder: builder,
 2953                    navigator: navigator,
 2954                    varPrefix: SetPrefix(varPrefix: varPrefix, type: key)
 2955                ) ?? builder;
 56            }
 57        }
 58
 3359        return builder;
 60    }
 61
 62    /// <summary>
 63    /// Retrieves a <see cref="ThemeState" /> associated with a given <see cref="ThemeType" />, if it exists.
 64    /// </summary>
 65    /// <param name="key">The <see cref="ThemeType" /> identifier to retrieve.</param>
 66    /// <returns>The corresponding <see cref="ThemeState" /> if found; otherwise, <see langword="null" />.</returns>
 657867    private ThemeState? Get(ThemeType key) => _children.GetValueOrDefault(key: key);
 68
 69    /// <summary>
 70    /// Applies a <see cref="ThemeUpdater" /> to update or create <see cref="ThemeState" /> entries for all matching
 71    /// <see cref="ThemeType" /> values in this variant.
 72    /// </summary>
 73    /// <param name="updater">The <see cref="ThemeUpdater" /> instance containing the update definition.</param>
 74    /// <returns>The current <see cref="ThemeVariant" /> instance, allowing fluent configuration.</returns>
 75    internal ThemeVariant Set(ThemeUpdater updater)
 76    {
 2437477        foreach (var key in updater.Navigator.ThemeTypes)
 78        {
 654979            if (!_children.ContainsKey(key: key))
 80            {
 40281                _children.Add(key: key, value: new ThemeState());
 82            }
 83
 654984            Get(key: key)?.Set(updater: updater);
 85        }
 86
 563887        return this;
 88    }
 89
 90    /// <summary>Generates a hierarchical CSS variable prefix string combining the provided prefix and theme type.</summ
 91    /// <param name="varPrefix">The existing variable prefix, if any.</param>
 92    /// <param name="type">The <see cref="ThemeType" /> to append to the prefix.</param>
 93    /// <returns>A normalized CSS-compatible prefix string.</returns>
 94    private static string SetPrefix(string? varPrefix, ThemeType type)
 95    {
 3496        var prefix = varPrefix?.ToCssName() ?? string.Empty;
 97
 3498        return string.IsNullOrWhiteSpace(value: prefix)
 3499            ? string.Empty
 34100            : $"{prefix}-{type}".ToCssName();
 101    }
 102}