Skip to content

Commit

Permalink
Fix HexFromArgb, add ThemeBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
albi005 committed May 17, 2023
1 parent a7f3bd0 commit f5cf055
Show file tree
Hide file tree
Showing 19 changed files with 266 additions and 106 deletions.
21 changes: 21 additions & 0 deletions MaterialColorUtilities.Tests/StringUtilsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using MaterialColorUtilities.Utils;

namespace MaterialColorUtilities.Tests;

[TestClass]
public class StringUtilsTests
{
[TestMethod]
[DataRow(0x00000000U, "#000000")]
[DataRow(0x000000FFU, "#0000FF")]
[DataRow(0xFF0000FFU, "#0000FF")]
[DataRow(0x0000FF00U, "#00FF00")]
[DataRow(0x00FF0000U, "#FF0000")]
[DataRow(0x00FFFFFFU, "#FFFFFF")]
[DataRow(0xFFFFFFFFU, "#FFFFFF")]
public void HexFromArgb(uint argb, string expected)
{
string actual = StringUtils.HexFromArgb(argb);
Assert.AreEqual(expected, actual);
}
}
1 change: 1 addition & 0 deletions MaterialColorUtilities.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Microsoft.VisualStudio.TestTools.UnitTesting;
2 changes: 1 addition & 1 deletion MaterialColorUtilities/Utils/StringUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public static class StringUtils
/// Hex string representing color, ex. #0000FF for blue.
/// </summary>
/// <param name="argb">ARGB representation of a color.</param>
public static string HexFromArgb(uint argb) => "#" + argb.ToString("X6").Substring(2);
public static string HexFromArgb(uint argb) => "#" + argb.ToString("X8").Substring(2);
}
}
72 changes: 72 additions & 0 deletions Playground/Playground.Wasm/CssVariables.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Text;
using MaterialColorUtilities.Schemes;
using MaterialColorUtilities.Utils;

namespace Playground.Wasm;

public static class CssVariables
{
public static string Create(Scheme<uint> scheme, Scheme<uint> dark = null, string selector = ":root")
{
StringBuilder builder = new();

builder.Append(selector);
builder.Append(" {\n");
foreach (var color in scheme.Enumerate())
{
builder.Append(" --md-sys-color-");
builder.Append(PascalToKebab(color.Key));
builder.Append(": ");
string hex = StringUtils.HexFromArgb(color.Value);
builder.Append(hex);
builder.Append(";\n");
}
builder.Append('}');

if (dark != null)
{
builder.Append("\n\n@media (prefers-color-scheme: dark) {\n");
builder.Append(" ");
builder.Append(selector);
builder.Append(" {\n");
foreach (var color in dark.Enumerate())
{
builder.Append(" --md-sys-color-");
builder.Append(PascalToKebab(color.Key));
builder.Append(": ");
string hex = StringUtils.HexFromArgb(color.Value);
builder.Append(hex);
builder.Append(";\n");
}
builder.Append(" }\n}");
}

return builder.ToString();
}

private static string PascalToKebab(ReadOnlySpan<char> pascalCase)
{
if (pascalCase.Length == 0) return string.Empty;

Span<char> kebabCase = stackalloc char[pascalCase.Length + pascalCase.Length / 2];
int kebabCaseIndex = 0;
kebabCase[kebabCaseIndex++] = char.ToLower(pascalCase[0]);

for (int i = 1; i < pascalCase.Length; i++)
{
char currentChar = pascalCase[i];

if (char.IsUpper(currentChar))
{
kebabCase[kebabCaseIndex++] = '-';
kebabCase[kebabCaseIndex++] = char.ToLower(currentChar);
}
else
{
kebabCase[kebabCaseIndex++] = currentChar;
}
}

return new(kebabCase[..kebabCaseIndex]);
}
}
10 changes: 2 additions & 8 deletions Playground/Playground.Wasm/Pages/CssVariablesPage.razor
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
@page "/css"
@inherits SeedColorSelector

