Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
@namespace Bit.BlazorUI
@namespace Bit.BlazorUI
@inherits BitComponentBase

@{
var thumbStyle = FormattableString.Invariant($"top:{_saturationPickerThumbPosition?.Top}px;left:{_saturationPickerThumbPosition?.Left}px;background-color:{Rgb}");

var alphaSliderBg = "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAJUlEQVQYV2N89erVfwY0ICYmxoguxjgUFKI7GsTH5m4M3w1ChQC1/Ca8i2n1WgAAAABJRU5ErkJggg==)";
var alphaSliderStyle = $"background:linear-gradient(to left,{Rgb} 0%, transparent 100%), {alphaSliderBg};";
}

<div @ref="RootElement"
@attributes="HtmlAttributes"
id="@_Id"
Expand All @@ -21,9 +28,7 @@
style="@_saturationPickerStyle">
<div class="bit-clp-light"></div>
<div class="bit-clp-dark"></div>
<div class="bit-clp-thumb"
style="@(FormattableString.Invariant($"top:{_saturationPickerThumbPosition?.Top}px;left:{_saturationPickerThumbPosition?.Left}px;background-color:{Rgb}"))">
</div>
<div class="bit-clp-thumb" style="@thumbStyle"></div>
</div>

<div class="bit-clp-cnt">
Expand All @@ -46,8 +51,7 @@

@if (ShowAlphaSlider)
{
<div class="bit-clp-sld bit-clp-asd"
style=@($"background:linear-gradient(to left,{Rgb} 0%, transparent 100%), url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAJUlEQVQYV2N89erVfwY0ICYmxoguxjgUFKI7GsTH5m4M3w1ChQC1/Ca8i2n1WgAAAABJRU5ErkJggg==);")>
<div class="bit-clp-sld bit-clp-asd" style=@alphaSliderStyle>
<input @oninput="HandleOnAlphaInput"
step="0.01"
min="0"
Expand All @@ -59,9 +63,9 @@
aria-label="Alpha"
class="bit-clp-inp"
aria-valuemax="1"
value="@_color.A"
aria-valuenow="@_color.A"
aria-valuetext="@_color.A">
value="@(FormattableString.Invariant($"{_color.A}"))"
aria-valuenow="@(FormattableString.Invariant($"{_color.A}"))"
aria-valuetext="@(FormattableString.Invariant($"{_color.A}"))">
</div>
}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
namespace Bit.BlazorUI;
using System.Globalization;

namespace Bit.BlazorUI;

