Switch
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/SpinnerDocumentation.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/SpinnerDocumentation.razor
new file mode 100644
index 000000000..cdf7cdb15
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/SpinnerDocumentation.razor
@@ -0,0 +1,64 @@
+@page "/spinner"
+
+@title
+
+
+
+Blazor Spinner
+
+ Visualize the loading state of a component or page using the Blazor Bootstrap Spinner component.
+
+
+@* *@
+
+
+Use the border spinners for a lightweight loading indicator.
+
+
+
+
+ The border spinner's border color inherits the element's color (currentColor
). This means you can easily customize the spinner's color by changing the Color
parameter on the standard spinner.
+
+
+
+
+
+ If you don't fancy a border spinner, switch to the grow spinner, while it doesn't technically spin, it does repeatedly grow!
+
+
+
+
+
+The loading dots are a special indicator for a lightweight loading indicator.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@code{
+ private string pageUrl = "/spinner";
+ private string title = "Blazor Spinner Component";
+ private string description = "Visualize the loading state of a component or page using the Blazor Bootstrap Spinner component.";
+ private string imageUrl = "https://i.imgur.com/273TamX.png"; // TODO: update this
+}
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_01_Border_Spinner.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_01_Border_Spinner.razor
new file mode 100644
index 000000000..19883cb3f
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_01_Border_Spinner.razor
@@ -0,0 +1 @@
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_02_Colors.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_02_Colors.razor
new file mode 100644
index 000000000..d8269f61a
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_02_Colors.razor
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_03_Grow_spinner_A.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_03_Grow_spinner_A.razor
new file mode 100644
index 000000000..b937167d8
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_03_Grow_spinner_A.razor
@@ -0,0 +1 @@
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_03_Grow_spinner_B.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_03_Grow_spinner_B.razor
new file mode 100644
index 000000000..c11ad48de
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_03_Grow_spinner_B.razor
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_04_Loading_dots_spinner_A.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_04_Loading_dots_spinner_A.razor
new file mode 100644
index 000000000..13eb71bbf
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_04_Loading_dots_spinner_A.razor
@@ -0,0 +1 @@
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_04_Loading_dots_spinner_B.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_04_Loading_dots_spinner_B.razor
new file mode 100644
index 000000000..38bed6132
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_04_Loading_dots_spinner_B.razor
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_A_Margin.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_A_Margin.razor
new file mode 100644
index 000000000..610f53f16
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_A_Margin.razor
@@ -0,0 +1 @@
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_B_Palcement_Flex_01.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_B_Palcement_Flex_01.razor
new file mode 100644
index 000000000..a1bc75cfe
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_B_Palcement_Flex_01.razor
@@ -0,0 +1,3 @@
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_B_Palcement_Flex_02.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_B_Palcement_Flex_02.razor
new file mode 100644
index 000000000..dabeecfb8
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_B_Palcement_Flex_02.razor
@@ -0,0 +1,4 @@
+
+ Loading...
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_C_Palcement_Floats.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_C_Palcement_Floats.razor
new file mode 100644
index 000000000..cfac61c99
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_C_Palcement_Floats.razor
@@ -0,0 +1,3 @@
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_D_Palcement_Text_align.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_D_Palcement_Text_align.razor
new file mode 100644
index 000000000..a26a69e1b
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_05_Alignment_D_Palcement_Text_align.razor
@@ -0,0 +1,3 @@
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_A_Border.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_A_Border.razor
new file mode 100644
index 000000000..6f43beb0f
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_A_Border.razor
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_B_Grow.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_B_Grow.razor
new file mode 100644
index 000000000..86b6883e9
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_B_Grow.razor
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_C_Dots.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_C_Dots.razor
new file mode 100644
index 000000000..0d13af404
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_06_Size_C_Dots.razor
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_07_Visible.razor b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_07_Visible.razor
new file mode 100644
index 000000000..f15cc5ae0
--- /dev/null
+++ b/BlazorBootstrap.Demo.RCL/Pages/Spinner/Spinner_Demo_07_Visible.razor
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+@code {
+ private bool visible = true;
+
+ private void Hide() => visible = false;
+
+ private void Show() => visible = true;
+}
diff --git a/BlazorBootstrap.Demo.RCL/Shared/MainLayout.razor.cs b/BlazorBootstrap.Demo.RCL/Shared/MainLayout.razor.cs
index 016dd643f..63bd27569 100644
--- a/BlazorBootstrap.Demo.RCL/Shared/MainLayout.razor.cs
+++ b/BlazorBootstrap.Demo.RCL/Shared/MainLayout.razor.cs
@@ -66,9 +66,10 @@ private IEnumerable GetNavItems()
new (){ Id = "518", Text = "Progress", Href = "/progress", IconName = IconName.UsbC, ParentId = "5" },
new (){ Id = "519", Text = "Script Loader", Href = "/script-loader", IconName = IconName.CodeSlash, ParentId = "5" },
new (){ Id = "520", Text = "Sidebar", Href = "/sidebar", IconName = IconName.LayoutSidebar, ParentId = "5" },
- new (){ Id = "521", Text = "Tabs", Href = "/tabs", IconName = IconName.WindowPlus, ParentId = "5" },
- new (){ Id = "522", Text = "Toasts", Href = "/toasts", IconName = IconName.ExclamationTriangleFill, ParentId = "5" },
- new (){ Id = "523", Text = "Tooltips", Href = "/tooltips", IconName = IconName.ChatSquareDotsFill, ParentId = "5" },
+ new (){ Id = "521", Text = "Spinner", Href = "/spinner", IconName = IconName.ArrowRepeat, ParentId = "5" },
+ new (){ Id = "522", Text = "Tabs", Href = "/tabs", IconName = IconName.WindowPlus, ParentId = "5" },
+ new (){ Id = "523", Text = "Toasts", Href = "/toasts", IconName = IconName.ExclamationTriangleFill, ParentId = "5" },
+ new (){ Id = "524", Text = "Tooltips", Href = "/tooltips", IconName = IconName.ChatSquareDotsFill, ParentId = "5" },
new (){ Id = "6", Text = "Data Visualization", IconName = IconName.BarChartFill, IconColor = IconColor.Warning },
new (){ Id = "600", Text = "Bar Chart", Href = "/charts/bar-chart", IconName = IconName.BarChartFill, ParentId = "6", Match = NavLinkMatch.All },
diff --git a/blazorbootstrap/Components/Spinner/Spinner.razor b/blazorbootstrap/Components/Spinner/Spinner.razor
new file mode 100644
index 000000000..01424d629
--- /dev/null
+++ b/blazorbootstrap/Components/Spinner/Spinner.razor
@@ -0,0 +1,24 @@
+@namespace BlazorBootstrap
+@inherits BlazorBootstrapComponentBase
+
+@if (Visible)
+{
+ @if (Type == SpinnerType.Dots)
+ {
+
+ }
+ else
+ {
+
+ @VisuallyHiddenText
+
+ }
+}
diff --git a/blazorbootstrap/Components/Spinner/Spinner.razor.cs b/blazorbootstrap/Components/Spinner/Spinner.razor.cs
new file mode 100644
index 000000000..afaf82437
--- /dev/null
+++ b/blazorbootstrap/Components/Spinner/Spinner.razor.cs
@@ -0,0 +1,138 @@
+namespace BlazorBootstrap;
+
+public partial class Spinner : BlazorBootstrapComponentBase
+{
+ #region Fields and Constants
+
+ private SpinnerColor color = SpinnerColor.None;
+
+ private SpinnerType type = SpinnerType.Border;
+
+ #endregion
+
+ #region Methods
+
+ ///
+ protected override void BuildClasses(CssClassBuilder builder)
+ {
+ builder.Append(BootstrapClassProvider.Spinner(Type));
+ builder.Append(BootstrapClassProvider.Spinner(Color));
+ builder.Append(BootstrapClassProvider.Spinner(Type, Size), Type is (SpinnerType.Border or SpinnerType.Grow));
+
+ base.BuildClasses(builder);
+ }
+
+ protected override void OnInitialized()
+ {
+ Attributes ??= new Dictionary();
+
+ if (Type != SpinnerType.Dots)
+ {
+ if (string.IsNullOrWhiteSpace(Title))
+ Attributes.Remove("title");
+ else if (!Attributes.TryGetValue("title", out _))
+ Attributes.Add("title", Title);
+ else if (Attributes.TryGetValue("title", out _))
+ Attributes["title"] = Title;
+ }
+
+ base.OnInitialized();
+ }
+
+ ///
+ /// Calculates width, height, and circles information for the spinner SVG.
+ ///
+ /// A tuple containing width, height, and a list of spinner circles.
+ private (int Width, int Height, List Circles) GetSpinnerSvgInfo()
+ {
+ // Calculate radius based on Size
+ var radius = 4; // default: SpinnerSize.Medium
+
+ if (Size == SpinnerSize.Small)
+ radius = 2;
+ else if (Size == SpinnerSize.Large)
+ radius = 6;
+ else if (Size == SpinnerSize.ExtraLarge)
+ radius = 8;
+
+ var defaultSpace = 4;
+
+ // Calculate other dimensions based on radius
+ var diameter = 2 * radius;
+
+ var circle1 = new SpinnerCircle(radius, radius, diameter);
+ var circle2 = new SpinnerCircle(radius, circle1.Cx + diameter + defaultSpace, diameter);
+ var circle3 = new SpinnerCircle(radius, circle2.Cx + diameter + defaultSpace, diameter);
+
+ var width = defaultSpace + diameter * 3 + defaultSpace;
+ var height = defaultSpace + diameter + defaultSpace;
+
+ return (width, height, new List { circle1, circle2, circle3 });
+ }
+
+ #endregion
+
+ #region Properties, Indexers
+
+ ///
+ protected override bool ShouldAutoGenerateId => true;
+
+ ///
+ /// Gets or sets the color of the spinner.
+ ///
+ [Parameter]
+ public SpinnerColor Color
+ {
+ get => color;
+ set
+ {
+ color = value;
+ DirtyClasses();
+ }
+ }
+
+ ///
+ /// Gets or sets the size of the spinner.
+ ///
+ [Parameter]
+ public SpinnerSize Size { get; set; } = SpinnerSize.Medium;
+
+ ///
+ /// Gets the width, height, and circles information for the spinner SVG.
+ ///
+ private (int Width, int Height, List Circles) SpinnerSvg => GetSpinnerSvgInfo();
+
+ ///
+ /// Gets or sets the title text used as an accessibility attribute.
+ ///
+ [Parameter]
+ public string? Title { get; set; }
+
+ ///
+ /// Gets or sets the type of the spinner.
+ ///
+ [Parameter]
+ public SpinnerType Type
+ {
+ get => type;
+ set
+ {
+ type = value;
+ DirtyClasses();
+ }
+ }
+
+ ///
+ /// Gets or sets whether the spinner is visible or not.
+ ///
+ [Parameter]
+ public bool Visible { get; set; } = true;
+
+ ///
+ /// Gets or sets the visually hidden text.
+ ///
+ [Parameter]
+ public string? VisuallyHiddenText { get; set; } = "Loading...";
+
+ #endregion
+}
diff --git a/blazorbootstrap/Components/Spinner/Spinner.razor.css b/blazorbootstrap/Components/Spinner/Spinner.razor.css
new file mode 100644
index 000000000..b7e248257
--- /dev/null
+++ b/blazorbootstrap/Components/Spinner/Spinner.razor.css
@@ -0,0 +1,88 @@
+/* scss-docs-start spinner-dots-keyframes */
+@keyframes spinner-dots {
+ 0% {
+ opacity: 1;
+ }
+
+ 50%, 100% {
+ opacity: .3;
+ }
+}
+
+/* scss-docs-end spinner-dots-keyframes */
+.spinner-dots {
+ user-select: none;
+}
+
+ .spinner-dots > circle:first-of-type,
+ .spinner-dots > circle:last-of-type,
+ .spinner-dots > circle:nth-of-type(2) {
+ fill: currentcolor;
+ animation: spinner-dots .75s infinite ease-in-out alternate;
+ }
+
+ .spinner-dots > circle:nth-of-type(2) {
+ animation-delay: .25s;
+ }
+
+ .spinner-dots > circle:last-of-type {
+ animation-delay: .5s;
+ }
+
+/* Size: START */
+
+/* default */
+.spinner-border-sm {
+ --bs-spinner-width: 1rem;
+ --bs-spinner-height: 1rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+/* custom CSS classes */
+.spinner-border-md {
+ --bs-spinner-width: 2rem;
+ --bs-spinner-height: 2rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+.spinner-border-lg {
+ --bs-spinner-width: 3rem;
+ --bs-spinner-height: 3rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+.spinner-border-xl {
+ --bs-spinner-width: 4rem;
+ --bs-spinner-height: 4rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+
+/* default */
+.spinner-grow-sm {
+ --bs-spinner-width: 1rem;
+ --bs-spinner-height: 1rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+/* custom CSS classes */
+.spinner-grow-md {
+ --bs-spinner-width: 2rem;
+ --bs-spinner-height: 2rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+.spinner-grow-lg {
+ --bs-spinner-width: 3rem;
+ --bs-spinner-height: 3rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+.spinner-grow-xl {
+ --bs-spinner-width: 4rem;
+ --bs-spinner-height: 4rem;
+ --bs-spinner-border-width: 0.25em;
+ --bs-spinner-vertical-align: -0.125em;
+}
+
+/* Size: END */
\ No newline at end of file
diff --git a/blazorbootstrap/Enums/SpinnerSize.cs b/blazorbootstrap/Enums/SpinnerSize.cs
new file mode 100644
index 000000000..9fc6f1708
--- /dev/null
+++ b/blazorbootstrap/Enums/SpinnerSize.cs
@@ -0,0 +1,24 @@
+namespace BlazorBootstrap;
+
+public enum SpinnerSize
+{
+ ///
+ /// Makes an element small size.
+ ///
+ Small,
+
+ ///
+ /// Makes an element medium size.
+ ///
+ Medium,
+
+ ///
+ /// Makes an element large.
+ ///
+ Large,
+
+ ///
+ /// Makes an element extra large.
+ ///
+ ExtraLarge
+}
diff --git a/blazorbootstrap/Enums/SpinnerType.cs b/blazorbootstrap/Enums/SpinnerType.cs
new file mode 100644
index 000000000..ab1968da5
--- /dev/null
+++ b/blazorbootstrap/Enums/SpinnerType.cs
@@ -0,0 +1,8 @@
+namespace BlazorBootstrap;
+
+public enum SpinnerType
+{
+ Border,
+ Grow,
+ Dots
+}
diff --git a/blazorbootstrap/Models/SpinnerCircle.cs b/blazorbootstrap/Models/SpinnerCircle.cs
new file mode 100644
index 000000000..5e82c6e2b
--- /dev/null
+++ b/blazorbootstrap/Models/SpinnerCircle.cs
@@ -0,0 +1,3 @@
+namespace BlazorBootstrap;
+
+public record SpinnerCircle(int Radius, int Cx, int Cy);
\ No newline at end of file
diff --git a/blazorbootstrap/Utilities/BootstrapClassProvider.cs b/blazorbootstrap/Utilities/BootstrapClassProvider.cs
index d38306d60..4d4637642 100644
--- a/blazorbootstrap/Utilities/BootstrapClassProvider.cs
+++ b/blazorbootstrap/Utilities/BootstrapClassProvider.cs
@@ -169,6 +169,11 @@ public class BootstrapClassProvider
public string ProgressBarStriped() => $"{ProgressBar()}-striped";
public string Show() => "show";
+
+ public string Spinner() => "spinner";
+ public string Spinner(SpinnerColor color) => ToSpinnerColor(color)!;
+ public string Spinner(SpinnerType type) => $"{Spinner()}-{ToSpinnerType(type)}";
+ public string Spinner(SpinnerType type, SpinnerSize size) => $"{Spinner(type)}-{ToSpinnerSize(size)}";
public string Table() => "table";
public string TableActive() => "table-active";
@@ -601,6 +606,39 @@ public string ToPosition(Position position) =>
_ => null
};
+ public string? ToSpinnerColor(SpinnerColor color) =>
+ color switch
+ {
+ SpinnerColor.Primary => "text-primary",
+ SpinnerColor.Secondary => "text-secondary",
+ SpinnerColor.Success => "text-success",
+ SpinnerColor.Danger => "text-danger",
+ SpinnerColor.Warning => "text-warning",
+ SpinnerColor.Info => "text-info",
+ SpinnerColor.Light => "text-light",
+ SpinnerColor.Dark => "text-dark",
+ _ => null
+ };
+
+ public string ToSpinnerSize(SpinnerSize size) =>
+ size switch
+ {
+ SpinnerSize.Small => "sm",
+ SpinnerSize.Medium => "md",
+ SpinnerSize.Large => "lg",
+ SpinnerSize.ExtraLarge => "xl",
+ _ => "md"
+ };
+
+ public string ToSpinnerType(SpinnerType type) =>
+ type switch
+ {
+ SpinnerType.Border => "border",
+ SpinnerType.Grow => "grow",
+ SpinnerType.Dots => "dots",
+ _ => "border"
+ };
+
public string? ToTabColor(TabColor color) =>
color switch
{
diff --git a/blazorbootstrap/Utilities/BootstrapStyleProvider.cs b/blazorbootstrap/Utilities/BootstrapStyleProvider.cs
new file mode 100644
index 000000000..9a9a92cea
--- /dev/null
+++ b/blazorbootstrap/Utilities/BootstrapStyleProvider.cs
@@ -0,0 +1,10 @@
+namespace BlazorBootstrap;
+
+public class BootstrapStyleProvider
+{
+ #region Methods
+
+ // TODO: place holder for custom styles
+
+ #endregion
+}
diff --git a/docs/blog/2024-02-04-blazorbootstrap-1.11.0.md b/docs/blog/2024-02-04-blazorbootstrap-1.11.0.md
index ef154472e..a37c2e6eb 100644
--- a/docs/blog/2024-02-04-blazorbootstrap-1.11.0.md
+++ b/docs/blog/2024-02-04-blazorbootstrap-1.11.0.md
@@ -16,15 +16,15 @@ We are excited to release version 1.11.0, featuring new PDF Viewer, Range Input,
## What's New
-- 'PDF Viewer' component
+- `PDF Viewer` component
- Allows users to view PDF files directly in the browser, eliminating the need for third-party browser tools or extensions.
- Supports two callback events: OnDocumentLoaded and OnPageChanged
-- 'Range Input' component
+- `Range Input` component
- Disabled
- Min and Max
- Step
- Tick marks
-- 'Script Loader' component
+- `Script Loader` component
- Allows users to load JS sctipt files dynamically on the fly.
## What's changed