<MudPaper Class="pa-4 ma-4" Style="width: 460px">
<ColorScheme Scheme="@ThemeService.Scheme"/>
<div class="pb-4"></div>
<ColorInput/>
<div class="pb-4"></div>
<StyleSelector/>
<div class="pb-4"></div>
<ImageInput />
<MudPaper Class="pa-4 ma-4" Style="margin: auto; max-width: 512px">
<ThemeBuilder />
</MudPaper>
<CssVariablesDisplay />

Expand Down
27 changes: 1 addition & 26 deletions Playground/Playground.Wasm/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
@page "/"
@inject ThemeService ThemeService
@using Playground.Wasm.Extensions
@using Playground.Wasm.Services
@using MaterialColorUtilities.ColorAppearance
@using MaterialColorUtilities.Utils
@using MudBlazor.Utilities
@implements IDisposable

<PageTitle>Material Color Utilities .NET</PageTitle>

<div class="d-flex flex-wrap justify-center gap-4 py-4">
<MudPaper Class="pa-4" Style="width: 460px">
<div class="d-flex pb-4">
<ColorItem Name="Seed"
Color="@ThemeService.Seed"
OnColor="@(Hct.FromInt(ThemeService.Seed).Tone > 49.7 ? 0xFF000000 : 0xFFFFFFFF)"/>
</div>
<ColorScheme Scheme="@ThemeService.Scheme"/>
<div class="pb-4"></div>
<ColorInput/>
<div class="pb-4"></div>
<StyleSelector/>
<div class="pb-4"></div>
<ImageInput />
<ThemeBuilder />
</MudPaper>
<MudPaper Class="pa-4" Style="width: 460px">
<h3>
Expand Down Expand Up @@ -111,12 +97,6 @@

@code {

protected override void OnInitialized()
{
base.OnInitialized();
ThemeService.Changed += StateHasChanged;
}

private uint Hsl(double x, double y)
{
MudColor mudColor = new(x, 1, y, 1);
Expand Down Expand Up @@ -147,9 +127,4 @@
return (okhsl.h, okhsl.l);
}

public void Dispose()
{
ThemeService.Changed -= StateHasChanged;
}

}
48 changes: 48 additions & 0 deletions Playground/Playground.Wasm/Pages/ThemeBuilderPage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@page "/theme-builder"
@using System.Web
@using System.Globalization
@using MaterialColorUtilities.Palettes
@layout EmptyLayout
@inject NavigationManager NavigationManager
@inject IJSRuntime JsRuntime
@inherits SchemeDisplay

<style>
html {
background-color: var(--mud-palette-surface);
}
body {
background-color: transparent;
}
</style>

<ThemeBuilder Small="true" />

@{
JsRuntime.InvokeVoidAsync("postScheme", ThemeService.CreateCssVariables());
}

