Skip to content

Commit

Permalink
- Add all new components:
Browse files Browse the repository at this point in the history
1. InputSlider
2. InputSwitch
3. InputTimeSpan
4. QuickDate
5. QuickNumber
6. SplutButtonDropdown
7. ToggleChooser

- Update Package versions
  • Loading branch information
taylorchasewhite committed Jan 31, 2024
1 parent 0122e96 commit 55242ed
Show file tree
Hide file tree
Showing 19 changed files with 721 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
<RepositoryUrl>https://github.com/BlazingApple/Components</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>2.5.4</AssemblyVersion>
<FileVersion>2.5.5</FileVersion>
<Version>2.5.5</Version>
<PackageReleaseNotes>2.5.5 - Target .NET 8</PackageReleaseNotes>
<AssemblyVersion>2.5.6</AssemblyVersion>
<FileVersion>2.5.6</FileVersion>
<Version>2.5.6</Version>
<PackageReleaseNotes>2.5.6 - Add new SpanType enum</PackageReleaseNotes>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand All @@ -27,4 +27,8 @@
<PackagePath>\</PackagePath>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Humanizer" Version="2.14.1" />
</ItemGroup>
</Project>
15 changes: 15 additions & 0 deletions src/BlazingApple.Components.Shared/Models/Time/SpanType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace BlazingApple.Components.Shared.Models.Time;

