Browse Source

Merge pull request #16838 from abpframework/liangshiwei/theming

Add Theme system to Blazor UI
pull/16843/head
Enis Necipoglu 3 years ago
committed by GitHub
parent
commit
55a01288e2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/StandardLayouts.cs
  2. 13
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/AbpThemingOptions.cs
  3. 34
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/DefaultThemeManager.cs
  4. 36
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/DefaultThemeSelector.cs
  5. 8
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ITheme.cs
  6. 6
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/IThemeManager.cs
  7. 6
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/IThemeSelector.cs
  8. 23
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeDictionary.cs
  9. 27
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeExtensions.cs
  10. 24
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeInfo.cs
  11. 23
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeNameAttribute.cs
  12. 16
      modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/AbpAspNetCoreComponentsWebBasicThemeModule.cs
  13. 26
      modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/BasicTheme.cs
  14. 3
      modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NullLayout.razor

7
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/StandardLayouts.cs

@ -1,6 +1,11 @@
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Layout;
using System;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Layout;
public static class StandardLayouts
{
public const string Application = "Application";
public const string Account = "Account";
public const string Public = "Public";
public const string Empty = "Empty";
}

13
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/AbpThemingOptions.cs

@ -0,0 +1,13 @@
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public class AbpThemingOptions
{
public ThemeDictionary Themes { get; }
public string DefaultThemeName { get; set; }
public AbpThemingOptions()
{
Themes = new ThemeDictionary();
}
}

34
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/DefaultThemeManager.cs

@ -0,0 +1,34 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public class DefaultThemeManager : IThemeManager, IScopedDependency, IServiceProviderAccessor
{
public IServiceProvider ServiceProvider { get; }
public ITheme CurrentTheme => GetCurrentTheme();
private ITheme _currentTheme;
protected IThemeSelector ThemeSelector { get; }
public DefaultThemeManager(
IServiceProvider serviceProvider,
IThemeSelector themeSelector)
{
ServiceProvider = serviceProvider;
ThemeSelector = themeSelector;
}
protected virtual ITheme GetCurrentTheme()
{
if (_currentTheme != null)
{
return _currentTheme;
}
_currentTheme = (ITheme)ServiceProvider.GetRequiredService(ThemeSelector.GetCurrentThemeInfo().ThemeType);
return CurrentTheme;
}
}

36
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/DefaultThemeSelector.cs

@ -0,0 +1,36 @@
using System.Linq;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public class DefaultThemeSelector : IThemeSelector, ITransientDependency
{
protected AbpThemingOptions Options { get; }
public DefaultThemeSelector(IOptions<AbpThemingOptions> options)
{
Options = options.Value;
}
public virtual ThemeInfo GetCurrentThemeInfo()
{
if (!Options.Themes.Any())
{
throw new AbpException($"No theme registered! Use {nameof(AbpThemingOptions)} to register themes.");
}
if (Options.DefaultThemeName == null)
{
return Options.Themes.Values.First();
}
var themeInfo = Options.Themes.Values.FirstOrDefault(t => t.Name == Options.DefaultThemeName);
if (themeInfo == null)
{
throw new AbpException("Default theme is configured but it's not found in the registered themes: " + Options.DefaultThemeName);
}
return themeInfo;
}
}

8
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ITheme.cs

@ -0,0 +1,8 @@
using System;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public interface ITheme
{
Type GetLayout(string name, bool fallbackToDefault = true);
}

6
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/IThemeManager.cs

@ -0,0 +1,6 @@
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public interface IThemeManager
{
ITheme CurrentTheme { get; }
}

6
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/IThemeSelector.cs

@ -0,0 +1,6 @@
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public interface IThemeSelector
{
ThemeInfo GetCurrentThemeInfo();
}

