ant-design-blazor/components/slider/Slider.razor.cs

843 lines
29 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Globalization;
2020-04-30 01:21:06 +08:00
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using AntDesign.core.Extensions;
using AntDesign.Core.Helpers;
using AntDesign.JsInterop;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
2020-04-30 01:21:06 +08:00
namespace AntDesign
2020-04-30 01:21:06 +08:00
{
public partial class Slider<TValue> : AntInputComponentBase<TValue>
2020-04-30 01:21:06 +08:00
{
private const string PreFixCls = "ant-slider";
private HtmlElement _sliderDom;
private HtmlElement _leftHandleDom;
private HtmlElement _rightHandleDom;
2020-04-30 01:21:06 +08:00
private ElementReference _leftHandle;
private ElementReference _rightHandle;
private string _leftHandleStyle = "left: 0%; right: auto; transform: translateX(-50%);";
private string _rightHandleStyle = "left: 0%; right: auto; transform: translateX(-50%);";
private string _trackStyle = "left: 0%; width: 0%; right: auto;";
private bool _mouseDown;
private bool _mouseMove;
2020-04-30 01:21:06 +08:00
private bool _right = true;
private bool _initialized = false;
private double _initialLeftValue;
private double _initialRightValue;
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private Tooltip _toolTipRight;
private Tooltip _toolTipLeft;
2020-04-30 01:21:06 +08:00
private string RightHandleStyleFormat
{
get
{
if (Reverse)
{
if (Vertical)
{
return "bottom: auto; top: {0}; transform: translateY(-50%);";
}
else
{
return "right: {0}; left: auto; transform: translateX(50%);";
}
}
else
{
if (Vertical)
{
return "top: auto; bottom: {0}; transform: translateY(50%);";
}
else
{
return "left: {0}; right: auto; transform: translateX(-50%);";
}
}
}
}
private string LeftHandleStyleFormat
{
get
{
if (Reverse)
{
if (Vertical)
{
return "bottom: auto; top: {0}; transform: translateY(-50%);";
}
else
{
return "right: {0}; left: auto; transform: translateX(50%);";
}
}
else
{
if (Vertical)
{
return "top: auto; bottom: {0}; transform: translateY(50%);";
}
else
{
return "left: {0}; right: auto; transform: translateX(-50%);";
}
}
}
}
private string TrackStyleFormat
{
get
{
if (Reverse)
{
if (Vertical)
{
return "bottom: auto; height: {1}; top: {0};";
}
else
{
return "right: {0}; width: {1}; left: auto;";
}
}
else
{
if (Vertical)
{
return "top: auto; height: {1}; bottom: {0};";
}
else
{
return "left: {0}; width: {1}; right: auto;";
}
}
}
}
[Inject]
private DomEventService DomEventService { get; set; }
#region Parameters
/// <summary>
/// The default value of slider. When <see cref="Range"/> is false, use number, otherwise, use [number, number]
/// </summary>
[Parameter]
public TValue DefaultValue { get; set; }
2020-04-30 01:21:06 +08:00
/// <summary>
/// If true, the slider will not be interactable
/// </summary>
[Parameter]
public bool Disabled { get; set; }
/// <summary>
/// Whether the thumb can drag over tick only
/// </summary>
[Parameter]
public bool Dots { get; set; }
/// <summary>
/// Make effect when <see cref="Marks"/> not null, true means containment and false means coordinative
/// </summary>
[Parameter]
public bool Included { get; set; } = true;
/// <summary>
/// Tick mark of Slider, type of key must be number, and must in closed interval [min, max], each mark can declare its own style
/// </summary>
[Parameter]
public SliderMark[] Marks { get; set; }
2020-04-30 01:21:06 +08:00
/// <summary>
/// The maximum value the slider can slide to
/// </summary>
[Parameter]
public double Max { get; set; } = 100;
/// <summary>
/// The minimum value the slider can slide to
/// </summary>
[Parameter]
public double Min { get; set; } = 0;
/// <summary>
/// dual thumb mode
/// </summary>
//[Parameter]
private bool? _range;
public bool Range
{
get
{
if (_range == null)
{
Type type = typeof(TValue);
Type doubleType = typeof(double);
Type tupleDoubleType = typeof((double, double));
if (type == doubleType)
{
_range = false;
}
else if (type == tupleDoubleType)
{
_range = true;
}
else
{
throw new ArgumentOutOfRangeException($"Type argument of Slider should be one of {doubleType}, {tupleDoubleType}");
}
}
return _range.Value;
}
//private set { _range = value; }
}
2020-04-30 01:21:06 +08:00
/// <summary>
/// reverse the component
/// </summary>
private bool _reverse;
2020-04-30 01:21:06 +08:00
[Parameter]
public bool Reverse
{
get { return _reverse; }
set
{
if (_reverse != value)
{
_reverse = value;
SetStyle();
}
}
}
2020-04-30 01:21:06 +08:00
/// <summary>
/// The granularity the slider can step through values. Must greater than 0, and be divided by (<see cref="Max"/> - <see cref="Min"/>) . When <see cref="Marks"/> no null, <see cref="Step"/> can be null.
/// </summary>
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private double? _step = 1;
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private int _precision;
2020-04-30 01:21:06 +08:00
[Parameter]
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
public double? Step
{
get { return _step; }
set
{
_step = value;
//no need to evaluate if no tooltip
if (_step != null && _isTipFormatterDefault)
{
char separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
string[] number = _step.ToString().Split(separator);
if (number.Length > 1)
{
_precision = number[1].Length;
_tipFormatter = (d) => string.Format(CultureInfo.CurrentCulture, "{0:N02}", Math.Round(d, _precision));
}
}
}
}
2020-04-30 01:21:06 +08:00
private double _leftValue = double.MinValue;
private double LeftValue
{
get => _leftValue;
set
{
double candidate = Clamp(value, Min, Max);
if (_leftValue != candidate)
{
_leftValue = candidate;
SetStyle();
(double, double) typedValue = DataConvertionExtensions.Convert<TValue, (double, double)>(CurrentValue);
if (value != typedValue.Item1)
CurrentValue = DataConvertionExtensions.Convert<(double, double), TValue>((_leftValue, RightValue));
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
if (_toolTipLeft != null)
_toolTipLeft.ChildElementMoved();
}
2020-04-30 01:21:06 +08:00
}
}
private double _rightValue = double.MaxValue;
// the default non-range value
private double RightValue
{
get => _rightValue;
set
{
double candidate;
if (Range)
2020-04-30 01:21:06 +08:00
{
candidate = Clamp(value, LeftValue, Max);
}
else
{
candidate = Clamp(value, Min, Max);
}
if (_rightValue != candidate)
{
_rightValue = candidate;
SetStyle();
if (Range)
{
//CurrentValue = TupleToGeneric((LeftValue, _rightValue));
(double, double) typedValue = DataConvertionExtensions.Convert<TValue, (double, double)>(CurrentValue);
if (value != typedValue.Item2)
CurrentValue = DataConvertionExtensions.Convert<(double, double), TValue>((LeftValue, _rightValue));
}
else
{
double typedValue = DataConvertionExtensions.Convert<TValue, double>(CurrentValue);
if (value != typedValue)
//CurrentValue = DoubleToGeneric(_rightValue);
CurrentValue = DataConvertionExtensions.Convert<double, TValue>(_rightValue);
}
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
if (_toolTipRight != null)
_toolTipRight.ChildElementMoved();
2020-04-30 01:21:06 +08:00
}
}
}
private double Clamp(
double value, double inclusiveMinimum, double inclusiveMaximum)
{
if (value < inclusiveMinimum)
{
value = inclusiveMinimum;
}
if (value > inclusiveMaximum)
{
value = inclusiveMaximum;
}
return GetNearestStep(value);
}
/// <summary>
2020-04-30 01:21:06 +08:00
/// If true, the slider will be vertical.
/// </summary>
[Parameter]
public bool Vertical { get; set; }
/// <summary>
/// Fire when onmouseup is fired.
/// </summary>
[Parameter]
public Action<TValue> OnAfterChange { get; set; } //use Action here intead of EventCallback, otherwise VS will not complie when user add a delegate
2020-04-30 01:21:06 +08:00
/// <summary>
/// Callback function that is fired when the user changes the slider's value.
/// </summary>
[Parameter]
public Action<TValue> OnChange { get; set; }
2020-04-30 01:21:06 +08:00
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
[Parameter]
public bool HasTooltip { get; set; } = true;
/// <summary>
/// Slider will pass its value to tipFormatter, and display its value in Tooltip
/// </summary>
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private bool _isTipFormatterDefault = true;
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private Func<double, string> _tipFormatter = (d) => d.ToString(LocaleProvider.CurrentLocale.CurrentCulture);
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
[Parameter]
public Func<double, string> TipFormatter
{
get { return _tipFormatter; }
set
{
_tipFormatter = value;
_isTipFormatterDefault = false;
}
}
2020-04-30 01:21:06 +08:00
/// <summary>
/// Set Tooltip display position. Ref Tooltip
2020-04-30 01:21:06 +08:00
/// </summary>
[Parameter]
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
public PlacementType TooltipPlacement { get; set; }
2020-04-30 01:21:06 +08:00
/// <summary>
/// If true, Tooltip will show always, or it will not show anyway, even if dragging or hovering.
/// </summary>
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private bool _tooltipVisible;
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private bool _tooltipRightVisible;
private bool _tooltipLeftVisible;
2020-04-30 01:21:06 +08:00
[Parameter]
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
public bool TooltipVisible
{
get { return _tooltipVisible; }
set
{
if (_tooltipVisible != value)
{
_tooltipVisible = value;
//ensure parameter loading is not happening because values are changing during mouse moving
//otherwise the tooltip will be vanishing when mouse moves out of the edge
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
if (!_mouseDown)
{
_tooltipRightVisible = _tooltipVisible;
_tooltipLeftVisible = _tooltipVisible;
}
}
}
}
2020-04-30 01:21:06 +08:00
/// <summary>
/// The DOM container of the Tooltip, the default behavior is to create a div element in body.
/// </summary>
[Parameter]
public object GetTooltipPopupContainer { get; set; }
#endregion Parameters
protected override void OnInitialized()
{
base.OnInitialized();
}
public async override Task SetParametersAsync(ParameterView parameters)
{
await base.SetParametersAsync(parameters);
var dict = parameters.ToDictionary();
if (!_initialized)
2020-04-30 01:21:06 +08:00
{
if (!dict.ContainsKey(nameof(Value)))
{
TValue defaultValue;
if (Range)
{
//if (typeof(T) == typeof((int, int)))
//{
// defaultValue = parameters.GetValueOrDefault(nameof(DefaultValue), DataConvertionExtensions.Convert<(int, int), T>((0, 0)));
//}
//else
//{
defaultValue = parameters.GetValueOrDefault(nameof(DefaultValue), DataConvertionExtensions.Convert<(double, double), TValue>((0, 0)));
//}
LeftValue = DataConvertionExtensions.Convert<TValue, (double, double)>(defaultValue).Item1;
RightValue = DataConvertionExtensions.Convert<TValue, (double, double)>(defaultValue).Item2;
}
else
{
//if (typeof(T) == typeof(int))
//{
// defaultValue = parameters.GetValueOrDefault(nameof(DefaultValue), DataConvertionExtensions.Convert<int, T>(0));
//}
//else
//{
defaultValue = parameters.GetValueOrDefault(nameof(DefaultValue), DataConvertionExtensions.Convert<double, TValue>(0));
//}
RightValue = DataConvertionExtensions.Convert<TValue, double>(defaultValue);
}
}
else
{
if (Range)
{
LeftValue = DataConvertionExtensions.Convert<TValue, (double, double)>(CurrentValue).Item1;
RightValue = DataConvertionExtensions.Convert<TValue, (double, double)>(CurrentValue).Item2;
}
else
{
RightValue = DataConvertionExtensions.Convert<TValue, double>(CurrentValue);
}
}
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
if (!dict.ContainsKey(nameof(TooltipPlacement)))
{
if (Vertical)
TooltipPlacement = PlacementType.Right;
else
TooltipPlacement = PlacementType.Top;
}
2020-04-30 01:21:06 +08:00
}
_initialized = true;
2020-04-30 01:21:06 +08:00
}
protected override void OnParametersSet()
{
base.OnParametersSet();
ValidateParameter();
ClassMapper.Clear()
.Add(PreFixCls)
.If($"{PreFixCls}-disabled", () => Disabled)
.If($"{PreFixCls}-vertical", () => Vertical)
.If($"{PreFixCls}-with-marks", () => Marks != null)
.If($"{PreFixCls}-rtl", () => RTL);
2020-04-30 01:21:06 +08:00
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
DomEventService.AddEventListener("window", "mousemove", OnMouseMove, false);
DomEventService.AddEventListener("window", "mouseup", OnMouseUp, false);
}
base.OnAfterRender(firstRender);
}
protected override void Dispose(bool disposing)
{
DomEventService.RemoveEventListerner<JsonElement>("window", "mousemove", OnMouseMove);
DomEventService.RemoveEventListerner<JsonElement>("window", "mouseup", OnMouseUp);
base.Dispose(disposing);
}
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
{
if (_toolTipRight != null && HasTooltip)
{
_rightHandle = _toolTipRight.Ref;
await _toolTipRight.ChildElementMoved();
if (_toolTipLeft != null)
{
_leftHandle = _toolTipLeft.Ref;
await _toolTipLeft.ChildElementMoved();
}
}
}
await base.OnAfterRenderAsync(firstRender);
}
2020-04-30 01:21:06 +08:00
private void ValidateParameter()
{
if (Step == null && Marks == null)
{
throw new ArgumentOutOfRangeException(nameof(Step), $"{nameof(Step)} can only be null when {nameof(Marks)} is not null.");
}
if (Step <= 0)
{
throw new ArgumentOutOfRangeException(nameof(Step), "Must greater than 0.");
}
if (Step != null && (Max - Min) / Step % 1 != 0)
2020-04-30 01:21:06 +08:00
{
throw new ArgumentOutOfRangeException(nameof(Step), $"Must be divided by ({Max} - {Min}).");
}
}
private async void OnMouseDown(MouseEventArgs args)
2020-04-30 01:21:06 +08:00
{
//// _sliderDom = await JsInvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, _slider);
//_sliderDom = await JsInvokeAsync<Element>(JSInteropConstants.GetDomInfo, _slider);
//decimal x = (decimal)args.ClientX;
//decimal y = (decimal)args.ClientY;
//_mouseDown = !Disabled
// && _sliderDom.clientLeft <= x && x <= _sliderDom.clientLeft + _sliderDom.clientWidth
// && _sliderDom.clientTop <= y && y <= _sliderDom.clientTop + _sliderDom.clientHeight;
_mouseDown = !Disabled;
2020-04-30 01:21:06 +08:00
}
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
private double _trackedClientX;
private double _trackedClientY;
private void OnMouseDownEdge(MouseEventArgs args, bool right)
{
_right = right;
_initialLeftValue = _leftValue;
_initialRightValue = _rightValue;
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
_trackedClientX = args.ClientX;
_trackedClientY = args.ClientY;
if (_toolTipRight != null)
{
if (_right)
{
_tooltipRightVisible = true;
}
else
{
_tooltipLeftVisible = true;
}
}
}
private bool IsMoveInEdgeBoundary(JsonElement jsonElement)
{
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
double clientX = jsonElement.GetProperty("clientX").GetDouble();
double clientY = jsonElement.GetProperty("clientY").GetDouble();
return (clientX == _trackedClientX && clientY == _trackedClientY);
}
2020-04-30 01:21:06 +08:00
private async void OnMouseMove(JsonElement jsonElement)
{
if (_mouseDown)
2020-04-30 01:21:06 +08:00
{
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
_trackedClientX = jsonElement.GetProperty("clientX").GetDouble();
_trackedClientY = jsonElement.GetProperty("clientY").GetDouble();
_mouseMove = true;
await CalculateValueAsync(Vertical ? jsonElement.GetProperty("pageY").GetDouble() : jsonElement.GetProperty("pageX").GetDouble());
2020-05-15 19:19:49 +08:00
OnChange?.Invoke(CurrentValue);
2020-04-30 01:21:06 +08:00
}
}
private async void OnMouseUp(JsonElement jsonElement)
2020-04-30 01:21:06 +08:00
{
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
bool isMoveInEdgeBoundary = IsMoveInEdgeBoundary(jsonElement);
if (_mouseDown)
2020-04-30 01:21:06 +08:00
{
_mouseDown = false;
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
if (!isMoveInEdgeBoundary)
{
await CalculateValueAsync(Vertical ? jsonElement.GetProperty("pageY").GetDouble() : jsonElement.GetProperty("pageX").GetDouble());
OnAfterChange?.Invoke(CurrentValue);
}
}
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
if (_toolTipRight != null)
{
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
if (_tooltipRightVisible != TooltipVisible)
{
_tooltipRightVisible = TooltipVisible;
_toolTipRight.SetVisible(TooltipVisible);
}
if (_tooltipLeftVisible != TooltipVisible)
{
_tooltipLeftVisible = TooltipVisible;
_toolTipLeft.SetVisible(TooltipVisible);
}
2020-04-30 01:21:06 +08:00
}
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
_initialLeftValue = _leftValue;
_initialRightValue = _rightValue;
2020-04-30 01:21:06 +08:00
}
private async Task CalculateValueAsync(double clickClient)
2020-04-30 01:21:06 +08:00
{
_sliderDom = await JsInvokeAsync<HtmlElement>(JSInteropConstants.GetDomInfo, Ref);
double sliderOffset = (double)(Vertical ? _sliderDom.AbsoluteTop : _sliderDom.AbsoluteLeft);
double sliderLength = (double)(Vertical ? _sliderDom.ClientHeight : _sliderDom.ClientWidth);
double handleNewPosition;
2020-04-30 01:21:06 +08:00
if (_right)
{
if (_rightHandleDom == null)
{
_rightHandleDom = await JsInvokeAsync<HtmlElement>(JSInteropConstants.GetDomInfo, _rightHandle);
2020-04-30 01:21:06 +08:00
}
if (Reverse)
{
if (Vertical)
{
handleNewPosition = clickClient - sliderOffset;
2020-04-30 01:21:06 +08:00
}
else
{
handleNewPosition = sliderLength - (clickClient - sliderOffset);
2020-04-30 01:21:06 +08:00
}
}
else
{
if (Vertical)
{
handleNewPosition = sliderOffset + sliderLength - clickClient;
2020-04-30 01:21:06 +08:00
}
else
{
handleNewPosition = clickClient - sliderOffset;
2020-04-30 01:21:06 +08:00
}
}
double rightV = Max * handleNewPosition / sliderLength;
if (rightV < LeftValue)
{
_right = false;
if (_mouseDown)
RightValue = _initialLeftValue;
LeftValue = rightV;
await FocusAsync(_leftHandle);
2020-04-30 01:21:06 +08:00
}
else
{
RightValue = rightV;
}
}
else
{
if (_leftHandleDom == null)
{
_leftHandleDom = await JsInvokeAsync<HtmlElement>(JSInteropConstants.GetDomInfo, _leftHandle);
2020-04-30 01:21:06 +08:00
}
if (_rightHandleDom == null)
{
_rightHandleDom = await JsInvokeAsync<HtmlElement>(JSInteropConstants.GetDomInfo, _rightHandle);
}
2020-04-30 01:21:06 +08:00
if (Reverse)
{
if (Vertical)
{
handleNewPosition = clickClient - sliderOffset;
2020-04-30 01:21:06 +08:00
}
else
{
handleNewPosition = sliderLength - (clickClient - sliderOffset);
2020-04-30 01:21:06 +08:00
}
}
else
{
if (Vertical)
{
handleNewPosition = sliderOffset + sliderLength - clickClient;
2020-04-30 01:21:06 +08:00
}
else
{
handleNewPosition = clickClient - sliderOffset;
2020-04-30 01:21:06 +08:00
}
}
double leftV = Max * handleNewPosition / sliderLength;
if (leftV > RightValue)
{
_right = true;
if (_mouseDown)
LeftValue = _initialRightValue;
RightValue = leftV;
await FocusAsync(_rightHandle);
2020-04-30 01:21:06 +08:00
}
else
{
LeftValue = leftV;
}
}
}
private void SetStyle()
{
_rightHandleStyle = string.Format(CultureInfo.CurrentCulture, RightHandleStyleFormat, Formatter.ToPercentWithoutBlank(RightValue / Max));
2020-04-30 01:21:06 +08:00
if (Range)
{
_trackStyle = string.Format(CultureInfo.CurrentCulture, TrackStyleFormat, Formatter.ToPercentWithoutBlank(LeftValue / Max), Formatter.ToPercentWithoutBlank((RightValue - LeftValue) / Max));
_leftHandleStyle = string.Format(CultureInfo.CurrentCulture, LeftHandleStyleFormat, Formatter.ToPercentWithoutBlank(LeftValue / Max));
2020-04-30 01:21:06 +08:00
}
else
{
_trackStyle = string.Format(CultureInfo.CurrentCulture, TrackStyleFormat, "0%", Formatter.ToPercentWithoutBlank(RightValue / Max));
2020-04-30 01:21:06 +08:00
}
StateHasChanged();
}
private string SetMarkPosition(double key)
{
return Formatter.ToPercentWithoutBlank(key / Max);
2020-04-30 01:21:06 +08:00
}
private string IsActiveMark(double key)
{
bool active = (Range && key >= LeftValue && key <= RightValue)
|| (!Range && key <= RightValue);
return active ? "ant-slider-dot-active" : string.Empty;
}
private double GetNearestStep(double value)
{
if (Step.HasValue && (Marks == null || Marks.Length == 0))
{
return Math.Round(value / Step.Value, 0) * Step.Value;
2020-04-30 01:21:06 +08:00
}
else if (Step.HasValue)
{
return new double[2] { Math.Round(value / Step.Value) * Step.Value, Math.Round(value / Step.Value + 1) * Step.Value }.Union(Marks.Select(m => m.Key)).OrderBy(v => Math.Abs(v - value)).First();
}
else if (Marks.Length == 0)
{
return Min;
}
else
{
return Marks.Select(m => m.Key).OrderBy(v => Math.Abs(v - value)).First();
}
}
protected override void OnValueChange(TValue value)
{
base.OnValueChange(value);
if (Range)
{
if (IsLeftAndRightChanged(value))
{
_leftValue = double.MinValue;
_rightValue = double.MaxValue;
}
LeftValue = DataConvertionExtensions.Convert<TValue, (double, double)>(value).Item1;
RightValue = DataConvertionExtensions.Convert<TValue, (double, double)>(value).Item2;
}
else
{
RightValue = DataConvertionExtensions.Convert<TValue, double>(value);
}
}
private bool IsLeftAndRightChanged(TValue value)
{
(double, double) typedValue = DataConvertionExtensions.Convert<TValue, (double, double)>(value);
return (typedValue.Item1 != LeftValue) && (typedValue.Item2 != RightValue);
}
private TValue _value;
/// <summary>
/// Gets or sets the value of the input. This should be used with two-way binding.
/// </summary>
/// <example>
/// @bind-Value="model.PropertyName"
/// </example>
[Parameter]
public sealed override TValue Value
{
get { return _value; }
set
{
TValue orderedValue = SortValue(value);
var hasChanged = !EqualityComparer<TValue>.Default.Equals(orderedValue, Value);
if (hasChanged)
{
_value = orderedValue;
OnValueChange(orderedValue);
}
}
}
private TValue SortValue(TValue value)
{
TValue orderedValue = value;
if (Range)
{
//sort if needed
(double, double) typedValue = DataConvertionExtensions.Convert<TValue, (double, double)>(value);
if (typedValue.Item1 > typedValue.Item2)
{
orderedValue = DataConvertionExtensions.Convert<(double, double), TValue>((typedValue.Item2, typedValue.Item1));
}
}
return orderedValue;
}
2020-04-30 01:21:06 +08:00
}
}