/// <summary>The type of span</summary>
/// <seealso cref="TimeSpan"/>
public enum SpanType
{
/// <summary>Render the span in days</summary>
Days,
/// <summary>Render the span in weeks</summary>
Weeks,
/// <summary>Render the span in months</summary>
Months,
/// <summary>Render the span in years</summary>
Years,
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
<RepositoryUrl>https://github.com/BlazingApple/Components</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>2.6</AssemblyVersion>
<FileVersion>2.6</FileVersion>
<Version>2.6</Version>
<PackageReleaseNotes>2.6 - Add toggle button</PackageReleaseNotes>
<AssemblyVersion>2.7.0</AssemblyVersion>
<FileVersion>2.7.0</FileVersion>
<Version>2.7.0</Version>
<PackageReleaseNotes>2.7.0 - New Input Components and Buttons</PackageReleaseNotes>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand All @@ -32,12 +32,12 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="BlazingApple.Components.Shared" Version="2.5.5" />
<PackageReference Include="BlazingApple.Components.Shared" Version="2.5.6" />
<PackageReference Include="BlazingApple.FontAwesome" Version="0.4.0" />
<PackageReference Include="Blazored.Toast" Version="4.1.0" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.4.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.1" PrivateAssets="all" />
<PackageReference Include="Syncfusion.Blazor" Version="20.4.0.38" />
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.175" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@
<CascadingValue Value="this">
<div class="dropdown">
<button class="@dropDownButtonClass" type="button" @onclick="ToggleOpen" @attributes="@AdditionalAttributes">
@Label: @Value?.ToString()
@Label:
@if(Items is not null)
{
DropDownItem<T>? item = Items.SingleOrDefault(i => i.Value != null && i.Value.Equals(Value));
@if(item?.ChildContent is not null)
{
@item.ChildContent
}
}
</button>

<ul class="@dropDownMenuClass" style="z-index: 1030;">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@using System.Numerics
@typeparam TNumber where TNumber : INumber<TNumber>

<div class="d-flex">
<input type="range" class="form-range" min="0" max="@Max" id="slider1" value="@Value" @onchange="ValueChangedInternal" @attributes="AdditionalAttributes">
@if (ShowCurrentValue)
{
<span class="mx-1">@Value</span>
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Numerics;

namespace BlazingApple.Components.HTMLElements;

/// <summary>Slider control.</summary>
/// <typeparam name="TNumber">A type of number</typeparam>
public partial class InputSlider<TNumber> : ComponentBase
where TNumber : INumber<TNumber>
{
private readonly Guid _uniqueId = Guid.NewGuid();

/// <summary>Captures/renders standard HTML attributes passed</summary>
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object> AdditionalAttributes { get; set; } = null!;

/// <summary>Label for the switch</summary>
[Parameter]
public string? Label { get; set; }

/// <summary>Whether or not to show the current value.</summary>
[Parameter]
public bool ShowCurrentValue { get; set; } = true;

/// <summary>Display text/title text to show on hover, if any.</summary>
[Parameter]
public string? TitleText { get; set; }

/// <summary>Child content to render, if any.</summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }

/// <summary>A reference to the Filter object that a consumer passes in.</summary>
[Parameter]
public TNumber Value { get; set; } = default!;

/// <summary>Min value of the range.</summary>
[Parameter]
public TNumber? Min { get; set; }

/// <summary>Max value of the range.</summary>
[Parameter]
public TNumber? Max { get; set; }

/// <summary>Step of the range slider.</summary>
[Parameter]
public TNumber Step { get; set; } = TNumber.One;

/// <summary>Allows binding to the Value parameter.</summary>
[Parameter]
public EventCallback<TNumber> ValueChanged { get; set; }

private async Task ValueChangedInternal(ChangeEventArgs args)
{
Value = TNumber.Parse(args.Value!.ToString()!, System.Globalization.NumberStyles.Number, null);
if (ValueChanged.HasDelegate)
await ValueChanged.InvokeAsync(Value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="form-check form-switch">
<input type="checkbox" checked="@Value" class="form-check-input" id="@($"isComplete-{_uniqueId}")" style="line-height:initial;" @onchange="ValueChangedInternal" />
<label class="form-check-label" for="@($"isComplete-{_uniqueId}")">
<span title="@TitleText">@Label</span>
@if (ChildContent is not null)
{
@ChildContent
}
</label>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace BlazingApple.Components.HTMLElements;

/// <summary>Renders a checkbox as a switch.</summary>
/// <remarks>See https://getbootstrap.com/docs/5.0/forms/checks-radios/#switches</remarks>
public partial class InputSwitch : ComponentBase
{
private readonly Guid _uniqueId = Guid.NewGuid();

/// <summary>Label for the switch</summary>
[Parameter]
public string? Label { get; set; }

/// <summary>Display text/title text to show on hover, if any.</summary>
[Parameter]
public string? TitleText { get; set; }

/// <summary>Child content to render, if any.</summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }

/// <summary>A reference to the Filter object that a consumer passes in.</summary>
[Parameter]
public bool Value { get; set; } = default!;

/// <summary>Allows binding to the Value parameter.</summary>
[Parameter]
public EventCallback<bool> ValueChanged { get; set; }

private async Task ValueChangedInternal(ChangeEventArgs args)
{
Value = (bool)args.Value!;
if (ValueChanged.HasDelegate)
await ValueChanged.InvokeAsync(Value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@using BlazingApple.Components.Shared.Models.Time
@using Humanizer
<div class="d-flex align-items-center">
<InputSlider TNumber="int" ShowCurrentValue="false" Value="_countOfSpan" ValueChanged="CountChanged" Max="_maxForSpan" Min="0" @attributes="AdditionalAttributes"></InputSlider>

@if (!Units.HasValue)
{
<DropDown T="SpanType" ButtonClass="ms-1 btn-outline-primary btn-sm" ValueChanged="@(async (SpanType val) => await SpanTypeChanged(val))" Value="_spanType">
@foreach (SpanType val in Enum.GetValues<SpanType>())
{
<DropDownItem Value="val">
<div class="d-flex align-items-center">
@val.ToString()
</div>
</DropDownItem>
}
</DropDown>
}
else
{
<span class="ms-1">@Units.Value.GetEnumDisplayName().ToQuantity(_countOfSpan)</span>
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
using Syncfusion.Blazor.InPlaceEditor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BlazingApple.Components.Shared.Models.Time;

namespace BlazingApple.Components.HTMLElements;

/// <summary>Allows setting a timespan, using only even numbers.</summary>
public partial class InputTimeSpan : ComponentBase
{
private readonly Guid _uniqueId = Guid.NewGuid();
private int _countOfSpan;
private int _maxForSpan;
private SpanType _spanType;

/// <summary>Captures/renders standard HTML attributes passed</summary>
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object> AdditionalAttributes { get; set; } = null!;

/// <summary>Label for the switch</summary>
[Parameter]
public string? Label { get; set; }

/// <summary>A reference to the Filter object that a consumer passes in.</summary>
[Parameter]
public TimeSpan? Value { get; set; } = default!;

/// <summary>Allows binding to the Value parameter.</summary>
[Parameter]
public EventCallback<TimeSpan?> ValueChanged { get; set; }

/// <summary>Forces the units of the control.</summary>
[Parameter]
public SpanType? Units { get; set; }

/// <summary>The maximum span.</summary>
[Parameter]
public TimeSpan Max { get; set; } = new(365, 0, 0, 0);

/// <inheritdoc />
protected override void OnInitialized()
{
base.OnInitialized();

if (Units.HasValue)
{
_spanType = Units.Value;
_maxForSpan = ToCount(_spanType, (int)Math.Floor(Max.TotalDays));
return;
}

if (Max == default)
{
_spanType = SpanType.Days;
_maxForSpan = 30;
}

if (Max.TotalDays <= 21)
{
_spanType = SpanType.Days;
_maxForSpan = (int)Math.Floor(Max.TotalDays);
}
else if (Max.TotalDays is > 21 and <= 84)
{
// 84 days == 12 weeks
_spanType = SpanType.Weeks;
_maxForSpan = (int)Math.Floor(Max.TotalDays / 7);
}
else if (Max.TotalDays is > 84 and <= 900)
{
_spanType = SpanType.Months;
_maxForSpan = (int)Math.Floor(Max.TotalDays / 30);
}
else if (Max.TotalDays > 900)
{
_spanType = SpanType.Years;
_maxForSpan = (int)Math.Floor(Max.TotalDays / 365);
}
}

/// <inheritdoc />
protected override void OnParametersSet()
{
base.OnParametersSet();
if (Value.HasValue)
_countOfSpan = ToCount(_spanType, (int)Math.Floor(Value.Value.TotalDays));
}

private static TimeSpan ToSpan(SpanType spanType, int count)
{
TimeSpan span = spanType switch
{
SpanType.Days => new TimeSpan(count, 0, 0, 0),
SpanType.Weeks => new TimeSpan(count * 7, 0, 0, 0),
SpanType.Months => new TimeSpan(count * 30, 0, 0, 0),
SpanType.Years => new TimeSpan(count * 365, 0, 0, 0),
_ => throw new ArgumentOutOfRangeException(nameof(spanType)),
};
return span;
}

private static int ToCount(SpanType spanType, int maxInDays)
{
int countForSpan = spanType switch
{
SpanType.Days => maxInDays,
SpanType.Weeks => maxInDays / 7,
SpanType.Months => maxInDays / 30,
SpanType.Years => maxInDays / 365,
_ => throw new ArgumentOutOfRangeException(nameof(spanType)),
};
return countForSpan;
}

private static int ToCountInDays(SpanType spanType, int countInSpan)
{
int countInDays = spanType switch
{
SpanType.Days => countInSpan,
SpanType.Weeks => countInSpan * 7,
SpanType.Months => countInSpan * 30,
SpanType.Years => countInSpan * 365,
_ => throw new ArgumentOutOfRangeException(nameof(spanType)),
};
return countInDays;
}

private static int ToCount(SpanType oldSpan, int countInOldSpan, SpanType newSpan)
{
int countInDays = ToCountInDays(oldSpan, countInOldSpan);
return ToCount(newSpan, countInDays);
}

private async Task UpdateValue()
{
Value = ToSpan(_spanType, _countOfSpan);
await ValueChangedInternal();
}

private async Task ValueChangedInternal()
{
if (ValueChanged.HasDelegate)
await ValueChanged.InvokeAsync(Value);
}

private async Task CountChanged(int count)
{
_countOfSpan = count;
await UpdateValue();
}

private async Task SpanTypeChanged(SpanType spanType)
{
_countOfSpan = ToCount(_spanType, _countOfSpan, spanType);
_spanType = spanType;

_maxForSpan = ToCount(_spanType, Convert.ToInt16(Math.Floor(Max.TotalDays)));

await UpdateValue();
}
}
Loading

0 comments on commit 55242ed

Please sign in to comment.