Add Carousel

This commit is contained in:
CHINBOY
2025-09-22 18:47:52 +08:00
parent d2c45f1fad
commit a598f52374
17 changed files with 838 additions and 1 deletions
@@ -6,7 +6,6 @@ namespace AtomUI.Controls;
public interface IWaveSpiritAwareControl : IMotionAwareControl
{
bool IsWaveSpiritEnabled { get; }
// Color WaveSpiritColor { get; }
}
public abstract class WaveSpiritAwareControlProperty : MotionAwareControlProperty
@@ -17,6 +17,7 @@
<ResourceInclude Source="CheckBox/Themes/CheckBoxThemes.axaml" />
<ResourceInclude Source="Chrome/Themes/ChromeThemes.axaml" />
<ResourceInclude Source="Card/Themes/CardThemes.axaml" />
<ResourceInclude Source="Carousel/Themes/CarouselThemes.axaml" />
<ResourceInclude Source="Collapse/Themes/CollapseItemThemes.axaml" />
<ResourceInclude Source="ComboBox/Themes/ComboBoxThemes.axaml" />
<ResourceInclude Source="DatePicker/Themes/DatePickerThemes.axaml" />
+226
View File
@@ -0,0 +1,226 @@
using AtomUI.Controls.Themes;
using AtomUI.Theme;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
namespace AtomUI.Controls;
public class Carousel : SelectingItemsControl,
IControlSharedTokenResourcesHost,
IMotionAwareControl
{
#region 公共属性定义
public static readonly StyledProperty<bool> IsShowNavButtonsProperty =
AvaloniaProperty.Register<Carousel, bool>(nameof(IsShowNavButtons));
public static readonly StyledProperty<bool> IsAutoPlayProperty =
AvaloniaProperty.Register<Carousel, bool>(nameof(IsAutoPlay));
public static readonly StyledProperty<TimeSpan> AutoPlaySpeedProperty =
AvaloniaProperty.Register<Carousel, TimeSpan>(nameof(AutoPlaySpeed), TimeSpan.FromMilliseconds(3000));
public static readonly StyledProperty<CarouselPaginationPosition> PaginationPositionProperty =
AvaloniaProperty.Register<Carousel, CarouselPaginationPosition>(nameof(PaginationPosition), CarouselPaginationPosition.Bottom);
public static readonly StyledProperty<bool> IsShowPaginationProperty =
AvaloniaProperty.Register<Carousel, bool>(nameof(IsShowPagination));
public static readonly StyledProperty<bool> IsDraggableProperty =
AvaloniaProperty.Register<Carousel, bool>(nameof(IsDraggable));
public static readonly StyledProperty<bool> IsInfiniteProperty =
AvaloniaProperty.Register<Carousel, bool>(nameof(IsInfinite));
public static readonly StyledProperty<TimeSpan> PageTransitionDurationProperty =
AvaloniaProperty.Register<Carousel, TimeSpan>(nameof(PageTransitionDuration));
public static readonly StyledProperty<Easing> PageInEasingProperty =
AvaloniaProperty.Register<Carousel, Easing>(nameof(PageInEasing));
public static readonly StyledProperty<Easing> PageOutEasingProperty =
AvaloniaProperty.Register<Carousel, Easing>(nameof(PageOutEasing));
public static readonly StyledProperty<CarouselTransitionEffect> TransitionEffectProperty =
AvaloniaProperty.Register<Carousel, CarouselTransitionEffect>(nameof(TransitionEffect));
public static readonly StyledProperty<bool> IsMotionEnabledProperty =
MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<Carousel>();
public bool IsShowNavButtons
{
get => GetValue(IsShowNavButtonsProperty);
set => SetValue(IsShowNavButtonsProperty, value);
}
public bool IsAutoPlay
{
get => GetValue(IsAutoPlayProperty);
set => SetValue(IsAutoPlayProperty, value);
}
public TimeSpan AutoPlaySpeed
{
get => GetValue(AutoPlaySpeedProperty);
set => SetValue(AutoPlaySpeedProperty, value);
}
public CarouselPaginationPosition PaginationPosition
{
get => GetValue(PaginationPositionProperty);
set => SetValue(PaginationPositionProperty, value);
}
public bool IsShowPagination
{
get => GetValue(IsShowPaginationProperty);
set => SetValue(IsShowPaginationProperty, value);
}
public bool IsDraggable
{
get => GetValue(IsDraggableProperty);
set => SetValue(IsDraggableProperty, value);
}
public bool IsInfinite
{
get => GetValue(IsInfiniteProperty);
set => SetValue(IsInfiniteProperty, value);
}
public TimeSpan PageTransitionDuration
{
get => GetValue(PageTransitionDurationProperty);
set => SetValue(PageTransitionDurationProperty, value);
}
public Easing PageInEasing
{
get => GetValue(PageInEasingProperty);
set => SetValue(PageInEasingProperty, value);
}
public Easing PageOutEasing
{
get => GetValue(PageOutEasingProperty);
set => SetValue(PageOutEasingProperty, value);
}
public CarouselTransitionEffect TransitionEffect
{
get => GetValue(TransitionEffectProperty);
set => SetValue(TransitionEffectProperty, value);
}
public bool IsMotionEnabled
{
get => GetValue(IsMotionEnabledProperty);
set => SetValue(IsMotionEnabledProperty, value);
}
#endregion
#region 内部属性定义
internal static readonly StyledProperty<IPageTransition?> PageTransitionProperty =
AvaloniaProperty.Register<Carousel, IPageTransition?>(nameof(PageTransition));
internal static readonly DirectProperty<Carousel, bool> PreviousNavButtonVisibleProperty =
AvaloniaProperty.RegisterDirect<Carousel, bool>(
nameof(PreviousNavButtonVisible),
o => o.PreviousNavButtonVisible,
(o, v) => o.PreviousNavButtonVisible = v);
internal static readonly DirectProperty<Carousel, bool> NextNavButtonVisibleProperty =
AvaloniaProperty.RegisterDirect<Carousel, bool>(
nameof(NextNavButtonVisible),
o => o.NextNavButtonVisible,
(o, v) => o.NextNavButtonVisible = v);
private static readonly FuncTemplate<Panel?> DefaultPanel =
new(() => new VirtualizingCarouselPanel());
public IPageTransition? PageTransition
{
get => GetValue(PageTransitionProperty);
set => SetValue(PageTransitionProperty, value);
}
private bool _previousNavButtonVisible;
internal bool PreviousNavButtonVisible
{
get => _previousNavButtonVisible;
set => SetAndRaise(PreviousNavButtonVisibleProperty, ref _previousNavButtonVisible, value);
}
private bool _nextNavButtonVisible;
internal bool NextNavButtonVisible
{
get => _nextNavButtonVisible;
set => SetAndRaise(NextNavButtonVisibleProperty, ref _nextNavButtonVisible, value);
}
Control IMotionAwareControl.PropertyBindTarget => this;
Control IControlSharedTokenResourcesHost.HostControl => this;
string IControlSharedTokenResourcesHost.TokenId => CarouselToken.ID;
#endregion
private IScrollable? _scroller;
static Carousel()
{
SelectionModeProperty.OverrideDefaultValue<Carousel>(SelectionMode.AlwaysSelected);
ItemsPanelProperty.OverrideDefaultValue<Carousel>(DefaultPanel);
}
public void Next()
{
if (SelectedIndex < ItemCount - 1)
{
++SelectedIndex;
}
}
public void Previous()
{
if (SelectedIndex > 0)
{
--SelectedIndex;
}
}
protected override Size ArrangeOverride(Size finalSize)
{
var result = base.ArrangeOverride(finalSize);
if (_scroller is not null)
{
_scroller.Offset = new(SelectedIndex, 0);
}
return result;
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_scroller = e.NameScope.Find<IScrollable>(CarouselThemeConstants.ScrollViewerPart);
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == SelectedIndexProperty && _scroller is not null)
{
var value = change.GetNewValue<int>();
_scroller.Offset = new(value, 0);
}
}
}
@@ -0,0 +1,15 @@
namespace AtomUI.Controls;
public enum CarouselPaginationPosition
{
Top,
Bottom,
Left,
Right
}
public enum CarouselTransitionEffect
{
Scroll,
Fade
}
@@ -0,0 +1,8 @@
using Avalonia.Controls;
namespace AtomUI.Controls;
public class CarouselPage : ContentControl
{
}
@@ -0,0 +1,8 @@
using Avalonia.Controls.Primitives;
namespace AtomUI.Controls;
internal class CarouselPageIndicator : TemplatedControl
{
}
@@ -0,0 +1,8 @@
using Avalonia.Controls.Primitives;
namespace AtomUI.Controls;
internal class CarouselPagination : TemplatedControl
{
}
@@ -0,0 +1,68 @@
using AtomUI.Theme.TokenSystem;
namespace AtomUI.Controls;
[ControlDesignToken]
internal class CarouselToken : AbstractControlDesignToken
{
public const string ID = "Carousel";
public CarouselToken()
: base(ID)
{
}
/// <summary>
/// 指示点宽度
/// Width of indicator
/// </summary>
public double IndicatorWidth { get; set; }
/// <summary>
/// 指示点高度
/// Height of indicator
/// </summary>
public double IndicatorHeight { get; set; }
/// <summary>
/// 指示点之间的间距
/// gap between indicator
/// </summary>
public double IndicatorGap { get; set; }
/// <summary>
/// 指示点距离边缘的距离
/// dot offset to Carousel edge
/// </summary>
public double IndicatorOffset { get; set; }
/// <summary>
/// 激活态指示点宽度
/// Width of active indicator
/// </summary>
public double IndicatorActiveWidth { get; set; }
/// <summary>
/// 切换箭头大小
/// Size of arrows
/// </summary>
public double ArrowSize { get; set; }
/// <summary>
/// 切换箭头边距
/// arrows offset to Carousel edge
/// </summary>
public double ArrowOffset { get; set; }
public override void CalculateFromAlias()
{
base.CalculateFromAlias();
IndicatorActiveWidth = 24;
ArrowSize = 16;
ArrowOffset = SharedToken.SpacingXS;
IndicatorWidth = 16;
IndicatorHeight = 3;
IndicatorGap = SharedToken.SpacingXXS;
IndicatorOffset = 12;
}
}
@@ -0,0 +1,13 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:atom="https://atomui.net"
x:ClassModifier="internal">
<ControlTheme x:Key="{x:Type atom:CarouselPageIndicator}" TargetType="atom:CarouselPageIndicator">
<Setter Property="Template">
<ControlTemplate>
</ControlTemplate>
</Setter>
</ControlTheme>
</ResourceDictionary>
@@ -0,0 +1,19 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:atom="https://atomui.net"
x:ClassModifier="internal">
<ControlTheme x:Key="{x:Type atom:CarouselPage}" TargetType="atom:CarouselPage">
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="ContentPresenter"
Margin="{TemplateBinding Margin}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</ControlTemplate>
</Setter>
</ControlTheme>
</ResourceDictionary>
@@ -0,0 +1,6 @@
namespace AtomUI.Controls.Themes;
internal static class CarouselThemeConstants
{
public const string ScrollViewerPart = "PART_ScrollViewer";
}
@@ -0,0 +1,13 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:atom="https://atomui.net"
x:ClassModifier="internal">
<ControlTheme x:Key="{x:Type atom:CarouselPagination}" TargetType="atom:CarouselPagination">
<Setter Property="Template">
<ControlTemplate>
</ControlTemplate>
</Setter>
</ControlTheme>
</ResourceDictionary>
@@ -0,0 +1,29 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:atom="https://atomui.net"
x:ClassModifier="internal">
<ControlTheme x:Key="{x:Type atom:Carousel}" TargetType="atom:Carousel">
<Setter Property="Template">
<ControlTemplate>
<Panel>
<ScrollViewer Name="{x:Static atom:CarouselThemeConstants.ScrollViewerPart}"
Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<ItemsPresenter
Name="PART_ItemsPresenter"
Margin="{TemplateBinding Padding}"
ItemsPanel="{TemplateBinding ItemsPanel}" />
</ScrollViewer>
<atom:IconButton Name="PreviousPageButton"/>
<atom:IconButton Name="NextPageButton"/>
<atom:CarouselPagination Name="Pagination"/>
</Panel>
</ControlTemplate>
</Setter>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</ControlTheme>
</ResourceDictionary>
@@ -0,0 +1,10 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="CarouselPageIndicatorTheme.axaml"/>
<ResourceInclude Source="CarouselPaginationTheme.axaml"/>
<ResourceInclude Source="CarouselPageTheme.axaml"/>
<ResourceInclude Source="CarouselTheme.axaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -0,0 +1,402 @@
using System.Collections.Specialized;
using System.Diagnostics;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
namespace AtomUI.Controls;
internal class VirtualizingCarouselPanel: VirtualizingPanel, ILogicalScrollable
{
private static readonly AttachedProperty<object?> RecycleKeyProperty =
AvaloniaProperty.RegisterAttached<VirtualizingStackPanel, Control, object?>("RecycleKey");
private static readonly object ItemIsItsOwnContainer = new object();
private Size _extent;
private Vector _offset;
private Size _viewport;
private Dictionary<object, Stack<Control>>? _recyclePool;
private Control? _realized;
private int _realizedIndex = -1;
private Control? _transitionFrom;
private int _transitionFromIndex = -1;
private CancellationTokenSource? _transition;
private EventHandler? _scrollInvalidated;
bool ILogicalScrollable.CanHorizontallyScroll { get; set; }
bool ILogicalScrollable.CanVerticallyScroll { get; set; }
bool ILogicalScrollable.IsLogicalScrollEnabled => true;
Size ILogicalScrollable.ScrollSize => new(1, 1);
Size ILogicalScrollable.PageScrollSize => new(1, 1);
Size IScrollable.Extent => Extent;
Size IScrollable.Viewport => Viewport;
Vector IScrollable.Offset
{
get => _offset;
set
{
if ((int)_offset.X != value.X)
{
InvalidateMeasure();
}
_offset = value;
}
}
private Size Extent
{
get => _extent;
set
{
if (_extent != value)
{
_extent = value;
_scrollInvalidated?.Invoke(this, EventArgs.Empty);
}
}
}
private Size Viewport
{
get => _viewport;
set
{
if (_viewport != value)
{
_viewport = value;
_scrollInvalidated?.Invoke(this, EventArgs.Empty);
}
}
}
event EventHandler? ILogicalScrollable.ScrollInvalidated
{
add => _scrollInvalidated += value;
remove => _scrollInvalidated -= value;
}
bool ILogicalScrollable.BringIntoView(Control target, Rect targetRect) => false;
Control? ILogicalScrollable.GetControlInDirection(NavigationDirection direction, Control? from) => null;
void ILogicalScrollable.RaiseScrollInvalidated(EventArgs e) => _scrollInvalidated?.Invoke(this, e);
protected override Size MeasureOverride(Size availableSize)
{
var items = Items;
var index = (int)_offset.X;
if (index != _realizedIndex)
{
if (_realized is not null)
{
var cancelTransition = _transition is not null;
// Cancel any already running transition, and recycle the element we're transitioning from.
if (cancelTransition)
{
_transition!.Cancel();
_transition = null;
if (_transitionFrom is not null)
RecycleElement(_transitionFrom);
_transitionFrom = null;
_transitionFromIndex = -1;
}
if (cancelTransition || GetTransition() is null)
{
// If don't have a transition or we've just canceled a transition then recycle the element
// we're moving from.
RecycleElement(_realized);
}
else
{
// We have a transition to do: record the current element as the element we're transitioning
// from and we'll start the transition in the arrange pass.
_transitionFrom = _realized;
_transitionFromIndex = _realizedIndex;
}
_realized = null;
_realizedIndex = -1;
}
// Get or create an element for the new item.
if (index >= 0 && index < items.Count)
{
_realized = GetOrCreateElement(items, index);
_realizedIndex = index;
}
}
if (_realized is null)
{
Extent = Viewport = new(0, 0);
_transitionFrom = null;
_transitionFromIndex = -1;
return default;
}
_realized.Measure(availableSize);
Extent = new(items.Count, 1);
Viewport = new(1, 1);
return _realized.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
var result = base.ArrangeOverride(finalSize);
if (_transition is null &&
_transitionFrom is not null &&
_realized is { } to &&
GetTransition() is { } transition)
{
_transition = new CancellationTokenSource();
var forward = (_realizedIndex > _transitionFromIndex);
if (Items.Count > 2)
{
forward = forward || (_transitionFromIndex == Items.Count - 1 && _realizedIndex == 0);
forward = forward && !(_transitionFromIndex == 0 && _realizedIndex == Items.Count - 1);
}
transition.Start(_transitionFrom, to, forward, _transition.Token)
.ContinueWith(TransitionFinished, TaskScheduler.FromCurrentSynchronizationContext());
}
return result;
}
protected override IInputElement? GetControl(NavigationDirection direction, IInputElement? from, bool wrap) => null;
protected override Control? ContainerFromIndex(int index)
{
if (index < 0 || index >= Items.Count)
return null;
if (index == _realizedIndex)
return _realized;
if (Items[index] is Control c && c.GetValue(RecycleKeyProperty) == ItemIsItsOwnContainer)
return c;
return null;
}
protected override IEnumerable<Control>? GetRealizedContainers()
{
return _realized is not null ? new[] { _realized } : null;
}
protected override int IndexFromContainer(Control container)
{
return container == _realized ? _realizedIndex : -1;
}
protected override Control? ScrollIntoView(int index)
{
return null;
}
protected override void OnItemsChanged(IReadOnlyList<object?> items, NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(items, e);
void Add(int index, int count)
{
if (index <= _realizedIndex)
_realizedIndex += count;
}
void Remove(int index, int count)
{
var end = index + (count - 1);
if (_realized is not null && index <= _realizedIndex && end >= _realizedIndex)
{
RecycleElement(_realized);
_realized = null;
_realizedIndex = -1;
}
else if (index < _realizedIndex)
{
_realizedIndex -= count;
}
}
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
Add(e.NewStartingIndex, e.NewItems!.Count);
break;
case NotifyCollectionChangedAction.Remove:
Remove(e.OldStartingIndex, e.OldItems!.Count);
break;
case NotifyCollectionChangedAction.Replace:
if (e.OldStartingIndex < 0)
{
goto case NotifyCollectionChangedAction.Reset;
}
Remove(e.OldStartingIndex, e.OldItems!.Count);
Add(e.NewStartingIndex, e.NewItems!.Count);
break;
case NotifyCollectionChangedAction.Move:
if (e.OldStartingIndex < 0)
{
goto case NotifyCollectionChangedAction.Reset;
}
Remove(e.OldStartingIndex, e.OldItems!.Count);
var insertIndex = e.NewStartingIndex;
if (e.NewStartingIndex > e.OldStartingIndex)
{
insertIndex -= e.OldItems.Count - 1;
}
Add(insertIndex, e.NewItems!.Count);
break;
case NotifyCollectionChangedAction.Reset:
if (_realized is not null)
{
RecycleElement(_realized);
_realized = null;
_realizedIndex = -1;
}
break;
}
InvalidateMeasure();
}
private Control GetOrCreateElement(IReadOnlyList<object?> items, int index)
{
Debug.Assert(ItemContainerGenerator is not null);
var e = GetRealizedElement(index);
if (e is null)
{
var item = items[index];
var generator = ItemContainerGenerator!;
if (generator.NeedsContainer(item, index, out var recycleKey))
{
e = GetRecycledElement(item, index, recycleKey) ??
CreateElement(item, index, recycleKey);
}
else
{
e = GetItemAsOwnContainer(item, index);
}
}
return e;
}
private Control? GetRealizedElement(int index)
{
return _realizedIndex == index ? _realized : null;
}
private Control GetItemAsOwnContainer(object? item, int index)
{
Debug.Assert(ItemContainerGenerator is not null);
var controlItem = (Control)item!;
var generator = ItemContainerGenerator!;
if (!controlItem.IsSet(RecycleKeyProperty))
{
generator.PrepareItemContainer(controlItem, controlItem, index);
AddInternalChild(controlItem);
controlItem.SetValue(RecycleKeyProperty, ItemIsItsOwnContainer);
generator.ItemContainerPrepared(controlItem, item, index);
}
controlItem.IsVisible = true;
return controlItem;
}
private Control? GetRecycledElement(object? item, int index, object? recycleKey)
{
Debug.Assert(ItemContainerGenerator is not null);
if (recycleKey is null)
return null;
var generator = ItemContainerGenerator!;
if (_recyclePool?.TryGetValue(recycleKey, out var recyclePool) == true && recyclePool.Count > 0)
{
var recycled = recyclePool.Pop();
recycled.IsVisible = true;
generator.PrepareItemContainer(recycled, item, index);
generator.ItemContainerPrepared(recycled, item, index);
return recycled;
}
return null;
}
private Control CreateElement(object? item, int index, object? recycleKey)
{
Debug.Assert(ItemContainerGenerator is not null);
var generator = ItemContainerGenerator!;
var container = generator.CreateContainer(item, index, recycleKey);
container.SetValue(RecycleKeyProperty, recycleKey);
generator.PrepareItemContainer(container, item, index);
AddInternalChild(container);
generator.ItemContainerPrepared(container, item, index);
return container;
}
private void RecycleElement(Control element)
{
Debug.Assert(ItemContainerGenerator is not null);
var recycleKey = element.GetValue(RecycleKeyProperty);
Debug.Assert(recycleKey is not null);
if (recycleKey == ItemIsItsOwnContainer)
{
element.IsVisible = false;
}
else
{
ItemContainerGenerator.ClearItemContainer(element);
_recyclePool ??= new();
if (!_recyclePool.TryGetValue(recycleKey, out var pool))
{
pool = new();
_recyclePool.Add(recycleKey, pool);
}
pool.Push(element);
element.IsVisible = false;
}
}
private IPageTransition? GetTransition() => (ItemsControl as Carousel)?.PageTransition;
private void TransitionFinished(Task task)
{
if (task.IsCanceled)
{
return;
}
if (_transitionFrom is not null)
{
RecycleElement(_transitionFrom);
}
_transition = null;
_transitionFrom = null;
_transitionFromIndex = -1;
}
}
@@ -19,6 +19,7 @@ namespace AtomUI.Theme
tokenTypes.Add(typeof(AtomUI.Controls.ButtonToken));
tokenTypes.Add(typeof(AtomUI.Controls.CalendarToken));
tokenTypes.Add(typeof(AtomUI.Controls.CardToken));
tokenTypes.Add(typeof(AtomUI.Controls.CarouselToken));
tokenTypes.Add(typeof(AtomUI.Controls.CheckBoxToken));
tokenTypes.Add(typeof(AtomUI.Controls.ChromeToken));
tokenTypes.Add(typeof(AtomUI.Controls.CollapseToken));
@@ -211,6 +211,17 @@ namespace AtomUI.Theme.Styling
public static readonly TokenResourceKey TabsMarginBottom = new TokenResourceKey("Card.TabsMarginBottom");
}
public static class CarouselTokenKey
{
public static readonly TokenResourceKey ArrowOffset = new TokenResourceKey("Carousel.ArrowOffset");
public static readonly TokenResourceKey ArrowSize = new TokenResourceKey("Carousel.ArrowSize");
public static readonly TokenResourceKey IndicatorActiveWidth = new TokenResourceKey("Carousel.IndicatorActiveWidth");
public static readonly TokenResourceKey IndicatorGap = new TokenResourceKey("Carousel.IndicatorGap");
public static readonly TokenResourceKey IndicatorHeight = new TokenResourceKey("Carousel.IndicatorHeight");
public static readonly TokenResourceKey IndicatorOffset = new TokenResourceKey("Carousel.IndicatorOffset");
public static readonly TokenResourceKey IndicatorWidth = new TokenResourceKey("Carousel.IndicatorWidth");
}
public static class CheckBoxTokenKey
{
public static readonly TokenResourceKey CheckedMarkSize = new TokenResourceKey("CheckBox.CheckedMarkSize");