diff --git a/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs b/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs index b42d734..44d9954 100644 --- a/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs +++ b/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs @@ -12,7 +12,7 @@ namespace Pure.Blazor.Components.AspNetCore; public static class HostApplicationBuilderExtensions { public static IHostApplicationBuilder AddPureBlazorComponents(this IHostApplicationBuilder builder, - IPureTheme? theme = null) + PureTheme? theme = null) { // javascript builder.Services.AddScoped(); @@ -24,7 +24,7 @@ public static IHostApplicationBuilder AddPureBlazorComponents(this IHostApplicat builder.Services.AddCascadingValue(sp => { theme ??= new DefaultTheme(); - var source = new CascadingValueSource(theme, isFixed: true); + var source = new CascadingValueSource(theme, isFixed: true); return source; }); diff --git a/src/Pure.Blazor.Components.Primitives/ComponentStyle.cs b/src/Pure.Blazor.Components.Primitives/ComponentStyle.cs index 032bb8a..fed06b5 100644 --- a/src/Pure.Blazor.Components.Primitives/ComponentStyle.cs +++ b/src/Pure.Blazor.Components.Primitives/ComponentStyle.cs @@ -1,19 +1,19 @@ namespace Pure.Blazor.Components.Primitives; -public class ComponentStyle +public record ComponentStyle { - private readonly IReadOnlyDictionary accents; - private readonly IReadOnlyDictionary> variants; - private readonly IReadOnlyDictionary sizes; + public readonly IReadOnlyDictionary Accents; + public readonly IReadOnlyDictionary> Variants; + public readonly IReadOnlyDictionary Sizes; public ComponentStyle(string baseStyle, IReadOnlyDictionary? accents, IReadOnlyDictionary>? variants, IReadOnlyDictionary? sizes) { - this.accents = accents ?? new Dictionary(); - this.variants = variants ?? new Dictionary>(); - this.sizes = sizes ?? new Dictionary(); + this.Accents = accents ?? new Dictionary(); + this.Variants = variants ?? new Dictionary>(); + this.Sizes = sizes ?? new Dictionary(); Base = baseStyle; } @@ -36,12 +36,12 @@ public ComponentStyle(string baseStyle, public string Accent(Accent accent) { - return accents.TryGetValue(accent, out var value) ? value : string.Empty; + return Accents.TryGetValue(accent, out var value) ? value : string.Empty; } public string Variant(PureVariant variant, Accent accent) { - if (variants.TryGetValue(variant, out var value) && value.TryGetValue(accent, out var style)) + if (Variants.TryGetValue(variant, out var value) && value.TryGetValue(accent, out var style)) { return style; } @@ -51,6 +51,6 @@ public string Variant(PureVariant variant, Accent accent) public string Size(PureSize size) { - return sizes.TryGetValue(size, out var value) ? value : string.Empty; + return Sizes.TryGetValue(size, out var value) ? value : string.Empty; } -} \ No newline at end of file +} diff --git a/src/Pure.Blazor.Components.Primitives/IPureTheme.cs b/src/Pure.Blazor.Components.Primitives/IPureTheme.cs deleted file mode 100644 index 6715625..0000000 --- a/src/Pure.Blazor.Components.Primitives/IPureTheme.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Pure.Blazor.Components.Primitives; - -public interface IPureTheme -{ - public ButtonDefaults ButtonDefaults { get; set; } - public IStylePrioritizer StylePrioritizer { get; set; } - public Dictionary Styles { get; set; } - - public ComponentStyle GetStyle(Type type) - { - return GetStyleByName(type.Name); - } - - public ComponentStyle GetStyleByName(string name) - { - // TODO: decide if we want this to be an exceptional event - return Styles.GetValueOrDefault(name) ?? new ComponentStyle("", null, null, null); - } -} diff --git a/src/Pure.Blazor.Components.Primitives/PureComponent.cs b/src/Pure.Blazor.Components.Primitives/PureComponent.cs index 99f8229..1f6e73d 100644 --- a/src/Pure.Blazor.Components.Primitives/PureComponent.cs +++ b/src/Pure.Blazor.Components.Primitives/PureComponent.cs @@ -26,7 +26,7 @@ protected override void OnParametersSet() /// The current theme styles /// [CascadingParameter] - public required IPureTheme PureTheme { get; set; } + public required PureTheme PureTheme { get; set; } [Parameter] public RenderFragment? ChildContent { get; set; } diff --git a/src/Pure.Blazor.Components.Primitives/PureTheme.cs b/src/Pure.Blazor.Components.Primitives/PureTheme.cs new file mode 100644 index 0000000..db7146a --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/PureTheme.cs @@ -0,0 +1,52 @@ +namespace Pure.Blazor.Components.Primitives; + +public record PureTheme +{ + public ButtonDefaults ButtonDefaults { get; set; } = new(); + public IStylePrioritizer? StylePrioritizer { get; set; } + public Dictionary Styles { get; set; } = new(); + + public ComponentStyle GetStyle(Type type) + { + return GetStyleByName(type.Name); + } + + public ComponentStyle GetStyleByName(string name) + { + // TODO: decide if we want this to be an exceptional event + return Styles.GetValueOrDefault(name) ?? new ComponentStyle("", null, null, null); + } + + /// + /// Merges the styles into the current theme, overwriting any existing styles. + /// + /// + public void Merge(Dictionary styles) + { + Styles = Styles.MergeLeft(styles); + } +} + +// https://stackoverflow.com/a/2679857/783284 +internal static class DictionaryExtensions +{ + // Works in C#3/VS2008: + // Returns a new dictionary of this ... others merged leftward. + // Keeps the type of 'this', which must be default-instantiable. + // Example: + // result = map.MergeLeft(other1, other2, ...) + public static T MergeLeft(this T me, params IDictionary[] others) + where T : IDictionary, new() + { + T newMap = new T(); + foreach (IDictionary src in + (new List> { me }).Concat(others)) { + // ^-- echk. Not quite there type-system. + foreach (KeyValuePair p in src) { + newMap[p.Key] = p.Value; + } + } + return newMap; + } + +} diff --git a/src/Pure.Blazor.Components/Common/DefaultTheme.cs b/src/Pure.Blazor.Components/Common/DefaultTheme.cs index 98fe476..17f7f98 100644 --- a/src/Pure.Blazor.Components/Common/DefaultTheme.cs +++ b/src/Pure.Blazor.Components/Common/DefaultTheme.cs @@ -6,50 +6,49 @@ namespace Pure.Blazor.Components.Common; -public class DefaultTheme : IPureTheme +public record DefaultTheme : PureTheme { - public ButtonDefaults ButtonDefaults { get; set; } = new() + public DefaultTheme() { - PressEffect = Effect.InsetShadow, - HoverEffect = Effect.Unset - }; - - public IStylePrioritizer StylePrioritizer { get; set; } = new StylePrioritizer(); - public Dictionary Styles { get; set; } = new() - { - { - nameof(PureButton), - new ComponentStyle(ButtonStyles.Base, null, ButtonStyles.Variants, ButtonStyles.Sizes) - }, + ButtonDefaults.PressEffect = Effect.InsetShadow; + ButtonDefaults.HoverEffect = Effect.Unset; + StylePrioritizer = new StylePrioritizer(); + Styles = new Dictionary { - nameof(PureIconButton), - new ComponentStyle(ButtonStyles.Base, null, ButtonStyles.Variants, ButtonStyles.Sizes) - }, - { - nameof(PureDropdown), - new ComponentStyle(DropdownStyles.Base, null, null, DropdownStyles.Sizes) { - InnerContainer = new ComponentStyle(DropdownStyles.Container.Base, null, null, null) - } - }, - { - nameof(PureDropdownItem), - new ComponentStyle(DropdownStyles.MenuItem.Base, DropdownStyles.MenuItem.Accents, null, - DropdownStyles.MenuItem.Sizes) - }, - { nameof(PureBanner), new ComponentStyle(BannerStyles.Base, null, BannerStyles.Variants, null) }, - { nameof(PureLink), new ComponentStyle(LinkStyles.Base, null, null, null) }, - { nameof(PureBadge), new ComponentStyle("", null, BadgeStyles.Variants, null) }, - { nameof(PureAlert), new ComponentStyle(AlertStyles.Base, AlertStyles.Accents, null, null) }, - { - nameof(PureColorIndicator), - new ComponentStyle("", null, null, null) + nameof(PureButton), + new ComponentStyle(ButtonStyles.Base, null, ButtonStyles.Variants, ButtonStyles.Sizes) + }, + { + nameof(PureIconButton), + new ComponentStyle(ButtonStyles.Base, null, ButtonStyles.Variants, ButtonStyles.Sizes) + }, + { + nameof(PureDropdown), + new ComponentStyle(DropdownStyles.Base, null, null, DropdownStyles.Sizes) + { + InnerContainer = new ComponentStyle(DropdownStyles.Container.Base, null, null, null) + } + }, + { + nameof(PureDropdownItem), + new ComponentStyle(DropdownStyles.MenuItem.Base, DropdownStyles.MenuItem.Accents, null, + DropdownStyles.MenuItem.Sizes) + }, + { nameof(PureBanner), new ComponentStyle(BannerStyles.Base, null, BannerStyles.Variants, null) }, + { nameof(PureLink), new ComponentStyle(LinkStyles.Base, null, null, null) }, + { nameof(PureBadge), new ComponentStyle("", null, BadgeStyles.Variants, null) }, + { nameof(PureAlert), new ComponentStyle(AlertStyles.Base, AlertStyles.Accents, null, null) }, { - InnerContainer = new ComponentStyle("", IndicatorStyles.Background, null, null) + nameof(PureColorIndicator), + new ComponentStyle("", null, null, null) { - OuterContainer = new ComponentStyle("", IndicatorStyles.Foreground, null, null) + InnerContainer = new ComponentStyle("", IndicatorStyles.Background, null, null) + { + OuterContainer = new ComponentStyle("", IndicatorStyles.Foreground, null, null) + } } - } - }, - }; + }, + }; + } } diff --git a/src/Pure.Blazor.Components/WebAssemblyHostBuilderExtensions.cs b/src/Pure.Blazor.Components/WebAssemblyHostBuilderExtensions.cs index 09c1093..189308a 100644 --- a/src/Pure.Blazor.Components/WebAssemblyHostBuilderExtensions.cs +++ b/src/Pure.Blazor.Components/WebAssemblyHostBuilderExtensions.cs @@ -12,7 +12,7 @@ namespace Pure.Blazor.Components; public static class WebAssemblyHostBuilderExtensions { public static WebAssemblyHostBuilder AddPureBlazorComponents(this WebAssemblyHostBuilder builder, - IPureTheme? theme = null) + PureTheme? theme = null) { // javascript builder.Services.AddSingleton(); @@ -23,7 +23,7 @@ public static WebAssemblyHostBuilder AddPureBlazorComponents(this WebAssemblyHos builder.Services.AddCascadingValue(sp => { theme ??= new DefaultTheme(); - var source = new CascadingValueSource(theme, isFixed: true); + var source = new CascadingValueSource(theme, isFixed: true); return source; }); return builder;