/// <summary>
/// The color picker (ColorPicker) is used to browse through and select colors. By default, it lets people navigate through colors on a color spectrum, or specify a color in either Red-Green-Blue (RGB), or alpha color code; or Hexadecimal textboxes.
/// The color picker (ColorPicker) is used to browse through and select colors.
/// By default, it lets people navigate through colors on a color spectrum,
/// or specify a color in either Red-Green-Blue (RGB), or alpha color code; or Hexadecimal textboxes.
/// </summary>
public partial class BitColorPicker : BitComponentBase
{
Expand Down Expand Up @@ -35,6 +39,7 @@ public double Alpha
if (_color.A == value) return;

_color.A = value;

AlphaChanged.InvokeAsync(value);
}
}
Expand All @@ -48,7 +53,7 @@ public string Color
get => _colorType == BitInternalColorType.Hex ? _color.Hex! : _color.Rgb!;
set
{
_colorType = value.HasValue() && value.StartsWith("#", StringComparison.InvariantCultureIgnoreCase)
_colorType = value.HasValue() && value.StartsWith('#')
? BitInternalColorType.Hex
: BitInternalColorType.Rgb;

Expand Down Expand Up @@ -85,10 +90,15 @@ public string Color


public string? Hex => _color.Hex;

public string? Rgb => FormattableString.Invariant($"rgb({_color.R},{_color.G},{_color.B})");

public string? Rgba => FormattableString.Invariant($"rgba({_color.R},{_color.G},{_color.B},{_color.A})");

public (double Hue, double Saturation, double Value) Hsv => _color.Hsv;



[JSInvokable(nameof(HandlePointerUp))]
public void HandlePointerUp(MouseEventArgs e)
{
Expand Down Expand Up @@ -132,6 +142,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
private async Task SetSaturationPickerThumbPositionAsync()
{
var (_, saturation, value) = _color.Hsv;

var saturationPickerRect = await _js.BitUtilsGetBoundingClientRect(_saturationPickerRef);

var width = saturationPickerRect?.Width ?? 0;
Expand All @@ -145,6 +156,7 @@ private async Task SetSaturationPickerThumbPositionAsync()
private void SetSaturationPickerStyle()
{
var rgb = BitInternalColor.ToRgb(_selectedHue, 1, 1).ToString();

_saturationPickerStyle = $"background-color:rgb{rgb}";
}

Expand All @@ -153,21 +165,25 @@ private async Task UpdateColor(MouseEventArgs e)
if (ColorHasBeenSet && ColorChanged.HasDelegate is false) return;

var pickerRect = await _js.BitUtilsGetBoundingClientRect(_saturationPickerRef);
var left = e.ClientX < pickerRect.Left ? 0

var left = e.ClientX < pickerRect.Left
? 0
: e.ClientX > pickerRect.Left + pickerRect.Width
? pickerRect.Width
: (e.ClientX - pickerRect.Left);
var top = e.ClientY < pickerRect.Top ? 0
? pickerRect.Width
: (e.ClientX - pickerRect.Left);
var top = e.ClientY < pickerRect.Top
? 0
: e.ClientY > pickerRect.Top + pickerRect.Height
? pickerRect.Height
: (e.ClientY - pickerRect.Top);
? pickerRect.Height
: (e.ClientY - pickerRect.Top);

_saturationPickerThumbPosition = new(left, top);

_selectedSaturation = Math.Clamp((e.ClientX - pickerRect.Left) / pickerRect.Width, 0, 1);
_selectedValue = Math.Clamp((pickerRect.Height - e.ClientY + pickerRect.Top) / pickerRect.Height, 0, 1);

_color.Update(_selectedHue, _selectedSaturation, _selectedValue, _color.A);

var colorValue = _colorType == BitInternalColorType.Hex ? _color.Hex : _color.Rgb;

SetSaturationPickerStyle();
Expand All @@ -183,7 +199,8 @@ private async Task HandleOnHueInput(ChangeEventArgs args)
{
if (ColorHasBeenSet && ColorChanged.HasDelegate is false) return;

_selectedHue = Convert.ToDouble(args.Value);
_selectedHue = Convert.ToDouble(args.Value, CultureInfo.InvariantCulture);

_color.Update(_selectedHue, _selectedSaturation, _selectedValue, _color.A);

var colorValue = _colorType == BitInternalColorType.Hex ? _color.Hex : _color.Rgb;
Expand All @@ -199,7 +216,8 @@ private async Task HandleOnAlphaInput(ChangeEventArgs args)
{
if (AlphaHasBeenSet && AlphaChanged.HasDelegate is false) return;

_color.A = Convert.ToDouble(args.Value);
_color.A = Convert.ToDouble(args.Value, CultureInfo.InvariantCulture);

var colorValue = _colorType == BitInternalColorType.Hex ? _color.Hex : _color.Rgb;

await ColorChanged.InvokeAsync(colorValue);
Expand All @@ -210,20 +228,20 @@ private async Task HandleOnAlphaInput(ChangeEventArgs args)
private async Task HandleOnSaturationPickerPointerDown(MouseEventArgs e)
{
_saturationPickerPointerDown = true;

await UpdateColor(e);
}

private string GetRootElAriaLabel()
{
var ariaLabel = $"Color picker, Red {_color.R} Green {_color.G} Blue {_color.B} ";
var ariaLabel = $"Color picker, Red {_color.R} Green {_color.G} Blue {_color.B}";

if (ShowAlphaSlider)
{
ariaLabel += $"Alpha {_color.A * 100}% selected.";
}
else
{
ariaLabel += "selected.";
ariaLabel += FormattableString.Invariant($" and Alpha {_color.A * 100}%");
}

ariaLabel += " selected.";

return ariaLabel;
}
Expand Down
Loading