23
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeDictionary.cs

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public class ThemeDictionary : Dictionary<Type, ThemeInfo>
{
public ThemeInfo Add<TTheme>()
where TTheme : ITheme
{
return Add(typeof(TTheme));
}
public ThemeInfo Add(Type themeType)
{
if (ContainsKey(themeType))
{
throw new AbpException("This theme is already added before: " + themeType.AssemblyQualifiedName);
}
return this[themeType] = new ThemeInfo(themeType);
}
}

27
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeExtensions.cs

@ -0,0 +1,27 @@
using System;
using Volo.Abp.AspNetCore.Components.Web.Theming.Layout;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public static class ThemeExtensions
{
public static Type GetApplicationLayout(this ITheme theme, bool fallbackToDefault = true)
{
return theme.GetLayout(StandardLayouts.Application, fallbackToDefault);
}
public static Type GetAccountLayout(this ITheme theme, bool fallbackToDefault = true)
{
return theme.GetLayout(StandardLayouts.Account, fallbackToDefault);
}
public static Type GetPublicLayout(this ITheme theme, bool fallbackToDefault = true)
{
return theme.GetLayout(StandardLayouts.Public, fallbackToDefault);
}
public static Type GetEmptyLayout(this ITheme theme, bool fallbackToDefault = true)
{
return theme.GetLayout(StandardLayouts.Empty, fallbackToDefault);
}
}

24
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeInfo.cs

@ -0,0 +1,24 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
public class ThemeInfo
{
public Type ThemeType { get; }
public string Name { get; }
public ThemeInfo([NotNull] Type themeType)
{
Check.NotNull(themeType, nameof(themeType));
if (!typeof(ITheme).IsAssignableFrom(themeType))
{
throw new AbpException($"Given {nameof(themeType)} ({themeType.AssemblyQualifiedName}) should be type of {typeof(ITheme).AssemblyQualifiedName}");
}
ThemeType = themeType;
Name = ThemeNameAttribute.GetName(themeType);
}
}

23
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Theming/ThemeNameAttribute.cs

@ -0,0 +1,23 @@
using System;
using System.Linq;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
[AttributeUsage(AttributeTargets.Class)]
public class ThemeNameAttribute : Attribute
{
public string Name { get; set; }
public ThemeNameAttribute(string name)
{
Name = name;
}
public static string GetName(Type themeType)
{
return themeType
.GetCustomAttributes(true)
.OfType<ThemeNameAttribute>()
.FirstOrDefault()?.Name ?? themeType.Name;
}
}

16
modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/AbpAspNetCoreComponentsWebBasicThemeModule.cs

@ -1,12 +1,24 @@
using Volo.Abp.AspNetCore.Components.Web.Theming;
using Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Components.Web.BasicTheme;
[DependsOn(
typeof(AbpAspNetCoreComponentsWebThemingModule)
)]
)]
public class AbpAspNetCoreComponentsWebBasicThemeModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpThemingOptions>(options =>
{
options.Themes.Add<BasicTheme>();
}
if (options.DefaultThemeName == null)
{
options.DefaultThemeName = BasicTheme.Name;
}
});
}
}

26
modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/BasicTheme.cs

@ -0,0 +1,26 @@
using System;
using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic;
using Volo.Abp.AspNetCore.Components.Web.Theming.Layout;
using Volo.Abp.AspNetCore.Components.Web.Theming.Theming;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.BasicTheme;
[ThemeName(Name)]
public class BasicTheme : ITheme, ITransientDependency
{
public const string Name = "Basic";
public virtual Type GetLayout(string name, bool fallbackToDefault = true)
{
switch (name)
{
case StandardLayouts.Application:
case StandardLayouts.Account:
case StandardLayouts.Empty:
return typeof(MainLayout);
default:
return fallbackToDefault ? typeof(MainLayout) : typeof(NullLayout);
}
}
}

3
modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NullLayout.razor

@ -0,0 +1,3 @@
@inherits LayoutComponentBase
@Body
Loading…
Cancel
Save