@code {

protected override void OnInitialized()
{
base.OnInitialized();

Uri uri = new(NavigationManager.Uri);
var queries = HttpUtility.ParseQueryString(uri.Query);

string colorQuery = queries["color"];
if (colorQuery != null && uint.TryParse(colorQuery, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint color))
{
ThemeService.Seed = color;
}

string styleQuery = queries["style"];
if (styleQuery != null && Enum.TryParse(styleQuery, true, out Style style))
{
ThemeService.Style = style;
}
}

}
3 changes: 1 addition & 2 deletions Playground/Playground.Wasm/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
using Playground.Wasm.Services;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor;
using MudBlazor.Services;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped(_ => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddMudServices();
builder.Services.AddSingleton<ThemeService>();

Expand Down
15 changes: 11 additions & 4 deletions Playground/Playground.Wasm/Services/ThemeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public Style Style
private CorePalette CorePalette { get; } = new();

public MudScheme<uint> Scheme { get; private set; }
public MudScheme<uint> LightScheme { get; private set; }
public MudScheme<uint> DarkScheme { get; private set; }

public MudTheme MudTheme { get; } = new()
{
ZIndex = new()
Expand All @@ -66,6 +69,8 @@ public Style Style
};

public event Action Changed;

public string CreateCssVariables() => CssVariables.Create(LightScheme, DarkScheme);

private void Apply()
{
Expand All @@ -78,11 +83,13 @@ private void Apply()
_prevStyle = _style;
CorePalette.Fill(_seed, _style);
}

LightScheme = _lightMapper.Map(CorePalette);
DarkScheme = _darkMapper.Map(CorePalette);
Scheme = IsDark
? DarkScheme
: LightScheme;

ISchemeMapper<CorePalette, MudScheme<uint>> mapper = IsDark
? _darkMapper
: _lightMapper;
Scheme = mapper.Map(CorePalette);
MudScheme<MudColor> mudColorScheme = Scheme.Convert(IntExtensions.ToMudColor);
if (IsDark)
MudTheme.PaletteDark = UpdatePalette(MudTheme.PaletteDark, mudColorScheme);
Expand Down
10 changes: 7 additions & 3 deletions Playground/Playground.Wasm/Shared/ColorInput.razor
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
ColorPickerMode="@ColorPickerMode.HEX"
Label="Seed color"
PickerVariant="@PickerVariant.Inline"
AnchorOrigin="Origin.BottomCenter"
Variant="Variant.Filled"
AnchorOrigin="Origin.CenterLeft"
Variant="Variant.Outlined"
Elevation="1"
DisableAlpha="true"
DisablePreview="true"
/>
DisableColorField="@Small"
/>

@code {
MudColor _color;
Expand All @@ -43,4 +44,7 @@
if (seed == ColorUint) return;
_color = StringUtils.HexFromArgb(seed);
}

[Parameter]
public bool Small { get; set; }
}
8 changes: 7 additions & 1 deletion Playground/Playground.Wasm/Shared/ColorItem.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@

<div
class="pa-2 flex-grow-1"
style="background-color: @(StringUtils.HexFromArgb(Color)); color: @(StringUtils.HexFromArgb(OnColor)); width: 150px; height: 32px; font-weight: bold">
style="
background-color: @(StringUtils.HexFromArgb(Color));
color: @(StringUtils.HexFromArgb(OnColor));
width: 150px; height: 32px;
font-weight: bold;
border-radius: @BorderRadius">
@Name
</div>

@code {
[Parameter] public string Name { get; set; }
[Parameter] [EditorRequired] public uint Color { get; set; }
[Parameter] public uint OnColor { get; set; }
[Parameter] public string BorderRadius { get; set; } = "0";
}
8 changes: 4 additions & 4 deletions Playground/Playground.Wasm/Shared/ColorScheme.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
@using MaterialColorUtilities.Utils

<div class="d-flex">
<ColorItem Name="Primary" Color="@Scheme.Primary" OnColor="@Scheme.OnPrimary" />
<ColorItem Name="PrimaryContainer" Color="@Scheme.PrimaryContainer" OnColor="@Scheme.OnPrimaryContainer" />
<ColorItem Name="Primary" Color="@Scheme.Primary" OnColor="@Scheme.OnPrimary" BorderRadius="4px 0 0 0" />
<ColorItem Name="PrimaryContainer" Color="@Scheme.PrimaryContainer" OnColor="@Scheme.OnPrimaryContainer" BorderRadius="0 4px 0 0" />
</div>
<div class="d-flex">
<ColorItem Name="Secondary" Color="@Scheme.Secondary" OnColor="@Scheme.OnSecondary" />
Expand All @@ -26,12 +26,12 @@
<ColorItem Name="Outline" Color="@Scheme.Outline" OnColor="@Scheme.Background" />
</div>
<div class="d-flex relative">
<ColorItem Color="@Scheme.Surface" />
<ColorItem Color="@Scheme.Surface" BorderRadius="0 0 0 4px" />
<ColorItem Color="@Scheme.Surface1" />
<ColorItem Color="@Scheme.Surface2" />
<ColorItem Color="@Scheme.Surface3" />
<ColorItem Color="@Scheme.Surface4" />
<ColorItem Color="@Scheme.Surface5" />
<ColorItem Color="@Scheme.Surface5" BorderRadius="0 0 4px 0" />
<div class="absolute pa-2" style="color: @(StringUtils.HexFromArgb(Scheme.OnSurface))">
Surface 0-5
</div>
Expand Down
Loading

0 comments on commit f5cf055

Please sign in to comment.